简易SpriteKit接触检测(太空射击游戏)无法正常启动 [英] Easy SpriteKit Contact Detection (Space Shooter Game) Not Wotking Properly
问题描述
我正在尝试制作一个简单的太空射击游戏。鱼雷与外星人之间或航天飞机与外星人之间应进行接触。问题在于,第二种接触(航天飞机与外星人)仅在第一种接触发生(鱼雷与外星人)之后才发生,而且它们并不总是很精确。这是在类外创建的结构
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 $ c时,不会造成混淆$ c>如下所示,因为这避免了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屋!