Ios 模仿另一个精灵

Ios 模仿另一个精灵,ios,swift,sprite-kit,swift2,sprite,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 = SKSp

因此,我有一个由玩家倾斜设备控制的精灵,我需要让其他精灵具有与第一个相同的“细节/特征”,如转弯,但遵循它,而不是由平铺设备控制。这是我的密码:

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()

    }

}
导入SpriteKit
导入CoreMotion
设Pi=CGFloat(M_Pi)
设弧度=Pi/180
设弧度为180度/Pi
类游戏场景:SKScene{
var snakeHead=SKSpriteNode()
var snakeBody=SKSpriteNode()
var food=SKSpriteNode()
var=SKSpriteNode()
var加速度计X:UIAccelerationValue=0
var加速度计:UIAccelerationValue=0
让motionManager=CMMotionManager()
var lastUpdateTime:CFTimeInterval=0
var playerAcceleration=CGVector(dx:0,dy:0)
var playerVelocity=CGVector(dx:0,dy:0)
设MaxPlayerAcceleration:CGFloat=150
让MaxPlayerSpeed:CGFloat=100
//改变人物的速度和加速度
设边界碰撞阻尼:CGFloat=0.8
//与边界碰撞后改变速度
变量playerAngle:CGFloat=0
var previousAngle:CGFloat=0
设ObstacleCollisionRadius:CGFloat=35
让PlayerHeadCollisionRadius:CGFloat=30
//玩家和障碍物的碰撞区半径
let PlayerBodyCollisionRadius:CGFloat=0
//***忽略***
让collisionSound=SKAction.PlaySoundFileName(“Collision/Death.wav”,waitForCompletion:false)
//玩家与障碍物碰撞时播放的文件名
让碰撞阻尼:CGFloat=0.8
//***待移除-仅用于实验***改变从障碍物反弹
覆盖func didMoveToView(视图:SKView){
/*在这里设置场景*/
蛇头=SKSpriteNode(图像名称:“蛇头”)
蛇头.size=CGSize(宽:60,高:60)
蛇头.position=CGPoint(x:self.frame.midX,y:self.frame.midY-50)
赛尔夫·阿德奇尔德(蛇头)
蛇体=SKSpriteNode(图像名称:“蛇体”)
蛇身.size=CGSize(宽:50,高:50)
snakeBody.position=CGPoint(x:self.frame.midX,y:self.frame.midY-100)
self.addChild(蛇身)
障碍物=SKSpriteNode(图像名称:“障碍物”)
障碍物尺寸=CGSize(宽:70,高:70)
障碍物位置=CGPoint(x:self.frame.midX,y:self.frame.midY)
self.addChild(障碍)
startMonitoringAcceleration()
}
脱硝{
停止监视加速()
}
func startMonitoringAcceleration(){
如果motionManager.Accelerometravailable{
motionManager.startAccelerometerUpdates()
NSLog(“加速度计更新时间…”)
}
}
函数停止监视加速(){
如果motionManager.Accelerometravailable&&motionManager.Accelerometravive{
motionManager.StopAccelerometrUpdates()
NSLog(“加速计更新关闭…”)
}
}
func updatePlayerAccelerationFromMotionManager(){
如果让加速度=motionManager.accelerometerData?加速度{
设FilterFactor=0.75
加速度计Rx=加速度.x*过滤器系数+加速度计Rx*(1-过滤器系数)
加速度计=加速度.y*过滤器系数+加速度计*(1-过滤器系数)
playerAcceleration.dx=CGFloat(加速度计)*-MaxPlayerAcceleration
playerAcceleration.dy=CGFloat(加速度计)*MaxPlayerAcceleration
}
}
func checkShipCannonCollision(){
设deltaX=蛇头.position.x-障碍物.position.x
设deltaY=蛇头.position.y-障碍物.position.y
让距离=sqrt(deltaX*deltaX+deltaY*deltaY)
如果距离大小。宽度{
newX=size.width
CollizedWithVerticalBorder=true
}
如果newY<0{
newY=0
CollizedWithHorizontalBorder=真
}否则,如果newY>size.height{
newY=大小。高度
CollizedWithHorizontalBorder=真
}
如果与垂直边界发生碰撞{
playerAcceleration.dx=-playerAcceleration.dx*边界碰撞阻尼
playerVelocity.dx=-playerVelocity.dx*边界碰撞阻尼
playerAcceleration.dy=playerAcceleration.dy*边界碰撞阻尼
playerVelocity.dy=playerVelocity.dy*边界碰撞阻尼
}
如果与水平边界碰撞{
playerAcceleration.dx=playerAcceleration.dx*边界碰撞阻尼
playerVelocity.dx=playerVelocity.dx*边界碰撞阻尼
playerAcceleration.dy=-playerAcceleration.dy*边界碰撞阻尼
playerVelocity.dy=-playerVelocity.dy*边界碰撞阻尼
}
snakeHead.position=CGPoint(x:newX,y:newY)
让旋转阈值:CGFloat=10
设RotationBlendFactor:CGFloat=0.2
让速度=sqrt(playerVelocity.dx*playerVelocity.dx+playerVelocity.dy*playerVelocity.dy)
如果速度>旋转阈值{
let angle=atan2(playerVelocity.dy,playerVelocity.dx)
//角度是从+π翻转到-π还是从-π翻转到+π?
如果角度-上一个角度>Pi{
playerAngle+=2*Pi
}否则,如果上一个角度-角度>Pi{
playerAngle-=2*Pi
}
以前的角度=角度
playerAngle=角度*旋转混合因子+playerAngle*(1-旋转混合因子)
snakeHead.zRotation=玩家角度-90*度弧度
}
}
覆盖功能触摸开始(触摸:设置,withEvent事件:UIEvent?){
/*当触摸开始时调用*/
}
覆盖函数更新(currentTime:CFTimeInterval){
/*在渲染每个帧之前调用*/
//为了计算速度,我们需要增量时间乘以每秒的点
//斯皮特基特返回第