How to make an enemy have stamina with swift's spritekit


In this article, I will introduce some of the points I stumbled upon in the process of creating a shooting game in swift, as well as some of the code I struggled to find out.
The article focuses on spritekit, a framework used to create games in swift.

In this article, I will write about how to set the strength of an enemy sprite in spritekit. I was able to find out how to delete sprite nodes that were hit by collisions in books and on the net, but I couldn't find anything about enemy stamina, so I finally found a solution on a foreign forum.

I made this game.

First of all, I would like to invite you to play my shooting game and see how I implemented it. It is a 2D vertical scrolling shmups with 6 stages.

It is running on xcode 12.5 and swift 5.4, so I think this code will work for a while.

Using SKSpriteNode's userData

SKSpriteNode has a very useful container called userData.
The second line from the bottom is that part.
(I'm going to assume that you can implement hit detection and so on.)

let enemy = SKSpriteNode(imageNamed: "enemy")   //Create an enemy sprite node.
//collision detection
enemy.physicsBody = SKPhysicsBody(circleOfRadius: enemy.frame.width / 2) //Use a circle half the size of the enemy's image to make a hit decision.
enemy.physicsBody?.categoryBitMask = enemyCategory //Enemy's own bit mask
enemy.physicsBody?.contactTestBitMask = fireCategory + jikiCategory //A shot of your ship and your own bit mask
enemy.physicsBody?.collisionBitMask = 0

//Define physical strength.
enemy.userData = ["health":10]  //Assign 10 to the name health
self.addChild(enemy) //Define the enemy as the current scene.

After entering the stats in the userData, call the function (func didBegin, etc.) from the required location (in this case, named Damage) to reduce the stats and save them in the enemy's userData again. If the enemy's health drops below 0, the node is deleted.

func Damage(){
//damage handling
var enemyLife = (enemy.userData!["health"] as! Int) //Extract the number from the enemy's "health" and assign it to the enemyLife as an Int type.
enemyLife -= 1  //1 deducted as damage

enemy.userData?.setValue(enemyLife, forKey: "health") //Assign the value of enemyLife to enemy as the current health.

//Handling enemy deaths
if enemyLife <= 0 {
                enemy.removeFromParent()  //Delete enemy node


Now you can set the enemy's stats.
Since userData can contain multiple elements, I put in the number of score points for defeating enemies, the number of items they produce, etc., in addition to enemy stats, as shown below, and refer to them when necessary.

Also, since it can contain not only numbers but also bool types, I use it to determine whether or not to process different effects upon death.

enemy.userData = ["health":60,"score":100,"point":2,"effect":true]

There may be other ways to do enemy stats, but this is how I created my game.
Please give it a try.