簡體   English   中英

檢測Swift中兩個對象之間的碰撞

[英]Detect collision between two objects in Swift

Swift 中的碰撞檢測非常簡單——但在這個特定項目中,身體碰撞並沒有像往常一樣觸發didBeginContact事件。

這是我的兩個物體碰撞的清單(使用士兵和子彈):

  1. SKPhysicsContactDelegate添加到類中。
  2. 適當地設置物理世界,通常: self.physicsWorld.contactDelegate = self
  3. 為您將擁有的每組節點創建類別。 例如let bulletCategory = 0x1 << 0
  4. 為每個子彈和士兵創建 SKNode。
  5. 給每個子彈和士兵一個形狀匹配的物理身體。
  6. 將每個子彈的categoryBitMask 設置為bulletCategory (士兵設置為soldierCategory)。
  7. 將每個子彈的contactBitMask 設置為soldierCategory (soldiers 設置為bulletCategory)。
  8. 定義didBeginContact()處理程序。

下面是我的完整代碼。 它是用於碰撞的最小約 20 行“Hello World”。

如果您創建一個新的“游戲”並將其復制粘貼到 GameScene.swift 中,它將運行,只是不會觸發任何碰撞事件。

import SpriteKit

class GameScene: SKScene, SKPhysicsContactDelegate {
    var soldier = SKShapeNode(circleOfRadius: 40)

    let soldierCategory:UInt32 = 0x1 << 0;
    let bulletCategory:UInt32 = 0x1 << 1;

    override func didMoveToView(view: SKView) {
        self.physicsWorld.contactDelegate = self

        // THE soldier
        soldier.fillColor = SKColor.redColor()
        soldier.position = CGPoint(x: CGRectGetMidX(self.frame), y: 40)
        soldier.physicsBody = SKPhysicsBody(circleOfRadius: 20)
        soldier.physicsBody!.dynamic = false
        soldier.physicsBody!.categoryBitMask = soldierCategory
        soldier.physicsBody!.contactTestBitMask = bulletCategory
        soldier.physicsBody!.collisionBitMask = 0


        // bulletS
        var timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("makeBullet"), userInfo: nil, repeats: true)

        self.addChild(soldier)
    }

    func makeBullet() {
        var bullet = SKShapeNode(rect: CGRect(x: CGRectGetMidX(self.frame), y: self.frame.height, width: 10, height: 40), cornerRadius: CGFloat(0))
        bullet.fillColor = SKColor.redColor()

        bullet.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: 10, height: 40))
        bullet.physicsBody?.dynamic = false
        bullet.physicsBody?.categoryBitMask = bulletCategory
        bullet.physicsBody?.contactTestBitMask = soldierCategory
        bullet.physicsBody?.collisionBitMask = soldierCategory

        var movebullet = SKAction.moveByX(0, y: CGFloat(-400), duration: 1)
        var movebulletForever = SKAction.repeatActionForever(movebullet)
        bullet.runAction(movebulletForever)

        self.addChild(bullet)
    }

    func didBeginContact(contact: SKPhysicsContact) {
        print("CONTACT")
    }

    override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
        /* Called when a touch begins */
    }

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

以下是您的清單中缺少的一些項目:

  1. 物理體之一必須是動態的
  2. 物理物體必須通過力/脈沖或通過設置它們的速度來移動
  3. 物理體的位置應與其對應的精靈/形狀節點匹配

對於(2),您通過使用SKAction隨時間改變其位置來移動每個子彈。

對於 (3),每個子彈的位置從 (0, 0) 開始,而形狀繪制在場景的頂部中心。 由於物理體以形狀節點的位置為中心,因此形狀和物理體的位置不匹配; 子彈的物理體永遠不會與士兵接觸。 要解決此問題,請嘗試

    var bullet = SKShapeNode(rectOfSize: CGSizeMake(10, 40))
    bullet.position = CGPointMake(self.size.width/2.0, self.size.height)

此外,士兵的物理身體是其形狀半徑的一半。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM