接續前一篇的範例,現在我們要讓火箭往前移動。
移動 Sprite
要移動 Sprite 只要簡單的兩行程式碼,請把以下程式碼加入 init 中 addChild 之後:CGSize size = [[CCDirector sharedDirector] winSize];
CCMoveBy *move = [CCMoveBy actionWithDuration:2.0f position:ccp(0, size.height/2)];
[rocket runAction:move];
CCMoveBy 是依目前 Sprite 所在座標往 x, y 軸各加多少 pixel 的位置移動。
在 position 中,x = 0, y = size.height/2,表示在 x 軸不會有任何改變,y 軸則往上移動螢幕一半的距離。actionWithDuration:2.0f 表示這個動作要花 2 秒的時間完成。
呼叫 rocket sprite 的 runAction 去指定要執行的動作,它就會從現在的位置(螢幕中央)移到螢幕上方。
註:由於 Sprite 的原點在正中央,所以如果要讓火箭剛好移出螢幕,必須在加上火箭的高度的一半,也就是它的中心點會移到螢幕外加上本身高度一半的地方。
另外一個移動的方式是使用 CCMoveTo,如下:
CCMoveTo *moveTo = [CCMoveTo actionWithDuration:2.0f position:ccp(size.width/2, size.height)];
CCMoveTo 是依絕座標來移動,也就是從現在的位置,移動到螢幕上的某個點,所以這裡指定 x = size.width/2,和原本的 x 相同,y = size.height 則是螢幕高度。這個動作會移動到和前面的 CCMoveBy 同一個位置,你可比較兩者座標的差異。
依序執行動作
我們讓 Sprite 執行一連串的動作,利用 CCSequence 來達到。程式碼如下://movie to
CCMoveTo *moveTo = [CCMoveTo actionWithDuration:2.0f position:ccp(size.width/2, size.height)];
//out to die
CCCallBlockN *outToDie = [CCCallBlockN actionWithBlock:^(CCNode *node){
[node removeFromParentAndCleanup:YES];
}];
CCAction *seqAction = [CCSequence actions:moveTo, outToDie, nil];
[rocket runAction:seqAction];
我們使用 CCMoveTo 將火箭從螢幕中央移動到螢幕上方。CCCallBlockN 用來製作回呼函數。我們用來移除 Sprite 。
CCSequence actions: 可以加入多個 action,它會依序執行。我們指定第一個動作是移動到螢幕上方,第二個動作是把自己移除掉。
最後將 CCSequence 指定給 rocket runAction: 去執行。
觸碰後才動作
前面的動作在一載入時就會立即執行,我們將把它修改成,觸碰火箭後才執行往前的動作。因為程式碼要修改的地方有點多,先貼出來再解釋。
GameLayer.m
//
// GameLayer.m
// HelloCocos2D
//
// Created by Tony on 13/10/17.
// Copyright (c) 2013年 TonyCubeSoft. All rights reserved.
//
#import "GameLayer.h"
#import "cocos2d.h"
@interface GameLayer()
@property (nonatomic,strong) CCSprite *rocket;
@end
@implementation GameLayer
@synthesize rocket;
- (id)init
{
if( (self=[super init]) ) {
CGSize size = [[CCDirector sharedDirector] winSize];
rocket = [CCSprite spriteWithFile:@"rocket.png"];
[rocket setPosition:ccp(size.width/2, size.height/2)];
[self addChild:rocket];
self.touchEnabled = YES;
}
return self;
}
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
NSLog(@"touch");
//觸碰的座標
UITouch *myTouch = [touches anyObject];
CGPoint location = [myTouch locationInView:[myTouch view]];
location = [[CCDirector sharedDirector] convertToGL:location];
//火箭的矩形範圍
CGRect rect = CGRectMake(rocket.position.x - rocket.contentSize.width/2,
rocket.position.y - rocket.contentSize.height/2,
rocket.contentSize.width,
rocket.contentSize.height);
//判斷是否有觸碰到火箭
if (CGRectContainsPoint(rect, location)) {
[self rocketLaunch];
}
}
- (void)rocketLaunch
{
CGSize size = [[CCDirector sharedDirector] winSize];
//move by
// CCMoveBy *moveBy = [CCMoveBy actionWithDuration:2.0f position:ccp(0, size.height/2)];
// [rocket runAction:moveBy];
//movie to
CCMoveTo *moveTo = [CCMoveTo actionWithDuration:2.0f position:ccp(size.width/2, size.height)];
//out to die
CCCallBlockN *outToDie = [CCCallBlockN actionWithBlock:^(CCNode *node){
[node removeFromParentAndCleanup:YES];
}];
CCAction *seqAction = [CCSequence actions:moveTo, outToDie, nil];
[rocket runAction:seqAction];
}
說明:要讓觸碰有反應,要
- 在 init 中將 self.touchEnabled 設為 YES,
- 實作 - (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event 方法。
角色動畫
動畫是指幾張圖片不斷的播放,看起來就像在動一樣,所以製作方法也是如此。我把原本的火箭圖檔稍做修改,讓火焰變小,於是當兩張圖片快速輪流播放時,火焰就會動了。原本火箭改名為 rocket1.png,加入新的圖檔 rocket2.png。程式碼如下:
- (void)rocketAnimation
{
CCAnimation *rocketAnim = [CCAnimation animation];
[rocketAnim addSpriteFrameWithFilename:@"rocket1.png"];
[rocketAnim addSpriteFrameWithFilename:@"rocket2.png"];
[rocketAnim setDelayPerUnit:0.1f];
[rocketAnim setRestoreOriginalFrame:YES];
CCAnimate *rocketAnimationAction = [CCAnimate actionWithAnimation:rocketAnim];
CCRepeatForever *repeatRocketAnimation = [CCRepeatForever actionWithAction:rocketAnimationAction];
[rocket runAction:repeatRocketAnimation];
}
在 init 中的 self.touchEnabled = YES; 之後加入
[self rocketAnimation];
就完成了。說明:
- CCAnimation 用來加入動畫用的圖檔,並且要設定每張圖片延遲的時間,這裡設為 0.1 秒。
- CCAnimate 指定要使用哪個動畫來產成動作。
- CCRepeatForever 指定動畫要永遠重覆執行。
- 最後讓 rocket sprite 去執行這個 action。
我要留言
留言小提醒:
1.回覆時間通常在晚上,如果太忙可能要等幾天。
2.請先瀏覽一下其他人的留言,也許有人問過同樣的問題。
3.程式碼請先將它編碼後再貼上。(線上編碼:http://bit.ly/1DL6yog)
4.文字請加上標點符號及斷行,難以閱讀者恕難回覆。
5.感謝您的留言,您的問題也可能幫助到其他有相同問題的人。