上一部分请查看使用Cocos2D、PhysicsEditor TexturePacker开发工具制作《Monkey Jump》第一部分

下一部分请查看使用Cocos2D、PhysicsEditor TexturePacker开发工具制作《Monkey Jump》第三部分

基于Gbox2D的触碰检测

GBox2D使得碰撞检测变成小菜一碟!这是因为你无需制作严肃的逻辑陈述或系列选择结构,从中探索各种可能的碰撞组合。
相反,GBox2D只是运用触碰类型的名称,通过类型名称衍生出的名称访问选择器。若你觉得这听起来有些抽象,查看如下例子:
假设你有一只猴子和一根香蕉,它们是class分别属于Monkey和Banana的物件。若两个物体都开始碰撞,GBox2D将访问如下选择器:
[banana beginContactWithMonkey:collisionA];
[monkey beginContactWithBanana:collisionB];

  • 若触碰已完成,物件就不再接触:
    [banana endContactWithMonkey:collisionA];
    [monkey endContactWithBanana:collisionB];

    A触碰和B触碰的参数包含触碰信息,例如触碰涉及哪些物件和固定装置。我们将通过此信息,查看猴子是否被击中头部或身体。

    AppDelegate

    我所改变的存在于原始Box2d项目的AppDelegate元素如下:
    首先,我将画面缓冲器的默认像数设置成RGBA8。这意味着,游戏会得到完整的24位元色彩深度。我关闭深度缓冲器,因为我们不再需要它。
    EAGLView *glView = [EAGLView viewWithFrame:[window bounds]
    pixelFormat:kEAGLColorFormatRGBA8
    depthFormat:0
    ];

    下个需要设置的重要元素是,预乘alpha。这是因为我们运用通过TexturePacker制作而成的预乘PVR图像。若我们未设置预乘alpha,我们的图像将会出现深色的边界。
    [CCTexture2D PVRImagesHavePremultipliedAlpha:YES];
    由于我们采用随机生成器选择将降落的物件,所以我们需要制作内容。最佳方式就是采用time()。若你忘记制作随机生成器,你依然会得到随机数据(dApps注:但它们会和游戏开始时的内容一模一样)。
    srand (time (NULL));
    完成初始化操作后,就轮到GameLayer内容:
    [[CCDirector sharedDirector] runWithScene: [GameLayer scene]];
    GameLayer
    GameLayer是源自CCLayer的简单class。它由空白的init函数构成。
    -(id) init
    {
    if( (self=[super init]))
    {
    }
    return self;
    }

    将CCLayer包装成CCScene,然后移交给Director的静态选择器:
    +(CCScene *) scene
    {
    // 'scene' is an autorelease object.
    CCScene *scene = [CCScene node];
    // 'layer' is an autorelease object.
    GameLayer *layer = [GameLayer node];
    // add layer as a child to scene
    [scene addChild: layer];
    // return the scene
    return scene;
    }

    声音资源

    我从http://incompetech.com/获得主题音乐tafi-maradi-loop.caf。
    由于我想要循环播放音乐,因此我亲自简化内容,选择没声道的主题。
    物件的音效来自http://soundbible.com。有些内容基于cfxr制作而成。
    所有音效和音乐文件都被转化成caf格式。
    编辑和运行项目后,你将看到黑色屏幕。现在就在此屏幕中添加些许内容。

    Xcode的基本设置

    此部分旨在设定基本游戏图层和背景,设定物理引擎。
    在深入编码内容前,还有一项工作需要完成:添加我们在PhysicsEditor中创建的资源。是否还记得?

    • background.plist
    • background.pvr.ccz
    • background-hd.plist
    • background-hd.pvr.ccz
    • jungle.plist
    • jungle.pvr.ccz
    • jungle-hd.plist
    • jungle-hd.pvr.ccz
    • shapes.plist

    双击Xcode中的Resources文件夹,选择Add Files To “MonekyJump”,然后选择上述文件,这样你就能够将上述文件添加至Xcode项目中的Resources文件夹中。
    现在轮到编码内容。首先,首先我们需要创建一个Floor class ,以代表游戏中的平面。然后通过iOS\Cocoa Touch\Objective-C类模版创建新文件,这样你就能够将Floor.h and Floor.mm文件添加至你的项目中。给类Floor命名,将其变成GB2Sprite的子类。内容创建完后,不要忘记将Floor.m的扩展名改成.mm。
    Floor.h包含如下内容:
    #pragma once
    #import "cocos2d.h"
    #import "GB2Sprite.h"
    @interface Floor : GB2Sprite
    {
    }
    +(Floor*) floorSprite;
    @end

    Floor.mm包含如下内容:
    #import "Floor.h"
    @implementation Floor
    +(Floor*) floorSprite
    {
    return [[[self alloc] initWithStaticBody:@"grassfront" spriteFrameName:@"floor/grassfront.png"] autorelease];
    }
    @end

    这里唯一值得注意的代码行是initWithStaticBody选择器的调用。这让我们的物件变成静态模式——未被物理引擎移动的物件,通过shapes.plist文件的“grassfront”模型将身体模型初始化。
    它还运用源自jungle.plist的floor/grassfront.png名称子画面图像。
    为什么我们从GB2Sprite中导出此类,而不是直接采用GB2Sprite?答案在于GBox2D的碰撞处理,其运用类的名称调用碰触物件的适合选择器。由于我们想要知晓物件何时同平面碰触,平面物件的类名称就需要区别于其他GB2Sprite物件。
    下步要进行的就是更新GameLayer。添加实体变量约束GameLayer.h中的必需物件:
    @interface GameLayer : CCLayer
    {
    CCSprite *background; // weak reference
    CCSprite *floorBackground; // weak reference
    CCSpriteBatchNode* objectLayer; // weak reference
    }

    我们将把物件存储成弱引用(dApps注:就是不保证不被垃圾回收器回收的对象)——也就是其未提高各物件的留存期限。
    你无需担心CCSprites被删除。它们会被添加成CCLayer衍生内容,这样其留存值至少是1。否则我们将被困于留存周期中,无法释放这些物件所包含的内存。
    然后在GameLayer.mm的init选择器中填充内容。首先是加载子画面表单。
    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"jungle.plist"];
    [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"background.plist"];

    接着将物理模型加载至GB2ShapeCache中:
    [[GB2ShapeCache sharedShapeCache] addShapesWithFile:@"shapes.plist"];
    然后,设置图层。我们将把游戏分成下列图层:

      背景图层:jungle图像
      平面图层:包含茂密小草的单个子画面
      物件图层:包含所有道具和猴子
      Hud图层存在分数和能量指示器。


    添加代码,在init中制作基本背景和平面背景:
    // Setup background layer
    background = [CCSprite spriteWithSpriteFrameName:@"jungle.png"];
    [self addChild:background z:0];
    background.anchorPoint = ccp(0,0);
    background.position = ccp(0,0);
    // Setup floor background
    floorBackground = [CCSprite spriteWithSpriteFrameName:@"floor/grassbehind.png"];
    [self addChild:floorBackground z:1];
    floorBackground.anchorPoint = ccp(0,0);
    floorBackground.position = ccp(0,0);

    然后添加物件图层。这将变成一批子画面的节点,旨在加速物件的渲染:
    objectLayer = [CCSpriteBatchNode batchNodeWithFile:@"jungle.pvr.ccz" capacity:150];
    [self addChild:objectLayer z:10];

    最后是调试图层: // add the debug draw layer, uncomment this if something strange happens 😉
    [self addChild:[[GB2DebugDrawLayer alloc] init] z:30];

    若你想要放弃调试图画,只需在第二行中添加注释。若启用此内容,物理模型将被绘制于子画面周围,让你能够呈现碰触的发生地点,以及所有模型是否协调一致。
    接着,将平面物件变成物件图层的衍生内容。在GameLayer.mm顶部植入Floor.h:
    #import "Floor.h"
    然后在init底部添加平面物件:
    [objectLayer addChild:[[Floor floorSprite] ccNode] z:20];
    我们无需在物理空间中再添加任何物件——其他内容都已包含于Gbox2D之中。
    然后在iPhone模拟器中编辑和运行项目。所呈现的内容应大致如下:

    iPhone simulator

    iPhone simulator


    好极了——现在我们可以着手在游戏中添加动作元素。

    降落物件

    这部分内容的两个相关目标是:让物件从天而降,添加音效。
    所有降落物件的基本类将被命做Object。其将处理音效及若干基本碰触探测。我们随后将谈及从Object类中导出其他子类。
    首先,通过iOS\Cocoa Touch\Objective-C类模版创建新文件。将类命作Object,将其变成GB2Sprite的子类(dApps注:记得要将Object.m的扩展名改成.mm)。