我正在尝试制作一个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
变量,但这显然是一个黑客。
答案 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];
。然后,您可以通过计算translation
和babiesStart
之间的差异来计算cgpoint
。
更新:实际上,您不会将结果与babiesStart
进行比较。您将它与在原始光标位置上完成的相同坐标转换的结果进行比较。因此,您计算的dragStart
与计算cgpoint
的方式类似。之后,你会把它们区别开来。
答案 3 :(得分:1)
请尝试此[theEvent locationInNode:self];
答案 4 :(得分:-1)
这是正常行为。
当您按事件报告的鼠标位置时,在重绘Sprite Kit视图之前经过一段时间,此时光标已移动到新位置。
你可以做的事情并不多,除了可以通过考虑先前的鼠标事件距离来预测非常快速移动的位置,从而预测下一个位置可能的位置,然后采用实际的鼠标位置并根据最近的一般运动方向稍微调整一下。
通常情况下这是过度杀伤。