我的游戏中有三个节点 -
播放器 -
这是一艘你用操纵杆拖动的船。
let collisionPlayer : UInt32 = 0x1 << 1
let apple = SKSpriteNode(texture: texture)
apple.position = position
apple.physicsBody = SKPhysicsBody(circleOfRadius: apple.size.width / 2.0)
apple.physicsBody?.affectedByGravity = false
apple.physicsBody?.isDynamic = true
apple.setScale(0.1)
addChild(apple)
(“苹果”是船)
The Enemy Boat -
这是一艘随机跟随玩家的CPU船。
let collisionNPC : UInt32 = 0x1 << 0
appleNPC.position = position
appleNPC.physicsBody = SKPhysicsBody(circleOfRadius: appleNPC.size.width / 2.0)
appleNPC.physicsBody?.isDynamic = true
appleNPC.physicsBody?.affectedByGravity = false
appleNPC.position = CGPoint(x: 600, y: 200)
appleNPC.setScale(0.1)
addChild(appleNPC)
子弹 (言自明)
let collisionBullet : UInt32 = 0x1 << 2
(以下代码在TouchesEnded中)
bullet?.name = "Bullet"
bullet?.position = (appleNode?.position)!
bullet?.setScale(0.05)
bullet?.zPosition = 1
bullet?.physicsBody = SKPhysicsBody(circleOfRadius: (bullet?.size.width)!/2)
bullet?.physicsBody?.isDynamic = true
bullet?.physicsBody?.affectedByGravity = false
bullet?.physicsBody?.usesPreciseCollisionDetection = true
要移动子弹我使用代码:
// Your code with delay
if bulletNumbers > 0 {
let offset = CGPoint(x: touchLocation.x - (bullet?.position.x)! , y: touchLocation.y - (bullet?.position.y)!)
//Stops Bullet from shooting backwards
//Get the direction of where to shoot
let direction = offset
//Make it shoot far enough to be guaranteed off screen
let shootAmount = CGPoint(x: direction.x * 10, y: direction.y * 10)
//Add the shoot amount to the current position
let realDest = CGPoint(x: shootAmount.x + (bullet?.position.x)!, y: shootAmount.y + (bullet?.position.y)!)
//Create the actions
addChild(bullet!)
self.bulletNumbers -= 1
let distance = sqrt(pow(realDest.x - (appleNode?.position.x)!, 2) +
pow(realDest.y - (appleNode?.position.y)!, 2))
// run the sequence of actions for the firing
let duration = TimeInterval(distance / PlayerMissileSpeed)
let missileMoveAction = SKAction.move(to: realDest, duration: duration)
let when = DispatchTime.now() + 10 // change 2 to desired number of seconds
DispatchQueue.main.asyncAfter(deadline: when) { self.bulletNumbers += 1
}
bullet?.run(missileMoveAction) {
self.bullet?.isHidden = true
self.bullet?.removeFromParent()
print("\(self.bulletNumbers)")
}}
else if bulletNumbers <= 0 {
print("reload")
let when = DispatchTime.now() + 2 // change 2 to desired number of seconds
DispatchQueue.main.asyncAfter(deadline: when) {
}
}
}
func didBegin(_ contact: SKPhysicsContact) {
print("test")
}
func setRandomStickColor() {
let randomColor = UIColor.random()
moveAnalogStick.stick.color = randomColor
}
func setRandomSubstrateColor() {
let randomColor = UIColor.random()
moveAnalogStick.substrate.color = randomColor
}
override func update(_ currentTime: TimeInterval) {
/* Called before each frame is rendered */
super.update(currentTime)
let _:UInt32 = arc4random_uniform(1) //
appleNodeCpuSpeed = CGFloat(1)
var locationx : CGFloat
var locationy: CGFloat
locationx = (appleNode?.position.x)!
locationy = (appleNode?.position.y)!
let dx = locationx - (appleNodeNPC?.position.x)!
let dy = locationy - (appleNodeNPC?.position.y)!
let angle = atan2(dy, dx)
let vx = cos(angle) * appleNodeCpuSpeed
let vy = sin(angle) * appleNodeCpuSpeed
self.appleNodeNPC?.position.x += vx
self.appleNodeNPC?.position.y += vy
let when = DispatchTime.now() + 0.25 // change 2 to desired number of seconds
DispatchQueue.main.asyncAfter(deadline: when) {
self.appleNodeNPC?.zRotation = angle + 90
}
//2
这很好用。子弹从船上发射到触摸位置,然而,当我试图引入碰撞时,事情开始出错。以下是我的代码:
appleNode?.physicsBody?.categoryBitMask = collisionPlayer
appleNode?.physicsBody?.collisionBitMask = collisionNPC
appleNode?.physicsBody?.contactTestBitMask = 0
appleNodeNPC?.physicsBody?.categoryBitMask = collisionNPC
appleNodeNPC?.physicsBody?.collisionBitMask = collisionPlayer
appleNodeNPC?.physicsBody?.contactTestBitMask = collisionBullet
bullet?.physicsBody?.categoryBitMask = collisionBullet
bullet?.physicsBody?.collisionBitMask = 0
bullet?.physicsBody?.contactTestBitMask = collisionNPC
physicsWorld.contactDelegate = self
view.showsPhysics = true
然后在我的didBegin函数中我有:
func didBegin(_ contact: SKPhysicsContact) {
print("test")
}
让我们从头开始。我点击屏幕,发射子弹。子弹不会与玩家碰撞,这是我最初想要的。然而,当子弹与敌舰接触时,它会发生碰撞。它环绕着船只并继续前往其原始目的地。我希望子弹与船只联系而不是其他任何东西 - 没有碰撞。我希望假设我的错误是因为我移动子弹的代码,但我不确定。任何帮助表示赞赏。
答案 0 :(得分:2)
SKPhysicsContactDelegate
,并让自己成为物理联系代表: //Physics categories
let appleCategory: UInt32 = 1 << 0
let enemyCategory: UInt32 = 1 << 1
let bulletCategory: UInt32 = 1 << 2
class GameScene: SKScene, SKPhysicsContactDelegate {
physicsWorld.contactDelegate = self
分配类别(通常在didMove(to view:)
:
apple.physicsBody.catgeoryBitMask = appleCategory
enemy.physicsBody.catgeoryBitMask = enemyCategory
bullet.physicsBody.catgeoryBitMask = bulletCategory
(确保您已为每个节点创建了物理实体)
apple.physicsBody?.collisionBitMask = 0 // apple/player collides with nothing
enemy.physicsBody?.collisionBitMask = 0 // enemy collides with nothing
bullet.physicsBody?.collisionBitMask = 0 // bullet collides with nothing
甚至:
for node in [apple, enemy, bullet] {
node.physicsBody?.collisionBitMask = 0 // collides with nothing
}
设置联系人
bullet.physicsBody?.collisionBitMask = enemyCategory // bullet contacts enemy
确保每个潜在联系人中涉及的至少一个对象的物理主体上的isDynamic
属性设置为true
,否则将不会生成任何联系人。两个对象都没有必要是动态的。
当子弹和敌人接触时,你现在应该被didBegin
召唤。您可以像这样编码didBegin
:
func didBegin(_ contact: SKPhysicsContact) {
print("didBeginContact entered for \(String(describing: contact.bodyA.node!.name)) and \(String(describing: contact.bodyB.node!.name))")
let contactMask = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch contactMask {
case bulletCategory | enemyCategory:
print("bullet and enemy have contacted.")
let bulletNode = contact.bodyA.categoryBitMask == bulletCategory ? contact.bodyA.node : contact.bodyB.node
enemyHealth -= 10
bulletNode.removeFromParent
default:
print("Some other contact occurred")
}
}