2017-02-01 5 views
0

だからこれは私が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

特定の大きさにベクトル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はそれを滑らかにする一つの方法です。

1

ジッタは、SKActionsがそれぞれ0.5秒実行されることによって発生します。一方で、他の複数の動きを引き起こすことができる複数の他のタッチイベントが発生する可能性があります。 スプライトに毎回新しいアクションを追加し、永遠に繰り返されます。

私はupdateメソッドにアニメーションを移動します:

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) 


} 
関連する問題