Как обнаружить столкновение в наборе Swift, Sprite
Я программировал эту простую космическую игру на Swift, пока не столкнулся с проблемой обнаружения столкновений. После просмотра форумов, учебных пособий и т. Д. Я попытался реализовать коллизии, объявив битовые маски следующим образом:
объект 1
enemy?.physicsBody = SKPhysicsBody(circleOfRadius: ((enemy?.size.width)!/2))
enemy?.physicsBody?.categoryBitMask = enemyBitMask
enemy?.physicsBody?.contactTestBitMask = bulletBitMask
enemy?.physicsBody?.collisionBitMask = 0
объект 2
bullet?.physicsBody? = SKPhysicsBody(rectangleOf: (bullet?.size)!)
bullet?.physicsBody?.categoryBitMask = bulletBitMask
bullet?.physicsBody?.contactTestBitMask = enemyBitMask
bullet?.physicsBody?.collisionBitMask = 0
bullet?.physicsBody?.usesPreciseCollisionDetection = true
Я также поместил заявление для печати в
func didBegin(_ contact: SKPhysicsContact) { print("Hello") }
вот как я настраиваю свои спрайты:
func CreateNewEnemy() {
var enemy : SKSpriteNode?
let moveEnemyDown = SKAction.repeatForever(SKAction.moveBy(x: 0, y: -1, duration: 0.01))
let rotateEnemy = SKAction.repeatForever(SKAction.rotate(byAngle: 25, duration: 5))
let enemyXpos = randomNum(high: self.frame.size.width/2, low: -1 * self.frame.size.width/2)
let enemyYpos = randomNum(high: 2.5*self.frame.size.height, low: self.frame.size.height/2)
let enemyOrigin : CGPoint = CGPoint(x: enemyXpos, y: enemyYpos)
enemy = SKSpriteNode(imageNamed: possibleEnemyImage[Int(arc4random_uniform(4))])
print(enemy?.size.height)
enemy?.scale(to: CGSize(width: player.size.height, height: player.size.height))
print(enemy?.size.height)
enemy?.position = enemyOrigin
enemy?.run(moveEnemyDown)
enemy?.run(rotateEnemy)
let enemyRadius : CGFloat = (enemy?.size.width)!/2
print(enemyRadius)
enemy?.physicsBody? = SKPhysicsBody(circleOfRadius: enemyRadius)
enemy?.physicsBody?.categoryBitMask = enemyCategory
enemy?.physicsBody?.contactTestBitMask = bulletCategory
enemy?.physicsBody?.collisionBitMask = 0
enemy?.zPosition = 1
enemiesArray.append(enemy!)
self.addChild(enemy!)
}
создать врага (Вызван ли переместить для просмотра функции)
func CreateAllEnemies(amountOfEnemies : UInt8) {
for _ in 0...amountOfEnemies {
CreateNewEnemy()
}
}
и другой спрайт
func CreateNewBullet() {
let bulletOrigin : CGPoint = CGPoint(x: player.position.x, y: player.position.y+player.size.height/2)
let moveBulletUp = SKAction.repeatForever(SKAction.moveBy(x: 0, y: 3, duration: 0.01))
var bullet : SKSpriteNode?
bullet = SKSpriteNode(imageNamed: "bulletImage")
bullet?.position = bulletOrigin
bullet?.run(moveBulletUp)
bullet?.physicsBody? = SKPhysicsBody(rectangleOf: (bullet?.size)!)
bullet?.physicsBody?.categoryBitMask = bulletCategory
bullet?.physicsBody?.contactTestBitMask = enemyCategory
bullet?.physicsBody?.collisionBitMask = 0
bullet?.physicsBody?.isDynamic = true
bullet?.physicsBody?.usesPreciseCollisionDetection = true
bullet?.zPosition = 1
bulletsArray.append(bullet!)
self.addChild(bullet!)
}
этот создан с таймером
bulletTimer = Timer.scheduledTimer(timeInterval: 0.25, target: self, selector: #selector(CreateNewBullet) , userInfo: nil, repeats: true)
К сожалению, в консоли ничего не печатается после того, как я вижу, как два объекта соприкасаются.
1 ответ
- Определите уникальные категории, убедитесь, что ваш класс
SKPhysicsContactDelegate
и сделайте себе физик, связавшись с делегатом:
//Physics categories
let enemyCategory: UInt32 = 1 << 1
let bulletCategory: UInt32 = 1 << 2
class GameScene: SKScene, SKPhysicsContactDelegate {
physicsWorld.contactDelegate = self
Назначьте категории (обычно в
didMove(to view:)
:enemy.physicsBody.catgeoryBitMask = enemyCategory bullet.physicsBody.catgeoryBitMask = bulletCategory
(Убедитесь, что вы создали физические тела для каждого узла)
- Настройте столкновения:
enemy.physicsBody?.collisionBitMask = 0 // enemy collides with nothing
bullet.physicsBody?.collisionBitMask = 0 // bullet collides with nothing
или даже:
for node in [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")
}
}