为什么mouseDragged位置落后于实际鼠标?

时间:2014-01-19 16:08:52

标签: objective-c macos sprite-kit

我正在尝试制作一个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变量,但这显然是一个黑客。

5 个答案:

答案 0 :(得分:4)

NSEvent在SpriteKit中有另一种方法- (CGPoint)locationInNode:(SKNode *)node。通过使用这个,我能够获得正确的偏移值,用于移动SKNode和鼠标。

答案 1 :(得分:2)

如果你没有在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
}

欢呼声

答案 2 :(得分:1)

我的猜测是问题在于坐标空间。您正在执行基于-[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];。然后,您可以通过计算translationbabiesStart之间的差异来计算cgpoint

更新:实际上,您不会将结果与babiesStart进行比较。您将它与在原始光标位置上完成的相同坐标转换的结果进行比较。因此,您计算的dragStart与计算cgpoint的方式类似。之后,你会把它们区别开来。

答案 3 :(得分:1)

请尝试此[theEvent locationInNode:self];

答案 4 :(得分:-1)

这是正常行为。

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

你可以做的事情并不多,除了可以通过考虑先前的鼠标事件距离来预测非常快速移动的位置,从而预测下一个位置可能的位置,然后采用实际的鼠标位置并根据最近的一般运动方向稍微调整一下。

通常情况下这是过度杀伤。