Cocos2d处理与多个层次的触摸

我已经忙了几天,试图找出如何处理我的Cocos2d项目中的触摸。 情况与平时有点不同。 我有几个不同的游戏图层,上面有需要用触摸控制的项目:

  • ControlLayer:控制游戏控制(移动,动作button)。 这一层在最上面。
  • GameplayLayer:保存游戏对象(CCSprites)。 这一层直接在ControlLayer下面。

现在我的Touch在ControlLayer中运行良好,我可以移动我的可玩angular色,让他跳起来做其他的傻事。 然而,我不能理解如何实施触及我的一些CCSprites。

到目前为止,我收集的信息让我觉得我需要从控制层获取所有触摸input。 然后,我需要将触摸信息“级联”到GameplayLayer,以便在那里处理input。 另一个select是我从我的精灵获取CGRect信息,通过创build一个指向应该可触摸的对象的指针的数组。 我应该能够使用ControlLayer中的信息来检查该列表中的每个项目是否被触摸。

什么是最好的select做到这一点,我该如何实现呢? 我是一种新的编程与cocoa和Objective C,所以我不知道什么是最好的select是这种语言,以及如何访问精灵CGRect信息([mySpriteName boundingBox])在另一个类,然后它是图层呈现。

目前唯一的方法,我一定要得到它的工作是为每个CCSprite位置创build重复的CGRects,所以我可以检查它们,但我知道这是不正确的做法。

我到目前为止(testing)是这样的:ControlLayer.m

- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [touches anyObject]; CGPoint location = [touch locationInView: [touch view]]; CGRect rect = CGRectMake(0.0f, 0.0f, 100.0f, 100.0f); //Tried some stuff here to get see if I could get a sprite by tagname so I could use it's bounding box but that didn't work // Check for touch with specific location if (CGRectContainsPoint([tree boundingBox], location)) { CCLOG(@"CGRect contains the location, touched!"); } CCLOG(@"Layer touched at %@", NSStringFromCGPoint(location)); 

}

预先感谢帮助我!

最简单最简单的方法来解决你的问题,国际海事组织,是通过使用ccTouchBegan / Moved / Ended而不是ccTouchesBegan / Moved / Ended 。 这意味着,您正在某个特定的时刻处理一个单一的触摸,以避免对多个触摸感到困惑,再加上ccTouchBegan最重要的特性是CCLayer可以“消费”触摸并阻止它传播到下一层。 下面的代码示例后的更多解释。

这里是步骤来做到这一点。 在应该处理触摸事件的所有CCLayer子类中实现这些方法集:

首先,向CCTouchDispatcher注册:

 - (void)registerWithTouchDispatcher { [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES]; } 

接下来,实现ccTouchBegan,下面的例子来自我创build的游戏(当然省略了一些部分):

 - (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event { if (scene.state != lvlPlaying) { // don't accept touch if not playing return NO; } CGPoint location = [self convertTouchToNodeSpace:touch]; if (scene.mode == modePlaying && !firstTouch) { if (CGRectContainsPoint(snb_putt.sprite.boundingBox, location)) { touchOnPutt = touch.timestamp; // do stuff // return YES to consume the touch return YES; } } // default to not consume touch return NO; } 

最后实现ccTouchMoved和ccTouchEnded,就像ccTouches *的同行一样,除了他们处理单一的触摸而不是触摸。 传递给这些方法的触摸仅限于在ccTouchBegan中使用的触摸,因此不需要在这两种方法中进行validation。

基本上这是如何工作的。 触摸事件由CCScene根据zsorting(即从顶层开始到底层)逐一传递给每个CCLayer,直到任何层消耗触摸为止。 因此,如果顶层(例如控制层)的图层消耗了触摸,那么触摸将不会传播到下一层(例如对象层)。 这样,每一层都只需要担心自己决定是否消费。 如果它决定不能使用触摸,那么它只需要不消耗触摸(从ccTouchBegan返回NO),触摸将自动向下传播。

希望这可以帮助。