2017-12-16 26 views
1

나는 SKAction을 통해 회전 행운 바퀴를 만들려고합니다. 나는 휠로 사용되는 SKNode을 가지고 있는데,이 SKNode은 4 분의 4 (4 분의 1의 각기 다른 색깔)로 나뉜 원입니다. 고정 된 지점 (노드의 중심)을 중심으로 SKNode을 돌리는 SKAction (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의 내장 물리 시뮬레이션을 사용하여이 같은 사실적인 움직임을 추가 할 수 있습니다. 이렇게하면 휠에 질량과 마찰을 부여한 다음 힘을 사용하여 휠을 회전시킬 수 있습니다. 그러면 현실적으로 속도가 느려집니다. 개요에서

는 애플 문서에 Simulating Physics를 참조하십시오

이 게임에서 물리학을 사용하려면 다음을 수행해야합니다

  • 노드 트리에서 노드로 물리기구를 부착하고 물리적 속성을 구성 . SKPhysicsBody을 참조하십시오.
  • 중력과 같은 장면의 물리 시뮬레이션의 전역 특성을 정의하십시오. SKPhysicsWorld을 참조하십시오.
  • 게임 플레이를 지원하려면 장면의 물리 구조 속도를 설정하거나 힘이나 충격을 적용하십시오. ... 당신의 휠

가장 적절한 방법은 현장에 바퀴 pinned을 다음 applyAngularImpulse으로 회전 아마.

+0

skypicsicsbody를 사용했지만 새로운 문제가 생겼습니다. @Ali Beadle – omerc

+0

@omerc a 각속과 각을 동시에 사용하지 마십시오. nudge, 또는 velocity로 설정하면 스핀이 계속 회전합니다. 또한 SO 응답을 다른 사람들에게 유용하게 유지하려면 새로운 질문을 별도로 요청하는 것이 가장 좋습니다. 기존 질문은 편집하지 않는 것이 좋습니다. –

+0

방금 ​​각속도를 삭제했지만 아무것도 변경하지 않았습니다. 이걸 설명 할 수 있니[email protected] Beadle – omerc