2016-07-09 6 views
-4

Последняя ошибка:Акселерометр введение? Код исправить?

enter image description here

Недавно я работал над приложением с учебником и прийти к точке, где я хотел бы отклониться от из учебника. Но у меня нет опыта работы с SpriteKit, поэтому я бы хотел, чтобы какая-то помощь работала с акселерометром, чтобы что-то контролировать в приложении.

часть, где вы управляете космическим кораблем в игре здесь:

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 

     for touch: AnyObject in touches{ 

      let pointOfTouch = touch.locationInNode(self) 
      let previousPointOfTouch = touch.previousLocationInNode(self) 

      let amountDragged = pointOfTouch.x - previousPointOfTouch.x 

      player.position.x += amountDragged 

      if player.position.x > CGRectGetMaxX(gameArea) - player.size.width/2{ 

       player.position.x = CGRectGetMaxX(gameArea) - player.size.width/2 


      } 

      if player.position.x < CGRectGetMinX(gameArea) + player.size.width/2{ 
       player.position.x = CGRectGetMinX(gameArea) + player.size.width/2  

Так может кто-либо изменить мой код для меня, чтобы использовать акселерометр, чтобы управлять кораблем или мы могли разговаривать по Skype, где я хотел бы немного помочь. Мой Skype - RoobTheMan.

// GameScene.swift 
// One Mission 
// 
// Created by Robert Smith on 7/8/16. 
// Copyright (c) 2016 RobTheMan. All rights reserved. 
// 

import SpriteKit 

class GameScene: SKScene, SKPhysicsContactDelegate{ 


    let bulletSound = SKAction.playSoundFileNamed("BulletSound.wav" , waitForCompletion: false) 


    struct physicsCategories { 
     static let None : UInt32 = 0 
     static let Player : UInt32 = 0b1 // 1 
     static let Bullet : UInt32 = 0b10 //2 
     static let Enemy : UInt32 = 0b100 // 4 

    } 

    let player = SKSpriteNode(imageNamed: "playerShip") 


    func random() -> CGFloat { 
     return CGFloat(Float(arc4random())/0xFFFFFFFF) 

    } 
    func random(min min: CGFloat, max: CGFloat) -> CGFloat{ 
     return random() * (max - min) + min 
    }  


    let gameArea: CGRect 

    override init(size: CGSize) { 

     let maxAspectRatio: CGFloat = 16.0/9.0 
     let playableWidth = size.height/maxAspectRatio 
     let margin = (size.width - playableWidth)/2 
     gameArea = CGRect(x: margin, y: 0 , width: playableWidth, height: size.height) 


     super.init(size: size) 

    } 

    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 


    override func didMoveToView(view: SKView) { 

     self.physicsWorld.contactDelegate = self 

     let background = SKSpriteNode(imageNamed: "background") 
     background.size = self.size 
     background.position = CGPoint(x: self.size.width/2, y: self.size.height/2) 
     background.zPosition = 0 
     self.addChild(background) 


     player.setScale(1) 
     player.position = CGPoint(x: self.size.width/2, y: self.size.height * 0.2) 
     player.zPosition = 2 
     player.physicsBody = SKPhysicsBody(rectangleOfSize: player.size) 
     player.physicsBody!.affectedByGravity = false 
     player.physicsBody!.categoryBitMask = physicsCategories.Player 
     player.physicsBody!.collisionBitMask = physicsCategories.None 
     player.physicsBody!.contactTestBitMask = physicsCategories.Enemy 
     self.addChild(player) 

     startNewLevel() 

    } 


    func startNewLevel(){ 


     let spawn = SKAction.runBlock(spawnEnemy) 
     let waitToSpawn = SKAction.waitForDuration(1) 
     let spawnSequence = SKAction.sequence([spawn, waitToSpawn]) 
     let spawnForever = SKAction.repeatActionForever(spawnSequence) 
     self.runAction(spawnForever) 


    } 


    func fireBullet() { 

     let bullet = SKSpriteNode(imageNamed: "bullet") 
     bullet.setScale(0.8) 
     bullet.position = player.position 
     bullet.zPosition = 1 
     bullet.physicsBody = SKPhysicsBody(rectangleOfSize: bullet.size) 
     bullet.physicsBody!.affectedByGravity = false 
     bullet.physicsBody!.categoryBitMask = physicsCategories.Bullet 
     bullet.physicsBody!.collisionBitMask = physicsCategories.None 
     bullet.physicsBody!.contactTestBitMask = physicsCategories.Enemy 
     self.addChild(bullet) 

     let moveBullet = SKAction.moveToY(self.size.height + bullet.size.height, duration: 1) 
     let deleteBullet = SKAction.removeFromParent() 
     let bulletSequence = SKAction.sequence([bulletSound, moveBullet, deleteBullet]) 
     bullet.runAction(bulletSequence) 


    } 


    func spawnEnemy(){ 

     let randomXStart = random(min: CGRectGetMinX(gameArea), max: CGRectGetMaxX(gameArea)) 
     let randomXEnd = random(min: CGRectGetMinX(gameArea), max: CGRectGetMaxX(gameArea)) 

     let startPoint = CGPoint(x: randomXStart, y: self.size.height * 1.2) 
     let endPoint = CGPoint(x: randomXEnd, y: -self.size.height * 0.2) 

     let enemy = SKSpriteNode(imageNamed: "enemyShip") 
     enemy.setScale(1) 
     enemy.position = startPoint 
     enemy.zPosition = 2 
     enemy.physicsBody = SKPhysicsBody(rectangleOfSize: enemy.size) 
     enemy.physicsBody!.affectedByGravity = false 
     enemy.physicsBody!.categoryBitMask = physicsCategories.Enemy 
     enemy.physicsBody!.categoryBitMask = physicsCategories.None 
     enemy.physicsBody!.contactTestBitMask = physicsCategories.Player | physicsCategories.Bullet 
     self.addChild(enemy) 

     let moveEnemy = SKAction.moveTo(endPoint, duration: 1.5) 

     let deleteEnemy = SKAction.removeFromParent() 
     let enemySequence = SKAction.sequence([moveEnemy, deleteEnemy]) 
     enemy.runAction(enemySequence) 

     let dx = endPoint.x - startPoint.x 
     let dy = endPoint.y - startPoint.y 
     let amountToRotate = atan2(dy, dx) 
     enemy.zRotation = amountToRotate 

    } 


    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 

     fireBullet() 
    } 


    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 

     for touch: AnyObject in touches{ 

      let pointOfTouch = touch.locationInNode(self) 
      let previousPointOfTouch = touch.previousLocationInNode(self) 

      let amountDragged = pointOfTouch.x - previousPointOfTouch.x 

      player.position.x += amountDragged 

      if player.position.x > CGRectGetMaxX(gameArea) - player.size.width/2{ 

       player.position.x = CGRectGetMaxX(gameArea) - player.size.width/2 


      } 

      if player.position.x < CGRectGetMinX(gameArea) + player.size.width/2{ 
       player.position.x = CGRectGetMinX(gameArea) + player.size.width/2 
      } 

     } 

    } 

} 

ответ

0

Не волнуйся, это довольно просто. Сначала вам нужно сделать import CoreMotion в верхней части файла Swift, где происходят другие импортные операции - за пределами определение класса.

Затем сделайте:

// GameScene.swift 
// One Mission 
// 
// Created by Robert Smith on 7/8/16. 
// Copyright (c) 2016 RobTheMan. All rights reserved. 
// 

import SpriteKit 
import CoreMotion 
class GameScene: SKScene, SKPhysicsContactDelegate{ 


let bulletSound = SKAction.playSoundFileNamed("BulletSound.wav" , waitForCompletion: false) 
var motionTimer = NSTimer() 
var motionManager: CMMotionManager = CMMotionManager() 

struct physicsCategories { 
    static let None : UInt32 = 0 
    static let Player : UInt32 = 0b1 // 1 
    static let Bullet : UInt32 = 0b10 //2 
    static let Enemy : UInt32 = 0b100 // 4 

} 

let player = SKSpriteNode(imageNamed: "playerShip") 


func random() -> CGFloat { 
    return CGFloat(Float(arc4random())/0xFFFFFFFF) 

} 
func random(min min: CGFloat, max: CGFloat) -> CGFloat{ 
    return random() * (max - min) + min 
} 




let gameArea: CGRect 

override init(size: CGSize) { 

    let maxAspectRatio: CGFloat = 16.0/9.0 
    let playableWidth = size.height/maxAspectRatio 
    let margin = (size.width - playableWidth)/2 
    gameArea = CGRect(x: margin, y: 0 , width: playableWidth, height: size.height) 


    super.init(size: size) 

} 

required init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 




override func didMoveToView(view: SKView) { 
    motionManager.deviceMotionUpdateInterval = 0.01 
    motionManager.startDeviceMotionUpdatesToQueue(NSOperationQueue.currentQueue(), withHandler:{ 
     deviceManager, error in 
    }) 
    motionManager.startAccelerometerUpdates() 
    motionTimer = NSTimer.scheduledTimerWithTimeInterval(0.001, target:self, selector: Selector("calculateMotion"), userInfo: nil, repeats: true) 
    self.physicsWorld.contactDelegate = self 

    let background = SKSpriteNode(imageNamed: "background") 
    background.size = self.size 
    background.position = CGPoint(x: self.size.width/2, y: self.size.height/2) 
    background.zPosition = 0 
    self.addChild(background) 


    player.setScale(1) 
    player.position = CGPoint(x: self.size.width/2, y: self.size.height * 0.2) 
    player.zPosition = 2 
    player.physicsBody = SKPhysicsBody(rectangleOfSize: player.size) 
    player.physicsBody!.affectedByGravity = false 
    player.physicsBody!.categoryBitMask = physicsCategories.Player 
    player.physicsBody!.collisionBitMask = physicsCategories.None 
    player.physicsBody!.contactTestBitMask = physicsCategories.Enemy 
    self.addChild(player) 

    startNewLevel() 

} 
func calculateMotion() { 
    if let data = motionManager.accelerometerData { 
     // you could do (you can change 2 to whatever you want - that makes it x times as fast/sensitive) 
     player.position.x+=(CGFloat(2)*CGFloat(data.acceleration.x)) 
     if data.acceleration.x >= 0.8 || data.acceleration.x <= -0.8{ 
      //Make whatever you want to happen when there is acceleration happen here 
     } 
    } 
} 

func startNewLevel(){ 


    let spawn = SKAction.runBlock(spawnEnemy) 
    let waitToSpawn = SKAction.waitForDuration(1) 
    let spawnSequence = SKAction.sequence([spawn, waitToSpawn]) 
    let spawnForever = SKAction.repeatActionForever(spawnSequence) 
    self.runAction(spawnForever) 


} 


func fireBullet() { 

    let bullet = SKSpriteNode(imageNamed: "bullet") 
    bullet.setScale(0.8) 
    bullet.position = player.position 
    bullet.zPosition = 1 
    bullet.physicsBody = SKPhysicsBody(rectangleOfSize: bullet.size) 
    bullet.physicsBody!.affectedByGravity = false 
    bullet.physicsBody!.categoryBitMask = physicsCategories.Bullet 
    bullet.physicsBody!.collisionBitMask = physicsCategories.None 
    bullet.physicsBody!.contactTestBitMask = physicsCategories.Enemy 
    self.addChild(bullet) 

    let moveBullet = SKAction.moveToY(self.size.height + bullet.size.height, duration: 1) 
    let deleteBullet = SKAction.removeFromParent() 
    let bulletSequence = SKAction.sequence([bulletSound, moveBullet, deleteBullet]) 
    bullet.runAction(bulletSequence) 


} 


func spawnEnemy(){ 

    let randomXStart = random(min: CGRectGetMinX(gameArea), max: CGRectGetMaxX(gameArea)) 
    let randomXEnd = random(min: CGRectGetMinX(gameArea), max: CGRectGetMaxX(gameArea)) 

    let startPoint = CGPoint(x: randomXStart, y: self.size.height * 1.2) 
    let endPoint = CGPoint(x: randomXEnd, y: -self.size.height * 0.2) 

    let enemy = SKSpriteNode(imageNamed: "enemyShip") 
    enemy.setScale(1) 
    enemy.position = startPoint 
    enemy.zPosition = 2 
    enemy.physicsBody = SKPhysicsBody(rectangleOfSize: enemy.size) 
    enemy.physicsBody!.affectedByGravity = false 
    enemy.physicsBody!.categoryBitMask = physicsCategories.Enemy 
    enemy.physicsBody!.categoryBitMask = physicsCategories.None 
    enemy.physicsBody!.contactTestBitMask = physicsCategories.Player | physicsCategories.Bullet 
    self.addChild(enemy) 

    let moveEnemy = SKAction.moveTo(endPoint, duration: 1.5) 

    let deleteEnemy = SKAction.removeFromParent() 
    let enemySequence = SKAction.sequence([moveEnemy, deleteEnemy]) 
    enemy.runAction(enemySequence) 

    let dx = endPoint.x - startPoint.x 
    let dy = endPoint.y - startPoint.y 
    let amountToRotate = atan2(dy, dx) 
    enemy.zRotation = amountToRotate 



} 


override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 

    fireBullet() 
} 


override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 

    for touch: AnyObject in touches{ 

     let pointOfTouch = touch.locationInNode(self) 
     let previousPointOfTouch = touch.previousLocationInNode(self) 

     let amountDragged = pointOfTouch.x - previousPointOfTouch.x 

     player.position.x += amountDragged 

     if player.position.x > CGRectGetMaxX(gameArea) - player.size.width/2{ 

      player.position.x = CGRectGetMaxX(gameArea) - player.size.width/2 


     } 

     if player.position.x < CGRectGetMinX(gameArea) + player.size.width/2{ 
      player.position.x = CGRectGetMinX(gameArea) + player.size.width/2 
     } 

    } 

} 


} 

Вы можете изменить 0.8 к чему-то еще позже -> Чем меньше число, тем ниже порог ускорения. Вы также можете изменить x на y или z - просто зависит от того, какая из осей вашего телефона вы хотите определить ускорение.

Если у вас есть какие-либо дополнительные вопросы или проблемы, не стесняйтесь, дайте мне знать :)

+0

У меня есть два вопроса, где бы я поставил код выше после того, как я импортировал CoreMotion и как бы я связать это с левым и правое движение (мне нужно только левое и правое) моего SKSpriteNode? – Rob

+0

@Rob Я не уверен точно, чего вы пытаетесь достичь - я думаю, вам может понадобиться чувствительность наклона, а не акселерометр. Для управления космическим кораблем в игре использование акселерометра было бы очень неудобным - пользователю пришлось бы перемещать свой телефон туда и обратно. Но вы бы поставили код выше, где находится ваш текущий код, - внутри объявления класса. Удостоверьтесь, что вы избавились от одной из функций didMoveToView, хотя - поместите код, который у вас есть в вашем текущем проекте, в тот, который был вставлен выше. У вас не может быть двух этих вызовов функций. – CoolPenguin

+0

@Rob Вы могли бы сделать что-то вроде player.position.x + = data.acceleration.x Это было бы внутри цикла if let, но вне цикла if, если оно больше 0,8 – CoolPenguin

 Смежные вопросы

  • Нет связанных вопросов^_^