长触摸手势识别选择实例节点



我正在制作游戏《2048》的修改版本。我找到了这个教程,用它来构建基本的游戏,然后编辑它来满足我想做的事情,但我遇到了一些问题。

为了提供进一步的信息,具有数字的"tiles"是它们自己的实例化类,简称为Tile。显示的网格只不过是一个数组,每个空格包含一个*_noTile,或者Tile类的一个实例。

我想使用UILongPressGestureRecognizer来"选择"并突出显示其中一个tile。我通过在这里找到的信息添加了这一点。最初我尝试使用下面的代码在我的网格类(从教程)作为包含滑动手势识别器的didLoadFromCCB方法的一部分,因为它使所有的手势识别在同一个地方。

UILongPressGestureRecognizer *longpress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(onLongPress:)];
[longpress setMinimumDuration:0.5];
[[[CCDirector sharedDirector] view] addGestureRecognizer:longpress];

我测试了这个,它的工作是检测长按很好。但是我遇到的问题是,当用户长按时,如何选择"Tile"。我试着查看教程中的移动方法,以弄清楚它是如何选择贴图的,但它更多地与滑动方向有关。

我在这里看到了一堆使用converttonospace进行选择的方法,但每个例子都来自精灵,而我没有使用精灵(在节点中有一个,但我需要选择节点而不是精灵)。我试过在Tile类和我的Grid类中这样做,似乎都不起作用,所以我来这里征求关于我如何做到这一点的建议。下面是我的手柄长按方法的一个例子,我把它放在Tile类中。

-(void)_handleLongPressGesture:(UILongPressGestureRecognizer *)recognizer {
    if(recognizer.state == UIGestureRecognizerStateBegan) {
        CCLog(@"long press");
        CGPoint touchPoint = [[CGDirector sharedDirector] convertToGL:[recognizer locationInView:[recognizer view]]];
        touchPoint = [self convertToNodeSpace:touchPoint];
        CGRect boundingBox = [self boundingBox];
        if(CGRectContainsPoint(boundingBox, touchPoint)) {
            self.backgroundNode.color = [CCColor whiteColor];
            self.valueLabel.color = [CCColor blackcolor];
        }
    }
}
有谁能帮我解决这个问题吗?基本上,我们的最终目标是能够长按一个贴图,通过改变颜色让它"高亮",然后当用户继续按住并滑动手指到长按的贴图旁边的贴图时,来自这些贴图的值将被组合在一起。我愿意通过Skype或任何其他方式来解决这个问题。谢谢。

------------------- 修复感谢denis alenti为我指明了正确的方向。我想我会在最后发布我是如何解决这个问题的。我的Tile类是我的Grid类的一个子类,所以我只是把手势识别移到了那里,并创建了下面的方法。我还在摆弄它,但是到目前为止,每次我按下一个瓷砖,它都能正常工作。

-(void)onLongPress:(UILongPressGestureRecognizer *) recognizer {
    CGPoint touchPoint = [[CCDirector sharedDirector] convertToGL:[recognizer locationInView:[recognizer view]]];
    touchPoint = [self convertToNodeSpace:touchPoint];
    if (recognizer.state == UIGestureRecognizerStateBegan) {
        for (Tile *tile in self.children) {
            if([tile isKindOfClass:[Tile class]) {
                CGRect tileBoundingBox = tile.boundingbox;
                if (CGRectContainsPoint(tileBoundingBox, touchPoint) {
                    // perform action here
                }
            }
        }
    }
}

试试这样做。在_handleLongPressGesture中,使用for循环遍历舞台上的所有项目,在本例中为CCSprite,然后使用radius或boundingBox解决方案进行限制。

for (CCSprite *item in self.children) {
   if ([item isKindOfClass:[CCSprite class]]) {
            float radius = item.contentSize.width/2.0;
            float distance = pow(item.position.x - touchPoint.x, 2) + pow(item.position.y - touchPoint.y, 2);
            distance = sqrt(distance);
            if (distance <= radius) {
                //do something
                break;
            }
    }
}

最新更新