(本文寫作基於千鋒3g學院提供的第三季講授視頻編寫,詳細請看筆記扉頁:傳送門)
這一期的視頻主要介紹如何在上一期創建關卡圖片之後加入點擊事件的響應,讓我們可以通過點擊關卡或者是返回鍵獲得事件的響應。
主要包括兩個內容:座標轉換&點擊事件響應&物體(包括觸摸點)之間的碰撞檢測
座標轉換:
關於座標,這裏有兩個不同的座標系:IOS View座標系 & OpenGL View座標系,下面列出兩個座標系的特徵
IOS View座標系:
1.座標原點(0,0)位於當前視圖的左上角,以屏幕寬爲x增量,屏高爲y增量
2.CGPoint座標點也就是位置,格式爲:(x, y)
3.CGSize表示某視圖寬度和高度,格式爲:(width, height)
4.CGRect同時表示視圖的CGPoint和CGSize,格式爲:(x, y, width, height)
5.frame是以父視圖的左上角點作爲原點的CGRect
6.bounds是指以自身視圖的左上角點作爲原點的CGRect
7.origin表示當前視圖左上角的CGPoint
(frame與bounds的origin有時候是不同的。原因在於5、6點)
8.center表示視圖中心位於父視圖中的CGPoint
OpenGL View座標系:
1.座標原點(0,0)位於視圖的左下角,以水平方向爲x軸,垂直方向爲y軸
2.AnchorPoint錨點位置(0.5,0.5)
3.frame和bounds的概念與UIView中一樣
4.position就是CCNode的位置(CGPoint),等同與IOS VIew中的center
(PS:視頻中,作者說到IOS View的座標原點是在左下角的,哦,旋迴去就是原來的習慣的座標了對吧?事情並沒那麼簡單,如果你在加入點擊響應之後試圖將觸摸點用兩種座標打印出來,你會發現IOS View 與 OpenGL View的座標原點無緣無故的從兩個角落走到了一起,爲什麼會有這麼基情的事情發生?且看iOS cocos2d學習筆記 之 《iOS View與OpenGL View的那些事》)
IOS View 與 OpenGL View之間的轉換方法:
下面是兩個座標通過導演類方法來轉換的方法,先用[[CCDirector sharedDirector]--
// 從UI View座標轉換到OpenGL View座標:
- (CGPoint) convertToGL: (CGPoint) uiPoint;
// 從OpenGL View座標轉換到UI View座標:
- (CGPoint) convertToUI: (CGPoint) glPoint;
在這兩個座標系中我們要搞清楚的是,我們究竟在哪個座標系上面進行操作。
點擊事件響應
下面我們先了解和添加點擊事件的響應:
首先要做的事情是:
在加載畫面的時候加入一行代碼打開觸摸開關:
[self setIsTouchEnabled:YES]
以下就是我們要添加代理相應的方法,與UIKit的觸摸事件相仿。
多個點擊事件響應ccTouches觸摸代理:
@protocol CCStandardTouchDelegate<NSObject>
@optional
- (void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void) ccTouchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;
@end
單個點擊事件響應ccTouch觸摸代理:
@protocol CCTargetedTouchDelegate <NSObject>
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event;
@optional
// touch updates:
- (void)ccTouchMoved:(UITouch *)touch withEvent:(UIEvent *)event;
- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event;
- (void)ccTouchCancelled:(UITouch *)touch withEvent:(UIEvent *)event;
@end
物體(包括觸摸點)之間的碰撞檢測
獲取物件(精靈)邊框的方法:
- (CGRect) boundingBox;
ps: 此方法適用於繼承於CCNode的所有繼承類的對象
eg: CCSprite *superman;
superman.boundingBox = (CGRect)Rect;
CGRect boundingBox = [superman boundingBox];
判斷矩形
// 判斷點point是否在矩形rect裏
- (bool) CGRectContainsPoint (CGRect rect, CGPoint point)
// 判斷兩個矩形是否相交
- (bool) CGRectIntersectsRect (CGRect rect1, CGRect rect2)
// 判斷矩形rect2是否在矩形rect1裏
- (bool) CGRectContainsRect (CGRect rect1, CGRect rect2)
好了,介紹了上面一堆東西之後,下面要列出真正要做的事情步驟:
1、獲取手指點擊屏幕的座標
2、將手指座標從UIKit座標轉換到OpenGL座標
3、獲取遊戲精靈的邊框
4、檢測手指座標與精靈邊框是否有包涵關係(即手指有木有點到精靈內)
5、精靈做出響應動作
下面給出實現中ccTouchesEnded方法的代碼:
- (void) ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
// 1. 拿到ui觸摸點
UITouch *oneTouch = [touches anyObject];
UIView *touchView = [oneTouch view];
NSLog(@"觸摸點所觸摸到的View:x = %f; y = %f",oneTouch.view.frame.origin.x, oneTouch.view.frame.origin.y);
// 取到當前觸摸到的一個uiview
// 這裏的touchview 就是 glview
CGPoint location = [oneTouch locationInView:touchView];
// oneTouch 相對 touchView 上的座標
NSLog(@"觸摸點於所在View上的位置:x = %f, y = %f", location.x, location.y);
// 2.轉成world opengl point
CGPoint worldGLPoint = [[CCDirector sharedDirector] convertToGL:location];
NSLog(@"觸摸點轉換成世界點:x = %f, y = %f", worldGLPoint.x, worldGLPoint.y);
CGPoint nodePoint = [self convertToNodeSpace:worldGLPoint];
NSLog(@"世界點轉換成node點:x = %f, y = %f", nodePoint.x, nodePoint.y);
// 把世界座標轉化爲node座標 self
// self.children.count self 上所有的孩子
for (int i = 0; i < self.children.count; i++) {
CCSprite *oneSprite = [self.children objectAtIndex:i];
// 取得第i個精靈
if (CGRectContainsPoint(oneSprite.boundingBox, nodePoint) && oneSprite.tag == 100) {
// 判斷觸碰點與精靈的關係,如果nodePoint包含在oneSprite中
// 並且tag爲100
CCScene *sc = [StartScene scene];
CCTransitionScene *trans = [[CCTransitionCrossFade alloc] initWithDuration:0.5f scene:sc];
[[CCDirector sharedDirector] replaceScene:trans];
[trans release];
}
else if (CGRectContainsPoint(oneSprite.boundingBox, nodePoint) && oneSprite.tag < succeedLevel + 1 && oneSprite.tag > 0)
{
NSLog(@"選中了第%d關", oneSprite.tag);
CCScene *gameScene = [GameScene sceneWithLevel:oneSprite.tag];
[[CCDirector sharedDirector] replaceScene:gameScene];
}
}
}
其實,這樣的點擊事件並不是我們常用的touchInsert方法,而是使用了檢測觸摸點與物件之間的位置檢測來實現點擊的,但從中我們卻可以獲取很多有用的相關知識。確實是值得一學的。
做到這一步,我們就可以進入我們遊戲的核心,製作遊戲內容了。
(學期開了就有很多東西要白忙,加上這篇文章寫得還是挺嘔心瀝血的,因爲裏面涉及的內容很多,需要搞懂的事情還是蠻多蠻複雜的,出於責任心,我搞懂了再寫好放上網啦)