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

下面我们来实现选手从起点开始移动到终点的代码.

首先在GameScene.h接口中添加matchRun方法:

#import "CCNode.h"

@interface GameScene : CCNode

-(void)matchRun;

@end

因为GameScene中覆盖了GameInterface交互层,里面有一个run按钮.这个按钮的功能肯定不是由GameInterface类来完成,最终需要调用GameScene中的matchRun方法.

在Xcode中新建GameInterface类,继承自CCNode.在其实现文件中加入以下代码:

#import "GameInterface.h"
#import "GameScene.h"

@implementation GameInterface{
    GameScene *_gameScene;
}

-(void)didLoadFromCCB{
    _gameScene = (GameScene *)self.parent;
}

-(void)run{
    [_gameScene matchRun];
}

@end

这样用户点击run后,就会执行GameScene中的matchRun方法.

接下来回到GameScene中,在完成该方法之前,我们还需要一些实例变量,所以先建立它们:

@implementation GameScene{
    CCNode *_track;
    NSMutableArray *_players;

    BOOL _matching;
    NSInteger _finishedCount;

    NSTimeInterval _bestElapsedTime;
}

其中_track是赛场背景的引用,我们需要将玩家加入到_track而不是GameScene中,这样新加入的大头贴不会将run按钮遮挡.(参考之前初始化玩家的代码).

_players是所有玩家的数组,前面初始化中创建的玩家需要加入其中.
对于一场比赛是否完成需要有一个变量标示,否则会打断正在进行中的比赛,_matching就是这个作用.

_finishedCount是个重要的变量,用来确定每个选手最终的名次.
最后一个变量_bestElapsedTime,顾名思义是比赛中选手的最好成绩,将来可以用来记录最好成绩榜,这个以后再说,现在先不管.

在GameScene.m中实现以下方法:

-(void)matchReset{
    if (!_matching) {
        [self initPlayPositon];
        _bestElapsedTime = 0;
    }
}

在每次比赛新开始前调用,用来初始化选手在赛车上的位置以及其他与比赛相关的参数.

别忘了还要在GameScene的初始化方法中初始化其ivar:

-(instancetype)init{
    self = [super init];
    if (self) {
        _players = [NSMutableArray array];
    }
    return self;
}

好了,准备工作基本就绪,可以着手实现matchRun方法了 ;)

时间: 2024-11-03 20:31:57

(NO.00001)iOS游戏SpeedBoy Lite成形记(四)的相关文章

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

这是本猫第一个原创iOS游戏,留此为证!看编号貌似要写9万多个,千锤百炼还是太少吧!? ;) 这是一个赛跑游戏,几位选手从起点跑到终点看谁用的时间最少.现在需要实现的功能是: 1.8位选手从起点移动至终点 2.到终点后记录每位选手所用的时间 第一步不是写代码,而是画素材,因为是原创,所以游戏人物和比赛跑道也需要自己打造.首先用Ai画一个简单的跑道,共有两场图分辨率分别为1036x640(iphone 5+)和960x640(iphone 4s),没打算在ipad上跑,所以2张就够了: 接着是选手

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

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

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

之前的10篇内容主要实现了选手从起点移动至终点的动作,比较随机的模拟了选手的速度变化,另外完成了选手到达终点时该做的事情. 接下来的几篇中我们进一步完善SpeedBoy Lite项目,使它真正成为一个可玩的小游戏. 首先添加几个新的人物大头像,好歹也是8条赛道,别老是8胞胎似得一起跑,起码人物要区分开.于是祭出Ai,在新加6个人物头像,如下: 全部本猫手绘出来的,手确实蛮累的 ;) 下面依次将新画的6副大头贴拖入SpriteBuilder,发布资源.然后修改player初始化的代码如下: Pla

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

游戏特效部分就先这样了,因为毕竟是Lite版本,而且是第一个App,所以咱们把主要精力放在游戏可玩逻辑上吧(虽然已经厚颜无耻的加了不少特效了). 说句题外话:游戏美工是独立开发者不可逾越的鸿沟,是无法治愈之痛.本猫三脚猫的美工素养暂时也只能实现这样了.这个不仅仅要恶补制图工具的使用技术,而且还需要一点点美学上的天赋吧.我看过网上有位国外的很热爱独立开发App游戏的仁兄,也在自己的blog上写开发的心路,开始前几个作品画的那叫一个丑啊-但是人家不放弃,后来越画越好了.虽说不能和专业人士相比,但事在

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

现在需要实现具体的游戏逻辑大致如下: 玩家点击某条赛道选择一个选手,然后会弹出菜单窗口让玩家输入压赌的金额,如果输入的金额值非法,则在GameInterface下部的状态栏中显示提示,要求玩家重新输入;如金额合法,则玩家可以关闭窗口,点击Run按钮运行游戏. 下面逐步实现,每一次都是功能上的小修小补. 首先在GameScene.m里添加实例变量,用来确定用户是否压过注了: BOOL _isBeted; 在matchRun方法里要判断,如果没有押注则提示用户并直接退出方法: if (!_isBet

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

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

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

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

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

打开SpriteBuilder生成的Xcode项目文件,首先在MainScene添加play回调函数: -(void)play{ CCScene *gameScene = [CCBReader loadAsScene:@"GameScene"]; [[CCDirector sharedDirector]replaceScene:gameScene]; } 这样玩家从游戏主界面点击play按钮就可以进入游戏界面. 下面新建一个GameScene类,继承自CCNode. 我们在GameSc

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

现在游戏中如果钱用光了赌场也是不管的,所以我们要加上Game Over的逻辑. 出现游戏结束条件很简单,就是GameState的totalMoney <= 0.而在游戏结束时我们要做些什么呢?有很多种展现的形式,我们这里就弹出一个菜单,然后让玩家选择重新开始或是回到游戏主菜单. 打开SpriteBuilder,新建一个GameOverLayer.ccb文件,类似于PopupMoneyLayer.ccb的设置,这里不再赘述.我们添加2个按钮,按合适的位置布局它们的位置,设置Root节点自定义类为P