所以这是我在touchesMoved函数和所有工作中放置的代码。我也有办法停止其他未在此处发布的功能中的每个动画和动作。
我遇到的问题,在我完成编码之前对我来说相当明显的是,机芯会断断续续/抖动,这不是我想要的平滑度。我还想问一下如何限制精灵移动的速度,你可以看到它按变量“v”移动,这取决于你从操纵杆移动的距离。
我的操纵杆的工作方式是初始触摸是“基础”,你移动的位置也是新方向。
TLDR:如何限制当前速度基于变量“v”的移动速度并使移动更加平滑?
for touch in touches {
let location = touch.location(in: self)
let v = CGVector(dx: location.x - joystickMove.x, dy: location.y - joystickMove.y)
let angle = atan2(v.dy, v.dx)
deg = angle * CGFloat(180/M_PI)
readyToMove = true
switch(deg){
case -44...45:
player.walkRight()
let action = SKAction.moveBy(x: v.dx, y: v.dy, duration: 0.5)
let repeatAction = SKAction.repeatForever(action)
player.run(repeatAction, withKey: "move")
break;
case 46...135:
player.walkUp()
let action = SKAction.moveBy(x: v.dx, y: v.dy, duration: 0.5)
let repeatAction = SKAction.repeatForever(action)
player.run(repeatAction, withKey: "move")
break;
case 136...180, (-180)...(-135):
player.walkLeft()
let action = SKAction.moveBy(x: v.dx, y: v.dy, duration: 0.5)
let repeatAction = SKAction.repeatForever(action)
player.run(repeatAction, withKey: "move")
break;
case (-134)...(-45):
player.walkDown()
let action = SKAction.moveBy(x: v.dx, y: v.dy, duration: 0.5)
let repeatAction = SKAction.repeatForever(action)
player.run(repeatAction, withKey: "move")
break;
default:
break;
}
}
答案 0 :(得分:1)
抖动是由SKActions每次运行0.5秒引起的。同时可以发生多个其他触摸事件,这可以触发多个其他动作。 您还将每次新动作添加到精灵中,并永久重复。
我会将动画移动到更新方法:
var lastUpdateTime = TimeInterval()
var yourSpriteSpeed: CGFloat = 100.0
override func update(_ currentTime: TimeInterval) {
let dt = CGFloat(currentTime - lastUpdateTime)
lastUpdateTime = currentTime
player.position = CGPoint(x: player.position.x + dx * yourSpriteSpeed * dt, y: player.position.x + dy * yourSpriteSpeed * dt)
}
答案 1 :(得分:0)
要将矢量v
限制为特定幅度,您需要检查其幅度是否超过阈值,然后将其标准化。
伪代码:
func mag(v) -> Double {
return sqrt(v.x * v.x + v.y * v.y)
}
func mult(v, amount) -> Vector {
return Vector(v.x * amount, v.y * amount)
}
func div(v, amount) -> Vector {
return Vector(v.x / amount, v.y / amount)
}
func unit(v) -> Vector {
return v.div(mag(v))
}
现在你做了:
// ... compute v as before
if mag(v) > MAX_SPEED {
v = unit(v).mult(MAX_SPEED)
}
// use v.x, v.y as before
虽然这种方法会限制你的操纵杆速度,但我怀疑它会彻底摆脱你的抖动问题(它只是将它缩回到MAX_SPEED的数量)。
PS:要获得完全平滑的运动,您需要将位置和速度保持为单独的变量,并且具有由操纵杆控制的目标速度的概念。在每一帧,您可以根据当前速度和 lerp 当前速度更新位置到目标速度。
速度的突然变化是引起紧张的原因; lerping是一种平滑它的方法。