2017-12-16 34 views
1

SKActionでスピニングホイールホイールアクションを作成しようとしています。私はホイールとして使用されるSKNodeを持っています、このSKNodeは四分の四に分けられた円です(異なった色の各四分の一)。固定小数点(ノードの中央)の周りにSKNodeを回転させる(これは10回繰り返しています)を設定しました。問題は、アクションがうまく実行されているが、実際のホイールのように突然停止して減速しないことです。私はこのアニメーションをどのように設定するのか考えていないので、アクションが止まる前に回転を遅くすることを意味します。 はここで、これまでに私のコードです:SpriteKitで現実的なスピニングホイールを作成する方法

class GameScene: SKScene { 

let colors = [SKColor.yellow, SKColor.red, SKColor.blue, SKColor.purple] 


override func didMove(to view: SKView) { 
    createWheel() 

    let sq = CGRect(x: size.width/2, y: size.height/2, width: 300, height: 300) 
    let sqx = SKShapeNode(rect: sq) 
    sqx.lineWidth = 2 
    sqx.fillColor = .clear 
    sqx.setScale(1.0) 
    addChild(sqx) 
    } 

func createWheel() { 
    let path = UIBezierPath() 
    path.move(to: CGPoint(x: 0, y: 0)) 
    path.addLine(to: CGPoint(x: 0, y: -200)) 
    path.addArc(withCenter: CGPoint.zero,radius: 200,startAngle: CGFloat(0.0), endAngle: CGFloat(3.0 * Double.pi/2),clockwise: false) 
    path.addLine(to: CGPoint(x: 200, y: 0)) 

    let obstacle = obstacleByDuplicatingPath(path, clockwise: true) 
    obstacle.position = CGPoint(x: size.width/2, y: size.height/2) 
    addChild(obstacle) 

    let rotateAction = SKAction.rotate(byAngle: CGFloat((3.0 * CGFloat(Double.pi/2)) - 90), duration: 0.5) 
    //obstacle.run(SKAction.repeatForever(rotateAction)) 
    obstacle.run(SKAction.repeat(rotateAction, count: 10)) 


} 

func obstacleByDuplicatingPath(_ path: UIBezierPath, clockwise: Bool) -> SKNode { 
    let container = SKNode() 

    var rotationFactor = CGFloat(Double.pi/2) 
    if !clockwise { 
     rotationFactor *= -1 
    } 

    for i in 0...3 { 
     let section = SKShapeNode(path: path.cgPath) 
     section.fillColor = colors[i] 
     section.strokeColor = colors[i] 
     section.zRotation = rotationFactor * CGFloat(i); 

     let origin = CGPoint(x: 0.0, y: 0.0) 
     switch i { 
     case 0: 
      section.position = CGPoint(x: (origin.x + 10), y: (origin.y - 10)) 
     case 1: 
      section.position = CGPoint(x: (origin.x + 10), y: (origin.y + 10)) 
     case 2: 
      section.position = CGPoint(x: (origin.x - 10), y: (origin.y + 10)) 
     case 3: 
      section.position = CGPoint(x: (origin.x - 10), y: (origin.y - 10)) 
     default: 
      print("bolbol") 

     } 

     container.addChild(section) 
    } 
    return container 
} 

}

編集: 、私は別のアクションを設定したが、この時間は、私は彼らの時間を設定し、私はそれについて考えていたと私はSKActionを経由して、それを実行しようとしました長いものに。まず、持続時間0.5のアクションを実行し、次に2のアクションを実行し、4の終了時にアクションを実行します。私はかなり良く見えますが、まだ滑らかではありません。 ここに私のコードです:

 let rotateAction = SKAction.rotate(byAngle: CGFloat(2.0 * CGFloat(M_PI)), duration: 0.5) 
    let rotateAction2 = SKAction.rotate(byAngle: CGFloat(2.0 * CGFloat(M_PI)), duration: 2) 
    let rotateAction3 = SKAction.rotate(byAngle: CGFloat(2.0 * CGFloat(M_PI)), duration: 4) 
    let wait = SKAction.wait(forDuration: 5) 
    let g1 = SKAction.repeat(rotateAction, count: 10) 
    let group = SKAction.group([wait, g1, rotateAction2, rotateAction3]) 

あなたはどう思いますか?それをもっとうまくいく方法はありますか?

編集2:私は、画面SKShapeNode(形状)に指をドラッグして回転し続けて停止したことがないとき が@Aliビードルの解答を続けが、私は物理学の体を介してそれを実行しようとしましたが、問題は今あります。何が間違っているかを検出できますか?

class GameScene: SKScene { 
var start: CGPoint? 
var end:CGPoint? 
var startTime: TimeInterval? 
let shape = SKShapeNode.init(rectOf: CGSize(width: 150, height: 150)) 

override func didMove(to view: SKView) { 

    self.physicsWorld.gravity = CGVector(dx: 0, dy: -9.8) 
    let sceneBody = SKPhysicsBody.init(edgeLoopFrom: self.frame) 
    sceneBody.friction = 0 
    self.physicsBody = sceneBody 


    shape.fillColor = SKColor.red 
    shape.position = CGPoint(x: self.size.width/2, y: self.size.height/2) 
    shape.physicsBody = SKPhysicsBody.init(rectangleOf: CGSize(width: 50, height: 50)) 
    shape.physicsBody?.affectedByGravity = false 
    shape.physicsBody?.isDynamic = true 
    addChild(shape) 
} 


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    guard let touch = touches.first else {return} 
    self.start = touch.location(in: self) 
    self.startTime = touch.timestamp 
} 

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 
    guard let touch = touches.first else {return} 
    self.end = touch.location(in: self) 
    var dx = ((self.end?.x)! - (self.start?.x)!) 
    var dy = ((self.end?.y)! - (self.start?.y)!) 

    let magnitude:CGFloat = sqrt(dx*dx+dy*dy) 
    if(magnitude >= 25){ 
     let dt:CGFloat = CGFloat(touch.timestamp - self.startTime!) 
     if dt > 0.1 { 
      let speed = magnitude/dt 
      dx = dx/magnitude 
      dy = dy/magnitude 
      print("dx: \(dx), dy: \(dy), speed: \(speed) ") 

     } 
    } 
    let touchPosition = touch.location(in: self) 
    if touchPosition.x < (self.frame.width/2) { 
     self.shape.physicsBody?.angularVelocity = 10 
     self.shape.physicsBody?.applyAngularImpulse(-180) 
    } else { 
     self.shape.physicsBody?.angularVelocity = 10 
     self.shape.physicsBody?.applyAngularImpulse(180) 
    } 
}} 

答えて

1

SpriteKitの組み込み物理シミュレーションを使用すると、このような現実的な動きを追加できます。これにより、ホイールに質量と摩擦を与え、力を使ってホイールを回転させることができます。それは現実的に遅くなります。アウトラインで

は、AppleのドキュメントにSimulating Physicsを参照してください。

があなたのゲームで物理学を使用するには、以下を行う必要があります。

  • は、ノードツリー内のノードに物理体を取り付け、それらの物理的性質を設定します。 SKPhysicsBodyを参照してください。
  • シーンの物理シミュレーションのグローバルな特性(重力など)を定義します。 SKPhysicsWorldを参照してください。
  • 必要に応じて、ゲームプレイをサポートするには、シーン内のフィジックスボディの速度を設定するか、シーンに力や衝動を適用します。 ...

あなたの車のための最も適切な方法は、シーンにホイールpinnedを行い、その後、applyAngularImpulseでそれを回転させることが考えられます。

+0

私は新しい編集を見ることができますが、私はskphysicsbodyを使用しましたが、私は新しい問題を抱えています... @Ali Beadle – omerc

+0

@omerc a角速度と角膜刺激を同時に使わないでください。ナッジ、またはベロシティは常に回転します。また、SOの回答を他の人に役立てるためには、新しい質問を別々に尋ねるのが最善です。古い質問は編集しないでください。 –

+0

角速度を削除するだけで何も変わりません。これを説明できますか?@Ali Beadle – omerc