0
votes
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.

1
you need to clean up your code, remove funcs that are unrelated to this question such as spawnEnemy and startNewLevel. You need to make it as easy as possible to notice what the issue might be. Secondly your second question needs to be moved to it's own question. Or better yet search stack overflow for that question, it's already been asked.Ron Myschuk
Why are you scaling your node? Do you know if the bullet is contacting the physics body, and that the physics body is indeed the correct size? Use view.showPhysics = true to see the bodiesKnight0fDragon
Alright. Added view.ShowPhysics = true. I have it figured out! Moved the func didBegin to the very bottom and apparently it worked. Not sure where the problem lies before this to be honest but the code worked for some reason :lJasonPythonBeginner
If moving to the bottom worked, then you did not provide an accurate representation of your code. You had a function inside of a function.Knight0fDragon
Alright. Thank you KnightDragon and Ron Myschuk.JasonPythonBeginner

1 Answers

0
votes

Probably had a function inside of another function as mentioned in the comment.

Added view.ShowPhysics = true. Moved the func didBegin to the very bottom and apparently it worked.