我正在尝试制作牛仔/枪手游戏。我需要弹丸(来自第一个牛仔)之间发生碰撞才能击中第二个牛仔。但是,didBegin函数没有被运行/调用。
我曾经尝试使用以前游戏中的代码来弄乱物理机构,但没有成功。 showPhysics = true。
物理类别:
struct PhysicsCategory {
static let none :UInt32 = 0
static let cowboy1Physics :UInt32 = 0x1 << 1
static let cowboy2Physics :UInt32 = 0x1 << 1
static let projectile1Physics:UInt32 = 0x1 << 0
static let projectile2Physics:UInt32 = 0x1 << 0
}
Fire Bullet1:
func fireProjectile1() {
let projectile1 = SKSpriteNode(imageNamed: "bullet1")
projectile1.position = cowboyNo1.position
projectile1.position.x += 5
projectile1.size = CGSize(width: projectile1.size.width / 4, height: projectile1.size.height / 4)
self.addChild(projectile1)
projectile1.physicsBody = SKPhysicsBody(rectangleOf: projectile1.size )
projectile1.physicsBody?.isDynamic = true
projectile1.physicsBody?.categoryBitMask = PhysicsCategory.projectile1Physics
projectile1.physicsBody?.contactTestBitMask = PhysicsCategory.cowboy2Physics
projectile1.physicsBody?.collisionBitMask = PhysicsCategory.none
projectile1.physicsBody?.usesPreciseCollisionDetection = true
projectile1.zPosition = 1
var actionArray = [SKAction]()
actionArray.append(SKAction.move(to: CGPoint(x: size.height + 1500, y: cowboyNo1.position.y), duration: TimeInterval(1.5)))
actionArray.append(SKAction.wait(forDuration: 1))
actionArray.append(SKAction.removeFromParent())
print("fire")
projectile1.run(SKAction.sequence(actionArray))
}
Cowboy2物理学:
func createCowboyNo2() {
cowboyNo2.position = CGPoint(x: 1800, y: 200)
cowboyNo2.zPosition = 1
cowboyNo2.size = CGSize(width: cowboyNo2.size.width / 2, height: cowboyNo2.size.height / 2)
// Cowboy2 physics
cowboyNo2.physicsBody = SKPhysicsBody(rectangleOf: cowboyNo2.size) // 1
cowboyNo2.physicsBody?.isDynamic = true // 2
cowboyNo2.physicsBody?.categoryBitMask = PhysicsCategory.cowboy2Physics // 3
cowboyNo2.physicsBody?.contactTestBitMask = 2 // 4
cowboyNo2.physicsBody?.collisionBitMask = PhysicsCategory.none
cowboyNo2.physicsBody?.usesPreciseCollisionDetection = true
physicsWorld.gravity = .zero
addChild(cowboyNo2)
}
DidBegin:
func didBegin(_ contact: SKPhysicsContact) {
// 1
var firstBody:SKPhysicsBody
var secondBody:SKPhysicsBody
print("test")
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask{
firstBody = contact.bodyA
secondBody = contact.bodyB
print("contact body's")
}
else{
firstBody = contact.bodyB
secondBody = contact.bodyA
print("more contact bodys")
}
if (firstBody.categoryBitMask & PhysicsCategory.projectile1Physics) != 0 && (secondBody.categoryBitMask & PhysicsCategory.cowboy2Physics) != 0{
projectileDidCollideWithCowboy2(nodeA: firstBody.node as! SKSpriteNode, nodeB: secondBody.node as! SKSpriteNode)
print("remove child")
}
DidCollideWithCowboy函数:
func projectileDidCollideWithCowboy2(nodeA: SKSpriteNode, nodeB: SKSpriteNode) {
print("hit")
nodeA.removeFromParent()
nodeB.removeFromParent()
score1 += 1
}
预期的输出是要删除项目符号,并在控制台上打印“ test”,但没有打印任何内容。射弹正朝牛仔开火。似乎应该在运行时未在代码中完全调用didBegin函数。
答案 0 :(得分:0)
它为什么不起作用尚不清楚。
您可以将此功能添加到代码中吗?设置完所有物理后,请致电checkPhysics()
,它将列出您定义的碰撞和联系方式:
//MARK: - Analyse the collision/contact set up.
func checkPhysics() {
// Create an array of all the nodes with physicsBodies
var physicsNodes = [SKNode]()
//Get all physics bodies
enumerateChildNodes(withName: "//.") { node, _ in
if let _ = node.physicsBody {
physicsNodes.append(node)
} else {
print("\(node.name) does not have a physics body so cannot collide or be involved in contacts.")
}
}
//For each node, check it's category against every other node's collion and contctTest bit mask
for node in physicsNodes {
let category = node.physicsBody!.categoryBitMask
// Identify the node by its category if the name is blank
let name = node.name != nil ? node.name! : "Category \(category)"
let collisionMask = node.physicsBody!.collisionBitMask
let contactMask = node.physicsBody!.contactTestBitMask
// If all bits of the collisonmask set, just say it collides with everything.
if collisionMask == UInt32.max {
print("\(name) collides with everything")
}
for otherNode in physicsNodes {
if (node.physicsBody?.dynamic == false) {
print("This node \(name) is not dynamic")
}
if (node != otherNode) && (node.physicsBody?.isDynamic == true) {
let otherCategory = otherNode.physicsBody!.categoryBitMask
// Identify the node by its category if the name is blank
let otherName = otherNode.name != nil ? otherNode.name! : "Category \(otherCategory)"
// If the collisonmask and category match, they will collide
if ((collisionMask & otherCategory) != 0) && (collisionMask != UInt32.max) {
print("\(name) collides with \(otherName)")
}
// If the contactMAsk and category match, they will contact
if (contactMask & otherCategory) != 0 {print("\(name) notifies when contacting \(otherName)")}
}
}
}
}
}
答案 1 :(得分:0)
可能是因为您尚未选择PhysicWorld委托:
确保您的课程实现了SKPhysicsContactDelegate
:
class GameScene: SKScene, SKPhysicsContactDelegate {
......
}
//Or whatever your class looks like
在您的didMove
中:
override func didMove(to view: SKView) {
self.scene?.physicsWorld.contactDelegate = self
....
}