触摸检测问题
我刚刚学习 Cocos2d 和 Objective-C,触摸检测方面存在一些问题。
我在 HelloWorldLayer
中有几个精灵和一些draggableSprites (NSMutableArray)。两个可拖动的精灵相互重叠(底部的较大)。
然后我有一些代码可以摇动触摸的精灵:
- (void)selectSpriteForTouch:(CGPoint)touchLocation {
CCSprite *touchSprite = nil;
for (CCSprite *sprite in dragableSprites) {
if (CGRectContainsPoint(sprite.boundingBox, touchLocation)) {
touchSprite = sprite;
break;
}
}
if (touchSprite != selSprite) {
[selSprite stopAllActions];
[selSprite runAction:[CCRotateTo actionWithDuration:0.1 angle:0]];
CCRotateTo * rotLeft = [CCRotateBy actionWithDuration:0.1 angle:-1.0];
CCRotateTo * rotCenter = [CCRotateBy actionWithDuration:0.1 angle:0.0];
CCRotateTo * rotRight = [CCRotateBy actionWithDuration:0.1 angle:1.0];
CCSequence * rotSeq = [CCSequence actions:rotLeft, rotCenter, rotRight, rotCenter, nil];
[touchSprite runAction:[CCRepeatForever actionWithAction:rotSeq]];
selSprite = touchSprite;
}
}
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
[self selectSpriteForTouch:touchLocation];
return TRUE;
}
但是当我触摸顶部或底部的精灵时,只有底部的精灵在摇动(它是在 init 中首先添加的)。
我认为我需要替换代码 CGRectContainsPoint(sprite.boundingBox, touchLocation)
,但我只是不知道如何替换。
我在论坛上呆了几个晚上,但我仍然不明白如何让顶部精灵摇动......
I'm just learning Cocos2d and Objective-C, and I have some problems with touch detection.
I have several sprites in HelloWorldLayer
and some draggableSprites (NSMutableArray). Two of the draggableSprites are located one over another (the bottom one is bigger).
Then i have some code that shakes a touched sprite:
- (void)selectSpriteForTouch:(CGPoint)touchLocation {
CCSprite *touchSprite = nil;
for (CCSprite *sprite in dragableSprites) {
if (CGRectContainsPoint(sprite.boundingBox, touchLocation)) {
touchSprite = sprite;
break;
}
}
if (touchSprite != selSprite) {
[selSprite stopAllActions];
[selSprite runAction:[CCRotateTo actionWithDuration:0.1 angle:0]];
CCRotateTo * rotLeft = [CCRotateBy actionWithDuration:0.1 angle:-1.0];
CCRotateTo * rotCenter = [CCRotateBy actionWithDuration:0.1 angle:0.0];
CCRotateTo * rotRight = [CCRotateBy actionWithDuration:0.1 angle:1.0];
CCSequence * rotSeq = [CCSequence actions:rotLeft, rotCenter, rotRight, rotCenter, nil];
[touchSprite runAction:[CCRepeatForever actionWithAction:rotSeq]];
selSprite = touchSprite;
}
}
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
[self selectSpriteForTouch:touchLocation];
return TRUE;
}
But when I touch the top or bottom sprites, only bottom one is shaking (it was added first in init).
I think that I need to replace the code CGRectContainsPoint(sprite.boundingBox, touchLocation)
, but I just don't know how.
I spent several nights on forums but I still can't understand how to make the top sprite shake...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
尝试更像这样的事情(注意它是
ccTouchesBegan
而不是ccTouchBegan
):在
selectSpriteForTouch
中设置 for 循环的方式只会导致第一个由于您的break
语句,要选择draggableSprites
中的对象。使用这个新代码,其边界框包含触摸的每个精灵都将被动画化。该代码可能并不完美,因为我直接将其输入 Chrome,但您明白了。另一件需要注意的重要事情是,您不能在两个不同的精灵上运行相同的操作,如下所示:
此代码将无法按预期工作;只有最后一个 sprite(
oneMoreSprite
) 才会被动画化。为了在多个精灵中重复使用 CC 动画,请使用以下代码:我们复制该动作,以便它可以由另一个精灵运行(
someOtherSprite
、oneMoreSprite
)而不将其从原始精灵someSprite
中删除。然后,我们自动释放它,这样就不会出现内存泄漏。Try something more like this (notice it is
ccTouchesBegan
notccTouchBegan
):The way the for loop is set up in
selectSpriteForTouch
will cause only the first object indraggableSprites
to be selected, because of yourbreak
statement. With this new code, each sprite whose bounding box contains the touch will be animated. The code might not be perfect because I typed it straight into Chrome, but you get the idea.Another important thing to note is that you cannot run the same action on two different sprites, like this:
This code will not work as intended; only the last sprite(
oneMoreSprite
) will be animated. In order to re-use CC animations with multiple sprites, use this code:We make a copy of the action so it can be run by another sprite (
someOtherSprite
,oneMoreSprite
) without removing it from the original sprite,someSprite
. Then, we autorelease it so we don't have a memory leak.