貝塞爾曲線:如何讓一個正在按照貝塞爾曲線運動的精靈減速或加速(動畫結束回調)


@implementation ActionBezier
- (void) callback
{
NSLog(@"callback");
}
-(void) onEnter
{
[super onEnter];

CGSize s = [[CCDirector sharedDirector] winSize];

//
// startPosition can be any coordinate, but since the movement
// is relative to the Bezier curve, make it (0,0)
//

// sprite 1
ccBezierConfig bezier;
bezier.controlPoint_1 = ccp(0, s.height/2);
bezier.controlPoint_2 = ccp(300, -s.height/2);
bezier.endPosition = ccp(300,100);

//結束時回調
id callback = [CCCallFunc actionWithTarget:self selector:@selector(callback)];

id bezierForward = [CCBezierBy actionWithDuration:5 bezier:bezier];
id bezierBack = [bezierForward reverse];
id seq = [CCSequence actions: bezierForward, bezierBack, callback,nil];
id rep = [CCRepeatForever actionWithAction:seq];

//設置速度
id speed = [CCSpeed actionWithAction:rep speed:2];
[speed setTag:222];

// sprite 2
//[tamara setPosition:ccp(80,160)];
ccBezierConfig bezier2;
bezier2.controlPoint_1 = ccp(100, s.height/2);
bezier2.controlPoint_2 = ccp(200, -s.height/2);
bezier2.endPosition = ccp(240,160);

id place1 = [CCPlace actionWithPosition:ccp(80,160)];
id bezierTo1 = [CCBezierTo actionWithDuration:2 bezier:bezier2];
[tamara runAction:[CCSequence actions: place1, bezierTo1, nil]];

// sprite 3
//[kathia setPosition:ccp(400,160)];
id place2 = [CCPlace actionWithPosition:ccp(400,160)];
id bezierTo2 = [CCBezierTo actionWithDuration:2 bezier:bezier2];
[kathia runAction:[CCSequence actions: place2, bezierTo2, nil]];

[grossini runAction: speed];
//設置速度
[((CCSpeed *)[[self getChildByTag:999] getActionByTag:222])setSpeed:4];
NSLog(@"%f",((CCSpeed *)[grossini getActionByTag:222]).speed);
//[tamara runAction:bezierTo1];
//[kathia runAction:bezierTo2];

}
-(NSString *) title
{
return @"BezierBy / BezierTo";
}
@end

 

素材:http://www.cocoachina.com/bbs/simple/?t73237.html

請大大們進來幫忙看下【貝塞爾曲線:如何讓一個正在按照貝塞爾曲線運動的精靈減速或加速】

    ccBezierConfig config;
    config.endPosition=ccp(600,600);
    config.controlPoint_1=ccp(200,500);
    config.controlPoint_2=ccp(500,200);
    [[self getChildByTag:998] runAction:[CCSequence actions:[CCBezierTo actionWithDuration:5.0f bezier:config],[CCCallFunc actionWithTarget:self selector:@selector(moveDone:)], nil]];

一個精靈正在執行CCBezierTo 這個動作,如何讓她在中途減速或者加速呢?

方法

  

     CCSprite *sprite3=[CCSprite spriteWithFile:@"giantAnt.png"];        
sprite3.position=ccp(100,100);
[self addChild:sprite3 z:999 tag:9987];

id move = [CCBezierTo actionWithDuration:5.0f bezier:config];
id speed =[CCSpeed actionWithAction:move speed:1.0f];
[speed setTag:222];
[sprite3 runAction:speed];


如何要減速的話
就執行這行代碼:
[(CCSpeed*)[[self getChildByTag:9987] getActionByTag:222] setSpeed:0.5f];

加速:
[(CCSpeed*)[[self getChildByTag:9987] getActionByTag:222] setSpeed:1.5f];


[(CCSpeed*)[self getActionByTag:222] setSpeed:1.5f];




 

【iOS-Cocos2d游戲開發之二十二 】CCSpeed實現CCAnimate動畫進行時設置慢動作以及設置游戲加減速進行(塔防游戲必備)!

1.利用CCSpeed當精靈執行CCAnimate動作途中設置其播放的速度;

           2.設置游戲的速率,讓你自由設置整個游戲的速度;

首先介紹第一個知識點:

對於第一個知識點,精靈執行CCAnimate動作途中設置播放速度,說白一點就是當主角或者怪物播放一套幀動作(動畫)的時候,可能突然受到其他因素影響希望主角或者怪物等動作放慢,也就是慢動作的感覺,那么這時候我們就需要設置動作的播放速度拉,也就是今天要介紹的CCSpeed這個類;可能Himi這里哇哇哇的說這么多還是沒亭台明白吧…=。 = 那么下面我們來看看代碼等就應該明白了;

至於精靈如何利用CCAnimate實現幀集合動畫教程在之前已經講述過,那么這里就不在贅述,如果還不清楚如何利用很多幀形成動畫讓精靈播放的童鞋請移步到:【iOS-Cocos2d游戲開發之二十一 】自定義精靈類並為你的精靈設置攻擊幀(指定開始幀)以及擴展Cocos2d源碼的CCAnimation簡化動畫創建!

直接上一段代碼如下:

[[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來實現了,代碼如下:

[[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獲取到,這個大家肯定很熟悉,那么獲取動作方式如下:

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

獲取的時候是你之前runAction的精靈來利用getActionByTag來獲取的!

那么下面繼續添加代碼,我們讓一個由CCSpeed包裝一個幀動畫並讓精靈執行后的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];
-(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的創建很簡單,那么設置速率的方法如下:

[CCSpeed* setSpeed:XX];

這里的XX參數指的是倍率,傳入1表示原速,大於1表示增快,小於1表示放慢速度~

下面直接給出全部測試項目代碼:

//
// 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

  這里備注下:除了利用CCSpeed來實現慢動作之外,還有其他的一些方法,不怕麻煩的童鞋甚至可以嘗試當需要慢動作的時候,取出當前的幀下標,然后利用指定幀下標的方法創建一個新的幀動畫同時增加播放時間即可;(在上一節《iOS-Cocos2d游戲開發之二十一》中Himi封裝了一個指定幀下標進行創建幀動畫的方法,還沒有看過的童鞋請移步到這里:【iOS-Cocos2d游戲開發之二十一 】自定義精靈類並為你的精靈設置攻擊幀(指定開始幀)以及擴展Cocos2d源碼的CCAnimation簡化動畫創建!);再或者直接去修改Cocos2d-iphone引擎的源碼;

    Himi當時做的時候因為用CCSpeed方式有問題一直不行,就去改了源碼弄的。后來才發現CCSpeed正確用法,我去了=。 =

這里Himi必須強調一點!!!!!!!

    很多時候你的主角的動作利用CCAction來實現,移動則是在update刷幀函數或者一些選擇器的方法中進行的,那么為了讓你的主角慢動作比較逼真,那么Himi建議不要使用scheduleUpdate函數,因為這個你無法修改每次調用update的時間默認都是每幀都調用,那么你應該自己定義一個選擇器當刷邏輯的函數,這樣就能配合CCSpeed實現逼真慢動作拉~


下面我們來介紹第二個知識點:設置游戲速度

對於游戲速度最常見的出現在塔防游戲中,當玩家創建好防守的東東后開始出怪后,可能怪物移動速度慢,而玩家着急看到結果,那么我們就會人性化的加上加快游戲速度的按鈕拉~那么這個功能在Cocos2d引擎中封裝好的,一句代碼即可完成,如下代碼即可:


[[CCScheduler sharedScheduler] setTimeScale:XX];

這里的XX仍然是倍率:傳入1表示原速,大於1表示增快,小於1表示放慢速度~

 















免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM