Я переделываю ретро игру Астероиды.
У меня есть три типа астероидов: большой, средний и маленький. И я пытаюсь добавить обнаружение попадания на корабль, чтобы когда астероид попадал в космический корабль, астероид удалялся от родителя.
Но это не работает, и я случайно получаю ошибку Fatal Error: Unexpectedly found nil while unwrapping an optional value.
Я получаю ее в случайных местах и не знаю, как ее исправить, но чаще всего в строкахкоторые устанавливают значение isDynamic. (КСТАТИ я насильно разворачиваю их!)
Код для категорий:
struct PhysicsCategory {
static let none: UInt32 = 0
static let bulletCategory: UInt32 = 0x1 << 1
static let spaceShipCategory: UInt32 = 0x1 << 2
static let bigAsteroidCategory: UInt32 = 0x1 << 3
static let mediumAsteroidCategory: UInt32 = 0x1 << 4
static let smallAsteroidCategory: UInt32 = 0x1 << 5
}
Это код моего космического корабля:
override func didMove(to view: SKView) {
SpaceShip = childNode(withName: "Spaceship") as? SKSpriteNode
SpaceShip!.physicsBody = SKPhysicsBody(texture: SpaceShip!.texture!, size: CGSize(width: SpaceShip!.size.width, height: SpaceShip!.size.height))
SpaceShip!.physicsBody!.isDynamic = true
SpaceShip!.physicsBody!.categoryBitMask = PhysicsCategory.spaceShipCategory
SpaceShip!.physicsBody!.contactTestBitMask = PhysicsCategory.bigAsteroidCategory | PhysicsCategory.mediumAsteroidCategory | PhysicsCategory.smallAsteroidCategory
SpaceShip!.physicsBody!.collisionBitMask = PhysicsCategory.none
self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
self.physicsWorld.contactDelegate = self
self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
//This is the code which runs the asteroid functions:
run(SKAction.repeatForever(
SKAction.sequence([
SKAction.run(bigAsteroids),
SKAction.wait(forDuration: 7.0),
])
))
run(SKAction.repeatForever(
SKAction.sequence([
SKAction.run(mediumAsteroids),
SKAction.wait(forDuration: 15.0)
])
))
run(SKAction.repeatForever(
SKAction.sequence([
SKAction.run(smallAsteroids),
SKAction.wait(forDuration: 20.0)
])
))
}
Этоявляется функцией астероида (их три, но все они очень похожи, поэтому я просто покажу одну)
func bigAsteroids() {
let bigAsteroid = SKSpriteNode(imageNamed: "Asteroid")
bigAsteroid.physicsBody = SKPhysicsBody(texture: bigAsteroid.texture!, size: bigAsteroid.texture!.size())
let yCoordinate = random(lowest: -self.size.height, highest: self.size.height - bigAsteroid.size.height)
var xCoordinate = -self.size.width - bigAsteroid.size.width/2
let xCoordinateChooser = arc4random_uniform(2)
if xCoordinateChooser == 0 {
xCoordinate = self.size.width - bigAsteroid.size.width/2
}
else {
xCoordinate = -self.size.width - bigAsteroid.size.width/2
}
bigAsteroid.physicsBody!.isDynamic = true
bigAsteroid.physicsBody!.collisionBitMask = PhysicsCategory.none
bigAsteroid.physicsBody!.categoryBitMask = PhysicsCategory.bigAsteroidCategory
bigAsteroid.position = CGPoint(x: xCoordinate, y: yCoordinate)
addChild(bigAsteroid)
let moveAsteroid = SKAction.moveBy(x: -xCoordinate, y: -yCoordinate, duration: 8.0)
let spinAsteroid = SKAction.rotate(byAngle: CGFloat.pi * 2, duration: 8.0)
let asteroidMovement = SKAction.group([moveAsteroid, spinAsteroid])
bigAsteroid.run(asteroidMovement)
}
Это код, который проверяет наличие столкновений
func didBegin(_ contact: SKPhysicsContact) {
let collision: UInt32 = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
if collision == PhysicsCategory.bigAsteroidCategory | PhysicsCategory.bigAsteroidCategory {
print("big collision")
contact.bodyA.node?.removeFromParent()
contact.bodyB.node?.removeFromParent()
}
else if collision == PhysicsCategory.mediumAsteroidCategory | PhysicsCategory.mediumAsteroidCategory {
print("medium collision")
contact.bodyA.node?.removeFromParent()
contact.bodyB.node?.removeFromParent()
}
else if collision == PhysicsCategory.smallAsteroidCategory | PhysicsCategory.smallAsteroidCategory {
print("small collision")
contact.bodyA.node?.removeFromParent()
contact.bodyB.node?.removeFromParent()
}
}
Любая помощь илиРешение приветствуется.