Cocos2d如何扩大按钮的触摸区域

8

我有一些单选按钮,但触摸区域太小了。触摸区域取决于图像大小。是否有一种优雅的方法能够在不使用更大的图像或使用cgrect自己创建触摸区域的情况下扩展触摸区域?setContentSize可以实现我的要求。不幸的是,图像移动到了内容大小的左下角。设置锚点会移动内容大小,但是图像仍然停留在左下角。

    CCMenuItem* pickEasy = [CCMenuItemImage itemFromNormalImage:@"radiobutton_off.png" selectedImage:@"radiobutton_on.png" target:self selector:@selector(pickEasyTapped:)];
    pickEasy.position = ccp(ss.width * 0.40, ss.height * 0.78);
    [pickEasy setContentSize:CGSizeMake(50, 50)];

Thanks in advance.

4个回答

11
获取原始答案代码...
CCMenuItem* pickEasy = [CCMenuItemImage itemFromNormalImage:@"radiobutton_off.png" selectedImage:@"radiobutton_on.png" target:self selector:@selector(pickEasyTapped:)];
pickEasy.position = ccp(ss.width * 0.40, ss.height * 0.78);
[pickEasy setContentSize:CGSizeMake(50, 50)];

你只需要将图像放在正确的位置即可...

[[[pickEasy children] objectAtIndex:0] setAnchorPoint:ccp(0.5,0.5)];
[[[pickEasy children] objectAtIndex:1] setAnchorPoint:ccp(0.5,0.5)];
[[[pickEasy children] objectAtIndex:0] setPosition:ccp(pickEasy.contentSize.width/2,pickEasy.contentSize.height/2)];
[[[pickEasy children] objectAtIndex:1] setPosition:ccp(pickEasy.contentSize.width/2,pickEasy.contentSize.height/2)];

只需4行代码即可完成!玩得开心!


太棒了!这对我非常有效。我无法正确地让子类起作用,所以这是一个不错的技巧。非常感谢。 - Arbel
天才不能够为这个完美的解决方案做出公正评价,我认为。+1 感谢分享。 - S.H.

4
此外,您可以更改CCMenuItem的activeArea属性。(cocos2d 2.x)
CGRect active = [someMenuItem activeArea];
[someMenuItem setActiveArea:CGRectMake(active.origin.x - active.size.width * 2.f, active.origin.y - active.size.height * 2.5f, active.size.width * 2.f, active.size.height * 2.f)];
[someMenu addChild:someMenuItem];

因为activeArea是标准的,所以我认为这个解决方案是正确的。如果您使用旧版本,请参考Sébastien Dabet的帖子(http://2sa-studio.blogspot.kr/2013/01/custom-touch-area-for-ccmenuitem-in.html)并手动修补您的cocos2d。 - Dalinaum
这个在Cocos2dx中可用吗?我找不到它。 - Anil

2

您需要覆盖rectInPixels方法

- (CGRect)rectInPixels
{
CGSize s = [self contentSize];
return CGRectMake(0, 0, s.width, s.height);
}

- (BOOL)containsTouchLocation:(UITouch *)touch
{   
CGPoint p = [self convertTouchToNodeSpace:touch];
CGRect r = [self rectInPixels];
return CGRectContainsPoint(r, p);
}

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {

NSSet *allTouches = [event allTouches];
for (UITouch *aTouch in allTouches) {

        if ( ![self containsTouchLocation:aTouch] ) return NO;
}

return YES;
}

这只是让精灵检查触摸是否在您修改过的CGRect范围内。

编辑以显示CCSprite子类 ---

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

- (void)onExit
{
[[CCTouchDispatcher sharedDispatcher] removeDelegate:self];
[super onExit];
}   

感谢您的回复。我不知道在哪里覆盖rectInPixels。经过尝试ccnode、ccsprite、ccmenu、ccmenuitem和我的自定义类,我找到了一个适合我的解决方法。 - zeiteisen
这只是一个简单的CCSprite重写,但你需要将类添加到CCTouchDispatcher。请查看我的编辑答案。 - Bongeh

2
我通过重写CCMenu中的-(CCMenuItem*) itemForTouch:(UITouch *)touch方法来解决了问题。
-(CCMenuItem*) itemForTouch:(UITouch *)touch
{
    CGPoint touchLocation = [touch locationInView:[touch view]];
    touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation];
    CCMenuItem* item;
    CCARRAY_FOREACH(children_, item) 
    {
        if ([item visible] && [item isEnabled]) {
            CGPoint local = [item convertToNodeSpace:touchLocation];
            CGRect r = [item rect];
            r.origin = CGPointZero;
            // 将矩形区域增加2倍
            // 图像左下角处的矩形
            CGRect bigR = CGRectMake(r.origin.x - r.size.width, r.origin.y - r.size.height, r.size.width * 2, r.size.width * 2);
            // 图像右上角处的矩形
            CGRect bigR2 = CGRectMake(0, 0, r.size.width * 2, r.size.width * 2);
            if (CGRectContainsPoint(bigR, local) || CGRectContainsPoint(bigR2, local)) {
                return item;
            }
        }
    }
    return nil;
}

将矩形区域居中到图像中央并没有起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接