在我的游戏中,我正在创建许多按钮。 我发现许多按钮都没有检测到用户何时向下/向上触摸按钮右侧。 换句话说,当触摸按钮的左侧时,按钮会正确响应,但不会在右侧触摸。 简而言之,如果您将按钮切成三部分,则按钮的右侧 1/3 没有响应,而按钮的其他 2/3 可以完美工作。 下面是我用来实现按钮的代码。 谁能告诉我我可能做错了什么? 当我第一次开始使用精灵套件时,我确实注意到当 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
这段代码到底在做什么?为什么要增加 x 和 y 值?为什么需要 k 值?我认为您正在抵消触摸的位置,请尝试记录所有触摸位置并将它们绘制在屏幕上。
有一些本机方法可以检测节点中的触摸并将坐标转换为场景位置。
在每个事件上重新创建手势识别器似乎效率低下,当发生多次触摸时,locationInScene 也没有多大意义(不知道你想在那里实现什么)
也就是说,如果您的按钮仅在更改 zPosition 时才开始工作,我假设您确实存在重叠问题。由于在(默认)zPosition 0 处涉及其他节点(无论是否可见),因此您必须显示更多代码才能获得帮助。