大佬教程收集整理的这篇文章主要介绍了【吼吼睡cocos2d学习笔记】第四章 - 第一个游戏,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
来让我们开始第一个游戏的制作。
这个过程可能有点艰辛,但是只要坚持下来,第一个游戏往往能给我们带来巨大的收益(当然这个收益不是经济上的:-p)
先上截图:
iPad中:
游戏构思
角色
在屏幕的上方,有一定数量的敌人(蜘蛛),屏幕下方有一只玩家控制的熊猫。
游戏流程
每间隔一段时间,会有一只蜘蛛爬下来袭击熊猫,熊猫通过移动来躲避攻击。随着游戏的进行,蜘蛛下降的速度会越来越快,出动的频率会越来越高。
胜负判定
熊猫躲避过一定数目的蜘蛛以后获胜,在此之前玩家用完所有生命则失败。
游戏展示动画,其实是有音效的,可能屏幕录像的软件不能捕捉来自模拟器的声音:展示动画
分析
我们按照事务流的方式来对整个游戏进行简单分析:
1.启动游戏,加载主页面。本示例不做菜单,不做配置,直接进入游戏场景。
2.将游戏置为READY状态;初始化各种数据;根据屏幕的宽度计算蜘蛛的个数,初始化蜘蛛精灵;初始化熊猫精灵
3.当玩家触摸屏幕以后,游戏开始,游戏状态设置为PLAYING,启动以下计时器:
3a.播放蜘蛛帧动画的计时器
3c.碰撞检测的计时器
4.玩家用手指控制熊猫在屏幕下方移动,这里要注意的是,接收触摸事件的是熊猫,如果触摸点不在熊猫上,它是不能移动的。因此需要给熊猫精灵添加一个targetedTouchDelegate。同时要防止熊猫划出屏幕边界。
5.定时检测下一个出动的蜘蛛,找到以后,让蜘蛛下移的屏幕低部,然后复位,如果熊猫躲避过来此次攻击,加分。当出动的蜘蛛次数超过一定量的时候(本游戏中是8次),加快游戏速度,加快蜘蛛出动频率。同时判断是否已经满足胜利条件。
6.当碰撞检测计时器检测到碰撞后,停止出动蜘蛛计时器、碰撞检测计时器、动画播放计时器,生命减一,判断是否还有剩余生命。如果没有,Game Over,游戏状态设置为END;如果还有生命,游戏状态设置为DEAD。
7.当玩家触摸屏幕的时候:
7.a.如果游戏状态是READY,开始游戏。
7.b 如果游戏状态是DEAD,复位蜘蛛和熊猫,启动各个计时器。
7.c 如果游戏状态为其他状态,无视。
8.对熊猫精灵的事件分析:
当熊猫精灵接收到触摸事件以后,判断是否命中到了精灵范围内,如果是,吃掉该事件,否则让该事件继续下发给其他对象。
9.注意,为了无缝的向iPad设备上移植,需要注意:计量避免出现假设性代码,所有的尺寸都根据屏幕尺寸计算。
开工
XCode->New Project->IOS->cocos2d-name it->finish!
删掉默认的HelloWorld层,按照下图,创建Group:
Sprites:盛放精灵类
Layers:盛放所有层
Scenes:盛放所有的场景
RootViewController.m
#elif GAME_AUTOROTATION == kGameAutorotationUIViewController return ( UIInterfaceOrientationIsLandscape( interfaceOrientation ) );修改为
#elif GAME_AUTOROTATION == kGameAutorotationUIViewController return ( UIInterfaceOrientationIsLandscape( interfaceOrientation ) );
AppDelegate.m
因为删除了HelloWorld层,现在需要启动我们自己添加的GameScene场景,因此需要修改AppDelegate.m的相关代码:
找到applicationDidFinishLaunching方法中[CCDirector sharedDirector] runWithScene的代码,此代码的作用是让【导演】运行第一个游戏场景,将之修改成:
[[CCDirector sharedDirector] runWithScene: [GameScene scene]];
+(CCScene *)scene;
-(void)dealloc { [super dealloc]; } +(CCScene *)scene { CCScene *sc = [CCScene node]; [sc addChild:[GameLayer node]]; return sc; }
其实在IOS开发中,scene对象中的代码量往往非常少,代码大部分出现在层和精灵中。
在看关键的GameLayer以前,我们先来看一下熊猫精灵(PandaSpritE)类
这个类继承自CCSprite,同时实现了CCTargetedTouchDelegate协议。这是.m中的代码
// // GameLayer.h // CH04 // // Created by 李庆辉 on 11-12-8. // QQ:66927785 // Blog:http://blog.csdn.net/redparty // Copyright 2011年 __MS__. All rights reserved. // #import "PandaSprite.h" @implementation PandaSprite @synthesize curLayer; //释放delegate -(void)onExit { [[CCTouchDispatcher sharedDispatcher] removeDelegate:self]; [super onExit]; } //当被node的时候,触发该事件,注册targetedDelegate -(void)onEnter { [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES]; [super onEnter]; } //获得自身的rect,用来进行命中判定 -(CGRect)rect { return CGRectMake(-rect_.size.width * 0.5,-rect_.size.height * 0.5,rect_.size.width,rect_.size.height); } //当touch开始的时候,判定是否命中了自身,如果是,吃掉该事件,反之忽略该事件 -(BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event { if (CGRectContainsPoint([self rect],[self convertTouchToNodeSpaceAR:touch])) { return YES; } return NO; } //根据玩家的触摸,变换主角的位置。 -(void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event { //获得GameLayer中的gameStatus的值,如果不是PLAYING,则忽略当前触摸。 if ([curLayer getGameStatus] != @"PLAYING") { return; } CGSize sizeOfWin = [[CCDirector sharedDirector] winSize]; //获得自己的尺寸的一半,用来对左右两边缘的位置进行校正 CGSize halfOfMyself; halfOfMyself = CGSizeMake([self contentSize].width * 0.5,[self contentSize].height * 0.5); //根据自身的大小确定自己在x轴方向上的最小值和最大值 CGFloat minX = halfOfMyself.width; CGFloat maxX = sizeOfWin.width - halfOfMyself.width; CGPoint posOfTouch = [touch LOCATIOnInView:touch.view]; CGPoint posForGL = [[CCDirector sharedDirector] convertToGL:posOfTouch]; //对越界情况进行校正 if (posForGl.x < minX) { posForGl.x = minX; } if (posForGl.x > maxX) { posForGl.x = maxX; } //坐标系转换 posForGl.y = [self contentSize].height * 0.5; self.position = posForGL; } @end
//获得GameLayer中的gameStatus的值,如果不是PLAYING,则忽略当前触摸。 if ([curLayer getGameStatus] != @"PLAYING") { return; }
// // GameLayer.h // CH04 // // Created by 李庆辉 on 11-12-8. // QQ:66927785 // Blog:http://blog.csdn.net/redparty // Copyright 2011年 __MS__. All rights reserved. // #import <Foundation/Foundation.h> #import "cocos2d.h" @interface PandaSprite : CCSprite<CCTargetedTouchDelegate> { id curLayer; } @property (nonatomic,retain)id curLayer; @end
好,现在看是来看重量级的GameLayer类
先看.h文件
// // GameLayer.h // CH04 // // Created by 李庆辉 on 11-12-8. // QQ:66927785 // Blog:http://blog.csdn.net/redparty // Copyright 2011年 __MS__. All rights reserved. // #import <Foundation/Foundation.h> #import "cocos2d.h" #import "PandaSprite.h" #import "SimpleAudioENGIne.h" @interface GameLayer : CCLayer { //窗口尺寸 CGSize sizeOfWin ; //蜘蛛的尺寸 CGSize sizeOfSpider; //熊猫的尺寸 CGSize sizeOfPanda; //盛放蜘蛛精灵的数组 CCArray *spiders; //盛放熊猫生命的数组 CCArray *LivesPandas; //主角精灵 PandaSprite *panda; //蜘蛛的个数 int spidernumber; //控制游戏速度的一个因子,会被用在计算蜘蛛的下降速度和下降频率上 CGFloat speed; //当前的游戏状态,分为:READY,PLAYING,DEAD,END,OVER NSString *gameStatus; //显示分数的label CCLabelTTF *lblscoreShow; //显示游戏信息的label CCLabelTTF *lblInfo; //动画播放分数的label CCLabelBMFont *lblscoreAnimate; //没有什么具体含义,仅仅被用来控制分数计算的频率 int numSpidersMoved; int livesCount; //游戏得分 int score; } //播放蜘蛛动画 -(void)playSpiderAnimate; //重置蜘蛛们的位置 -(void)resetSpider; //寻找下一个行动的蜘蛛 -(void)checkSpider:(cctimE)dt; //将checkSpider寻找到的蜘蛛下坠并复位 -(void)downSpider:(CCSprite *)spider; //作为downSpider中action的回调函数,负责让到达屏幕底部的蜘蛛复位 -(void)makeSpiderBACk:(CCSprite *)spider; //碰撞检测 -(void)checkCollision; //停止所有发生在蜘蛛和主角上的动作。 -(void)stopAllAction; //返回gameStatus的值,这个值会在PandaSprite中用到 -(NSString *)getGameStatus; //该方法根据speed来改变蜘蛛出动的频率。 -(void)changecheckTimeout; @R_772_9789@死亡label -(void)createLables; @R_772_9789@蜘蛛数组 -(void)createSpiderArray; @R_772_9789@显示生命的熊猫 -(void)createLivesPandas; @R_772_9789@主角 -(void)createPanda; //初始化游戏 -(void)initGame; //用Action来显示实时分数 -(void)showAnimatescore; //当胜利的时候 -(void)whenWin; //当碰撞的时候 -(void)whenCollision; //根据当前剩余的生命显示对应个数的熊猫 -(void)showLives; //开始游戏相关的计时器 -(void)startschedule; //停止游戏相关的计时器 -(void)stopschedule; @end
// // GameLayer.h // CH04 // // Created by 李庆辉 on 11-12-8. // QQ:66927785 // Blog:http://blog.csdn.net/redparty // Copyright 2011年 __MS__. All rights reserved. // #import "GameLayer.h" @implementation GameLayer #define SPRITETAG 100 #define LABLE_TAG 150 #define score_HEIGHT 30 #define SCALE_SPIDER 0.5 #define SCALE_PANDA 0.8 #define FADE_score 45 #define SPEED 2 #define DTSPEED 250 #define MAXLIVES 5 #define SCALE_LIVESPANDA 0.25 static int framIndex; //释放层用到的非autoRelease资源 -(void)dealloc { [super dealloc]; [spiders release]; spiders = nil; } -(id)init { if (self = [super init]) { [self initGame]; } return self; } -(void)initGame { //获得屏幕尺寸 sizeOfWin = [[CCDirector sharedDirector] winSize]; @R_772_9789@label(分数、生命、死亡信息、win) [self createLables]; @R_772_9789@蜘蛛数组 [self createSpiderArray]; @R_772_9789@主角 [self createPanda]; @R_772_9789@显示生命用的熊猫 [self createLivesPandas]; //重置蜘蛛位置 [self resetSpider]; //预加载音效文件,如果不予加载的话,第一次播放此音效的时候会卡至少一秒钟。 [[SimpleAudioENGIne sharedENGIne] preloadEffect:@"bomb.caf"]; numSpidersMoved = 1; score = 0; livesCount = MAXLIVES; framIndex = 1; speed = SPEED; gameStatus = @"READY"; [self setIsTouchEnabled:YES]; } -(void)createPanda { //添加主角 CCSpriteFrameCache *frameCache = [CCSpriteFrameCache sharedSpriteFrameCache]; [frameCache addSpriteFramesWithFile:@"sprite.plist"]; panda = [PandaSprite node]; [panda setDisplayFrame:[frameCache spriteFrameByName:@"panda.png"]]; sizeOfPanda = [panda contentSize]; sizeOfPanda.width *= SCALE_PANDA; sizeOfPanda.height *= SCALE_PANDA; [self addChild:panda z:3]; //将本层传入panda对象中,实现层和精灵的信息传递 panda.curLayer = self; } -(void)createLivesPandas { CCSpriteFrameCache *frameCache = [CCSpriteFrameCache sharedSpriteFrameCache]; [frameCache addSpriteFramesWithFile:@"sprite.plist"]; CCSprite *tmpPanda = [CCSprite spriteWithSpriteFrame:[frameCache spriteFrameByName:@"zz1.png"]]; //获得生命区熊猫的尺寸 CGSize sizeOfLivesPanda = [tmpPanda contentSize]; sizeOfLivesPanda.width *= SCALE_LIVESPANDA; sizeOfLivesPanda.height *= SCALE_LIVESPANDA; LivesPandas = [[CCArray alloc] initWithCapacity:MAXLIVES]; for (int i = 0; i < MAXLIVES; i++) { CCSprite * tmpPanda = [CCSprite spriteWithSpriteFrame:[frameCache spriteFrameByName:@"panda.png"]]; [LivesPandas addObject:tmpPanda]; tmpPanda.scale = SCALE_LIVESPANDA; tmpPanda.position = CGPointMake((i+1)*sizeOfLivesPanda.width,sizeOfWin.height - sizeOfLivesPanda.height - 5 ); [self addChild:tmpPanda]; } } -(void)createSpiderArray { @R_772_9789@蜘蛛精灵表的帧缓存,并加载蜘蛛精灵动作的plist文件 CCSpriteFrameCache *frameCache = [CCSpriteFrameCache sharedSpriteFrameCache]; [frameCache addSpriteFramesWithFile:@"sprite.plist"]; //生成临时蜘蛛,获取缩放以后蜘蛛的尺寸。 CCSprite* spider = [CCSprite spriteWithSpriteFrame:[frameCache spriteFrameByName:@"zz1.png"]]; spider.scale = SCALE_SPIDER; sizeOfSpider = [spider contentSize]; sizeOfSpider.width *= SCALE_SPIDER; sizeOfSpider.height *= SCALE_SPIDER; //根据蜘蛛的尺寸计算可以放置的蜘蛛的个数,根据个数初始化蜘蛛数组 spidernumber = sizeOfWin.width/sizeOfSpider.width; spiders = [[CCArray alloc] initWithCapacity:spidernumber]; for (int i = 0; i < spidernumber; i++) { CCSprite *tmpSpider = [CCSprite spriteWithSpriteFrame:[frameCache spriteFrameByName:@"zz1.png"]]; [spiders addObject:tmpSpider]; tmpSpider.scale = SCALE_SPIDER; [self addChild:tmpSpider z:0 tag:SPRITETAG + i]; } } -(void)createLables { //信息 lblInfo = [CCLabelTTF labelWithString:@"" fontName:@"Arial" fontSize:22]; lblInfo.position = CGPointMake(sizeOfWin.width * 0.5,sizeOfWin.height * 0.5); [self addChild:lblInfo z:100 tag:LABLE_TAG]; [lblInfo setVisible:NO]; [lblInfo setOpacity:125]; //分数 CCLabelTTF *lblscore = [CCLabelTTF labelWithString:@"分数:" fontName:@"Arial" fontSize:14]; lblscore.anchorPoint = CGPointMake(1,1); lblscore.position = CGPointMake(sizeOfWin.width - 60 - [lblscore contentSize].width/2,sizeOfWin.height - 10); [self addChild:lblscore]; lblscoreShow = [CCLabelTTF labelWithString:@"0000000" fontName:@"Arial" fontSize:14]; lblscoreShow.anchorPoint = CGPointMake(1,1); lblscoreShow.position = CGPointMake(sizeOfWin.width - [lblscore contentSize].width/2,sizeOfWin.height - 10); [self addChild:lblscoreShow]; //实时显示当前得分的标签,用到了BMFont,使用Hiero制作 lblscoreAnimate = [CCLabelBMFont labelWithString:@"" fntFile:@"myfont.fnt"]; lblscoreAnimate.scale = 0; [lblscoreAnimate setOpacity:FADE_score]; lblscoreAnimate.position = CGPointMake(sizeOfWin.width * 0.5,sizeOfWin.height * 0.5); [self addChild:lblscoreAnimate]; //生命 } -(void)resetSpider { //将蜘蛛们复位 CGSize halfSize = CGSizeMake(sizeOfSpider.width * 0.5,sizeOfSpider.height * 0.5); CGFloat leftMargin = (sizeOfWin.width - sizeOfSpider.width * spidernumber) * 0.5; for (int i = 0; i < spidernumber; i++) { CCSprite *spider = (CCSprite *)[self getChildByTag:SPRITETAG + i]; spider.position = CGPointMake((i+1)*sizeOfSpider.width - halfSize.width+leftMargin,sizeOfWin.height - halfSize.height - score_HEIGHT); [spider stopAllActions]; } //将熊猫复位 panda.position = CGPointMake(sizeOfWin.width * 0.5,sizeOfPanda.height * 0.5); } -(void)playSpiderAnimate { CCSpriteFrameCache *frameCache = [CCSpriteFrameCache sharedSpriteFrameCache]; [frameCache addSpriteFramesWithFile:@"sprite.plist"]; if (++framIndex >2) { framIndex = 1; } for (int i = 0; i<spidernumber; i++) { CCSprite *tmpspider = [spiders objectATindex:i]; if ([tmpspider numberOfRunningActions] == 0) { //为了让蜘蛛的动画产生不一致,避免所有的蜘蛛播放相同的纹理,将i也加入了计算中,最终得到的是一个介于1-2的整数 [tmpspider setDisplayFrame:[frameCache spriteFrameByName:[NSString StringWithFormat:@"zz%d.png",(framIndex + i)%2 +1]]]; } } } -(void)changecheckTimeout { [self unschedule:@SELEctor(checkSpider:)]; [self schedule:@SELEctor(checkSpider:) interval:0.25 * speed]; } //寻找下一个出动的蜘蛛 -(void)checkSpider:(cctimE)dt { for (int i = 0; i<20; i++) { int checkIndex = CCRANDOM_0_1() * spidernumber; CCSprite *spider = [spiders objectATindex:checkIndex]; //如果找到了一个本身没有动作的蜘蛛,说明该蜘蛛还没有出动,出动之。 if ([spider numberOfRunningActions] == 0) { //出动蜘蛛 [self downSpider:spider]; break; } } } -(void)whenWin { [lblInfo setString:@"you win!"]; [lblInfo setVisible:YES]; [self stopAllAction]; [self unschedule:@SELEctor(checkSpider:)]; [self unschedule:@SELEctor(checkCollision)]; gameStatus = @"END"; } //计算分数,用动画的方式现在在屏幕中间,同时累加到分数变量,显示在右上角。 -(void)showAnimatescore { //根据当前speed计算当前得分,原则上是:速度越快,单位得分越高 int scoreBySpeed = ((SPEED+0.1)-speed) * DTSPEED; score += scoreBySpeed; [lblscoreAnimate setString:[NSString StringWithFormat:@"%d",scoreBySpeed]]; [lblscoreShow setString:[NSString StringWithFormat:@"%07d",score]]; //播放动画前,将label透明度调大,尺寸缩小到0 lblscoreAnimate.scale = 0; [lblscoreAnimate setOpacity:FADE_score]; @R_772_9789@一个放大动作和一个隐出动作 CCAction *acS = [CCScaleTo actionWithDuration:0.2 scale:3]; CCAction *acE= [CCFadeTo actionWithDuration:0.2 opacity:0]; //用CCSpawn的方式同步执行两个动作 [lblscoreAnimate runAction:[CCSpawn actions:acS,acE,nil]]; } //出动蜘蛛 -(void)downSpider:(CCSprite *)spider { //蜘蛛移动的目标位置 CGPoint targetPos = CGPointMake(spider.position.x,[spider contentSize].height * 0.5); CCAction *ac = [CCMoveTo actionWithDuration:speed position:targetPos]; //当蜘蛛执行玩ac动作以后,回来执行callBACk指向的回调函数:makeSpiderBACk CCCallFuncN *callBACk = [CCCallFuncN actionWithTarget:self SELEctor:@SELEctor(makeSpiderBACk:) ]; //用CCSequence的方式执行ac和callBACk [spider runAction:[CCSequence actions:ac,callBACk,nil]]; } //回调函数,让蜘蛛复位 -(void)makeSpiderBACk:(CCSprite *)spider { CGPoint BACkPos = CGPointMake(spider.position.x,sizeOfWin.height - sizeOfSpider.height * 0.5 - score_HEIGHT); CCAction *BACk = [CCMoveTo actionWithDuration:1 position:BACkPos]; [spider runAction:BACk]; //播放加分动画,加分 [self showAnimatescore]; //每有一只蜘蛛被躲避开,就加快游戏速度,同时进行获胜判定 numSpidersMoved++; if (numSpidersMoved %5 == 0) { //在本游戏中,如果速度快到0.7,认为玩家获胜。 if (speed < 0.7) { [self whenWin]; return; } speed -= 0.02; [self changecheckTimeout]; numSpidersMoved = 1; } } //当用户点击屏幕的时候,根据不同的情景改变游戏状态。 -(void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { //如果当前是死亡状态,继续游戏 if (gameStatus == @"DEAD") { [panda stopAllActions]; [panda setVisible:YES]; [lblInfo setVisible:NO]; [self resetSpider]; gameStatus = @"PLAYING"; [self changecheckTimeout]; [self startschedule]; } //如果当前是READY状态,开始游戏 if (gameStatus == @"READY") { gameStatus = @"PLAYING"; [self changecheckTimeout]; [self startschedule]; } } //开始游戏相关的计时器 -(void)startschedule { //让蜘蛛动起来 [self unschedule:@SELEctor(playSpiderAnimatE)]; [self schedule:@SELEctor(playSpiderAnimatE) interval:0.4]; //启动碰撞检测 [self unschedule:@SELEctor(checkCollision)]; [self schedule:@SELEctor(checkCollision) interval:0.02]; } //停止游戏相关的计时器 -(void)stopschedule { [self unschedule:@SELEctor(playSpiderAnimatE)]; [self unschedule:@SELEctor(checkCollision)]; } //碰撞检测 -(void)checkCollision { //计算熊猫和蜘蛛的最大相距半径,大于此值认为发生了碰撞。 float maxDistance = sizeOfSpider.width * 0.45 +sizeOfPanda.width * 0.45; //依次判定每一个蜘蛛是否与熊猫发生了碰撞 for (int i = 0; i < spidernumber; i++) { CCSprite *spider; spider = [spiders objectATindex:i]; //忽略没有出动的蜘蛛 if ([spider numberOfRunningActions] == 0) { conTinue; } //得到当前蜘蛛和熊猫的距离 float actualDistance = ccpDistance(spider.position,panda.position); if (actualDistance < maxDistancE) { [self whenCollision]; break; } } } //当碰撞发生的时候,进行处理 -(void)whenCollision { //播放音频 [[SimpleAudioENGIne sharedENGIne] playEffect:@"bomb.caf"]; [self unschedule:@SELEctor(checkSpider:)]; [self stopschedule]; [self stopAllAction]; gameStatus = @"DEAD"; //blink the spider CCAction *blink = [CCBlink actionWithDuration:0.5 blinks:3]; [panda runAction:blink]; livesCount--; [lblInfo setVisible:YES]; if (livesCount == 0) { [lblInfo setString:@"GAME OVER!"]; gameStatus = @"OVER"; return; } [self showLives]; [lblInfo setString:@"你挂了!点击屏幕重新来过!"]; } -(void)showLives { for (int i = livesCount; i<MAXLIVES; i++) { CCSprite *tmpSprite = [LivesPandas objectATindex:i]; [tmpSprite setVisible:NO]; } } //停止所有蜘蛛和主角的动作 -(void)stopAllAction { for (int i = 0; i < spidernumber; i++) { CCSprite *spider = [spiders objectATindex:i]; [spider stopAllActions]; } [panda stopAllActions]; } //该方法用在向panda精灵中传递游戏状态,实现:只有在PLAYING的时候才可以移动主角。 -(NSString *)getGameStatus { return gameStatus; } @end
程序员应该尽量少写基于假设的代码
比如spider.positon = CGPointMake(160,32)。
你写这行代码的本意可能是想将熊猫精灵放在屏幕的底部的中间,听起来似乎不错,因为当前你做的是iphone的开发,熊猫的高度是64px。但是这都基于两个假设:
假设一:屏幕宽度是320px,显然并非所有的IOS设备都是这样。
假设二:熊猫高度是64px。
事实上,我们很容易在游戏进行到一定的程度以后,要添加新的需求,比如移植到iPad上,比如说你想增加一个关卡,这次主角是一个蚂蚁或者一只大象。那么这些基于假设的代码就会成为让你加班的原因。也很有可能会耽误你和女儿的周末晚餐⋯⋯
资源
本例中,用到了以下资源:
bomb.caf:主角死亡时候播放的音效。
sprite.plist & sprite.png:精灵贴图列表,使用Zwoptex文件制作,这个工具使用起来非常简单,大家可以google之。
@H_966_4@myfont.fnt & myfont.png:自定义字体类表和图像,使用hiero制作。游戏开发必备。说得再多,不如自己动手写一遍。
奉上源码:cocos2d-蜘蛛人源码
回见。
以上是大佬教程为你收集整理的【吼吼睡cocos2d学习笔记】第四章 - 第一个游戏全部内容,希望文章能够帮你解决【吼吼睡cocos2d学习笔记】第四章 - 第一个游戏所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。