cocos2d 从按钮扩展触摸区域

Posted

技术标签:

【中文标题】cocos2d 从按钮扩展触摸区域【英文标题】:cocos2d extend touch area from a button 【发布时间】:2011-08-03 02:29:57 【问题描述】:

我有一些单选按钮,但触摸区域太小。触摸区域取决于图像大小。有没有一种优雅的方法可以用 cocos2d 扩展触摸区域而不使用更大的图像或使用 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)];

提前致谢。

【问题讨论】:

【参考方案1】:

你需要重写 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 和我自己的课程后,我找到了适合我的解决方法。 它是一个简单的 ccsprite 覆盖,但您必须将该类添加到 CCTouchDispatcher。查看我编辑的答案【参考方案2】:

我通过从 CCMenu 覆盖 -(CCMenuItem*) itemForTouch:(UITouch *)touch 来解决问题。

-(CCMenuItem*) itemForTouch:(UITouch *)touch CGPoint touchLocation = [touch locationInView:[touch view]]; touchLocation = [[CCDirector sharedDirector] convertToGL:touchLocation]; CCMenuItem* 项目; CCARRAY_FOREACH(儿童_,项目) if ([item visible] && [item isEnabled]) CGPoint local = [item convertToNodeSpace:touchLocation]; CGRect r = [项目矩形]; r.origin = CGPointZero; // 将 rect 增加 * 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)) 归还物品; 返回零;

将矩形居中在图像中间不起作用

【讨论】:

【参考方案3】:

取原来的答案码...

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 行代码!玩得开心!

【讨论】:

天才!这对我来说很完美。我无法让子类正常工作,所以这是一个不错的 hack。非常感谢。 Genius 并没有对此做出公正,在我看来,完美的解决方案。 +1 感谢分享。【参考方案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 的帖子 (2sa-studio.blogspot.kr/2013/01/…) 并手动修补您的 cocos2d。 Cocos2dx 有这个功能吗?找不到。

以上是关于cocos2d 从按钮扩展触摸区域的主要内容,如果未能解决你的问题,请参考以下文章

cocos2d 3.x 如何处理精灵外部的触摸

触摸事件 Cocos2d iPhone

cocos2d-x 3.x 触摸事件

弹出菜单层后cocos2d层不响应触摸

cocos2D for iPhone 和触摸检测的问题

cocos2dx 3.x 触摸事件