【问题标题】:Why does mouseDragged position lag behind actual mouse?为什么 mouseDragged 位置落后于实际鼠标?
【发布时间】:2014-01-19 16:08:52
【问题描述】:

我正在尝试制作一个 SpriteKit 游戏,玩家可以在其中拖动一组精灵,但我不知道如何让精灵跟随鼠标光标。使用 SpriteKit 样板,我得到了这个:

这是我如何移动“Hello, world!”的相关逻辑SKNode中的精灵babies

SKNode *babies;

-(void)mouseDown:(NSEvent *)theEvent {
    dragStart = [theEvent locationInWindow];
    babiesStart = babies.position;
}

-(void)mouseDragged:(NSEvent *)theEvent {
    CGPoint translation = CGPointMake([theEvent locationInWindow].x - dragStart.x,
                                      [theEvent locationInWindow].y - dragStart.y);
    float adjust = 1.0;
    babies.position = CGPointMake(babiesStart.x + translation.x * adjust,
                                  babiesStart.y + translation.y * adjust);
}

我尝试了许多不同的方法,例如theEvent 上的 deltaX 和 Y,但我得到了相同的结果。我发现的唯一解决方案是使用 adjust 变量,但这显然是一个 hack。

【问题讨论】:

  • 您的场景是 3D 的吗?这可能是由于透视?
  • 据我所知,这是一个 2D 场景。我的其余代码是 Xcode 在您创建新的 SceneKit 项目时为您提供的。
  • 当我看到一个 SceneKit 问题时我感到非常兴奋,但在阅读之后我很确定 OP 正在谈论 SpriteKit(SKNode 它是 SpriteKit 的一部分,而 SCNNode 是 SceneKit 的一部分,OP 还提到制作游戏)
  • 你指的是什么 SpriteKit 样板?请提供一个链接,以便我们查看您发布的代码的上下文。

标签: objective-c macos sprite-kit


【解决方案1】:

NSEvent 在 SpriteKit 中有另一个方法,- (CGPoint)locationInNode:(SKNode *)node。通过使用它,我能够获得正确的偏移值,以便将 SKNode 与鼠标一起移动。

【讨论】:

  • 啊,他们真周到。 ;) 显然比我的多步骤方法更好。
【解决方案2】:

请试试这个[theEvent locationInNode:self];

【讨论】:

    【解决方案3】:

    如果你没有在 mouseDragged 中累积 delta,损失是不可避免的。 在我的情况下,以下工作相当不错。

    mouseDown()
    {
        previous = event.location(in: self)
    }
    
    mouseDragged()
    {
       current = event.location(in: self)
       ...
       delta += (current - previous)
       previous = current
       ...
    }
    
    update()
    {
       ...
       use up your delta
       delta = 0
    }
    

    干杯

    【讨论】:

      【解决方案4】:

      我的猜测是问题出在坐标空间上。您正在执行基于-[NSEvent locationInWindow] 的计算,这当然是在窗口坐标系中。 babies.position 在哪个坐标系中?它至少在视图的坐标系中,虽然也许 SprikeKit 也强加了另一个坐标空间。

      要将点转换为视图的坐标空间,您需要使用NSPoint point = [theView convertPoint:[NSEvent locationInWindow] fromView:nil];。要将点从视图的坐标空间转换到场景的坐标空间,您可以使用CGPoint cgpoint = [theScene convertPointFromView:NSPointToCGPoint(point)];。如果babies 不是场景对象,那么要转换为babies.position 使用的坐标系,您可以使用cgpoint = [babies.parent convertPoint:cgpoint fromNode:scene];。然后,您将通过计算 babiesStartcgpoint 之间的差异来计算 translation

      更新:实际上,您不会像这样将结果与babiesStart 进行比较。您可以将其与在原始光标位置上进行的相同坐标变换的结果进行比较。因此,您计算 dragStart 的方式与计算 cgpoint 的方式类似。稍后,您将了解它们之间的差异。

      【讨论】:

        【解决方案5】:

        这是正常行为。

        当您按照事件报告的鼠标位置时,在重新绘制 Sprite Kit 视图之前会经过一段时间,此时光标已经移动到新位置。

        您无能为力,除了可以通过考虑先前的鼠标事件距离来预测快速移动的位置,从而预测下一个位置可能在哪里,然后使用实际的鼠标位置并根据最近的一般运动方向稍微调整一下。

        不过,这通常是矫枉过正的。

        【讨论】:

        • 这与绘图赶上鼠标光标的延迟无关。这是关于距离小于鼠标移动的距离,即使您停下来等待它赶上。问题中的动画显示了这一点。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多