简易SpriteKit接触检测(太空射击游戏)无法正常启动 [英] Easy SpriteKit Contact Detection (Space Shooter Game) Not Wotking Properly

查看:150
本文介绍了简易SpriteKit接触检测(太空射击游戏)无法正常启动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个简单的太空射击游戏。鱼雷与外星人之间或航天飞机与外星人之间应进行接触。问题在于,第二种接触(航天飞机与外星人)仅在第一种接触发生(鱼雷与外星人)之后才发生,而且它们并不总是很精确。这是在类外创建的结构

I'm trying to make a simple Space Shooter game. The contact should happen either between the torpedo and the alien or the shuttle and the alien. The problem is that this second contact (shuttle vs. alien) only happens after the first kind of contact has happend (torpedo vs. alien) and further more they're not always precise. This is a struct created outside the class

struct PhysicsCategory {
static let alien : UInt32 = 1
static let torpedo : UInt32 = 2
static let shuttle : UInt32 = 3 }

班车:

shuttle.physicsBody = SKPhysicsBody(rectangleOfSize: shuttle.size)
shuttle.physicsBody?.categoryBitMask = PhysicsCategory.shuttle
shuttle.physicsBody?.contactTestBitMask = PhysicsCategory.alien 
shuttle.physicsBody?.dynamic = false 
shuttle.physicsBody?.affectedByGravity = false

鱼雷:

torpedo.physicsBody = SKPhysicsBody(rectangleOfSize: torpedo.size)
torpedo.physicsBody?.categoryBitMask = PhysicsCategory.torpedo
torpedo.physicsBody?.contactTestBitMask = PhysicsCategory.alien
torpedo.physicsBody?.affectedByGravity = false
torpedo.physicsBody?.dynamic = false

Alien:

alien.physicsBody = SKPhysicsBody(rectangleOfSize: torpedo.size)
alien.physicsBody?.categoryBitMask = PhysicsCategory.alien
alien.physicsBody?.contactTestBitMask = PhysicsCategory.torpedo
alien.physicsBody?.affectedByGravity = false
alien.physicsBody?.dynamic = true

最后,这是我的联系代码:

Finally, here's my contact code:

    func didBeginContact(contact: SKPhysicsContact) {
    var firstBody : SKPhysicsBody = contact.bodyA
    var secondBody : SKPhysicsBody = contact.bodyB

    if ((firstBody.categoryBitMask == PhysicsCategory.alien) && (secondBody.categoryBitMask == PhysicsCategory.torpedo)) ||
    ((firstBody.categoryBitMask == PhysicsCategory.torpedo) && (secondBody.categoryBitMask == PhysicsCategory.alien)) {
        self.contactWithTorpedo(firstBody.node as! SKSpriteNode, torpedo: secondBody.node as! SKSpriteNode)
    } else if ((firstBody.categoryBitMask == PhysicsCategory.shuttle) && (secondBody.categoryBitMask == PhysicsCategory.alien)) {
            self.contactWithShuttle(firstBody.node as! SKSpriteNode, shuttle: secondBody.node as! SKSpriteNode)
    }
}


func contactWithTorpedo (alien: SKSpriteNode, torpedo : SKSpriteNode) {
    alien.removeFromParent()
    torpedo.removeFromParent()
    score++
    scoreLabel.text = "score: " + "\(score)"
}

func contactWithShuttle (alien:SKSpriteNode, shuttle:SKSpriteNode) {
    alien.removeFromParent()
    shuttle.removeFromParent()

    self.view?.presentScene(EndScene())

}

我不太确定问题出在哪里,而且我已经看到一些教程可以做到这一点。我不知道这是否有意义,但这不是iOS游戏,而是OSX。预先谢谢您!

I'm not really sure where the problem is, plus I've seen a couple of tutorials do the same. I don't know if it's relevant by the way, but this is not an iOS game but an OSX. Thank you in advance!

推荐答案

您可能会发现,重新构造 didBeginContact 如下所示,因为这避免了firstBody / secondbody的内容,也避免了复杂的 if ...然后条件,以查看与哪些内容联系了:

You might find it less confusing to restructure your didBeginContact as follows, as this avoids the firstBody/secondbody stuff and the complicated if...then conditions to see what has contacted what:

func didBeginContact(contact: SKPhysicsContact) {
    let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

    switch contactMask {
    case PhysicsCategory.alien | PhysicsCategory.torpedo:
       // alien and torpedo have contacted
       contact.bodyA.removeFromParent()
       contact.bodyB.removeFromParent()
       score += 1
       scoreLabel.text = "score: " + "\(score)"

    case PhysicsCategory.alien | PhysicsCategory.shuttle:
       // alien and shuttle have contacted
       contact.bodyA.removeFromParent()
       contact.bodyB.removeFromParent()

       self.view?.presentScene(EndScene())

    default :
        //Some other contact has occurred
        print("Some other contact")
    }
}

您可以添加许多 PhysicsCategory.enemy | PhysicsCategory.player 案例,因为您需要在游戏中采取行动的所有联系人。对每个潜在的联系人进行单独编码,如果...然后...其他,您就不会陷入困境。

You can just add as many PhysicsCategory.enemy | PhysicsCategory.player cases as you need for all the contacts that you have to take action for in your game. Code each potential contact individually and you won't loose yourself in if...then...else.

如果您只需要引用所涉及的节点之一在联系人中(例如,在敌人击中玩家后将其移除),您可以这样做:

if you do need to reference only one of the nodes involved in a contact, (e.g. to remove the player after an enemy hits it), you can do it like this:

let playerNode = contact.bodyA.categoryBitMask == PhysicsCategory.player ? contact.bodyA.node! : contact.bodyB.node!
playernode.removefromParent

这篇关于简易SpriteKit接触检测(太空射击游戏)无法正常启动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆