模仿另一个精灵

时间:2015-12-15 20:32:51

标签: ios swift sprite-kit swift2 sprite

所以我有一个由玩家控制的精灵倾斜他们的设备,我需要让其他精灵具有相同的“细节/特征”,就像转弯作为第一个,但是跟随它而不是被设备控制瓷砖。这是我的代码:

import SpriteKit
import CoreMotion

let Pi = CGFloat(M_PI)

let DegreesToRadians = Pi / 180
let RadiansToDegrees = 180 / Pi

class GameScene: SKScene {

    var snakeHead = SKSpriteNode()
    var snakeBody = SKSpriteNode()

    var food = SKSpriteNode()

    var Obstacle = SKSpriteNode()

    var accelerometerX: UIAccelerationValue = 0
    var accelerometerY: UIAccelerationValue = 0

    let motionManager = CMMotionManager()

    var lastUpdateTime: CFTimeInterval = 0

    var playerAcceleration = CGVector(dx: 0, dy: 0)
    var playerVelocity = CGVector(dx: 0, dy: 0)

    let MaxPlayerAcceleration: CGFloat = 150
    let MaxPlayerSpeed: CGFloat = 100
    //Change speed of character and acceleration

    let BorderCollisionDamping: CGFloat = 0.8
    //Change speed after colliding with border

    var playerAngle: CGFloat = 0
    var previousAngle: CGFloat = 0

    let ObstacleCollisionRadius: CGFloat = 35
    let PlayerHeadCollisionRadius: CGFloat = 30
    //Radius of collision zone for the player and the obstacles

    let PlayerBodyCollisionRadius: CGFloat = 0
    //*** IGNORE ***

    let collisionSound = SKAction.playSoundFileNamed("Collision/Death.wav", waitForCompletion: false)
    //File name to play on player's collision with obstacle

    let CollisionDamping: CGFloat = 0.8
    //*** TO BE REMOVED - JUST FOR EXPERIMENTAL *** Change bounce off obstacle

    override func didMoveToView(view: SKView) {
        /* Setup your scene here */

        snakeHead = SKSpriteNode(imageNamed: "snakeHead")
        snakeHead.size = CGSize(width: 60, height: 60)
        snakeHead.position = CGPoint(x: self.frame.midX, y: self.frame.midY - 50)
        self.addChild(snakeHead)

        snakeBody = SKSpriteNode(imageNamed: "snakeBody")
        snakeBody.size = CGSize(width: 50, height: 50)
        snakeBody.position = CGPoint(x: self.frame.midX, y: self.frame.midY - 100)
        self.addChild(snakeBody)

        Obstacle = SKSpriteNode(imageNamed: "Obstacle")
        Obstacle.size = CGSize(width: 70, height: 70)
        Obstacle.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
        self.addChild(Obstacle)

        startMonitoringAcceleration()

    }

    deinit {

        stopMonitoringAcceleration()

    }

    func startMonitoringAcceleration() {

        if motionManager.accelerometerAvailable {
            motionManager.startAccelerometerUpdates()
            NSLog("accelerometer updates on...")
        }
    }

    func stopMonitoringAcceleration() {

        if motionManager.accelerometerAvailable && motionManager.accelerometerActive {
            motionManager.stopAccelerometerUpdates()
            NSLog("accelerometer updates off...")
        }
    }

    func updatePlayerAccelerationFromMotionManager() {

        if let acceleration = motionManager.accelerometerData?.acceleration {

            let FilterFactor = 0.75

            accelerometerX = acceleration.x * FilterFactor + accelerometerX * (1 - FilterFactor)
            accelerometerY = acceleration.y * FilterFactor + accelerometerY * (1 - FilterFactor)

            playerAcceleration.dx = CGFloat(accelerometerY) * -MaxPlayerAcceleration
            playerAcceleration.dy = CGFloat(accelerometerX) * MaxPlayerAcceleration

        }
    }

        func checkShipCannonCollision() {

            let deltaX = snakeHead.position.x - Obstacle.position.x
            let deltaY = snakeHead.position.y - Obstacle.position.y

            let distance = sqrt(deltaX * deltaX + deltaY * deltaY)
            if distance <= ObstacleCollisionRadius + PlayerHeadCollisionRadius {
                runAction(collisionSound)

                playerAcceleration.dx = -playerAcceleration.dx * CollisionDamping
                playerAcceleration.dy = -playerAcceleration.dy * CollisionDamping
                playerVelocity.dx = -playerVelocity.dx * CollisionDamping
                playerVelocity.dy = -playerVelocity.dy * CollisionDamping

                //This code adds the bouce when it collides, this is experimental
                let offsetDistance = ObstacleCollisionRadius + PlayerHeadCollisionRadius - distance
                let offsetX = deltaX / distance * offsetDistance
                let offsetY = deltaY / distance * offsetDistance
                snakeHead.position = CGPoint(
                    x: snakeHead.position.x + offsetX,
                    y: snakeHead.position.y + offsetY)
            }
    }

    func updatePlayer(dt: CFTimeInterval) {

        // 1
        playerVelocity.dx = playerVelocity.dx + playerAcceleration.dx * CGFloat(dt)
        playerVelocity.dy = playerVelocity.dy + playerAcceleration.dy * CGFloat(dt)

        // 2
        playerVelocity.dx = max(-MaxPlayerSpeed, min(MaxPlayerSpeed, playerVelocity.dx))
        playerVelocity.dy = max(-MaxPlayerSpeed, min(MaxPlayerSpeed, playerVelocity.dy))

        // 3
        var newX = snakeHead.position.x + playerVelocity.dx * CGFloat(dt)
        var newY = snakeHead.position.y + playerVelocity.dy * CGFloat(dt)

        var collidedWithVerticalBorder = false
        var collidedWithHorizontalBorder = false

        if newX < 0 {
            newX = 0
            collidedWithVerticalBorder = true
        } else if newX > size.width {
            newX = size.width
            collidedWithVerticalBorder = true
        }

        if newY < 0 {
            newY = 0
            collidedWithHorizontalBorder = true
        } else if newY > size.height {
            newY = size.height
            collidedWithHorizontalBorder = true
        }

        if collidedWithVerticalBorder {
            playerAcceleration.dx = -playerAcceleration.dx * BorderCollisionDamping
            playerVelocity.dx = -playerVelocity.dx * BorderCollisionDamping
            playerAcceleration.dy = playerAcceleration.dy * BorderCollisionDamping
            playerVelocity.dy = playerVelocity.dy * BorderCollisionDamping
        }

        if collidedWithHorizontalBorder {
            playerAcceleration.dx = playerAcceleration.dx * BorderCollisionDamping
            playerVelocity.dx = playerVelocity.dx * BorderCollisionDamping
            playerAcceleration.dy = -playerAcceleration.dy * BorderCollisionDamping
            playerVelocity.dy = -playerVelocity.dy * BorderCollisionDamping
        }

        snakeHead.position = CGPoint(x: newX, y: newY)

        let RotationThreshold: CGFloat = 10
        let RotationBlendFactor: CGFloat = 0.2

        let speed = sqrt(playerVelocity.dx * playerVelocity.dx + playerVelocity.dy * playerVelocity.dy)
        if speed > RotationThreshold {
            let angle = atan2(playerVelocity.dy, playerVelocity.dx)

            // did angle flip from +π to -π, or -π to +π?
            if angle - previousAngle > Pi {
                playerAngle += 2 * Pi
            } else if previousAngle - angle > Pi {
                playerAngle -= 2 * Pi
            }

            previousAngle = angle
            playerAngle = angle * RotationBlendFactor + playerAngle * (1 - RotationBlendFactor)
            snakeHead.zRotation = playerAngle - 90 * DegreesToRadians
        }

    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
       /* Called when a touch begins */



    }

    override func update(currentTime: CFTimeInterval) {
        /* Called before each frame is rendered */

        // to compute velocities we need delta time to multiply by points per second
        // SpriteKit returns the currentTime, delta is computed as last called time - currentTime
        let deltaTime = max(1.0/30, currentTime - lastUpdateTime)
        lastUpdateTime = currentTime

        updatePlayerAccelerationFromMotionManager()
        updatePlayer(deltaTime)

        checkShipCannonCollision()

    }

}

0 个答案:

没有答案