(NO.00001)iOS游戏SpeedBoy Lite成形记(二十九):增加排行榜功能2

接下来回到Xcode中,首先在PopupLayer.m中添加justClose方法:

-(void)justClose{
    [self.gameScene removePopup];
}

然后在GameInterface.m中添加showRecords方法:

-(void)showRecords{
    [_gameScene showPopupNamed:@"Layers/RecordsLayer"];
}

接着,在GameScene.m中添加实例变量_recordsLabel.

好了,在GameScene.m中继续添加代码之前我们先考虑一下GameState里对应的记录如何存放以及需要提供什么功能的方法.

我们打算使用字典来存放记录,key为选手的名字(so不应该有重名选手),对应的值就是该选手的最好成绩.我们不想从外面洞悉该记录字典的内容,所以该字典应该是私有变量,我们在GameState.m里添加它:

    NSMutableDictionary *_playerRecords;

我们需要2个方法作为其读取器方法,在GameState.h接口文件中添加:

-(void)addPlayer:(NSString*)playerName;
-(CCTime)playerRecord:(NSString*)playerName;

以下是上面2个方法的实现:

-(void)addPlayer:(NSString *)playerName{
    //设置一个较大值以便被超越 ;)
    CCTime record = 100.f;
    //不重复添加player,在这个例子中没有什么必要.
    if (_playerRecords[playerName]) {
        return;
    }

    [_playerRecords setObject:@(record) forKey:playerName];

}

-(CCTime)playerRecord:(NSString *)playerName{
    NSNumber *record = (NSNumber*)_playerRecords[playerName];
    NSAssert(record, @"No such player!");
    return record.floatValue;
}

我们再添加一个更新选手记录的方法,同样要在头文件里导出:

-(void)updatePlayerRecord:(NSString *)playerName withRecord:(CCTime)record{
    if (!_playerRecords[playerName]) {
        return;
    }

    NSNumber *objRec = (NSNumber*)_playerRecords[playerName];
    if (record < objRec.floatValue) {
        [_playerRecords setObject:@(record) forKey:playerName];
    }
}

功能为如果选手不在字典中直接退出,否则只有当新记录小于旧记录时才更新字典中的值.

下一篇我们实现GameState中最重要的排序功能,see you ;)

时间: 2024-10-22 20:00:42

(NO.00001)iOS游戏SpeedBoy Lite成形记(二十九):增加排行榜功能2的相关文章

(NO.00001)iOS游戏SpeedBoy Lite成形记(二十八):增加排行榜功能

游戏大体上基本也就完成了,还差一个排行榜.否则如何激励各位选手创造新纪录呢? 排行榜功能也没什么难的,不过需要一点点排序的算法上的考虑. 这里我们把排行榜记录数据和排序都放在GameState类中,在GameScene类中只要完成2件事: 1.每次选手到达终点时更新记录 2.玩家点击Record后弹出排行榜菜单窗口,里面按成绩将选手排序. 首先我们打开SpriteBuilder,新建一个菜单窗口: 在Layers文件夹中新建RecordsLayer.ccb文件,类型为Node. 然后拖入背景图片

(NO.00001)iOS游戏SpeedBoy Lite成形记(二十二)

自己的游戏自己更需要多玩,这样才能首先发现不足的地方.所以本猫到现在已经忍一个地方很久了,就是弹出moneyLayer后每次都要输入数字才能关闭,这多少让人不爽.于是本篇我们就修正这个小小的不便. 首先在第一次弹出该窗口时我们随机设置一个合适的数字,如果是第二次弹出该窗口我们只是保持原先的值不便即可. 我们打开PopupLayer.m修改didLoadFromCCB方法: -(void)didLoadFromCCB{ if (_moneyText) { _moneyText.textField.

(NO.00001)iOS游戏SpeedBoy Lite成形记(二十)

下面修改最为关键的matchRun方法里的代码: CCActionCallBlock *blk = [CCActionCallBlock actionWithBlock:^{ _finishedCount++; [player endMatch]; [player stopAction:repeatJump]; [player stopAction:repeatSkew]; [self removeChild:player.streak]; if (_finishedCount == 1) {

(NO.00001)iOS游戏SpeedBoy Lite成形记(二十四)

我们回到Xcode,打开GameScene.m,首先要添加实例变量: CCNode *_trackLine; 为了根据选中的赛道更新_trackLine的位置,我们添加一个显示方法: -(void)selectTrack:(NSInteger)betPlayerIndex{ NSInteger i = PlayerCount - betPlayerIndex; NSValue *value = _trackRects[i]; CGRect rect = value.CGRectValue; _t

(NO.00001)iOS游戏SpeedBoy Lite成形记(二十五)

每次压赌要打开弹出菜单还是让人略觉不爽,下面我们再添加一个随机押注的按钮:自动随机选择选手和下赌金额. 打开spriteBuilder,修改GameInterface.ccb的界面,在Run按钮旁边添加一个新Rnd按钮,设置其回调方法为randomPick: 回到Xcode中,写别忙着写代码.简单考虑下,randomPick最终应该在哪里实现?因为修改betPlayer要在GameScene类里,所以我们应该在GameScene.m中添加该方法. 但是首先我们需要在GameInterface.m

(NO.00001)iOS游戏SpeedBoy Lite成形记(二十六)

到目前为止,选手跑到终点时仿佛没什么激动人心的事情发生呢?貌似需要添加一些胜利的特效啊! 前面说好的不添加特效,只完成游戏功能的诺言呢? T T 我们主要想实现这样一个特效效果: 1.胜利的玩家突出显示在屏幕中心位置 2.玩家激动的jump中 3.玩家背后放射出万丈胜利的光芒 前2个可以用动作来搞定,最后一个需要用粒子效果完成.好在有SpriteBuilder,我们不用写一行代码 ;) 直接打开SpriteBuilder,新建一个PlayerWin.ccb,类型为粒子效果.我们可以从模板中选择一

(NO.00001)iOS游戏SpeedBoy Lite成形记(三十):增加排行榜功能3

在这个例子中,我们的显示代码只需要选手的名字以及对应的成绩.根据选手名字取对应的成绩可以用前面实现的playerRecord:方法,我们只需要将按照成绩排序后的选手名字返回就可以了. 我只需要再实现一个函数,就是返回已经排好序选手的姓名数组,在GameState.h接口文件中添加allSortedPlayers方法: -(NSArray*)allSortedPlayers; 接下来在GameState.m中实现它: -(NSArray*)allSortedPlayers{ NSArray *ke

(NO.00001)iOS游戏SpeedBoy Lite成形记(二十七)

切换回Xcode,在GameScene.m中添加新的实例变量:_winLayer. 接下来在第一个选手到达终点时,我们可以完成选手胜利的动画特效了. 首先,在GameScene.m中添加一个新方法playerWin: -(void)playerWin:(CCSprite*)player{ } 我们需要将冠军玩家传递给该方法.注意参数的类型是CCSprite而不是Player,虽然Player直接继承自CCSprite.这是因为我们只是需要玩家外形相关的内容,不关Player类特有的属性什么事.

(NO.00001)iOS游戏SpeedBoy Lite成形记(二十三)

现在还有一个视觉上的问题:玩家每次在游戏开始前选择某一赛道时,无法直观的看到所选的是哪条赛道.只能通过界面上方的gambleLabel中的文字非直观的看到.我们现在来完善它! 为了能让玩家清楚地看到,可以尝试增加选中的视觉效果.这里我们打算给选中赛道增加一个选择框表示当前选中. 要实现该功能有多种方法: 1.在draw回调方法中添加OpenGL的绘图代码,在对应位置画选择边框. 2.使用cocos2D的CCDrawNode在任何地方绘制选择框. 我们这里却使用更简单的第3种方法:移动现成的选择框