iOS   发布时间:2022-03-31  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了【吼吼睡cocos2d学习笔记】第四章 - 第一个游戏大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

来让我们开始第一个游戏的制作。

这个过程可能有点艰辛,但是只要坚持下来,第一个游戏往往能给我们带来巨大的收益(当然这个收益不是经济上的:-p)

先上截图:


iPad中:


游戏构思

角色

在屏幕的上方,有一定数量的敌人(蜘蛛),屏幕下方有一只玩家控制的熊猫。

游戏流程

每间隔一段时间,会有一只蜘蛛爬下来袭击熊猫,熊猫通过移动来躲避攻击。随着游戏的进行,蜘蛛下降的速度会越来越快,出动的频率会越来越高。

胜负判定

熊猫躲避过一定数目的蜘蛛以后获胜,在此之前玩家用完所有生命则失败。

游戏展示动画,其实是有音效的,可能屏幕录像的软件不能捕捉来自模拟器的声音:展示动画

分析

我们按照事务流的方式来对整个游戏进行简单分析:

1.启动游戏,加载主页面。本示例不做菜单,不做配置,直接进入游戏场景。

2.将游戏置为READY状态;初始化各种数据;根据屏幕的宽度计算蜘蛛的个数,初始化蜘蛛精灵;初始化熊猫精灵

3.当玩家触摸屏幕以后,游戏开始,游戏状态设置为PLAYING,启动以下计时器:

3a.播放蜘蛛帧动画的计时器

3b.搜索一个出动的蜘蛛计时器

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]];

GameScene使我们自己设计的场景类,在Scenes文件组中,scene是该类的初始化方法,负责返回一个GameScene对象。


做完这些以后我们来实现主场景类: GameScene

首先在.h文件添加静态scene方法的声明:

+(CCScene *)scene;

.m文件中实现该方法,同时加上对资源的释放:

-(void)dealloc
{
    [super dealloc];
}
+(CCScene *)scene
{
    CCScene *sc = [CCScene node];
    [sc addChild:[GameLayer node]];
    return  sc;
}

scene方法中构造了一个CCScene对象,并将GameLayer层作为子节点加入其中。

其实在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

代码中已经注视的非常清楚了,这里不再赘述。需要说明的是,在CCTouchMoved方法中,有如下代码

//获得GameLayer中的gameStatus的值,如果不是PLAYING,则忽略当前触摸。
    if ([curLayer getGameStatus] != @"PLAYING") {
        return;
    }

curLayer是在.h中声明的id类型的对象:

//
//  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

id是Objective-C中所有节点的父类,相当于c#中的Object类。该对象将来会传入一个GameLayer的对象。之所以这样做是因为在熊猫精灵并非在任何时候都被允许移动的,只有在游戏状态为PLAYING的时候才响应该事件。具体可以参看GameLayer.m中的getGameStatus方法。这是一种在精灵和层之间传递数据的方式。


好,现在看是来看重量级的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

有点多,但是每一行我的加上了注释,每个方法的实现都在.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 "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

我想注释已经足够清楚了,有序虑到了向iPad平台的兼容,所以有大量的代码用来计算尺寸和位置。千万不要认为这是在浪费时间,记住一句话:

程序员应该尽量少写基于假设的代码

比如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,请注明来意。