检测Swift中两个对象之间的冲突

时间:2014-12-20 01:38:52

标签: ios swift sprite-kit collision-detection

在Swift中碰撞检测非常简单 - 但在这个特定项目中,身体碰撞并不像往常一样触发didBeginContact事件。

这是我的两个尸体碰撞的清单(使用士兵和子弹):

  1. SKPhysicsContactDelegate添加到班级。
  2. 适当地设置physicsWorld,通常是:self.physicsWorld.contactDelegate = self
  3. 为您将拥有的每组节点创建类别。例如。 let bulletCategory = 0x1 << 0
  4. 为每个子弹和士兵创建SKNode。
  5. 给每个子弹和士兵一个具有匹配形状的物理身体。
  6. 将每个项目符号的categoryBitMask设置为bulletCategory(士兵设置为soldierCategory)。
  7. 将每个项目符号的contactBitMask设置为soldierCategory(士兵设置为bulletCategory)。
  8. 定义didBeginContact()处理程序。
  9. 以下是我的完整代码。它是一个最小的~20行&#34; Hello World&#34;碰撞。

    如果你创建一个新的游戏&#34;并将其粘贴到GameScene.swift中,它将运行,不会触发任何碰撞事件。

    //
    //  GameScene.swift
    //  Thesoldier
    //
    //  Created by Donald Pinkus on 12/19/14.
    //  Copyright (c) 2014 Don Pinkus. All rights reserved.
    //
    
    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) {
            println("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 个答案:

答案 0 :(得分:5)

以下是您的核对清单中缺少的一些项目:

  1. 其中一个物理机构必须是动态的
  2. 必须通过力/冲动或通过设定速度来移动物理实体
  3. 物理实体的位置应与其对应的精灵/形状节点匹配
  4. 对于(2),您通过使用SKAction更改其位置来移动每个项目符号。

    对于(3),每个项目符号的位置从(0,0)开始,而形状在场景的顶部中心绘制。由于物理体以形状节点的位置为中心,因此形状和物理体之间存在不匹配;子弹的物理身体永远不会与士兵接触。要解决此问题,请尝试

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

    此外,士兵的物理身体是其形状半径的一半。