转自:http://article.ityran.com/archives/2544
转自:http://article.ityran.com/archives/2544
手把手教你使用CocosBuilder一次性导出Cocos2d-html5,Cocos2d-x和Cocos2d-iPhone的游戏资源文件。这个游戏90%的工作量是用工具完成。
The Game
设置工程
创建动画类型的主界面
主界面我们会包含一个渐变的背景,一个logo,一个开始游戏的按钮,和几片云彩的动画。首先,让我们开始加入渐变的背景。在窗口顶部的工具栏点击CCLayerGradient
我们希望渐变层(gradient layer)充满整个屏幕。选择这个层,设置填充(content size)大小单位为“%”并且设置宽高为100×100.
让我们把颜色修改为其他值以遍更适合我们游戏的主色调。点击开始颜色(start color)和完成颜色(
继续添加logo到主界面(
当启动主选单场景时会有漂亮的动画,但是我们还需要在启动时增加logo的动画。首先,点击canvas
你可以点击Play来测试一下这个动画。你也可以移动时间戳来看看每个帧的位置。
这个动画我们完成的很漂亮并且每帧的过渡很平滑,但是让我们再加点料。在关键帧之间右击
OK,我们让logo被覆盖了,但是我们依然需要一个启动游戏的按钮。我们将用CCMenu
点击‘Play’来测试动画。我们现在有一个很漂亮的主菜单介绍动画。当动画播放完毕后,整个场景就是完全禁止的。这不是很好,所以后面我们还会完善。
CocosBuilder提供了多个时间线。在文件中,多个时间线可以连续或者不连续播放,也可以通过代码控制回放。两个不同动画的时间线可以实现平滑过渡。我们这个工程会实现多个时间线,当介绍动画的时间线播放完成后,会循环播放另一个动画。
在动画菜单选择编辑时间线(Edit Timelines)。在弹出框中,先将默认的时间线重命名为Intro。然后点击plus-sign添加一条时间线并命名为Loop,点击完成。
我们选择要编辑的时间线,点击drop-down按钮(图上已经标出),选中Timelines->Loop。
现在我们有一条未添加关键帧的时间线。这条时间线默认是10秒钟,我们的工程刚好就要这么长。为了方便看出完成后的长度,你可以拖动比例条(scale slider)到左边。
按住option键点击两个关键帧中间,就在时间线的开头和结尾之间添加一个新的关键帧。点击这个新建的关键帧让它出于选中状态,通过调整比例值,或者拖动云彩,让云彩稍微变大一点。
回放动画,你可以看到一片云彩慢慢变大,然后再变回原始大小。让我们给每片云彩做相同的操作。点击所有的关键帧让选择框包含他们。你也可以用shift来选中。选中后,在Edit菜单选择 复制。把时间戳移动到时间线原点,选择另一片云彩点击粘贴。并重复在所有云彩中操作(并没有添加关键帧)。
最后,我们要让动画在我们需要的时候自动循环,就要用到链式时间线功能(chain timeline
主菜单的大部分已经完成,我们剩下的仅仅是在代码中调用这个界面。要调用这个场景,我们要给根节点设置一个定制类。选择根节点(在文件document的CCLayer中)。设置类名为“MainMenuScene”。我们会在稍后在代码中创建MainMenuScene。
游戏场景
我们使用游戏场景来载入在实际游戏中需要的所有东西。同时它也用来显示分数。在file菜单中选择New File
对于这个游戏来说,我们会使用和菜单场景一样的背景梯度。或是再创建一遍,或是通过双击项目视图的MainMenuScene,选择CCLayerGradient,复制黏贴到你的新文件处。
点击工具栏上的CCLayer图标来给场景加一个层。稍后在代码中我们会使用这个空的层来加载一个关卡。
如图所示,把位置设成(160,40),字体设置成o
我们也需要连接刚才创建的那个空层到代码。处理步骤同上并将变量明设为levelLayer。
现在我们已经完成这个游戏场景啦。让我们继续创建一些游戏对象。
增加游戏物体
我们这个游戏会用到4种游戏物体。游戏的主角:龙,以及钱币,炸弹,和爆炸效果。所有游戏物体都是我们稍后创建的GameObject类的子类。GameObject类是CCNode的一个子类。因此,CocosBuilder创建的游戏中的所有对象都继承自CCNode。(当然还有可能作为GameObject的插件程序存在,但是在本游戏中,我们并需要使用)。
龙
让我们开始创建游戏中最复杂的物体—龙。在File菜单中选取New File,创建一个新文件。选择根节点对象为CCNode,反选全屏选项(full screen),选择分辨率选项为iphone。
龙由几个不同的移动部件组成:身体和2个翅膀。首先我们先加入翅膀这样他们就会出现在身体的后面。在项目视图拖动gameobjects.plist/dragon-wing.png
然后,增加身体部分。拖动gameobjects.plist/dragon-body.png到画布区域。设置身体的位置为(0,0)。你的文件看起来就会是这样:
我们现在有了扑腾的翅膀啦,但是通过增加Bounce Out缓冲,我们可以让它显示的更加自然。在第一帧和中间帧之间右键,选择Bounce Out.。在中间那帧和最后一帧也做同样的设置。
现在来创建另外一只翅膀。首先确保没有帧被选中,然后选择翅膀。在edit菜单中选择Copy,并Paste.第二个翅膀就被复制到龙的身体前面了,因此我们需要使用Object菜单中的Arrange /Send Backward选项。请 确保新的翅膀在检查器中FilpX选项有被选中。这只会翻转图像,我们同意需要设置它的位置和锚点,设置位置为(8,4),锚点 (0.16,0.094)。这个翅膀的动画现在看起来不错了,但是选择的方向是错的。双击中间的那一帧来锁定它。你可以改变检查器(inspector) 中的旋转角度(大概80度左右)。继续播放动画,这时候,龙的两只翅膀应该都正常了。
在游戏中,我们的小龙会在碰到炸弹的时候停止扑腾它的翅膀。当撞到炸弹的时候,我们会播放另一个剪短的动画,然后再扑腾翅膀。因此我们需要2个时间轴。选择Animation
剩下还有要做的就是创建一个龙被击中的动画。移动时间轴的标记到末尾,选择每个翅膀并按R来增加旋转动画。现在移动标记到开头。将每个翅膀旋转向下,我分别设置了-123和123的值。为每个翅膀增加一个Bounce Out属性。
Bomb
炸弹
在街机游戏中怎么可能会少了坏人?我们需要一些很酷的炸弹~创建一个新文件就像dragon文件一样(选项也一样)。命名文件为Bomb并保存。选择根节点并设置自定义类为Bomb。
我们现在要为我们的炸弹增加一些旋转的钉子。设置时间轴长度为2s。拖曳gameobjects.plist-bomb-spikes.png到画布处并设置位置为(0,0),同样的拖曳thegameobjects.plist/bomb-body.png。炸弹身体会在尖刺的上方。
最后,请确保时间轴自动的循环播放,你可以动过点击No chained timeline
Coin
硬币
在我们的游戏中我们会看到2种硬币,普通硬币和结束硬币。吃了普通硬盘会给与我们的龙一个短暂的加速,吃了结束硬币会结束当前关卡。我们可以使用相同的类对于这2种硬币,但是在其中加一个额外的属性以方便我们在代码中区分他们。
用和dragon,bomb文件一样的设置创建一个新文件。命名为Coin,设置自定义类为Coin。
拖曳gameobjects.plist/coin01.png到画布区并设置位置为(0,0)。现在我们想要增加一帧基于硬币的动画,设置时间轴的长度为00:01:06.确保时间轴标记在最前面而且硬币精灵被选中。现在选择项目视图中的coin01.png到coin18.png。
选择Animation
现在我们开始创建“结束硬币”。打开Finder,复制Coin.ccb文件,并重命名为EndCoin.ccb。切回到CocosBuilder,双击项目视图来新建一个文件。为了区别这2种硬币,我们需要在根节点增加一个自定义的属性。选择根节点并点击检查器中的Edit Custom Properties。创建一个新的属性,命名为isEndCoin,设置种类为Bool并设置值为1.点击Done、
爆炸
当炸弹爆炸的时候,我们需要一些花哨的爆炸效果。我们可以使用粒子系统。每一个爆炸由2个粒子系统构成。
首先创建一个新文件,设置都同前面创建龙、炸弹和硬币的一样并命名文件为Explosion。设置时间轴长度为2秒,并定义根节点的自定义类名为Explosion。点击工具栏的粒子系统的图标2次,来增加2个粒子系统的文件。
两个粒子系统的参数设置如下图所示。如果想看一下效果,你可以点击检查器中的Start Particles按钮。
创建一个关卡
我们完成了我们所有的游戏物体。唯一还没做的界面就是关卡地图了。创建一个新文件,请确保根节点中CCLayer和full screen的选项被选择,选择iPhone Portrait的分辨率,但是设置高度为4096.
现在,从项目视图中拖曳并放置更多游戏物体。在我这种情况下,第一关看起来像这样:
游戏编码
现在我们已经为游戏创建好了所有接口文件,下一步开始编码。
用Xcode打开项目,右键单击Resources文件夹并选择Add Files to “CocosDragon”…….确保“Create groups for any added folders”单选框被选中,并且“CocosDragon
下一步,我们要添加CCBReader到项目下。CCBReader在示例代码的文件夹下。将他添加到“你项目 /cocos2d-iphone”。将CCBReader文件夹添加到你项目之后,确认Create groups for any added folders被选中,并且Copy items into destination group’s folder被选中。
Xcode下,打开Prefix.pch文件,它在Supporting Files组下。引入头文件的代码如下:
#ifdef __OBJC__ #import #import #import “cocos2d.h” #endif
MainMenuScene
我们现在开始编码。让我们一起创建一个主菜单(main menu)!选择File菜单下的New/File。选择Objective-C class,命名该类为MainMenuScene并设定该类为CCLayer的子类。
在MainMenuScene.m的最上部import
- (void) pressedPlay:(id)sender
{
}
当我们按下play按钮,我们将第一次通过ccbi文件加载游戏场景。然后通知CCDirector去用游戏场景 replace掉当前的场景。这部分的代码我们需要写到MainMenuScene里,而且需要在游戏开始时候加载。打开AppDelegate.m文 件,引入CCBReader.h,然后用下面的代码替换既存的引入初始场景的代码:
// Load the main menu scene from the ccbi-file
CCScene* mainScene = [CCBReader sceneWithNodeGraphFromFi
// Then add the scene to the stack. The director will run it when it automatically when the view is displayed.
[director_ pushScene: mainScene];
然后,还是在AppDelegate.m文件,用如下代码替换shouldAutorotateToInterf
- (BOOL)shouldAutorotateToInterf
这将确保我们的游戏以竖屏模式运行。你可以在github上找到源文件:
MainMenuScene.h
GameScene
当我们按下play按钮之后,GameScene.ccbi文件将会被加载,并创建GameScene的实例。现在我们需要创建GameScene类。创建一个新类命名为GameScene,让其继承自CCLayer。
在CocosBuilder里,我们添加了两个成员变量(levelLayer和scoreLabel)。我们需要添加它们到文件中去。并且也需要加载等级(Level)以及动态的记录当前的分数。在GameScene.h添加前面提到的两个成员变量:
@interface GameScene : CCLayer
为了从别的类里更好的管理分数,我们将在GameScene类里增加一个属性。我们也将增加方法去管理游戏结束以及升级的情况。
@property (nonatomic,assign) int score;
+ (GameScene*) sharedScene;
- (void) handleGameOver;
- (void) handleLevelComplete;
@end
下面我们来实现GameScene类的方法。打开GameScene.m。在头部importCCBReader.h。在开始实现该类之前,先定义一个静态变量以方便共享该类的实例。
static
在该类的类方法中返回这个共享实例。
+ (GameScene*) sharedScene
我也需要去synthesize这个分数属性。
@synthesize score;
当一个ccbi文件被加载的时候,CCBReader将会调用创建每个节点的方法didLoadFromCCB。通过实现该方法,你将在文件加载完毕的时候收到一个回调函数。我们将会利用回调信息去设置当前场景以及加载等级。
- (void) didLoadFromCCB
这部分代码加载Level.ccbi文件并且将其作为一个子节点加到我们在CocosBuilder里创建的levelLayer上。在真实的游戏当中我们可能会有不止一个的等级文件,并且对应玩家在游戏中的进度选择不同的文件。
当分数属性改变时,我们希望更新label上分数的显示。我们通过setscore:方法来实现。记住我们已经在CocosBuilder定义了scoreLabel。
- (void) setscore:(int)s
离开GameScene之前的最后一步是为控制游戏结束以及升级编码。在实际游戏中你可能做更多的事情在这些方法中,但是在该例子中,我们只是简单的返回主菜单场景。
- (void) handleGameOver
- (void) handleLevelComplete
你可以在github找到源码
GameObject
GameObject是一个抽象类,它是所有游戏对象的父类。他让我们可以等同对待所有的游戏对象。创建一个CCNode的子类,命名为GameObject。这个类包含一些基础属性的设置以及一些基础的方法,以便我们在游戏当中控制游戏对象。如果我们想移除一个对象那么可以设置isScheduledForRemove属性。这个更新方法会在每个框架更新游戏对象状态的时候调用一次。我们将在检测冲突的时候(在我们的游戏当中每一个游戏对象都视为圆形)使用radius属性。最后,如果两个游戏对象发生碰撞,两个发生碰撞的游戏对象的handleCollisionWith:方法将被调用。下面就是头文件的定义代码:
@interface GameObject : CCNode
- (void) update;
- (void) handleCollisionWith:(GameObject*)gameObject;
@implementation GameObject
@synthesize isScheduledForRemove;
// Update is called for every game object once every frame
- (void) update
{}
// If this game object has collided with another game object this method is called
- (void) handleCollisionWith:(GameObject *)gameObject
// Returns the radius of this game object
- (float) radius
{
Dragon
龙是我们游戏中最复杂的游戏对象。它控制着玩家将要控制的这个角色的行为,同时这也是游戏的主要行为。创建一个GameObject的子类命名为Dragon。
为了控制龙的运动,我们需要两个变量,纵向速度ySpeed,以及横向目标xTarget。xTarget将会在点击iPhone上的打击目标的时候被设置。之后变量将会被外部类设定,我们将会将他作为一个属性。下面是我们需要添加的头文件:
@interface Dragon : GameObject
.m文件将会更加有趣。首先,我们会整合一些其他的类进来,我们来引入他们。(我们将会在完成Dragon类之后,编写Coin和Bomb类)
#import “Dragon.h”
#import “Coin.h”
#import “Bomb.h”
#import “GameScene.h”
#import “CCBAnimationManager.h”
下面,我们来定义几个常量来方便对龙的行为的控制。使用常量是一个非常不错的选择,因为这样很方便我们去从感官上控制游戏。
#define kCJStartSpeed 8
#define kCJCoinSpeed 8
#define kCJStartTarget 160
#define kCJTargetFilterFactor 0.05
#define kCJSlowDownFactor 0.995
#define kCJGravitySpeed 0.1
#define kCJGameOverSpeed -10
#define kCJDeltaToRotationFactor
实现Dragon类的第一步,我们需要synthesize属性xTarget。
@synthesize xTarget;
然后来到init方法,在这里我们将初始化我们的成员变量。xTarget的初始值为160,位于屏幕中心。
- (id) init
我们将使用update方法让龙在屏幕上平滑的移动。在每个frame下,update方法会被调用一次。我们将利用一 个计算原始点和目标点之间距离的过滤器方法来获得一个新的X坐标。我所说的目标点就是玩家在屏幕上触摸的点。Y坐标则是在原始坐标的基础上增加现有速度来 计算得出的。之后我们更新速度,我们不但可以通过增加常量的方式加快速度,也可以利用参数减慢速度(这将防止龙的攻击速度过快)。我们同时依靠水平速度翘 起龙的一侧。如果纵向速度向下过快,那么游戏结束。
在Dragon类里我们也需要去控制碰撞。我们将通过判断是碰撞了哪种对象来相应的做出动作。如果碰到了钱币,我们增加 分数并且给龙一个向上增长的速度。如果我们碰到了炸弹,龙会降低速度并且播放在CocosBuilder里面制作的Hit动画。我们在 userObject里用CCBReader保存的CCBAnimationManager,之后调用 runAnimationsForSequence
最后我们要实现radius(半径)属性。它将用于控制碰撞。
完整的Dragon类,请参见:
Coin
金币有一个相当简单的逻辑,金币在碰到龙的时候会被移除。如果最后一枚金币碰撞到了龙,该等级的任务完成。创建一个名为 Coin的类,他是GameObject的子类。在CocosBuilder我们增加了一些自定义的属性,isEndCoin是专门针对最后一枚金币的, 普通金币也使用相同的自定义类。我们需要实现这个属性在我们的类里,下文是头部文件:
@interface Coin : GameObject
.m文件,我们首先要synthesize属性isEndCoin。
@synthesize isEndCoin;
我们不必移动金币,所以我们不用实现update方法。但是,当背龙碰撞的时候我们想移除它。并且,如果是最后一枚金币的话,我们想升级。
最后,让我们来设定金币的半径。
完整的代码,参见下方:
Bomb
炸弹是我们游戏当中的一个障碍物。创建名为Bomb的类,他是GameObject的子类。当炸弹碰撞到玩家的时候,它 会爆炸。这个效果是通过移除炸弹并且动态的加载爆炸效果来实现的。我们没有添加任何新的属性进来,所以头文件不需要修改。在.m文件中,我们需要实现 handleCollisionsWith:方法。
之后,我们需要设定炸弹的半径。
完整的代码,如下:
Explosion
最后一个游戏对象,我们将会实现爆炸(Explosion)。爆炸不会影响其他的任何游戏对象。但是我们会在它完成播放 之后移除调它。为此我们必须实现CCBAnimationManagerDeleg
@interface Explosion : GameObject
.m文件,我们将分配Explosion类作为CCBActionManager的代理,这步的创建将发生在爆炸加载的时候。我们将在didLoadFromCCB:方法来实现这步。
至此,当动画播放完毕我们将收到回调函数completedAnimationSequen
- (void) completedAnimationSequen
完整的代码见下方:
Level
我们就还剩一个Level类没有完成。Level将会控制所有的玩家输入,并且负责更新和移除我们的游戏对象。创建名为Level的类,它是CCLayer的子类。在CocosBuilder里,我们添加了一个成员变量dragon,所以我们要把它加到头文件。
@class Dragon;
.m文件,我们将引入计划访问的类。
#import “GameObject.h”
我们也将定义两个常量用于层的滚动。因为龙需要是一直可见的。
#define kCJScrollFilterFactor 0.1
#define kCJDragonTargetOffset 80
我们使用onEnter方法,在每个frame之前,去提供一个回调函数update:。在onExit我们移除这个回调。
- (void) onEnter
- (void) onExit
在update:方法我们将更新所有游戏对象。记住,在CocosBuilder里我们增加的游戏对象都是level的 子对象。之后,游戏对象更新以及发生位置改变的时候我们将检测是否有碰撞。在这个游戏里我们只检测与龙之间的碰撞,因为只有他是移动的。在其他的游戏里, 你可能需要写更多更复杂的代码去检测碰撞,或者有可能用到诸如Chipmunk,Box2d的物理引擎。因为所有的碰撞都是可控的,我们将会遍历游戏的所 有对象去看哪些对象被定时移除了。我们为这些对象创建一个数组,使用这个队列来移除他们。最后,我们调整层的位置,所以龙总是可见的。当调整位置的时候我 们使用过滤器代理去确保移动的平滑。
- (void) update:(ccTime)delta
- (void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
- (void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
完整的代码请参见:
总结
用所有的CocosBuilder文件为游戏创建的类,你应该可以在虚拟机或者真机上编译运行。很感谢花时间读这个教程,祝你编码愉快!
原文链接:https://www.f2er.com/cocos2dx/347098.html