Cocos2D 2.1开发简单iPhone游戏(1)

一、原文出处

   http://www.raywenderlich.com/25736/how-to-make-a-simple-iphone-game-with-cocos2d-2-x-tutorial

二、

1.新建一个cocos2d iOS项目工程,名为 Cocos2DSimpleGame

   a.运行工程,可以看到 Hello World。

   b.Cocos2D主要应用的是场景(scenes)的概念。所谓场景就是游戏里的各个层次或者显示屏幕。例如游戏初始菜单的场景,游戏中的场景,游戏结束的场景。

   c.一个场景可以有很多的层(layers)(类似Photoshop里的层),而每个层可以有各种不同的节点,如精灵(sprites),标签(labels),菜单(menus)。一个节点可以包含别的节点,例如一个精灵可以包含子精灵。

   d.看下工程里的文件,你会发现有两个层IntroLayer和HelloWorldLayer,各个层都有自己的场景。看下code,director里调用的第一个场景是IntroLayer的场景,在IntroLayer里切换成HelloWorldLayer的场景。


2.增加一个精灵

   a.从resources for this tutorial下载资源,将资源文件加到工程,记得勾选 “Copy items into destination group's folder (if needed)”。

   b.在Coco2D里,屏幕的左下角是坐标原点。如果手机是横向模式的,对4寸屏来说,右上角坐标就是(568,320)。Retina显示屏,1点=2像素。

   c.打开HelloWorldLayer.m,修改init函数,给层添加一个玩家精灵

       if((self = [super init])){

        CGSize size = [CCDirectorsharedDirector].winSize;

CCSprite *player = [CCSpritespriteWithFile:@"player.png"];

        player.position =ccp(player.contentSize.width/2,size.height/2); //ccp是一个宏,会返回一个CGPoint对象

        [selfaddChild:player];

    }

    return self;


  d.打开HelloWorldLayer.h,修改接口

    @interface HelloWorldLayer: CCLayerColor

     修改init函数,将[super init] 改为[super initWithColor:ccc4(255,255,255,255)],把背景色改为白色

ccc4是一个宏,返回一个ccColor4B类型


3.增加怪物精灵

a.给HelloWorldLayer增加成员函数addMonster,这个函数负责产生一个从右向左移动的怪物精灵

-(void) addMonster

{

   CCSprite * monster = [CCSpritespriteWithFile:@"monster.png"];

    CGSize size = [[CCDirectorsharedDirector]winSize];

   int minY = monster.contentSize.height/2;

   int maxY = size.height - monster.contentSize.height/2;

   int rangeY = maxY - minY;

    

    //The arc4random() function returns pseudo-random numbers in the range of 0 to (2**32)-1

   int actualY = (arc4random()%rangeY)+minY;

    

    // Create the monster slightly off-screen along the right edge,

    // and along a random position along the Y axis as calculated above

    monster.position =ccp(size.width + monster.contentSize.width/2, actualY);

    [selfaddChild:monster];


    //Determine the speed of monster

   int minDuration =2;

   int maxDuration =4;

   int rangeDuration = maxDuration - minDuration;

   int actualDuration = (arc4random()%rangeDuration)+ minDuration;

    

    //Create the actions

   CCMoveTo * actionMove = [CCMoveToactionWithDuration:actualDurationposition:ccp(-monster.contentSize.width/2,actualY)];

    

   CCCallBlockN *actionMoveDone = [CCCallBlockNactionWithBlock:^(CCNode *node) {

        [node removeFromParentAndCleanup:YES];

    }];

    

    [monsterrunAction:[CCSequenceactions:actionMove,actionMoveDone,nil]];

}

   这个函数用到了Cocos2D提供的3种行为CCMoveTo,CCCallBlockN,CCSequence。

   CCMoveTo指定要到达的目标点及所花的时间,这里目标是屏幕左边刚好看不到精灵的位置,时间为2到4秒的随机时间。

   CCCallBlockN容许我们指定行为结束后要执行的代码块,这里是当怪物精灵从屏幕左边消失时,把它从层里删除,避免内存泄露。

   CCSequence容许我们将各种行为串接在一起,按顺序执行,这里是先执行CCMoveTo,然后执行CCCallBlockN。

   

  b.在HelloWorldLayer的init函数返回前增加

    [selfschedule:@selector(gameLogic:)interval:1.0];

    gamelogic是个回调函数,每隔1秒会被调用一次。

  c.增加gameLogic函数

-(void)gamelogic:(ccTime)dt

{

    [selfaddMonster];

}


4.射击

  有许多方法可以完成射击功能,本游戏实现的是当用户点击屏幕时,子弹会从玩家精灵射出到用户点击的方向。

  作为入门,我想用行为CCMoveTo来实现它,但这需要简单的数学计算,因为CCMoveTo需要我们提供子弹经过用户点击的位置,离开屏幕的最后一个点的坐标。

  a.在init函数里添加代码,使HelloWorldLayer能接受屏幕点击事件

    [self setIsTouchEnabled:YES]; 或者 [selfsetTouchEnabled:YES];

  b.增加函数,具体算法看原文,不复杂的三角运算

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    // Choose one of the touches to work with

   UITouch *touch = [touchesanyObject];

   CGPoint location = [selfconvertTouchToNodeSpace:touch];//from view to current layer

    

    // Set up initial location of projectile

   CGSize winSize = [[CCDirectorsharedDirector]winSize];

   CCSprite *projectile = [CCSpritespriteWithFile:@"projectile.png"];

    projectile.position =ccp(20, winSize.height/2);

    

    // Determine offset of location to projectile

   CGPoint offset =ccpSub(location, projectile.position);

    

    // Bail out if you are shooting down or backwards

   if (offset.x <=0)return;

    

    // Ok to add now - we've double checked position

    [selfaddChild:projectile];

    

   int realX = winSize.width + (projectile.contentSize.width/2);

   float ratio = (float) offset.y / (float) offset.x;

   int realY = (realX * ratio) + projectile.position.y;

   CGPoint realDest =ccp(realX, realY);

    

    // Determine the length of how far you're shooting

   int offRealX = realX - projectile.position.x;

   int offRealY = realY - projectile.position.y;

   float length =sqrtf((offRealX*offRealX)+(offRealY*offRealY));

   float velocity =480/1;// 480pixels/1sec

   float realMoveDuration = length/velocity;

    

    // Move projectile to actual endpoint

    [projectilerunAction:

     [CCSequence actions:

      [CCMoveToactionWithDuration:realMoveDurationposition:realDest],

      [CCCallBlockNactionWithBlock:^(CCNode *node) {

         [node removeFromParentAndCleanup:YES];

     }],

     nil]];

    }


4.击中检测

  有很多种方法可以实现击中检测,例如使用Box2D或者ChipMunk。简单起见,由自己来实现检测函数。

  a.打开HelloWorldLayer.h

   @interface HelloWorldLayer :CCLayerColor

   {

   NSMutableArray* _monsters;//怪物数组

   NSMutableArray* _projectiles;//子弹数组

   }

  b.在init函数初始化

    _monsters = [[NSMutableArrayalloc]init];

   _projectiles = [[NSMutableArrayalloc]init];

  c.在dealloc里释放

    [_monsters release];

     _monsters = nil;

    [_projectiles release];

     _projectiles =nil;

  d.修改addMonster函数,增加

    monster.tag =1;//以后会用

    [_monstersaddObject:monster];

    修改CCCallBlock的回调代码如下

    [_monstersaddObject:monster];

CCCallBlockN *actionMoveDone = [CCCallBlockNactionWithBlock:^(CCNode *node) {

       [_monstersremoveObject:node];

       [node removeFromParentAndCleanup:YES];

    }];

  e.修改ccTouchesEnded函数,增加

    projectile.tag = 2;//以后会用

    [_projectiles addObject:projectile];

    修改CCCallBlock的回调代码如下

    [projectile runAction:

     [CCSequence actions:

      [CCMoveTo actionWithDuration:realMoveDurationposition:realDest],

      [CCCallBlockN actionWithBlock:^(CCNode *node) {

         [_projectiles removeObject:node];

         [node removeFromParentAndCleanup:YES];

     }],

      nil]];

  f.增加新函数,在场景中清除击中的怪物和子弹

- (void)update:(ccTime)dt {

    NSMutableArray *projectilesToDelete = [[NSMutableArrayalloc]init];

    for (CCSprite *projectilein_projectiles) {

        

        NSMutableArray *monstersToDelete = [[NSMutableArrayalloc]init];

        for (CCSprite *monsterin_monsters) {

            //判断两个矩形是否相交,相交则表示怪物被击中

            if (CGRectIntersectsRect(projectile.boundingBox, monster.boundingBox)) {

                [monstersToDelete addObject:monster];

            }

        }

        

        for (CCSprite *monsterin monstersToDelete) {

            [_monsters removeObject:monster];

            [self removeChild:monster cleanup:YES];

        }

        

        if (monstersToDelete.count >0) {

            [projectilesToDelete addObject:projectile];

        }

        [monstersToDelete release];

    }

    

    for (CCSprite *projectilein projectilesToDelete) {

        [_projectiles removeObject:projectile];

        [self removeChild:projectilecleanup:YES];

    }

    [projectilesToDelete release];

}

   g.在init函数里增加定时刷新任务

     [self schedule:@selector(update:)];


5.增加游戏音效和音乐

  修改HelloWorldLayer.m

   增加 #import "SimpleAudioEngine.h"

   在init函数增加背景音乐

[[SimpleAudioEnginesharedEngine]playBackgroundMusic:@"background-music-aac.caf"];

   在ccTouchesEnded函数增加子弹音效

[[SimpleAudioEnginesharedEngine]playEffect:@"pew-pew-lei.caf"];


6.增加游戏结束层

 a.从CCNode类创建新类GameOverLayer,改其父类为CCLayerColor

 b.GameOverLayer.h代码如下

#import <Foundation/Foundation.h>

#import "cocos2d.h"


@interface GameOverLayer :CCLayerColor {

    

}

+(CCScene*) sceneWithWon:(BOOL)won;

-(id) initWithWon:(BOOL)won;

@end

 c.GameOverLayer.m代码如下

#import "GameOverLayer.h"

#import "HelloWorldLayer.h"


@implementation GameOverLayer


+(CCScene *) sceneWithWon:(BOOL)won {

   CCScene *scene = [CCScenenode];

   GameOverLayer *layer = [[[GameOverLayeralloc]initWithWon:won]autorelease];

    [sceneaddChild: layer];

   return scene;

}


- (id)initWithWon:(BOOL)won {

   if ((self = [superinitWithColor:ccc4(255,255,255,255)])) {

        

       NSString * message;

       if (won) {

            message =@"You Won!";

        }else {

            message =@"You Lose :[";

        }

        

       CGSize winSize = [[CCDirectorsharedDirector]winSize];

       CCLabelTTF * label = [CCLabelTTFlabelWithString:messagefontName:@"Arial"fontSize:32];

        label.color =ccc3(0,0,0);

        label.position =ccp(winSize.width/2, winSize.height/2);

        [selfaddChild:label];

        

        [selfrunAction:

         [CCSequenceactions:

          [CCDelayTimeactionWithDuration:3],

          [CCCallBlockNactionWithBlock:^(CCNode *node) {

             [[CCDirectorsharedDirector]replaceScene:[HelloWorldLayerscene]];

         }],

         nil]];

    }

    return self;

}

@end

c. 游戏胜利条件
  给HelloWorldLayer增加成员变量 int _monstersDestroyed,记录击中怪物的个数,大于30个为胜利。

 修改update函数,在 [selfremoveChild:monstercleanup:YES];后面添加代码:

 _monstersDestroyed++;

 if (_monstersDestroyed >30) {

         CCScene *gameOverScene = [GameOverLayersceneWithWon:YES];

         [[CCDirectorsharedDirector]replaceScene:gameOverScene];

  }

d.游戏失败条件

  修改addMonster函数,在[noderemoveFromParentAndCleanup:YES];后面添加代码:

  CCScene *gameOverScene = [GameOverLayersceneWithWon:NO];

  [[CCDirectorsharedDirector]replaceScene:gameOverScene];


7.结束
   到这里,一个简单的游戏就完成了。
   源代码可以从 simple Cocos2D iPhone game下载。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值