import SpriteKit
import GameplayKit
class GameScene: SKScene, SKPhysicsContactDelegate {
let player = SKSpriteNode(imageNamed: "Player")
struct PhysicsCategories {
static let None: UInt32 = 0
static let Player: UInt32 = 0b1 //1
static let Bullet: UInt32 = 0b10 //2
static let Enemy: UInt32 = 0b100 //4
}
override func didMove(to view: SKView) {
self.physicsWorld.contactDelegate = self
player.setScale(0.2)
player.position = CGPoint(x: self.size.width/2, y: self.size.height * 0.2)
player.zPosition = 2
player.physicsBody = SKPhysicsBody(rectangleOf: player.size)
player.physicsBody!.affectedByGravity = false
player.physicsBody!.categoryBitMask = PhysicsCategories.Player
player.physicsBody!.collisionBitMask = PhysicsCategories.None
player.physicsBody?.isDynamic = true
player.physicsBody!.contactTestBitMask = PhysicsCategories.Enemy
self.addChild(player)
}
func didBeginContact(contact: SKPhysicsContact) {
var body1 = SKPhysicsBody()
var body2 = SKPhysicsBody()
if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
body1 = contact.bodyA
body2 = contact.bodyB
}
else {
body1 = contact.bodyB
body2 = contact.bodyA
}
if body1.categoryBitMask == PhysicsCategories.Player && body2.categoryBitMask == PhysicsCategories.Enemy {
// if player hit enemy
if body1.node != nil {
spawnExplosion(spawnPosition: body1.node!.position)
}
if body2.node != nil {
spawnExplosion(spawnPosition: body2.node!.position)
}
body1.node!.removeFromParent()
body2.node!.removeFromParent()
}
if body1.categoryBitMask == PhysicsCategories.Bullet && body2.categoryBitMask == PhysicsCategories.Enemy {
// if bullet hit enemy
if body2.node != nil {
if body2.node!.position.y > self.size.height {
return
}
else {
spawnExplosion(spawnPosition: body2.node!.position)
}
}
body1.node!.removeFromParent()
body2.node!.removeFromParent()
}
}
func fireBullet() {
let bullet = SKSpriteNode(imageNamed: "Bullet")
bullet.setScale(0.8)
bullet.position = player.position
bullet.zPosition = 1
bullet.physicsBody = SKPhysicsBody(rectangleOf: bullet.size)
bullet.physicsBody!.affectedByGravity = false
bullet.physicsBody!.categoryBitMask = PhysicsCategories.Bullet
bullet.physicsBody!.collisionBitMask = PhysicsCategories.None
bullet.physicsBody?.isDynamic = true
bullet.physicsBody!.contactTestBitMask = PhysicsCategories.Enemy
self.addChild(bullet)
let moveBullet = SKAction.moveTo(y: self.size.height + bullet.size.height, duration: 1)
let deleteBullet = SKAction.removeFromParent()
let bulletSequence = SKAction.sequence([bulletSound, moveBullet, deleteBullet])
bullet.run(bulletSequence)
}
func spawnEnemy()
let randomxStart = randomBetweenNumbers(firstNum: 0, secondNum: frame.width)
let randomxEnd = randomBetweenNumbers(firstNum: 0, secondNum: frame.width)
let startPoint = CGPoint(x: randomxStart, y: self.size.height * 1.2 )
let endPoint = CGPoint(x: randomxEnd, y: -self.size.height * 0.2)
let Enemy = SKSpriteNode(imageNamed: "EnemyShip")
Enemy.setScale(0.2)
Enemy.position = startPoint
Enemy.zPosition = 2
Enemy.physicsBody = SKPhysicsBody(rectangleOf: Enemy.size)
Enemy.physicsBody!.affectedByGravity = false
Enemy.physicsBody!.categoryBitMask = PhysicsCategories.Enemy
Enemy.physicsBody!.collisionBitMask = PhysicsCategories.None
Enemy.physicsBody?.isDynamic = true
Enemy.physicsBody!.contactTestBitMask = PhysicsCategories.Player | PhysicsCategories.Bullet
self.addChild(Enemy)
let moveEnemy = SKAction.move(to: endPoint, duration: 1.5)
let deleteEnemy = SKAction.removeFromParent()
let enemySequence = SKAction.sequence([moveEnemy, deleteEnemy])
Enemy.run(enemySequence)
let dx = endPoint.x - startPoint.x
let dy = endPoint.y - startPoint.y
let amountToRotate = atan2(dy, dx)
let degreesToRadians = CGFloat.pi / 180
// let radiansToDegree = 180 / CGFloat.pi
Enemy.zRotation = amountToRotate - 90 * degreesToRadians
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
fireBullet()
}
}
So I'm just beginning to learn SpriteKit and Swift through building simple game. The code is to build space invader-like game. I am stuck on Contact Reporting part of the code where bullet and enemy get deleted on contact / enemy and player get deleted on contact.
I have set up the Physics Body of Player, Enemy, Bullet. Seen some StackOverFlow question on similar issue and put in isDynamic = true. Put in the ifBeginContact -> removeFromParent but currently I don't know why, the enemy does not get deleted when hit by a bullet. I have left the essential code in. Please help.
view.showPhysics = true
to see the bodies – Knight0fDragon