使用SpriteBuilder创建Levels(Create Levels with SpriteBuilder)
发射企鹅很有趣,然而企鹅和雪豹发生碰撞更有乐趣,下面我们来学习如何创建和加载Level。
设置地面
我们现在打算在游戏场景中载入一个平稳的地面。首先我们要做的就是增加一个地面(ground)到CCPhysicsNode并设置为物理物件。拖动ground节点到CCPhysicsNode时间轴:
选中ground,在属性窗格(右窗格中第三个选项卡)打开物理选项卡。启用物理并将其设置为“静态”。静态用于对象从不移动,并不会受到重力或其它力。由于我们的地面不平坦,我们要收缩它的界限了一下。否则,我们会在一些地方出现漂浮物。通过移动粉红色角落下来几个像素做到这一点:
现在我们有一个坚实的地面,这将停止物体坠落出屏幕外。
设立一个Level加载机制
现在我们要解决我们的第一个小难题。问题:我们希望在我们的游戏中能够有无限量的levels。因此,我们不希望游戏机制(发射,碰撞检测等)是level的一部分。否则,我们将有大麻烦,如果我们想改变他们,我们就需要将更改应用到各个层面。
这意味着我们不会在我们的Gameplay.ccb中直接添加一个Level信息。一个更好的解决方案是在Gameplay.ccb中定义一个区域,这个区域专门用于具体Level及Level的数据加载。
添加一个Level节点
拖动一个新的CCNode到你的时间轴上并让它成为CCPhysicsNode的子类,因为我们要加载的levels需要包含物理对象(在cocos2d每个物理对象必须是一个CCPhysicsNode的子类)。
使用于以下尺寸:X:469,Y:47,宽度:490,高度:275:
这个节点是我们在后面即将要加载的Level的容器。实际加载将发生在代码中,因此创建要一个代码连接,使levelNode能在Gameplay类中访问。调用变量“_levelNode”。
创建Level
在你的Spritebuilder项目中创建一个名为“levels”的新文件夹。在这个文件夹创建一个新的接口文件。称之为“Level1”,选择“Layer”作为根节点,并设置它的大小为(490,275)。
您的第一级和文件夹结构应该是这样的:
恭喜你,这是你的第一个层次!现在添加一些内容。拉出多个seal.ccb文件和冰块(不同的图像tallblock.png等)放置在这个场景中。一定要在Level中放置一些物品在靠近左边缘的地方(使得他们在Level加载后能够被看见,即使是使用了滚动机制)。你的场景可能看起来有点像这样:
添加水平加载代码
现在,我们要添加一些Level的加载代码。在Xcode打开Gameplay.m。在 @implementation块中添加一个成员变量(你添加的_physicsNode变量):
CCNode *_levelNode;
将下面代码添加到didLoadFromCCB方法的末尾:
CCScene *level = [CCBReader loadAsScene:@"Levels/Level1"];
[_levelNode addChild:level];
这将加载Level1,并把它作为levelNode的子节点。当你运行你的游戏,你应该看到你的等级会出现在游戏场景中:
滚动场景
现在,我们可发射企鹅了,当企鹅发射以后我们要跟随它穿过我的Level来提升体验。很幸运的是cocos2d已经提供了这样的一个非常方便的方式。
你以前使用CCActions吗?CCActions提供了很多方便的方法在代码中来实现移动,缩放等的动画。执行CCAction始终是一个两步过程:
设置一组参数(如规模,持续时间等)一CCAction
告诉所有的CCNode来运行CCAction
为了实现我们的摄像头能进行企鹅的跟踪动作,我们要用到CCActionFollow。你需要定义一个被跟随的CCNode节点,你也可以定制边界,让摄像头不会滚动到背景图片以外的区域。
下面代码需要添加到Gameplay.m的launchPenguin的方法的末尾:
// ensure followed object is in visible are when starting
self.position = ccp(0, 0);
CCActionFollow *follow = [CCActionFollow actionWithTarget:penguin worldBoundary:self.boundingBox];
[self runAction:follow];
再次运行你的游戏,你会看到:
正如你所看到的企鹅不与冰块碰撞呢。这是因为它们不是物理对象的关系。让我们进入下一个步骤!
捶冰块
在你的SpriteBuilder项目中打开Level1.ccb。选择每个冰块,使它物理化。请记住,你可以拖动粉色圆点来改变物理体的形式。
一旦你做完了,发布您的SpriteBuilder项目,然后再次运行它。你现在应该能够碰撞到冰块:
为Level添加复位(Retry)
现在我们能够轻易地摧毁这个Level,当然我们也可以很容易地恢复它,让我们为这个Level添加一个复位功能吧。
在SpriteBuilder打开Gameplay.ccb。拖动一个按钮到屏幕的左上角。设置标题和按钮的代码连接:
实现是很容易的。我们只需要使用CCDirector重新加载这个场景:
- (void)retry {
// reload this level
[[CCDirector sharedDirector] replaceScene: [CCBReader loadAsScene:@"Gameplay"]];
}
太棒了!现在运行该应用程序,并利用新的“Retry”按钮。你可以预见哪些问题是要来了?没错!该按钮是游戏的场景,是跟随企鹅滚动的一部分。这意味着屏幕的按钮滚动。哎呀!在继续阅读之前,再想想这个问题可能的解决方案。当你面对这种障碍的时候想出一些想法是很重要的。
固定Level的复位,第1部分
我们将通过增加一个内容节点重组游戏的场景。所有的游戏动作将被添加到内容节点,所有的UI元素将对该内容节点的顶部加入。
打开Gameplay.ccb并添加位置为(0,0)的内容节点CCNode。现在,我们要重组场景的时间轴,拖动除了按钮节点外的所有节点到内容节点中,成为内容节点的子节点。当你完成你的场景层次应该是这样的:
我们已经重组了现场,但,这并不能改变什么呢。我们还能在游戏中滚动我们的retry按钮。那么,我们第二步应该怎么固定这个retry按钮到屏幕左上角呢?
固定Level的复位,第2部分
我们需要滚动contentNode,而不是游戏的场景!为contentNode添加代码连接,使得在Gameplay.m中能够访问。当代码连接建立,在Xcode打开Gameplay.m。添加你需要的代码连接的成员变量。然后修改实际的滚动代码。使新的内容节点上执行,而不是游戏场景的动作。你的代码的设置和执行的动作现在看起来应该像这样:
// ensure followed object is in visible are when starting
self.position = ccp(0, 0);
CCActionFollow *follow = [CCActionFollow actionWithTarget:penguin worldBoundary:self.boundingBox];
[_contentNode runAction:follow];
现在,内容节点的滚动,而不是完整的游戏场景。由于内容节点仅用于构建场景,没有内容的大小,我们仍然使用游戏场景的背景来定义边界。
如果你现在运行游戏,按钮应该留在左上角,并允许您轻松地在任何时间重新开始Level。
原文:
https://www.makegameswith.us/tutorials/getting-started-with-spritebuilder/levels/
从下一节开始我们要进入Chipmunk物理引擎的学习了,这个也是模拟现实物理世界游戏的精髓,如果你对Chipmunk还不是很了解的话可以先“google it”,在下一节中我们将直接介绍如何在Spritebuilder中运用它!转载请说明出处,wealpan将和您一起学习Spritebuilder!谢谢大家!