【iOS-Cocos2d游戏开发之二十二 】CCSpeed实现CCAnimate动画进行时设置慢动作以及设置游戏加减速进行(塔防游戏必备)! ....

Himi 原创, 欢迎转载,转载请在明显处注明! 谢谢。

原文地址:http://blog.csdn.net/xiaominghimi/article/details/7009503


最近也一直在忙,所以也只能每周的某一天抽出时间来分享一些知识点给童鞋们,希望童鞋们体谅下~

那么废话不多说了,本篇知识点两个:

1.利用CCSpeed当精灵执行CCAnimate动作途中设置其播放的速度;

2.设置游戏的速率,让你*设置整个游戏的速度;

首先介绍第一个知识点:

对于第一个知识点,精灵执行CCAnimate动作途中设置播放速度,说白一点就是当主角或者怪物播放一套帧动作(动画)的时候,可能突然受到其他因素影响希望主角或者怪物等动作放慢,也就是慢动作的感觉,那么这时候我们就需要设置动作的播放速度拉,也就是今天要介绍的CCSpeed这个类;可能Himi这里哇哇哇的说这么多还是没亭台明白吧...=。 = 那么下面我们来看看代码等就应该明白了;

至于精灵如何利用CCAnimate实现帧集合动画教程在之前已经讲述过,那么这里就不在赘述,如果还不清楚如何利用很多帧形成动画让精灵播放的童鞋请移步到:【iOS-Cocos2d游戏开发之二十一 】自定义精灵类并为你的精灵设置攻击帧(指定开始帧)以及扩展Cocos2d源码的CCAnimation简化动画创建!

直接上一段代码如下:

  1. [[CCSpriteFrameCachesharedSpriteFrameCache]addSpriteFramesWithFile:@"animationsFrames.plist"];
  2. CCSprite*mySprite=[CCSpritespriteWithSpriteFrameName:@"himi1.png"];
  3. mySprite.position=ccp(120,150);
  4. [selfaddChild:mySprite];
  5. CCAnimation*anim=[CCAnimationanimationWithFrame:@"himi"frameCount:12delay:0.1];
  6. CCAnimate*animate=[CCAnimateactionWithAnimation:anim];
  7. CCSequence*seq=[CCSequenceactions:animate,nil];
  8. CCRepeatForever*repeat=[CCRepeatForeveractionWithAction:seq];
  9. [mySpriterunAction:repeat];
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:@"animationsFrames.plist"]; CCSprite*mySprite=[CCSprite spriteWithSpriteFrameName:@"himi1.png"]; mySprite.position=ccp(120,150); [self addChild:mySprite]; CCAnimation*anim=[CCAnimation animationWithFrame:@"himi" frameCount:12 delay:0.1]; CCAnimate* animate = [CCAnimate actionWithAnimation:anim]; CCSequence *seq = [CCSequence actions:animate,nil]; CCRepeatForever* repeat = [CCRepeatForever actionWithAction:seq]; [mySprite runAction:repeat];
以上代码创建一个帧动画(帧资源都在animationFrames.plist加载到内存中了),然后创建一个精灵并让其永久循环执行这个帧动画;

童鞋们想一想,如果在这个永久动作执行后,你想在一个任意时间设置这个动画播放的速度,那么就利用CCSpeed来实现了,代码如下:

  1. [[CCSpriteFrameCachesharedSpriteFrameCache]addSpriteFramesWithFile:@"animationsFrames.plist"];
  2. //左侧正常速度的播放
  3. CCSprite*mySprite=[CCSpritespriteWithSpriteFrameName:@"himi1.png"];
  4. mySprite.position=ccp(120,150);
  5. [selfaddChild:mySprite];
  6. CCAnimation*anim=[CCAnimationanimationWithFrame:@"himi"frameCount:12delay:0.1];
  7. CCAnimate*animate=[CCAnimateactionWithAnimation:anim];
  8. CCSequence*seq=[CCSequenceactions:animate,nil];
  9. //让你的永久动作放入speed中
  10. CCSpeed*speed=[CCSpeedactionWithAction:[CCRepeatForeveractionWithAction:seq]speed:1.0f];
  11. [speedsetTag:888];//设置tag能任意获取到其实例,并且对其进行操作
  12. [mySpriterunAction:speed];
[[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:@"animationsFrames.plist"]; //左侧正常速度的播放 CCSprite*mySprite=[CCSprite spriteWithSpriteFrameName:@"himi1.png"]; mySprite.position=ccp(120,150); [self addChild:mySprite]; CCAnimation*anim=[CCAnimation animationWithFrame:@"himi" frameCount:12 delay:0.1]; CCAnimate* animate = [CCAnimate actionWithAnimation:anim]; CCSequence *seq = [CCSequence actions:animate,nil]; //让你的永久动作放入speed中 CCSpeed *speed =[CCSpeed actionWithAction:[CCRepeatForever actionWithAction:seq] speed:1.0f]; [speed setTag:888];//设置tag能任意获取到其实例,并且对其进行操作 [mySprite runAction:speed];
这段代码和第一段代码不同点就是第二段将CCRepeatForever永久动作又包装到了CCSpeed中,整个动作等同与交给了CCSpeed来控制了,那么下面我还设置了[speed setTag:888];这个是留出接口,当你需要设置整个CCSpeed包装的动作速度的时候利用tag获取到,这个大家肯定很熟悉,那么获取动作方式如下:

  1. CCSpeed*speed=(CCSpeed*)[spritegetActionByTag:88];
CCSpeed *speed=(CCSpeed*)[sprite getActionByTag:88];

获取的时候是你之前runAction的精灵来利用getActionByTag来获取的!


那么下面继续添加代码,我们让一个由CCSpeed包装一个帧动画并让精灵执行后的5秒后让其速度变成原有播放速度的一半,代码如下:

  1. CCSprite*mySpriteByF=[CCSpritespriteWithSpriteFrameName:@"himi1.png"];
  2. mySpriteByF.position=ccp(360,150);
  3. [selfaddChild:mySpriteByFz:0tag:66];
  4. anim=[CCAnimationanimationWithFrame:@"himi"frameCount:12delay:0.1];
  5. animate=[CCAnimateactionWithAnimation:anim];
  6. seq=[CCSequenceactions:animate,nil];
  7. CCSpeed*speed=[CCSpeedactionWithAction:[CCRepeatForeveractionWithAction:seq]speed:1.0f];
  8. [speedsetTag:88];
  9. [mySpriteByFrunAction:speed];
  10. [selfschedule:@selector(slowForHimi)interval:5];
CCSprite *mySpriteByF =[CCSprite spriteWithSpriteFrameName:@"himi1.png"]; mySpriteByF.position=ccp(360,150); [self addChild:mySpriteByF z:0 tag:66]; anim=[CCAnimation animationWithFrame:@"himi" frameCount:12 delay:0.1]; animate = [CCAnimate actionWithAnimation:anim]; seq =[CCSequence actions:animate, nil]; CCSpeed *speed =[CCSpeed actionWithAction:[CCRepeatForever actionWithAction:seq] speed:1.0f]; [speed setTag:88]; [mySpriteByF runAction:speed]; [self schedule:@selector(slowForHimi) interval:5];
  1. -(void)slowForHimi{
  2. [selfunschedule:@selector(slowForHimi)];//解除此选择器
  3. CCSprite*sprite=(CCSprite*)[selfgetChildByTag:66];
  4. CCSpeed*speed=(CCSpeed*)[spritegetActionByTag:88];
  5. [speedsetSpeed:0.5];//放慢原有速度的0.5倍
  6. }
-(void)slowForHimi{ [self unschedule:@selector(slowForHimi)];//解除此选择器 CCSprite*sprite=(CCSprite*)[self getChildByTag:66]; CCSpeed *speed=(CCSpeed*)[sprite getActionByTag:88]; [speed setSpeed:0.5];//放慢原有速度的0.5倍 }
CCSpeed的创建很简单,那么设置速率的方法如下:

  1. [CCSpeed*setSpeed:XX];
[CCSpeed* setSpeed:XX];
这里的XX参数指的是倍率,传入1表示原速,大于1表示增快,小于1表示放慢速度~

下面直接给出全部测试项目代码:


  1. //
  2. //HelloWorldLayer.m
  3. //SLowAnimationByHimi
  4. //
  5. //Createdby华明李on11-11-21.
  6. //CopyrightHimi2011年.Allrightsreserved.
  7. //
  8. //Importtheinterfaces
  9. #import"HelloWorldLayer.h"
  10. #import"CCAnimationHelper.h"
  11. //HelloWorldLayerimplementation
  12. @implementationHelloWorldLayer
  13. +(CCScene*)scene
  14. {
  15. //'scene'isanautoreleaseobject.
  16. CCScene*scene=[CCScenenode];
  17. //'layer'isanautoreleaseobject.
  18. HelloWorldLayer*layer=[HelloWorldLayernode];
  19. //addlayerasachildtoscene
  20. [sceneaddChild:layer];
  21. //returnthescene
  22. returnscene;
  23. }
  24. //CCJumpTo实现,抛物线
  25. //
  26. //on"init"youneedtoinitializeyourinstance
  27. -(id)init{
  28. if((self=[superinit])){
  29. CCLabelTTF*label=[CCLabelTTFlabelWithString:@"暂缓动作&设置整个游戏加速/减速"fontName:@"MarkerFelt"fontSize:24];
  30. label.position=ccp(260,260);
  31. [selfaddChild:labelz:0];
  32. label=[CCLabelTTFlabelWithString:@"正常速度的播放"fontName:@"MarkerFelt"fontSize:12];
  33. label.position=ccp(120,220);
  34. [selfaddChild:labelz:0tag:99];
  35. label=[CCLabelTTFlabelWithString:@"左侧动态放慢的速度的动作"fontName:@"MarkerFelt"fontSize:12];
  36. label.position=ccp(350,220);
  37. [selfaddChild:labelz:0];
  38. [[CCSpriteFrameCachesharedSpriteFrameCache]addSpriteFramesWithFile:@"animationsFrames.plist"];
  39. //左侧正常速度的播放
  40. CCSprite*mySprite=[CCSpritespriteWithSpriteFrameName:@"himi1.png"];
  41. mySprite.position=ccp(120,150);
  42. [selfaddChild:mySprite];
  43. CCAnimation*anim=[CCAnimationanimationWithFrame:@"himi"frameCount:12delay:0.1];
  44. CCAnimate*animate=[CCAnimateactionWithAnimation:anim];
  45. CCSequence*seq=[CCSequenceactions:animate,nil];
  46. CCRepeatForever*repeat=[CCRepeatForeveractionWithAction:seq];
  47. [mySpriterunAction:repeat];
  48. //左侧动态放慢的速度的动作
  49. CCSprite*mySpriteByF=[CCSpritespriteWithSpriteFrameName:@"himi1.png"];
  50. mySpriteByF.position=ccp(360,150);
  51. [selfaddChild:mySpriteByFz:0tag:66];
  52. anim=[CCAnimationanimationWithFrame:@"himi"frameCount:12delay:0.1];
  53. animate=[CCAnimateactionWithAnimation:anim];
  54. seq=[CCSequenceactions:animate,nil];
  55. CCSpeed*speed=[CCSpeedactionWithAction:[CCRepeatForeveractionWithAction:seq]speed:1.0f];
  56. [speedsetTag:88];
  57. [mySpriteByFrunAction:speed];
  58. [selfschedule:@selector(slowForHimi)interval:5];
  59. }
  60. returnself;
  61. }
  62. -(void)slowForHimi{
  63. [selfunschedule:@selector(slowForHimi)];//解除此选择器
  64. CCSprite*sprite=(CCSprite*)[selfgetChildByTag:66];
  65. CCSpeed*speed=(CCSpeed*)[spritegetActionByTag:88];
  66. [speedsetSpeed:0.5];//放慢原有速度的0.5倍
  67. }
  68. //on"dealloc"youneedtoreleaseallyourretainedobjects
  69. -(void)dealloc
  70. {
  71. //incaseyouhavesomethingtodealloc,doitinthismethod
  72. //inthisparticularexamplenothingneedstobereleased.
  73. //cocos2dwillautomaticallyreleaseallthechildren(Label)
  74. //don'tforgettocall"superdealloc"
  75. [superdealloc];
  76. }
  77. @end
// // HelloWorldLayer.m // SLowAnimationByHimi // // Created by 华明 李 on 11-11-21. // Copyright Himi 2011年. All rights reserved. // // Import the interfaces #import "HelloWorldLayer.h" #import "CCAnimationHelper.h" // HelloWorldLayer implementation @implementation HelloWorldLayer +(CCScene *) scene { // 'scene' is an autorelease object. CCScene *scene = [CCScene node]; // 'layer' is an autorelease object. HelloWorldLayer *layer = [HelloWorldLayer node]; // add layer as a child to scene [scene addChild: layer]; // return the scene return scene; } //CCJumpTo实现,抛物线 // // on "init" you need to initialize your instance -(id) init{ if( (self=[super init])) { CCLabelTTF *label = [CCLabelTTF labelWithString:@"暂缓动作&设置整个游戏加速/减速" fontName:@"Marker Felt" fontSize:24]; label.position = ccp(260,260); [self addChild: label z:0 ]; label = [CCLabelTTF labelWithString:@"正常速度的播放" fontName:@"Marker Felt" fontSize:12]; label.position = ccp(120,220); [self addChild: label z:0 tag:99]; label = [CCLabelTTF labelWithString:@"左侧动态放慢的速度的动作" fontName:@"Marker Felt" fontSize:12]; label.position = ccp(350,220); [self addChild: label z:0 ]; [[CCSpriteFrameCache sharedSpriteFrameCache]addSpriteFramesWithFile:@"animationsFrames.plist"]; //左侧正常速度的播放 CCSprite*mySprite=[CCSprite spriteWithSpriteFrameName:@"himi1.png"]; mySprite.position=ccp(120,150); [self addChild:mySprite]; CCAnimation*anim=[CCAnimation animationWithFrame:@"himi" frameCount:12 delay:0.1]; CCAnimate* animate = [CCAnimate actionWithAnimation:anim]; CCSequence *seq = [CCSequence actions:animate,nil]; CCRepeatForever* repeat = [CCRepeatForever actionWithAction:seq]; [mySprite runAction:repeat]; //左侧动态放慢的速度的动作 CCSprite *mySpriteByF =[CCSprite spriteWithSpriteFrameName:@"himi1.png"]; mySpriteByF.position=ccp(360,150); [self addChild:mySpriteByF z:0 tag:66]; anim=[CCAnimation animationWithFrame:@"himi" frameCount:12 delay:0.1]; animate = [CCAnimate actionWithAnimation:anim]; seq =[CCSequence actions:animate, nil]; CCSpeed *speed =[CCSpeed actionWithAction:[CCRepeatForever actionWithAction:seq] speed:1.0f]; [speed setTag:88]; [mySpriteByF runAction:speed]; [self schedule:@selector(slowForHimi) interval:5]; } return self; } -(void)slowForHimi{ [self unschedule:@selector(slowForHimi)];//解除此选择器 CCSprite*sprite=(CCSprite*)[self getChildByTag:66]; CCSpeed *speed=(CCSpeed*)[sprite getActionByTag:88]; [speed setSpeed:0.5];//放慢原有速度的0.5倍 } // on "dealloc" you need to release all your retained objects - (void) dealloc { // in case you have something to dealloc, do it in this method // in this particular example nothing needs to be released. // cocos2d will automatically release all the children (Label) // don't forget to call "super dealloc" [super dealloc]; } @end
运行截图如下: (图片中有个"左"写错了,应该是"右",懒得改了,大家知道就行了 娃哈哈)【iOS-Cocos2d游戏开发之二十二 】CCSpeed实现CCAnimate动画进行时设置慢动作以及设置游戏加减速进行(塔防游戏必备)! ....

【iOS-Cocos2d游戏开发之二十二 】CCSpeed实现CCAnimate动画进行时设置慢动作以及设置游戏加减速进行(塔防游戏必备)! ....


从截图中可能童鞋们看不出什么效果。等文章最后放出源码,大家运行就可以看到效果了-。 -

这里备注下:除了利用CCSpeed来实现慢动作之外,还有其他的一些方法,不怕麻烦的童鞋甚至可以尝试当需要慢动作的时候,取出当前的帧下标,然后利用指定帧下标的方法创建一个新的帧动画同时增加播放时间即可;(在上一节《iOS-Cocos2d游戏开发之二十一》中Himi封装了一个指定帧下标进行创建帧动画的方法,还没有看过的童鞋请移步到这里:【iOS-Cocos2d游戏开发之二十一 】自定义精灵类并为你的精灵设置攻击帧(指定开始帧)以及扩展Cocos2d源码的CCAnimation简化动画创建!);再或者直接去修改Cocos2d-iphone引擎的源码;

Himi当时做的时候因为用CCSpeed方式有问题一直不行,就去改了源码弄的。后来才发现CCSpeed正确用法,我去了=。 =

这里Himi必须强调一点!!!!!!!

很多时候你的主角的动作利用CCAction来实现,移动则是在update刷帧函数或者一些选择器的方法中进行的,那么为了让你的主角慢动作比较逼真,那么Himi建议不要使用scheduleUpdate函数,因为这个你无法修改每次调用update的时间默认都是每帧都调用,那么你应该自己定义一个选择器当刷逻辑的函数,这样就能配合CCSpeed实现逼真慢动作拉~


下面我们来介绍第二个知识点:设置游戏速度

对于游戏速度最常见的出现在塔防游戏中,当玩家创建好防守的东东后开始出怪后,可能怪物移动速度慢,而玩家着急看到结果,那么我们就会人性化的加上加快游戏速度的按钮拉~那么这个功能在Cocos2d引擎中封装好的,一句代码即可完成,如下代码即可:

  1. [[CCSchedulersharedScheduler]setTimeScale:XX];
[[CCScheduler sharedScheduler] setTimeScale:XX];
这里的XX仍然是倍率:传入1表示原速,大于1表示增快,小于1表示放慢速度~


OK,本篇就到此~

源码下载地址:http://download.csdn.net/detail/xiaominghimi/3839063