Title: Changes to GameScene+PhysicsContact
(I understand, it may be to late in your process to make such a change, but I’ll share here anyway, and would welcome feedback)
The GameScene+PhysicsContact extension was the source of one of my typos, and I also found the code to be quite “dense” to read.
I’m taking a bit of time at the end of Val’s Revenge to go in and make changes that seem good, but mainly to test that I’m getting the hang of Swift.
I added a couple of functions to factor out a lot of the common code and reduce the noise of reading the cases and then matching up the nodes. (On the plus side, my typo was accidentally having a collisionBitMask one place rather than a categoryBitMask (probably just a cursor key error with code completion, but I really don’t want to admit how long it took me to track that down). This code prevents that sort of error by placing it into the function where it’s done once, and will either be always right, or always wrong)
Anyway… as the tag says… Just a suggestion
This is my revised version of GameScene+PhysicsContact.swift:
import SpriteKit
extension GameScene: SKPhysicsContactDelegate {
func match(_ contact: SKPhysicsContact, body: PhysicsBody) -> (match:SKNode, other:SKNode) {
return contact.bodyA.categoryBitMask == body.categoryBitMask ?
(contact.bodyA.node!, contact.bodyB.node!) :
(contact.bodyB.node!, contact.bodyA.node!)
}
func collisionOf(_ bodyA :PhysicsBody, _ bodyB: PhysicsBody) -> UInt32 {
bodyA.categoryBitMask | bodyB.categoryBitMask
}
func didBegin(_ contact: SKPhysicsContact) {
let collision = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask
switch collision {
// MARK: - Player | Collectible
case collisionOf(.player,.collectible):
let (playerNode, collectible) = match(contact, body: .player)
if let player = playerNode as? Player {
player.collectItem(collectible)
}
// MARK: - Player | Door
case collisionOf(.player,.door):
let (playerNode, door) = match(contact, body: .player)
if let player = playerNode as? Player {
player.useKeyToOpenDoor(door)
}
// MARK: - Projectile | Collectible
case collisionOf(.projectile,.collectible):
let (projectileNode, collectibleNode) = match(contact, body: .projectile)
if let collectibleComponent = collectibleNode.entity?.component(ofType: CollectibleComponent.self) {
collectibleComponent.destroyedItem()
}
projectileNode.removeFromParent()
// MARK: - Player | Monster
case collisionOf(.player,.monster):
let (playerNode, _) = match(contact, body: .player)
if let healthComponent = playerNode.entity?.component(ofType: HealthComponent.self) {
healthComponent.updateHealth(-1, forNode: playerNode)
}
// MARK: - Projectile | Monster
case collisionOf(.projectile,.monster):
let (monsterNode, _) = match(contact, body: .monster)
if let healthComponent = monsterNode.entity?.component(ofType: HealthComponent.self) {
healthComponent.updateHealth(-1, forNode: monsterNode)
}
// MARK: - Player | Platform
case collisionOf(.player,.exit):
let (playerNode, _) = match(contact, body: .player)
// update the saved stats
if let player = playerNode as? Player {
GameData.shared.keys = player.getStats().keys
GameData.shared.treasure = player.getStats().treasure
}
GameData.shared.level += 1
loadSceneForLevel(GameData.shared.level)
default:
break
}
}
}