Sprite kit 如何在触摸屏中检测哪些节点仍被按下

Sprite kit 如何在触摸屏中检测哪些节点仍被按下,sprite-kit,touchesended,Sprite Kit,Touchesended,这个问题我已经纠缠了好几天了。我有多个SKSpriteNode,一个用于左箭头、右箭头和向上箭头。当我按住向右箭头时,我希望我的角色在按住向右箭头的同时继续向右移动,另一方面,如果按向上箭头,则无论是否按住它,都只会跳一次。 例如,我的问题是,当我按住向右箭头,然后按下向上箭头时,会调用touchesend,它会阻止我的角色向右移动,即使我的手指仍在向右箭头上 -(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

这个问题我已经纠缠了好几天了。我有多个SKSpriteNode,一个用于左箭头、右箭头和向上箭头。当我按住向右箭头时,我希望我的角色在按住向右箭头的同时继续向右移动,另一方面,如果按向上箭头,则无论是否按住它,都只会跳一次。 例如,我的问题是,当我按住向右箭头,然后按下向上箭头时,会调用touchesend,它会阻止我的角色向右移动,即使我的手指仍在向右箭头上

-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

[super touchesBegan:touches withEvent:event];

for (UITouch *touch in touches){


    CGPoint location = [touch locationInNode:self];


if (CGRectContainsPoint(rightArrow.frame, location)){

    [wizard setTexture:[SKTexture textureWithImageNamed:@"wizardRight"]];

    didTouchRightArrow = YES;
    isLookingRight = YES;
    isLookingLeft = NO;

    rightArrow.alpha = 0.5;
    NSLog(@"Touching right");

}

if (CGRectContainsPoint(leftArrow.frame, location)){

    [wizard setTexture:[SKTexture textureWithImageNamed:@"wizardLeft"]];

    isLookingRight = NO;
    isLookingLeft = YES;
    didTouchLeftArrow = YES;
    leftArrow.alpha = 0.5;
    NSLog(@"Touching left");

}

if (CGRectContainsPoint(upArrow.frame, location)){

    didTouchUpArrow = YES;
    upArrow.alpha = 0.5;
    NSLog(@"Touching up");

}

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

[super touchesBegan:touches withEvent:event];

if (rightArrow.alpha != 1.0){
    rightArrow.alpha = 1.0;
}
if (leftArrow.alpha != 1.0){
    leftArrow.alpha = 1.0;
}
if (upArrow.alpha != 1.0){
    upArrow.alpha = 1.0;

for (UITouch *touch in touches){

    CGPoint location = [touch locationInNode:self];

    if (CGRectContainsPoint(rightArrow.frame, location)){

        NSLog(@"Touching right");
        didTouchRightArrow = YES;
    } {

        NSLog(@"Not touching right");
        didTouchRightArrow = NO;
    }

    if (CGRectContainsPoint(leftArrow.frame, location)){

        NSLog(@"Touching Left");
        didTouchLeftArrow = YES;

    } else {

        NSLog(@"not touching left");
        didTouchLeftArrow = NO;
    }

    didTouchUpArrow = NO;



}

这可能不是解决问题的正确方法,但在touchesEnded中,我试图查看触摸是否仍在所需的矩形中。

您需要一种方法来识别正在注册触摸的不同节点。实现这一点的方法不止一种,但我始终发现使用节点的name属性是最简单、最容易使用的方法

通过使用BOOLs来注册触摸状态,您已经有了正确的想法

我编写了一些代码来处理您试图完成的任务:

#import "GameScene.h"

@implementation GameScene {

    SKSpriteNode *node0;
    SKSpriteNode *node1;
    BOOL node0touch;
    BOOL node1touch;
}

-(void)didMoveToView:(SKView *)view {
    self.backgroundColor = [SKColor blackColor];

    node0 = [SKSpriteNode spriteNodeWithColor:[SKColor redColor] size:CGSizeMake(100, 100)];
    node0.name = @"node0";
    node0.position = CGPointMake(100, 300);
    [self addChild:node0];

    node1 = [SKSpriteNode spriteNodeWithColor:[SKColor blueColor] size:CGSizeMake(100, 100)];
    node1.name = @"node1";
    node1.position = CGPointMake(400, 300);
    [self addChild:node1];

    node0touch = false;
    node1touch = false;
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    for (UITouch *touch in touches) {
        CGPoint touchLocation = [touch locationInNode:self];
        SKNode *node = [self nodeAtPoint:touchLocation];

        if([node.name isEqualToString:@"node0"])
            node0touch = true;

        if([node.name isEqualToString:@"node1"])
            node1touch = true;
    }
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    for (UITouch *touch in touches) {
        CGPoint touchLocation = [touch locationInNode:self];
        SKNode *node = [self nodeAtPoint:touchLocation];

        if([node.name isEqualToString:@"node0"])
            node0touch = false;

        if([node.name isEqualToString:@"node1"])
            node1touch = false;
    }
}

-(void)update:(CFTimeInterval)currentTime {

    if(node0touch)
        NSLog(@"node0 touch");

    if(node1touch)
        NSLog(@"node1 touch"); 
}

非常感谢。成功了!我只是有一个关于触摸部分的问题。我不明白为什么if语句在这里起作用。您能解释一下原因吗?因为它似乎不应该工作。@Xsv23-touchesend与touchestart或touchesMoved基本相同。只是不同的通话状态。所有触控方法中的for循环会循环当前注册的所有触控。请记住,一次可以有多个触摸,因此循环。if语句检查先前声明的节点的name属性是否匹配。由于我们有两个具有不同声明名称的节点,因此它能够使用字符串比较isEqualToString.ok区分这两个节点,这很有意义。非常感谢。还有一个问题。我试图实现touchesMoved,因为如果您触摸节点并将手指移出节点的rect,那么该变量仍然是真的。如何实现这一点,以便在手指移动时检测手指是否仍在直肠中@sangony@Xsv23-与开始和结束时完全相同的原则。使用for循环并检查每个节点的接触状态。