cocos2djs环境搭建 js空战游戏中跟踪弹怎么写 用的是贝塞尔曲线吗

当前位置: &
Cocos2d-x游戏实战指南 李宁
滚动鼠标滚轴,图片即可轻松放大、缩小
Cocos2d-x游戏实战指南 李宁(图1)
电&&&&&&话:
开&&&&&&本:16开
页&&&&&&数:524页
字&&&&&&数:759.000千字
I&&S&&B&&N:9
售&&&&&&价:55.30元
Copyright(C)
孔夫子旧书网
京ICP证041501号
海淀分局备案编号拒绝访问 |
| 百度云加速
请打开cookies.
此网站 () 的管理员禁止了您的访问。原因是您的访问包含了非浏览器特征(3911efc177fa4388-ua98).
重新安装浏览器,或使用别的浏览器今天看啥 热点:
Cocos2d-x《雷电大战》(6) 智能敌机AI来袭--飞行路径算法设计与实现(上),cocos2d
&&&&&&&&&& 林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka&&&&&& 本文要实现飞机类游戏中的一连串飞机的跟随出和和并行出出。而网上找了一些Cocos2dx开发的飞行类游戏,都只找到一些简单的智能敌机。基本上没什么AI,这样游戏玩起来就太没意思了。然后又去找敌机飞行路径的相关资料,发现相关的也很少。想想还是自己来设计吧!&&&&&& 飞机类游戏设计中,智机的飞行路径设计和智能子弹的设计绝对一个飞行类游戏好坏是的核心。敌机智能也是分级别的。BOSS机就不说了,而飞行游戏由于其特殊性,还经常有那种一连串一起出现的敌机。这种又可分为以下两种:跟随:相同的位置,相同的飞行路径,不同的启动时间,一般是按时间间隔。并飞:不同的位置,相同的运行路径,相同的启动时间。效果如下:&&&跟随,还未做碰撞判断& 并飞,还未做碰撞判断Cocos2d-x版本:3.4工程环境:VS30213一、跟随飞行&&&&&&& 在跟随飞行中,简单一点的跟随飞行路线就是直线了,比如从左到右,从一个角到另一个角。这种做法都比较简单,没什么难度。实际游戏开发中,也很少见这种的跟随飞行,比较多的还是变化的曲线。而这种曲线一般都是贝赛尔曲线。飞机中不仅要飞行,还是进行实时的角度变化,这样才更加模拟真实的游戏场景!1.1& 贝赛尔曲线简介&&&&&& 贝塞尔曲线是应用于二维图形应用程序的数学曲线。曲线的定义有四个点:起始点、终止点(也称锚点)以及两个相互分离的中间点。滑动两个中间点,贝塞尔曲线的形状会发生变化 .&&&&&& P0、P1、P2、P3四个点在平面或在三维空间中定义了三次方贝塞尔曲线。曲线起始于P0走向P1,并从P2的方向来到P3。一般不会经过P1或P2;这两个点只是在那里提供方向资讯。P0和P1之间的间距,决定了曲线在转而趋进P3之前,走向P2方向的“长度有多长”。p0起点,p3是终点,p1,p2是控制点1.2 游戏应用&&&&&& 我们可能需要在游戏中模拟导弹或箭的移动轨迹,用才cocos2d-x下的bezier可以轻松的模拟出来cocos2d-x下为我们提供了两个action BezierBy和BezierTo,使用也很简单,只需要填充结构体: //设置贝塞尔曲线参数
ccBezierConfig tr0;
tr0.endPosition = Vec2(0, 10);//终点
tr0.controlPoint_1 = Vec2(250, 300);//控制点1
tr0.controlPoint_2 = Vec2(180, 150);//控制点2
ActionInterval* bezierForward = BezierTo::create(3.f, tr0);//创建运行的贝塞尔曲线我们只需要提供两个控制点和一个终点位置就可以了,这里要注意的是CCBezier这个action是以当前位置为起始点的,两个控制点和终点都是相对于起始点的偏移值如:tr0.endPosition = ccp(280,240); 是相对于起始点的偏移1.3 代码& 这里只是要验证算法,所以代码还没有单独封装成类,而且也还没有将图像都打包成plist或用&SpriteBatchNode来优化内存。笔者打算把敌机飞行路径和敌机子弹设计完成之后,再统一来优化内存!在GameMain.h中添加一个定时器: void enemyBuild1(float dt);//跟随然后就是GameMain.cpp的init()函数打开定时,这里设置每隔0.5 //每隔0.5S调用一次
schedule(schedule_selector(GameMain::enemyBuild1), 0.5f);最后就是实现了:void GameMain::enemyBuild1(float dt){
Size winSize = Director::getInstance()-&getWinSize();
auto spritePlane = Sprite::create(&air3.png&);
spritePlane-&setRotation(90);
spritePlane-&setPosition(Vec2(0,400));
spritePlane-&setScale(0.25);
this-&addChild(spritePlane);
//设置贝塞尔曲线参数
ccBezierConfig tr0;
tr0.endPosition = Vec2(0, 10);//终点
tr0.controlPoint_1 = Vec2(250, 300);//控制点1
tr0.controlPoint_2 = Vec2(180, 150);//控制点2
ActionInterval* bezierForward = BezierTo::create(3.f, tr0);//创建运行的贝塞尔曲线
ActionInterval *forwardBy = RotateBy::create(3.f,180);
// 第二个参数:如果是正数则是顺时针,否则逆时针
Spawn* spawn = Spawn::create(bezierForward, forwardBy,NULL);//创建合成动作
//飞机执行完动作后进行函数回调,调用移除飞机函数
auto actionDone = CallFuncN::create(
CC_CALLBACK_1(GameMain::enemyRemove, this));
//连续动作
Sequence* sequence = Sequence::create(spawn,actionDone, NULL);
spritePlane-&runAction(sequence);
}别看代码少,里面涉及到的内容不少呢!其中删除飞机的函数:void GameMain::enemyRemove(Node* pNode){
if (NULL == pNode) {
Sprite* plane = (Sprite*)pN
this-&removeChild(plane,true);
}要记得先在GameMain.h中定义 void enemyRemove(Node* pNode);最后就是运行了,效果如下:二、并飞飞行&&&&&& 并飞就比简单了,因为是相同的路径方法。而且一般都不考虑到角度旋转的问题。游戏中最多出现的是左右并飞或者上下并飞。无非就是设置几架飞机在一排线上,然后设置飞行路径。最后执行就是了,下面直接来看看代码吧,注释很详细,有需要的直接拿过去,很方便自己扩展,把图像名改下就好。要记得,这里还未做内存优化,如果想做的话,有两种方法。一种是图像做成plist,另一种是用&SpriteBatchNode来做。在这里在,我推荐用前者,但是最好等游戏全开发完了再来弄吧。首先GameMain.h添加定时器: void enemyBuild2(float dt);//并飞打开定时器:
//每隔3S调用一次
schedule(schedule_selector(GameMain::enemyBuild2), 3.0f);最后就是实现了:void GameMain::enemyBuild2(float dt){
Size winSize = Director::getInstance()-&getWinSize();
Point origin = Director::getInstance()-&getVisibleOrigin();
//生成精灵
auto spritePlane1 = Sprite::create(&air4.png&);
auto spritePlane2 = Sprite::create(&air4.png&);
auto spritePlane3 = Sprite::create(&air4.png&);
//得到精灵宽和高
float height = spritePlane1-&getContentSize().
float width = spritePlane1-&getContentSize().
//旋转的角度
spritePlane1-&setRotation(180);
spritePlane2-&setRotation(180);
spritePlane3-&setRotation(180);
//设置缩放
//spritePlane1-&setScale(0.3);
//spritePlane2-&setScale(0.3);
//spritePlane3-&setScale(0.3);
//设置位置
spritePlane1-&setPosition(Vec2(width, winSize.height + height));
spritePlane2-&setPosition(Vec2(winSize.width / 2, winSize.height - height));
spritePlane3-&setPosition(Vec2(winSize.width - width, winSize.height + height));
//层中加入精灵
this-&addChild(spritePlane1);
this-&addChild(spritePlane2);
this-&addChild(spritePlane3);
//计算飞行时间
float flyVelocity =200;//运行速度,可以自己控制,每秒所走的像素
float flyLen = winSize.
float realFlyDuration = flyLen / flyV//实际飞行的时间
//子弹运行的距离和时间,从飞机处开始运行到屏幕底部
auto actionMove1 = MoveBy::create(realFlyDuration, Point(0, -winSize.height - height));
auto actionMove2 = MoveBy::create(realFlyDuration, Point(0, -winSize.height -height));
auto actionMove3 = MoveBy::create(realFlyDuration, Point(0, -winSize.height - height));
//子弹执行完动作后进行函数回调,调用移除子弹函数
auto actionDone = CallFuncN::create(
CC_CALLBACK_1(GameMain::enemyRemove, this));
//连续动作
Sequence* sequence1 = Sequence::create(actionMove1, actionDone, NULL);
Sequence* sequence2 = Sequence::create(actionMove2, actionDone, NULL);
Sequence* sequence3 = Sequence::create(actionMove3, actionDone, NULL);
//飞机开始跑动
spritePlane1-&runAction(sequence1);
spritePlane2-&runAction(sequence2);
spritePlane3-&runAction(sequence3);
}来看看效果:都还没做碰撞检测,可以看到。敌机按照我们的要求生成并运动了。&&&&&&&& 这就是群飞飞机群的两种方式,也可以将并飞和跟随相结合。就可以生成很多种不同的飞机路径。这在后头我将会再来讲解,今天就先到这里了。敌机类最好是自己封装,这里还没有实现。有需要的可以自己把函数改改就OK了!最后,再放张图!林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka
相关搜索:
相关阅读:
相关频道:
Android教程最近更新使用Cocos2D制作简单iPhone游戏的教程
作者:Ray Wenderlich
Cocos2D是个用于iPhone的强大开发库,可以为你的iPhone游戏开发节省大量的时间。它带有精灵支持、炫丽的图像效果、动画、实体库、音效引擎等等内容。
我刚刚开始学习使用Cocos2D,尽管有各种各样的Cocos2D初学教程,但我无法找到我真正想要的教程,即制作一款带有动画、碰撞和音频的简 单游戏,不带有过多的高级功能。最终,我自行制作了一款简单的游戏,我觉得需要根据此次开发经验编写教程,以便能为其他初学者所使用。
该教程将知道开发简单iPhone游戏的从头到尾的步骤。你可以按顺序学习,或者直接跳到文章末尾的示例项目上。
下载和安装Cocos2D
你可以从Cocos2D Google Code页面下载Cocos2D。
下载代码后,你需要做的就是安装有用的项目模板。打开末端窗口,输入以下命令:./install-templates.sh -f -u。
必须注意的是,如果你有在非标准directory上安装过XCode,你可以随意将参数输入安装文本中(游戏邦注:就像在同一台电脑上有多个SDK版本的做法一样)。
现在,让我们先开始创建简单的“Hello World”项目,并使用刚刚安装的Cocos2D模板来运行。打开XCode并新建Cocos2D项目,选择cocos2d中的“Application”模板,将项目命名为“Cocos2DSimpleGame”。
NewProject()
继续构建并运行这个模板。如果不出差错的话,你将会看到如下画面:
HelloWorld()
Cocos2D中融入了“界面”的概念,就像游戏中的“关卡”或“屏”一样。比如,游戏主菜单需要一个界面,主动作部分也需要一个界面,游戏结束同 样需要一个界面。界面分为多个层(游戏邦注:类似于Photoshop),曾包含精灵、标签、菜单等节点。节点也可能包含其他节点(游戏邦注:比如精灵中 可能有个子精灵)。
看下上述实例项目,你会发现其中只含有一个层,即HelloWorldLayer,我们将在此开始实施主要的游戏玩法。继续将其打开,你会发现现在初始方法中有个名为“Hello World”的标签。我们把这个标签拿走,用精灵来替换。
在我们添加精灵之前,我们需要某些图片。你可以用自己设计的图片,也可以使用这个项目中使用的图片,包括玩家图片、抛射物图片和目标图片。
获得图片后,将它们拖到XCode的资源文件夹中,确认“Copy items into destination group’s folder (if needed)”前打钩。
现在我们已经有图片了,下一步就需要为玩家图片指定位置。必须注意的是,在Cocos2D中屏幕左下角的坐标为(0, 0),往右或往上移动分别使X轴和Y轴值增加。因为这个项目采用的是风景模式,这意味着右上角的坐标为(480, 320)。
还必须注意的是,当我们设定某个物体的位置时,其位置的参考点所添加的精灵的中心点。因而,如果我们要让玩家图表在横轴上与边界对其,纵轴位于中心,我们应该:
1、位置的X轴坐标设置为“(玩家精灵宽度)/2”
2、位置的Y轴坐标设置为“(窗口高度)/2”
下图清晰地显示所设置的玩家精灵的位置:
Sprite Coordinates()
接下来,打开Classes文件夹,点击HelloWorldLayer.m,将初始方法用以下代码替换:
-(id) init
if( (self=[super init] )) {
CGSize winSize = [[CCDirector sharedDirector] winSize];
CCSprite *player = [CCSprite spriteWithFile:@&Player.png&
rect:CGRectMake(0, 0, 27, 40)];
player.position = ccp(player.contentSize.width/2, winSize.height/2);
[self addChild:player];
编辑运行,你会看到精灵显示完好,但背景默认为黑色。对于这个项目来说,白色的背景看起来会好很多。自定义Cocos2D中的层背景的方式之一是使用CCLayerColor。点击HelloWorldLayer.h,将HelloWorld界面声明定义如下:
HelloWorldLayer : CCLayerColor
然后点击HelloWorldLayer.m,对初始方法做以下些许修改就可以将背景设定为白色:
if( (self=[super initWithColor:ccc4(255,255,255,255)] )) {
继续编辑运行,你应该会看到精灵正位于白色的背景之上。
精灵正位于白色的背景之上(from raywenderlich)
接下来,我们将在界面中添加某些供忍者攻击的目标。为让游戏更为有趣,我们将目标设定为可以移动,否则游戏难度就太低了!因而,我们先将目标位置设定在右侧屏幕之外,然后为其设定动作,逐渐向左移动。
在最初方法之前添加以下方法:
-(void)addTarget {
CCSprite *target = [CCSprite spriteWithFile:@&Target.png&
rect:CGRectMake(0, 0, 27, 40)];
// Determine where to spawn the target along the Y axis
CGSize winSize = [[CCDirector sharedDirector] winSize];
int minY = target.contentSize.height/2;
int maxY = winSize.height – target.contentSize.height/2;
int rangeY = maxY – minY;
int actualY = (arc4random() % rangeY) + minY;
// Create the target slightly off-screen along the right edge,
// and along a random position along the Y axis as calculated above
target.position = ccp(winSize.width + (target.contentSize.width/2), actualY);
[self addChild:target];
// Determine speed of the target
int minDuration = 2.0;
int maxDuration = 4.0;
int rangeDuration = maxDuration – minD
int actualDuration = (arc4random() % rangeDuration) + minD
// Create the actions
id actionMove = [CCMoveTo actionWithDuration:actualDuration
position:ccp(-target.contentSize.width/2, actualY)];
id actionMoveDone = [CCCallFuncN actionWithTarget:self
selector:@selector(spriteMoveFinished:)];
[target runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
在这里,我用较为冗长的代码来使其中的动作更容易让人理解。第一部分代表的是我们之前讨论过的内容:我们做些简单的计算来设定所创建物体的位置,并以与设定玩家精灵同样的方式放置在场景中。
这里的新元素就是动作的添加。Cocos2D提供了大量内置动作,你可以用来设定精灵动作,比如移动、跳跃、消失及其他动画动作。在这里,我们在目标上使用了以下三个动作:
CCMoveTo:我们使用CCMoveTo动作来指导物体从屏幕之外逐渐向左移动。你会注意到,我们可以指定移动的间隔时长,这里我们设定时长在2秒至4秒间随意变化。
CCCallFuncN:CCCallFuncN功能允许我们指定在动作发生时物体发出回叫信号。我们指定一种称为“spriteMoveFinished”的回叫信号。
CCSequence:CCSequence动作让那个我们可以设置系列动作按次序发生,每次一个动作。以这种方式,我们可以首先执行CCMoveTo动作,等该动作结束后再执行CCCallFuncN动作。
接下来,便是添加我们在CCCallFuncN动作中提到的回叫功能。我们可以将以下代码添加至addTarget之前:
-(void)spriteMoveFinished:(id)sender {
CCSprite *sprite = (CCSprite *)
[self removeChild:sprite cleanup:YES];
该功能的目标在于,一旦精灵移动出屏幕后,就将其从屏幕中移除。这一点非常重要,这样就不会有大量无用的精灵存在于屏幕之上了。应该注意的是,还有其他更好的办法来处理这个问题,比如重复使用精灵,但在这个新手教程中我们采取这种较为简单的做法。
最后需要做的事情是,我们需要调用创造目标的方法!为让游戏变得有趣,我们让目标随时间不断变化。在Cocos2D中,我们可以通过将回叫功能设定为周期性回叫来实现这个目标。在初始方法中添加以下回调代码:
[self schedule:@selector(gameLogic:) interval:1.0];
然后以下列方法来执行回调功能:
-(void)gameLogic:(ccTime)dt {
[self addTarget];
现在,如果你编辑并运行项目,你应该会看到目标在屏幕中移动,如下图所示:
目标在屏幕中移动(from raywenderlich)
射击抛射物
此时此刻,我们的忍者正希望能够有所动作,因而让我们添加射击动作!执行射击动作的方式有许多种,但是在这款游戏中,我们将设计成,当用户点击屏幕时,忍者就会朝点击点的方向射出抛射物。
接下来,我将使用CCMoveTo动作来实现此目标,以使新手能够容易理解。为了实现这个目标,我们需要做些数学运算。这是因为CCMoveTo需 要我们指定抛射物的落点,但是我们不能只使用接触点,因为接触点代表的只是玩家角色射击的方向而已。我们想保证射出的子弹能够通过接触点然后射出屏幕。
下图显示我们所要做的工作:
保证子弹能够通过接触点然后射出屏幕(from raywenderlich)
因此,你可以看到原点和触点以及X和Y轴平行线组成了一个小三角形。我们只需要以同等的比例来绘制出大三角形,将一个落点设置在屏幕之外。
接下来,要处理的是代码问题。首先,我们要激活层上的触点。在初始方法中添加下列代码:
self.isTouchEnabled = YES;
激活层上的接触之后,我们现在可以接收到接触事件的回调函数。因而,让我们执行ccTouchesEnded方法,当用户接触屏幕时就可以产生回调,使用下列代码:
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
// Choose one of the touches to work with
UITouch *touch = [touches anyObject];
CGPoint location = [touch locationInView:[touch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
// Set up initial location of projectile
CGSize winSize = [[CCDirector sharedDirector] winSize];
CCSprite *projectile = [CCSprite spriteWithFile:@&Projectile.png&
rect:CGRectMake(0, 0, 20, 20)];
projectile.position = ccp(20, winSize.height/2);
// Determine offset of location to projectile
int offX = location.x – projectile.position.x;
int offY = location.y – projectile.position.y;
// Bail out if we are shooting down or backwards
if (offX &= 0)
// Ok to add now – we’ve double checked position
[self addChild:projectile];
// Determine where we wish to shoot the projectile to
int realX = winSize.width + (projectile.contentSize.width/2);
float ratio = (float) offY / (float) offX;
int realY = (realX * ratio) + projectile.position.y;
CGPoint realDest = ccp(realX, realY);
// Determine the length of how far we’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/
// Move projectile to actual endpoint
[projectile runAction:[CCSequence actions:
[CCMoveTo actionWithDuration:realMoveDuration position:realDest],
[CCCallFuncN actionWithTarget:self selector:@selector(spriteMoveFinished:)],
在第一部分中,我们选择了一个触点,获得触点在当前视图中的位置,然后调用convertToGL将坐标转化成当前的布局。这一点很重要,因为我们使用的是风景模式。
接下来,我们装载抛射物精灵,像往常那样设置初始位置。随后,我们决定希望抛射物移向何处,根据之前描述的运算法则,使用玩家和触点间的矢量作为指导方向。
应该注意的是,运算法则并不是很理想。我们强迫子弹一直移动,直到其到达屏幕外的X点。
我们必须做的最后一件事是决定移动的间隔。我们想要让子弹以恒定不变的速率沿某个方向射出,因而我们还得做些数学运算。利用Pythagorean Theorem,我们可以推导出移动的速度。从几何学公式上看,三角形斜边的平方等于两边的平方和。只要我们得到移动的距离,将其除以速度就可以得到间隔 时间。
剩下的工作就是像目标那样设定动作。编辑运行,现在你的忍者可以以恒定的速率射出子弹了。
你的忍者可以以恒定的速率射出子弹了(from raywenderlich)
现在,我们已经将忍者的武器射击设计完成了。但是在游戏中,忍者想要做的是击落目标。所以,让我们添加某些发现抛射物击中目标的代码。
在Cocos2D中的解决方案多种多样,包括使用物理库Box2D或Chipmunk。但是为保持这个教程的简单性,我们决定自行设置一种简单的碰撞检测。
为实现这个目标,我们首先需要将目标和抛射物设计在当前界面中。
添加以下代码至HelloWorldLayer中:
NSMutableArray *_
NSMutableArray *_
然后用初始方法来初始化:
_targets = [[NSMutableArray alloc] init];
_projectiles = [[NSMutableArray alloc] init];
清除dealloc方法中的记忆:
[_targets release];
_targets =
[_projectiles release];
_projectiles =
现在,修改addTarget方法,添加新目标至目标列表并设定供以后使用的标签:
target.tag = 1;
[_targets addObject:target];
然后修改ccTouchesEnded方法,添加新抛射物至抛射物列表并设定供以后使用的标签:
projectile.tag = 2;
[_projectiles addObject:projectile];
最后,修改spriteMoveFinished方法,根据标签从恰当的列表中移除内容:
if (sprite.tag == 1) { // target
[_targets removeObject:sprite];
} else if (sprite.tag == 2) { // projectile
[_projectiles removeObject:sprite];
编辑运行项目,保证项目仍然运转良好。现在应该还看不出什么很明显的差别,但是我们需要执行某些接触察觉。
添加下列方法至HelloWorldLayer:
- (void)update:(ccTime)dt {
NSMutableArray *projectilesToDelete = [[NSMutableArray alloc] init];
for (CCSprite *projectile in _projectiles) {
CGRect projectileRect = CGRectMake(
projectile.position.x – (projectile.contentSize.width/2),
projectile.position.y – (projectile.contentSize.height/2),
projectile.contentSize.width,
projectile.contentSize.height);
NSMutableArray *targetsToDelete = [[NSMutableArray alloc] init];
for (CCSprite *target in _targets) {
CGRect targetRect = CGRectMake(
target.position.x – (target.contentSize.width/2),
target.position.y – (target.contentSize.height/2),
target.contentSize.width,
target.contentSize.height);
if (CGRectIntersectsRect(projectileRect, targetRect)) {
[targetsToDelete addObject:target];
for (CCSprite *target in targetsToDelete) {
[_targets removeObject:target];
[self removeChild:target cleanup:YES];
if (targetsToDelete.count & 0) {
[projectilesToDelete addObject:projectile];
[targetsToDelete release];
for (CCSprite *projectile in projectilesToDelete) {
[_projectiles removeObject:projectile];
[self removeChild:projectile cleanup:YES];
[projectilesToDelete release];
以上代码看起来应该很清楚。我们只是不断重复抛射物和目标,创造与其界限盒保持一致的矩形,利用CGRectIntersectsRect来寻找交 叉点。如果找到了交叉点,我们将他们从界面和列表中移除。应该注意的是,我们必须将物体添加至“toDelete”列表中,因为你无法在重复物体时将其从 列表中移除。依然有多种方法可以实现这个目标,我还是会阐述较为简单的方法。
在我们开始运行项目之前,还必须做一件事情,添加以下代码至初始方法中,安排该方法以尽量高的频率运行:
[self schedule:@selector(update:)];
编辑运行,现在你的抛射物命中目标时,它们应该会同时消失!
现在,我们几乎快完成了这款游戏(游戏邦注:尽管游戏较为简单)。我们只需要添加些许音效和音乐以及某些简单的游戏逻辑。
如果你看过我关于iPhone游戏音频编程设计的系列博文,你就会知道Cocos2D开发者用此工作来在游戏中添加基础音效是多么的简单。
首先,拖动背景音乐和射击音效到资源文件夹中。你可以使用我所制作的背景音乐和音效,也可以自行制作。
然后,在HelloWorldLayer.m顶端添加下列导入:
#import “SimpleAudioEngine.h”
在初始方法中,以下列代码来控制背景音乐的播放:
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@”background-music-aac.caf”];
在ccTouchesEnded方法中,以下列代码来播放音效:
[[SimpleAudioEngine sharedEngine] playEffect:@”pew-pew-lei.caf”];
现在,让我们创造一个新界面,用来显示玩家的胜利或失败。点击Classes文件夹,然后点击File\New File,选择Objective-C类,确认子类NSObject已被选择。点击Next,然后输入GameOverScene作为文件名,确认 “Also create GameOverScene.h”已选择。
然后以下列代码替换GameOverScene.h:
#import “cocos2d.h”
GameOverLayer : CCLayerColor {
CCLabelTTF *_
@property (nonatomic, retain) CCLabelTTF *
GameOverScene : CCScene {
GameOverLayer *_
@property (nonatomic, retain) GameOverLayer *
然后以下列代码替换GameOverScene.m:
#import “cocos2d.h”
GameOverLayer : CCLayerColor {
CCLabelTTF *_
@property (nonatomic, retain) CCLabelTTF *
GameOverScene : CCScene {
GameOverLayer *_
@property (nonatomic, retain) GameOverLayer *
Then replace GameOverScene.m with the following code:
#import “GameOverScene.h”
#import “HelloWorldLayer.h”
@implementation GameOverScene
@synthesize layer = _
- (id)init {
if ((self = [super init])) {
self.layer = [GameOverLayer node];
[self addChild:_layer];
- (void)dealloc {
[_layer release];
[super dealloc];
@implementation GameOverLayer
@synthesize label = _
-(id) init
if( (self=[super initWithColor:ccc4(255,255,255,255)] )) {
CGSize winSize = [[CCDirector sharedDirector] winSize];
self.label = [CCLabelTTF labelWithString:@&& fontName:@&Arial& fontSize:32];
_label.color = ccc3(0,0,0);
_label.position = ccp(winSize.width/2, winSize.height/2);
[self addChild:_label];
[self runAction:[CCSequence actions:
[CCDelayTime actionWithDuration:3],
[CCCallFunc actionWithTarget:self selector:@selector(gameOverDone)],
- (void)gameOverDone {
[[CCDirector sharedDirector] replaceScene:[HelloWorldLayer scene]];
- (void)dealloc {
[_label release];
[super dealloc];
必须注意的是,这里有两个不同的概念:界面和层。界面可以包含任意数量的层,虽然在这个示例项目中只包含一个。层只是在屏幕中间设立一个标签,安排转化发生3秒之后切回Hello World界面。
最后,让我们添加某些基本的游戏逻辑。首先,让我们先设置玩家已经摧毁的抛射物。将HelloWorldLayer.h中的HelloWorldLayer类做下列修改:
int _projectilesD
在HelloWorldLayer.m中,添加GameOverScene类的导入:
#import “GameOverScene.h”
增加数量并在更新方法中检查胜利的状况,使用下列代码:
_projectilesDestroyed++;
if (_projectilesDestroyed & 30) {
GameOverScene *gameOverScene = [GameOverScene node];
_projectilesDestroyed = 0;
[gameOverScene.layer.label setString:@&You Win!&];
[[CCDirector sharedDirector] replaceScene:gameOverScene];
最后,让我们设置成,某只目标触及玩家时玩家就失败。修改spriteMoveFinished方法,添加下列代码到标签中:
GameOverScene *gameOverScene = [GameOverScene node];
[gameOverScene.layer.label setString:@&You Lose :[&];
[[CCDirector sharedDirector] replaceScene:gameOverScene];
继续将项目编辑运行,现在你应该可以看到胜利或失败界面。
这个项目只是个最基本的示例,你可以使用Cocos2D在项目中添加更多新功能。或许你可以尝试添加条状图显示你还需要摧毁多少个目标才能获得胜 利,也可以为怪物的死亡添加更加绚烂的动画,或出于游戏趣味性目的添加更多音效、艺术或游戏逻辑。你完全可以尽量发挥自己的才华!
教程很经典,入门必看

我要回帖

更多关于 cocosjs 的文章

 

随机推荐