iOS_31_cocos2d_圖層CCLayer_加速計
來源:程序員人生 發布時間:2014-10-08 08:00:00 閱讀次數:3268次
最終效果圖:
cocos2d-x中,圖層Layer的繼承結構圖:
從上面圖中可以看到:
重點的幾個直接子類是:Control、ScrollView、Menu、LayerColor
其中LayerColor可以讓圖層具有顏色
其中Control的子類,全都是與用戶交互的一些類,如:button、slider等
0、CCLayer概述
一個游戲中可以有很多個場景,每個場景里面又可能包含有多個圖層,這里的圖層一般就是CCLayer對象。
CCLayer本身幾乎沒什么功能,對比CCNode,CCLayer可用于接收觸摸和加速計輸入。(userInteractionEnabled為YES)
其實,cocos2d對圖層并沒有嚴格的要求,圖層不一定要使用CCLayer類,它也可以是一個簡單的CCNode
因為新建一個圖層就是為了能夠容納更多的子節點,而CCNode也可以添加子節點。
所以,如果圖層不需要接收觸摸和加速計輸入,就盡量使用CCNode表示圖層
CCLayer因為能夠接收觸摸和加速計輸入,會增加不必要的開銷。
移動、縮放、旋轉整個圖層,圖層上的所有節點也會跟著一起移動、縮放、旋轉。
注意:在cocos2d V3中,CCLayer已被取消
注意:
cocos2d v3版本中,由于不再使用CCLayer,因此,場景Scene遵守協議<CCAccelerometerDelegate>后,可以直接監聽加速計事件,
當手機豎著,x方向的加速值,約等于0
當手機向右傾斜,x方向的加速值,增加
當手機完全向右傾斜,x方向的加速值,約等于+1.0
當手機向左傾斜,x方向的加速值,減小
當手機完全向左傾斜,x方向的加速值,約等于-1.0
如下面代碼所示:
//
// AccelerometerScene.m
// 31_cocos2D入門
//
// Created by beyond on 14-9-27.
// Copyright (c) 2014年 com.beyond. All rights reserved.
// 實現:手機往右傾斜,位于中心的nanaSprite往右移動;手機往左傾斜,位于中心的nanaSprite往左移動;
#import "AccelerometerScene.h"
// 要想監聽加速計事件,必須遵守協議<CCAccelerometerDelegate>
@interface AccelerometerScene()<CCAccelerometerDelegate>
{
// 原則 : 在監聽加速計方法中,記錄 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
cocos2d v3中觸摸事件的做法:
設置 場景Node允許交互
self.userInteractionEnabled =YES;


下面是cocos2d v3以前的用法:
CCLayer常用設置
1.接收觸摸輸入
CCLayer默認情況是不接收觸摸輸入的,需要顯示地設置isTouchEnabled為YES
self.isTouchEnabled = YES;
設置isTouchEnabled為YES后,就會調用圖層相應的方法來處理觸摸輸入:
這些都是在CCStandardTouchDelegate協議中定義的方法
1> 當單指接觸到屏幕時
<span style="font-size:18px;">- (void)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;</span>
2> 當手指在屏幕上移動時
<span style="font-size:18px;">- (void)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;</span>
3> 當單指離開屏幕時
<span style="font-size:18px;">- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;</span>
4> 當觸摸被取消時
<span style="font-size:18px;">- (void)ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;</span>
很少會發生觸摸被取消的情況,
所以大多數情況下可忽略,或用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之前的圖層的觸摸輸入
2.coco2d 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代表三維中任意方向的加速度
}<span style="font-size:18px;">
</span>
3、CCLayerColor
默認情況下CCLayer是不能設置顏色的,
有時候,想給整個圖層設置一種背景顏色,
那么就需要用到CCLayerColor了,
CCLayerColor是CCLayer的子類
// 紅色:#ffff0000
ccColor4B color = ccc4(255, 0, 0, 255);
// 初始化一個顏色圖層
CCLayerColor *layerColor = [CCLayerColor layerWithColor:color];
// 添加到場景中
[scene addChild:layerColor];
效果圖:

4、CCLayerGradient
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];
效果圖:

5、CCLayerMultiplex
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];<span style="font-size:18px;"> </span>
圖層之間的切換是沒有過渡效果的
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈