2016-01-19 37 views
2

我正在研究一個「太空入侵者」遊戲,我已經實現了CMMotionManager來傾斜我的英雄船隻(遊戲只在風景中運行),但由於某種原因,我的船將移出該視圖儘管讓一個SKNode離開視圖

self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame) 

應該通過使物理邊緣阻止這一點。任何想法爲什麼?

import SpriteKit 
    import CoreMotion 

class GameScene: SKScene,SKPhysicsContactDelegate{ 
    let collisionBulletCategory: UInt32 = 0x1 << 0 
    let collisionHeroCategory: UInt32 = 0x1 << 1 
    let background = SKSpriteNode(imageNamed: "background") 
    let heroShip = SKSpriteNode(imageNamed: "heroShip") 
    let enemyShip = SKSpriteNode(imageNamed: "enemyShip") 
    let MotionManager = CMMotionManager() 



    override func didMoveToView(view: SKView) { 
     /* Setup your scene here */ 
     self.physicsWorld.contactDelegate = self 

     self.physicsBody = SKPhysicsBody(edgeLoopFromRect: self.frame) 
     background.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame)) 
     heroShip.anchorPoint = CGPointMake(1.0, 0.5) 
     heroShip.physicsBody?.mass = 0.02 
     heroShip.physicsBody?.dynamic = true 
     heroShip.physicsBody = SKPhysicsBody(rectangleOfSize: heroShip.size) 
     heroShip.physicsBody?.affectedByGravity = false 
     heroShip.physicsBody?.categoryBitMask = collisionHeroCategory 
     heroShip.physicsBody?.contactTestBitMask = collisionBulletCategory 
     heroShip.physicsBody?.collisionBitMask = 0x0 
     heroShip.position = CGPointMake(self.size.width/6.0, self.size.height/2.0) 
     enemyShip.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)) 
     enemyShip.zPosition = 1.0 
     self.heroShip.zPosition = 1.0 
     self.addChild(enemyShip) 
     self.addChild(background) 
     self.addChild(heroShip) 

     if MotionManager.accelerometerAvailable{ 
      MotionManager.startAccelerometerUpdates() 
     } 

    } 

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     let bullet = SKSpriteNode(imageNamed: "bullet") 
     bullet.position = CGPointMake(heroShip.position.x, heroShip.position.y) 
     bullet.zPosition = 1.0 
     // Add physics body for collision detection 
     bullet.physicsBody = SKPhysicsBody(rectangleOfSize: bullet.frame.size) 
     bullet.physicsBody?.dynamic = true 
     bullet.physicsBody?.affectedByGravity = false 
     bullet.physicsBody?.categoryBitMask = collisionBulletCategory 
     bullet.physicsBody?.contactTestBitMask = collisionHeroCategory 
     bullet.physicsBody?.collisionBitMask = 0x0; 
     let action = SKAction.moveToX(CGRectGetMaxX(self.frame) + bullet.size.width, duration: 0.75) 
     self.addChild(bullet) 
     bullet.runAction(action, completion: { 
      bullet.removeAllActions() 
      bullet.removeFromParent() 
     }) 
    } 

    func didBeginContact(contact: SKPhysicsContact) { 

    } 
    override func update(currentTime: CFTimeInterval) { 
     let data = MotionManager.accelerometerData 
     if data?.acceleration.x == nil{ 
      print("nil") 
     } 
     else if fabs((data?.acceleration.x)!) > 0.2 { 
      self.heroShip.physicsBody?.applyForce(CGVectorMake(0.0, CGFloat(50 * (data?.acceleration.x)!))) 

     } 

    } 
} 

回答

4

根據該文檔,這是衝突是如何發生的:

當兩個物理機構相互接觸,可能會發生衝突。 通過執行邏輯AND操作,將該身體的碰撞掩碼與其他身體的類別 掩碼進行比較。如果結果值爲非零值,則此正文會受到碰撞的影響。各自獨立 選擇是否要受其他機構的影響。例如,對於 示例,您可以使用此選項來避免碰撞計算,這些碰撞計算可能會使身體的速度發生微不足道的變化。

您已將玩家的collisionBitMask設置爲類似0x00000000(所有位已清除)。默認情況下,categoryBitMask設置爲0xFFFFFFFF(所有位設置)。因爲你沒有另外說明,所以場景的物理主體categoryBitMask設置爲0xFFFFFFFF。當在這兩者之間執行邏輯「與」(&)運算符時,結果將爲零,表示不發生衝突。

爲了解決這個問題,你可以刪除此行:

heroShip.physicsBody?.collisionBitMask = 0x0 

或者定義一個類牆設置正確......

提示:

  • 錨點定義了相對於節點位置繪製紋理的方式。它與物理體沒有任何關係。物理主體默認以節點的位置爲中心。如果開啓物理可視化表示(skView.showsPhysics = true),則在您的示例中,您將看到物理主體未按其應有的位置放置。

  • 在實際初始化它之前設置物理體是沒有意義的。你必須首先初始化物理體。

+0

這是正確的,我剛結束了0x0和沒有一個sceneCategory UInt32的設置呢。感謝您的幫助 –

0

添加到旋風的答案,你可能還希望啓用你的物理身體usesPreciseCollisionDetection。通過將其設置爲true,這將防止heroShip在遇到來自加速度計數據的強大力量時穿過牆壁。

基本上,物理的計算方式是它將會在哪裏。所以如果有巨大的力量,它可能會說,「哦,這個巨大的力量意味着我應該在邊界框外邊的路上。」如果啓用了精確的碰撞檢測,這將強制它計算從該幀的起始位置到計算位置的多個位置的物理量。如果它在達到計算出的位置之前碰到某個東西,那麼它會進行調整,以使其不會經過任何碰到的東西。大多數情況下,您不必擔心這一點,但最好是安全而不是抱歉。

於是就把這條線在某處你的物理身體的配置代碼它初始化後:

heroShip.physicsBody?.usesPreciseCollisionDetection = true