如何在Swift,SpriteKit中创建弹弓机制

时间:2015-07-26 04:04:52

标签: swift sprite-kit

我正在尝试创建一个Sling镜头机制,我在其中旋转一个节点,并在末尾附加一个对象。弹弓开始时通过触摸和保持交互来旋转对象并在释放时启动附着在末端的对象 - 看到类似的效果here

这是我的轮换代码。不知道如何开始加入和吊索部分。

var touchingScreen = false

override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    super.touchesBegan(touches, withEvent: event)
    touchingScreen = true
    println("Screen Touched")
}

override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
    super.touchesCancelled(touches, withEvent: event)
    touchingScreen = false
    println("Screen Not Touched")
}

override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
    super.touchesEnded(touches, withEvent: event)
    touchingScreen = false
    println("Screen Not Touched")
}

override func update(currentTime: CFTimeInterval) {

    if touchingScreen {

        var RotatingAngle = CGFloat(M_PI)
        var rotationDuration = 20.0
        var rotateCanon = SKAction.rotateByAngle(CGFloat(RotatingAngle), duration: rotationDuration)
        canon.runAction(rotateCanon)

    } else if !touchingScreen {


        var RotatingAngleTwo = CGFloat(0)
        var rotationDurationTwo = 0.0
        var rotateCanon = SKAction.rotateByAngle(CGFloat(RotatingAngleTwo), duration: rotationDurationTwo)
        canon.runAction(rotateCanon)
    }

}

感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

一些想法......

  1. 如果你把它分解成更小的步骤,那么实施弹弓是相当简单的,如图所示
  2. 如果你用极坐标表示球在圆上的位置,你可以通过简单地随时间增加角度然后从极坐标转换为笛卡尔坐标来旋转球
  3. 发射时,球的轨迹应与球在圆上的位置相切,其速度应与其角速度相同。
  4. 和一些代码......

    enum State {
        case Stopped
        case Rotating
        case Launched
    }
    
    let two_pi = CGFloat(M_PI*2.0)
    let pi = CGFloat(M_PI)
    
    // These are useful vector/point operators
    func * (left:CGPoint, right:CGFloat) -> CGPoint {
        return CGPointMake(left.x*right, left.y*right)
    }
    
    func += (inout left:CGPoint, right:CGPoint) {
        left = CGPointMake(left.x+right.x, left.y+right.y)
    }
    
    func * (left:CGVector, right:CGFloat) -> CGVector {
        return CGVectorMake(left.dx*right, left.dy*right)
    }
    
    func / (left:CGVector, right:CGFloat) -> CGVector {
        return CGVectorMake(left.dx/right, left.dy/right)
    }
    
    class GameScene: SKScene {
        let shape = SKShapeNode(circleOfRadius: 7)
        let radius:CGFloat = 30
        var center = CGPointZero
        var currentAngle = -pi/2
        let angleIncr = two_pi / 60.0
        var state:State = .Stopped
    
        override func didMoveToView(view: SKView) {
            scaleMode = .ResizeFill
            // Set the center of the sling
            center = CGPointMake (CGRectGetMidX(view.frame),CGRectGetMidY(view.frame))
            addBall()
            let circle = SKShapeNode(circleOfRadius: radius)
            circle.position = CGPointMake (CGRectGetMidX(view.frame),CGRectGetMidY(view.frame))
            addChild(circle)
        }
    
        // Adds a circle shape node at the bottom of the sling
        func addBall() {
            currentAngle = -pi/2
            shape.fillColor = SKColor.blueColor()
            shape.position = CGPointMake (center.x, center.y-radius)
            shape.physicsBody = SKPhysicsBody(circleOfRadius: 7)
            shape.physicsBody?.affectedByGravity = false
            shape.physicsBody?.mass = 0.5
            shape.zPosition = 1
            addChild(shape)
        }
    
        override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
            if let touch = touches.first as? UITouch {
                let location = touch.locationInNode(self)
                if (state == .Stopped) {
                    // Start rotating the ball around the sling
                    state = .Rotating
                }
            }
        }
    
        override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
            if (state == .Rotating) {
                // Launch the ball on a vector tangent to its current position on the circle
                state = .Launched
                // Normal vector
                var normal = CGVectorMake(shape.position.x-center.x, shape.position.y-center.y)
                normal = normal / magnitude(normal)
                // Tangent vector
                let vector = CGVectorMake(normal.dy, -normal.dx)
                // Convert angular to linear speed
                let speed = angleIncr * 60.0 * radius
                shape.physicsBody?.velocity = vector*speed
    
                runAction(SKAction.waitForDuration(1.0)) {
                    self.shape.removeFromParent()
                    self.state = .Stopped
                    self.addBall()
                }
            }
        }
    
        override func update(currentTime: CFTimeInterval) {
            switch (state) {
            case .Rotating:
                var point = angleToPoint(currentAngle) * radius
                point += center
                shape.position = point
                currentAngle -= angleIncr
                // Wrap at 2 pi
                currentAngle %= two_pi
            default:
                break
            }
        }
    
        func angleToPoint(angle:CGFloat) -> CGPoint {
            return CGPointMake(cos(angle), sin(angle))
        }
    
        func magnitude(v1:CGVector) -> CGFloat {
            return sqrt(v1.dx*v1.dx+v1.dy*v1.dy)
        }
    }
    

    和视频...

    enter image description here