// // AccelerometerScene.m // 31_cocos2D入門 // // Created by beyond on 14-9-27. // Copyright (c) 2014年 com.beyond. All rights reserved. // 實現:手機往右傾斜,位於中心的nanaSprite往右移動;手機往左傾斜,位於中心的nanaSprite往左移動; #import "AccelerometerScene.h" // 要想監聽加速計事件,必須遵守協議@interface AccelerometerScene() { // 原則 : 在監聽加速計方法中,記錄 accelerameterX,在時鐘方法update中更次精靈的Position CGFloat _accelerationX; } @end @implementation AccelerometerScene #pragma mark - 覆蓋父類方法 -(id)init { if (self=[super init]) { // 1、場景Node 允許交互 self.userInteractionEnabled = YES; } return self; } // 實現父類的方法,添加一個按鈕到屏幕上 - (void)addShowBtns { } #pragma mark - 加速計代理方法 // 場景必須先遵守協議CCAccelerometerDelegate // 不像觸摸事件,加速計事件,只有一個方法,就是:didAccelerate - (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { // 范圍是:-1 ~ 1,例如:x,手機豎直狀態下,往右傾斜,x從0逐漸增加到+1 // x,手機豎直狀態下,往左傾斜,x從0逐漸減少到-1 CCLOG(@"x=%f, y=%f, z=%f", acceleration.x, acceleration.y, acceleration.z); // 靈敏度 int lingmindu = 6; _accelerationX = acceleration.x * lingmindu; } // 唯一關於,圖層,加速計的注意事項:在監聽加速計方法中,記錄加速計的值,並且,只能在update刷幀的時候,設置sprite的position;這樣做的目的是:保證畫面的流暢!!!因為update方法,1秒鐘能夠調用60次,而加速計的監聽方法,1秒鐘才調用10次 - (void)update { self.sprite.position = ccpAdd(self.sprite.position, ccp(6, 0)); } @end
設置 場景Node允許交互
self.userInteractionEnabled =YES;
CCLayer常用設置
CCLayer默認情況是不接收觸摸輸入的,需要顯示地設置isTouchEnabled為YES
self.isTouchEnabled = YES;設置isTouchEnabled為YES後,就會調用圖層相應的方法來處理觸摸輸入:
這些都是在CCStandardTouchDelegate協議中定義的方法
1> 當單指接觸到屏幕時
- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
2> 當手指在屏幕上移動時
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
3> 當單指離開屏幕時
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
4> 當觸摸被取消時
- (void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
很少會發生觸摸被取消的情況,
所以大多數情況下可忽略,或用ccTouchesEnded代替,
因為ccTouchesCancelled和ccTouchesEnded類似
大部分情況下,需要知道觸摸發生在什麼位置。這裡的觸摸事件是由UIKit框架接收的,因此需要把觸摸位置轉換為OpenGL坐標。
比如在手指移動過程中:
- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { // 獲取觸摸對象 UITouch *touch = [touches anyObject]; // 獲取觸摸在UIView視圖上的位置 CGPoint uiPoint = [touch locationInView:touch.view]; // 轉換為OpenGL坐標 CGPoint glPoint = [[CCDirector sharedDirector] convertToGL:uiPoint]; }
下面利用一個小例子來綜合使用上述的方法,假設圖層上有個精靈,手指觸摸到哪,這個精靈的位置就在哪
首先在圖層初始化的時候添加精靈
// 圖層的init方法 -(id) init { if( (self=[super init])) { // 初始化一個精靈 CCSprite *nana = [CCSprite spriteWithFile:@"nana.png"]; CGSize size = [[CCDirector sharedDirector] winSize]; nana.position = ccp(size.width * 0.5f, size.height * 0.5f); // 添加精靈,並設置標記 [self addChild: nana z:0 tag:kNanaTag]; self.isTouchEnabled = YES; } return self; }
接下來是在圖層中接收觸摸輸入
// 計算觸摸在圖層中的位置(OpenGL坐標) - (CGPoint)locationInLayer:(NSSet *)touches { // 獲取觸摸對象 UITouch *touch = [touches anyObject]; // 獲取觸摸在UIView視圖上的位置 CGPoint uiPoint = [touch locationInView:touch.view]; // 轉換為OpenGL坐標 CGPoint glPoint = [[CCDirector sharedDirector] convertToGL:uiPoint]; return glPoint; } // 由於ccTouchesBegan、ccTouchesMoved、ccTouchesEnded中的做法都是一樣,所以抽成一個方法 - (void)dealTouches:(NSSet *)touches { // 計算觸摸的位置 CGPoint point = [self locationInLayer:touches]; // 根據標記獲取精靈 CCSprite *nana = (CCSprite *)[self getChildByTag:kNanaTag]; // 設置精靈的位置 nana.position = point; } - (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self dealTouches:touches]; } - (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { [self dealTouches:touches]; } - (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { [self dealTouches:touches]; }
上面就是cocos2d v3之前的圖層的觸摸輸入
CCLayer默認情況是不接收加速計輸入的,需要顯示地設置isAccelerometerEnabled為YES
self.isAccelerometerEnabled = YES;設置isAccelerometerEnabled為YES後,就會調用圖層相應的方法來處理加速計輸入:
這是在UIAccelerometerDelegate協議中定義的方法
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration { // typedef double UIAccelerationValue; UIAccelerationValue x = acceleration.x; UIAccelerationValue y = acceleration.y; UIAccelerationValue z = acceleration.z; // x,y,z代表三維中任意方向的加速度 }
默認情況下CCLayer是不能設置顏色的,
有時候,想給整個圖層設置一種背景顏色,
那麼就需要用到CCLayerColor了,
CCLayerColor是CCLayer的子類
// 紅色:#ffff0000 ccColor4B color = ccc4(255, 0, 0, 255); // 初始化一個顏色圖層 CCLayerColor *layerColor = [CCLayerColor layerWithColor:color]; // 添加到場景中 [scene addChild:layerColor];效果圖:
CCLayerGradient是CCLayerColor的子類,
可以給圖層設置漸變色
// 紅色:#ffff0000 ccColor4B red = ccc4(255, 0, 0, 255); // 藍色:#ff0000ff ccColor4B blue = ccc4(0, 0, 255, 255); // 初始化一個漸變圖層,從紅色漸變到藍色 CCLayerGradient *layerGradient = [CCLayerGradient layerWithColor:red fadingTo:blue]; // 添加到場景中 [scene addChild:layerGradient];效果圖:
CCLayerMultiplex繼承自CCLayer,稱為"多重圖層"。
它可以包含多個CCLayer對象,
但在任意時刻只可以有一個CCLayer處於活動狀態,
通過switchTo:和switchToAndReleaseMe:方法
可以讓某個圖層處於活動狀態,
區別在於switchToAndReleaseMe:方法
會先釋放當前處於活動狀態的圖層,
再讓參數中要求的圖層處於活動狀態
// 創建2個圖層 CCLayer *layer1 = [CCLayer node]; CCLayer *layer2 = [CCLayer node]; // 創建一個多重圖層,包含了layer1和layer2,但是,一次只能顯示 其中一個圖層 CCLayerMultiplex *plex = [CCLayerMultiplex layerWithLayers:layer1, layer2, nil]; // 讓layer1處於活動狀態(layer2還在內存中) [plex switchTo:0]; // 讓layer2處於活動狀態(layer1還在內存中) [plex switchTo:1]; // 釋放當前處於活動狀態的layer2(layer2從內存中移除),然後讓layer1處於活動狀態 [plex switchToAndReleaseMe:0];
圖層之間的切換是沒有過渡效果的