【问题标题】:SKSpriteNode button stuck (iOS) after letting go. Advice neededSKSpriteNode 按钮在松开后卡住(iOS)。需要建议
【发布时间】:2014-11-25 02:26:25
【问题描述】:

所以...我正在为 iOS 开发这款类似马里奥的小型游戏,但遇到了一个我似乎无法解决的问题。

当使用我的控件时(见屏幕截图),它们有时会“卡住”,iOS 设备没有注意到我松开按钮。这会导致玩家在您松开按钮后继续朝某个方向移动。

编辑:当我同时单击两个按钮时似乎发生了故障。

希望有人能够发现我在以下代码中的不同之处:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches) {
        CGPoint touchLocation = [touch locationInNode:self];
        [self touchStateChanged:touchLocation buttonState:YES];
    }
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches) {
        CGPoint prevTouchLocation = [touch previousLocationInNode:self];
        [self touchStateChanged:prevTouchLocation buttonState:NO];
        CGPoint touchLocation = [touch locationInNode:self];
        [self touchStateChanged:touchLocation buttonState:YES];
    }   
}

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches) {
        // Some other logic... {...}

        [self touchStateChanged:touchLocation buttonState:NO];
    }
}

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (UITouch *touch in touches) {
        CGPoint touchLocation = [touch locationInNode:self];
        [self touchStateChanged:touchLocation buttonState:NO];
    }
}

-(void)touchStateChanged:(CGPoint)location buttonState:(BOOL)state
{
    SKNode *n = [self nodeAtPoint:location];

    if ([n.name isEqualToString:@"LeftMove"]) {
        self.player.moveLeft = state;
    }

    else if ([n.name isEqualToString:@"RightMove"]) {
        self.player.moveRight = state;
    }
    else if ([n.name isEqualToString:@"Jump"]) {
        self.player.didJump = state;
    }  
} 

显示按钮的屏幕截图:

谢谢:-)


部分解决了...

当前解决方案:

添加了一个名为_touchEvent 类型为UIEvent 的实例变量,并将以下行添加到touchesEnded

_touchEvent = event;

将以下代码添加到我的update 方法中:

if (_touchEvent && (int)[[_touchEvent allTouches]count] == 0) {
    self.player.moveLeft = NO;
    self.player.moveRight = NO;
    self.player.didJump = NO;
}

if (_touchEvent && (int)[[_touchEvent allTouches]count] == 1) {
    for (UITouch *touch in [_touchEvent allTouches]) {
        SKNode *n = [self nodeAtPoint:[touch locationInNode:self]];
        if ([n.name isEqualToString:@"Jump"]) {
            self.player.moveLeft = NO;
            self.player.moveRight = NO;
        }
    }
}

【问题讨论】:

  • 请不要在外部网站上发布代码(链接可能会中断)。如果此处粘贴的代码过多,则无论如何都应该缩小范围。
  • 谢谢。我会在其他时间记住这一点。

标签: ios objective-c iphone ios7 sprite-kit


【解决方案1】:

我认为问题在于触摸的位置(在-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 方法中)在任何节点之外。

尝试实现类似的东西

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    for (SKNode *node in yourButtonsArray) {
        // Some other logic... {...}

        [node setState:NO];
    }
}

或者你应该看看来自 KoboldKit 框架的 KKButtonBehaviour。

【讨论】:

  • 如果我正确理解您的建议,将会发生新的故障。现在,如果您 1) 跳跃并立即向左移动,以及 2) 放开跳跃,即使您可能仍然按住“向左移动”按钮,它也会自动停止向左移动。不过谢谢 :-)!
  • @MFaarkrog 是的,我的建议有点不完美。如果一次触摸的最大数量可能超过一个,请在touchesBegan 时在某个数组中添加您按下的节点,当touchesEnded 检查节点仍然“按下”并将state:NO 设置为那些没有按下。
  • 谢谢。我最终使用了您的想法的一些修改版本。我从实例变量中的点击中保存了 UIEvent,然后在我的更新方法中使用它。这样我就可以检查是否真的按下了任何按钮。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-19
  • 1970-01-01
  • 2016-06-28
  • 1970-01-01
相关资源
最近更新 更多