1

在我的游戏中,我创建了许多按钮。我发现当用户在按钮右侧向下/向上触摸时,许多按钮都没有检测到。换句话说,当在按钮的左侧触摸按钮时,按钮会正确响应,而不是在右侧。简而言之,如果您将按钮分成三部分,则右侧 1/3 的按钮没有响应,而另外 2/3 的按钮可以正常工作。下面是我用来实现按钮的代码。谁能告诉我我可能做错了什么?当我第一次开始使用 Sprite Kit 时,我确实注意到,当 SKSpriteNode::zPosition 属性未设置为 1 或更大时,我的按钮根本不会响应……一旦我设置了这个属性,我的按钮就开始工作了。无论按钮精灵节点是否是场景中唯一的精灵节点,都会出现这个 zPosition 问题,这让我认为问题也不是重叠问题。有什么想法吗?

我已经扩展了 SKSpriteNode 类,增加了一个方法 GESpriteNode::setGestureHandler:withKey:,它具有以下签名:

- (void) setGestureHandler: (void (^)(SKNode *node, GEGestureRecognizer *recognizer))handler withKey: (NSString *)key;
- (void) removeGestureHandlerWithKey: (NSString *)key;

并且,像这样实现(其中 _event 是 NSMutableDictionary):

- (void) setGestureHandler: (void (^)(SKNode *node, GEGestureRecognizer *recognizer))handler withKey: (NSString *)key {
    if (key != nil) {
        [_events setObject: [handler copy] forKey: key];
    }
}

- (void) removeGestureHandlerWithKey: (NSString *)key {
    if (key != nil) {
        [_events removeObjectForKey: key];
    }
}

- (void) touchesBegan: (NSSet *)touches withEvent: (UIEvent *)event {
    if (![self isHidden]) {
        void (^handler)(SKNode *, GEGestureRecognizer *);

        handler = [_events objectForKey: GETouchDownGestureHandlerKey];

        if (handler != nil) {
            GEGestureRecognizer *recognizer = [[GEGestureRecognizer alloc] initWithScene: [self scene] withTouches: touches];
            if (recognizer != nil) {
                handler(self, recognizer);
            }
        }
    }
}

- (void) touchesEnded: (NSSet *)touches withEvent: (UIEvent *)event {
    if (![self isHidden]) {
    void (^handler)(SKNode *, GEGestureRecognizer *);

        handler = [_events objectForKey: GETouchUpGestureHandlerKey];

        if (handler != nil) {
            GEGestureRecognizer *recognizer = [[GEGestureRecognizer alloc] initWithScene: [self scene] withTouches: touches];
            if (recognizer != nil) {
                handler(self, recognizer);
            }
        }
    }
}

它们的用法如下:

GESpriteNode *spriteNode = [GESpriteNode spriteNodeWithImageNamed: NODE_BUTTON_1];
[spriteNode setAlpha: ALPHA_OPAQUE];
[spriteNode setGestureHandler: ^(SKNode *node, GEGestureRecognizer *recognizer) {
    [node setScale: SCALE_95];
} withKey: GETouchDownGestureHandlerKey];
[spriteNode setGestureHandler: ^(SKNode *node, GEGestureRecognizer *recognizer) {
[node setScale: SCALE_100];
} withKey: GETouchUpGestureHandlerKey];
[spriteNode setHidden: NO];
[spriteNode setName: NODE_BUTTON_1];
[spriteNode setPosition: CGPointMake(384.0f, 387.0f)];
[spriteNode setScale: SCALE_100];
[spriteNode setUserInteractionEnabled: YES];
[spriteNode setZPosition: 1];
[self addChild: spriteNode];

我的 GEGestureRecognizer.h 类定义如下:

#import <SpriteKit/SpriteKit.h>

extern NSString * const GETouchDownGestureHandlerKey;
extern NSString * const GETouchUpGestureHandlerKey;

@interface GEGestureRecognizer : NSObject

// public properties
@property (nonatomic, strong) SKScene *scene;

// public methods
- (instancetype) initWithScene: (SKScene *)scene withTouches: (NSSet *)touches;
- (CGPoint) locationInScene: (SKScene *)scene;

@end

并且,它的 GEGestureRecognizer.m 定义为:

#import "GEGestureRecognizer.h"

#pragma mark -
#pragma mark Constants

NSString * const GETouchDownGestureHandlerKey = @"GETouchDownGestureHandlerKey";
NSString * const GETouchUpGestureHandlerKey = @"GETouchUpGestureHandlerKey";

@interface GEGestureRecognizer () {

    @private
        SKScene *_scene;
        NSSet *_touches;

}

@end

@implementation GEGestureRecognizer

@synthesize scene = _scene;

- (instancetype) initWithScene: (SKScene *)scene withTouches: (NSSet *)touches {
    if ((self = [super init])) {
        _scene = scene;
        _touches = touches;
    }
    return self;
}

- (CGPoint) locationInScene: (SKScene *)scene {
    CGFloat x = 0;
    CGFloat y = 0;
    CGFloat k = 0;

    for (UITouch *touch in _touches) {
        const CGPoint point = [touch locationInNode: scene];
        x += point.x;
        y += point.y;
        k++;
    }

    if (k > 0) {
        return CGPointMake(x/k, y/k);
    }

    return CGPointZero;
}

@end
4

2 回答 2

0

这段代码到底在做什么?为什么要增加 x 和 y 值?为什么需要k值?我认为您正在偏移触摸位置,请尝试记录所有触摸位置并将它们绘制在屏幕上。
有本地方法可以检测节点中的触摸并将坐标转换为场景位置。

于 2013-11-02T19:53:05.500 回答
0

在每个事件上重新创建 GestureRecognizer 似乎效率很低,当发生多次触摸时 locationInScene 也没有多大意义(不知道你想在那里实现什么)

也就是说,如果您的按钮仅在您更改 zPosition 时才开始工作,我认为您确实有重叠问题。由于在(默认)zPosition 0 处涉及其他节点(无论是否可见),因此您必须显示更多代码才能获得帮助。

于 2014-06-17T10:23:05.573 回答