cocos2d教程大全(编辑修改稿)内容摘要:

Projectile image, anda Target image.一旦你获得了这些图片,你就可以把它们用鼠标拖到xcode的resource文件夹中去,并且保证“ Copy items into destination group’s folder (if needed)”勾上了。 现在,我们拥有自己的图片了,我们先得计算一下,应该把player放在哪里。 请注意,cocos2d坐标系的原点在屏幕的左下角,即(0,0)位置在左下角,这与一般的窗口坐标系统在左上角有所区别。 x方向往右是正,y方向往上是正。 由于项目是landscape(横版)模式,这就意味着右上角的坐标是(480,320)。 还有需要注意的是,当我们设置一个对象的位置的时候,这个位置是相对于所加精灵的中心点来加的。 因此,如果我们想让我们的player精灵与屏幕的左边界水平对齐,并且垂直居中的话。 那么对于x轴:我们需要设置为[player sprite’s width]/2。 y坐标设置为[window height]/2。 下面有一张图,可以更加清楚一些:好,让他开始射击吧。 ,然后把init方法用下面的代码替换掉:(id) init{if( (self=[super init] )) {CGSize winSize=[[CCDirector sharedDirector] winSize]。 CCSprite*player=[CCSprite spriteWithFile:@rect:CGRectMake(0,0,27,40)]。 =ccp(, )。 [self addChild:player]。 }returnself。 }编译并运行,你的精灵这时候应该出现在正确的位置上了。 但是,这个前景默认是黑的。 对于这张忍者图片来说,白色的背景可能看起来更好一些。 在cocos2d里面,有一种非常简单的方式来改变层的背景颜色,那就是使用CCColoredLayer类。 好,跟我来吧。 ,然后把HelloWorld接口声明改成下面这样:@interface HelloWorld : CCColorLayer,在init方法里面做一些小小的修改,以便使我们能把层的背景颜色改成白的:if( (self=[super initWithColor:ccc4(255,255,255,255)] )) {编译并运行,这时你将看到你的精灵是在一个白色的背景上面了。 哈哈,我们的忍者看起来整装待发呢。 移动目标接下来,我们想增加一些目标怪物来与我们的忍者战斗。 为了使事情变得更加有趣,我想让这些目标可以移动–实际上这也并不是很难。 因此,让我们先在屏幕的右边靠外一点点创建一些目标,然后设置一个action,并使之从右边移动到左边。 接下来,紧接着上面init函数,添加下面代码:(void)addTarget {CCSprite*target=[CCSprite spriteWithFile:@rect:CGRectMake(0,0,27,40)]。 //Determine where to spawn the target along the Y axisCGSize winSize=[[CCDirector sharedDirector] winSize]。 intminY=intmaxY=intrangeY=maxYminY。 intactualY=(arc4random()%rangeY)+minY。 //Create the target slightly offscreen along the right edge,//and along a random position along the Y axis as calculated above=ccp(+(), actualY)。 [self addChild:target]。 //Determine speed of the targetintminDuration=intmaxDuration=intrangeDuration=maxDurationminDuration。 intactualDuration=(arc4random()%rangeDuration)+minDuration。 //Create the actionsid actionMove=[CCMoveTo actionWithDuration:actualDurationposition:ccp(, actualY)]。 id actionMoveDone=[CCCallFuncN actionWithTarget:selfselector:@selector(spriteMoveFinished:)]。 [target runAction:[CCSequence actions:actionMove, actionMoveDone, nil]]。 }在这里我将以一种非常啰嗦的形式来介绍,目的是方便大家理解。 第一部分需要解释的是我们之前已经讨论过了的:我们做一些简单的计算来决定把对象放在什么位置,然后设置对象的position,然后并把它加在场景上面,就和加载player精灵一样。 这里增加的新的元素就是actions。 cocos2d里面提供了许多非常方便的内置的action,你可以使用这样action来让你的精灵动起来。 比如move action,jump action,fade action,animation action(就是播放图片序列)等等。 这里,我们对目标对象使用了3种类型的action:• CCMoveTo:我们使用CCMoveTo action让目标从屏幕右边一直往左移动,直到移出屏幕。 注意,这里我们可以指定这个过程要花费多长时间。 这里使用了变化的时间间隔24秒。 • CCCallFuncN:它可以让你为某个执行此action的对象指定一个回调函数。 我们指定的回调函数是:spriteMoveFinished—目前并没有,到后面会具体给了来。 • CCSequence:它允许我们把一系列的action组成一个action序列,并且这些acton可以按顺序执行。 一次执行完所有的action。 在上面的例子中,我们让对象首先执行CcMoveTo,等CCMoveTo完成后,马上就会执行CCCallFuncN action。 接下来, 为CCCallFuncN action增加一个回调函数。 你可以在addTarget前面增加下面的代码:(void)spriteMoveFinished:(id)sender {CCSprite*sprite=(CCSprite*)sender。 [self removeChild:sprite cleanup:YES]。 }这个函数的目的是当精灵飞出屏幕之后,需要移除出当前的scene。 这个非常重要,这样的话我们就不会因为屏幕外面积累太多没有用到的精灵而造成内存泄漏。 注意,其实还有其它更好的方式来解决这个问题,比如使用一组可以重用的精灵等。 不过,对于初学者来说,我在这篇教程里,尽量简单化。 在我们继续之前,还有最后一件事没做。 我们需要调用这个方法来创建我们的目标怪物。 而且,为了使事情变得更加有趣,我们会随着时间连续不断地发射一些怪物出来。 我们可以使用cocos2d的定时scheduler,并指定一个回调函数来完成此功能。 一秒钟调用一次回调函数就可以了。 因此,在init函数返回之前,我们再加入下面的代码:[self schedule:@selector(gameLogic:) interval:]。 然后简单的实现一下这个回调函数,如下:(void)gameLogic:(ccTime)dt {[self addTarget]。 }就这么多。 现在编译再运行一下工作,你可以看到怪物在屏幕上面happy地移动了。 发射飞盘在这里,我们的忍者需要有一些行动了–因此让我们增加一些射击吧。 这里有许许多多实现射击的方式,但是在这个游戏里面,我们想让用户触摸一下屏幕,然后飞盘就会从player开始,沿着你触摸的位置发射出来。 我们使用CCMoveTo action来实现这个功能。 但是,为了使用这个功能,我们必须首先来做一些数学题。 这是因为,CCMoveTo需要我们为飞盘指定目的地。 但是我们又不能使用触摸点,因为触摸点仅仅代表飞盘飞的方向。 我们实际上想让子弹超过触摸点,然后飞出屏幕之外去。 下面这张图解释了这个问题:因此,就像你看到的,在触摸点和player之间有一个小的三角形,由origin点,offx和offy组成。 我们只需要画一个更大的三角形,同时使用一样的比率就行了。 然后我们就可以根据比例算出飞盘飞出屏幕的位置。 好了,让我们看看代码怎么写。 首先我们需要让layer能接收touch事件。 在你的init方法面添加下面一行代码:=YES。 由于我们激活了layer的touch,因此我们能够接收到touch事件的回调。 这里,我们实现ccTouchesEnded方法,这是在用户完成一次touch之后调用的,代码如下:(void)ccTouchesEnded:(NSSet*)touches withEvent:(UIEvent*)event{//Choose one of the touches to work withUITouch*touch=[touches anyObject]。 CGPoint location=[touch locationInView:[touch view]]。 location=[[CCDirector sharedDirector] convertToGL:location]。 //Set up initial location of projectileCGSize winSize=[[CCDirector sharedDirector] winSize]。 CCSprite*projectile=[CCSprite spriteWithFile:@rect:CGRectMake(0,0,20,20)]。 =ccp(20, )。 //Determine offset of location to projectileintoffX=intoffY=//Bail out if we are shooting down or backwardsif(offX=0)return。 //Ok to add now – we’ve double checked position[self addChild:projectile]。 //Determine where we wish to shoot the projectile to
intrealX=+()。 floatratio=(float) offY/(float) offX。 intrealY=(realX*ratio)+
CGPoint realDest=ccp(realX, realY)。 //Determine the length of how far we’re shooting
intoffRealX=realX
intoffRealY=realY
floatlength=sqrtf((offRealX*offRealX)+(offRealY*offRealY))。 floatvelocity=480/1。 //480pixels/1sec
floatrealMoveDuration=length/velocity。 //Move projectile to actual endpoint
[projectile runAction:[CCSequence actions:
[CCMoveTo actionWithDuration:realMoveDuration position:realDest],
[CCCallFuncN actionWithTarget:self selector:@selector(spriteMoveFinished:)],
nil]]。 }在第一部分,我们选择一个touch来处理,获得它在当前view中的位置,然后调用convertToGL把坐标转换成我们当前层的坐标系中去。 这个非常重要,因为我们使用的是landscape模式。 接下来,我们加载飞盘精灵并且设置它的初始位置。 然后,我们计算出它需要飞往何处,使用player和touch之间的向量并且根据前面描述的算法计算出来。 注意,这个算法并不完美。 我们强迫子弹飞出屏幕x轴的外边–即使在它已经飞出屏幕y轴的外边界了。 这里有许多方向来解决这个问题,比如检查飞出屏幕的最短距离,或者使用一个游戏回调函数来检查一个飞盘是否飞出,飞出就移出场景。 但是,在这里,我们尽量保持简单。 最后一件事情就是,决定飞盘移动的时间。 我们想让子弹以常量速度飞行,不管飞行方向如何。 因此,我们不得不再做一点点数学。 我们能够使用Pythagorean Theorem来计算我们移动了多久。 记得几何学中,三角形的斜边=两个直角边的平方和再开根号。 一旦我们得到了距离,我们就可以通过除了速度来得到时间。 因为速度=距离/时间。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。