How to Make a Game Like Monster Island Tutorial
Learn how to make a game like Monster Island. By Brian Broom.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
How to Make a Game Like Monster Island Tutorial
30 mins
- Getting Started
- Creating the Projectile
- Throwing the Beaker
- Adding the Explosion Animation
- Animate the Explosion
- Setting the Explosion Range
- Making Sprites React
- Power Meter
- Accessing the Power Meter From Code
- Updating the Meter
- Throwing With the Correct Impulse
- Win or Lose
- Finishing Touches
- Where to Go From Here?
Update 10/7/16: This tutorial has been updated for Xcode 8 and Swift 3.
Update 10/7/16: This tutorial has been updated for Xcode 8 and Swift 3.
In this how to make a game like Monster Island tutorial, you will level up your knowledge of the SpriteKit physics system by creating a game named ZombieCat. Your goal as a zombie, is to defeat evil cats by throwing beakers of zombie goo at them—turning them into zombie cats. To do that, you’ll implement one of the major UI features of Monster Island: A large power meter showing the strength and direction of your throw.
Zombies AND cats—what could be better!
In case you’ve never played it, Monster Island is a fun physics-based puzzle game by Miniclip in which you defeat monsters by flinging bombs at them.
If you haven’t used Apple’s SpriteKit framework before, check out Sprite Kit Swift 2 Tutorial for Beginners. This tutorial assumes you’re familiar with actions, the physics system and the scene editor.
Let’s dive in!
Getting Started
This project uses Swift 3 and requires, at a minimum, Xcode beta 4. Once you have that, go ahead and download a copy of the starter project, and look through it.
Open GameScene.sks to see the basic elements of a physics puzzle level already set up.
The walls, cats and obstacles all have physics bodies defined for them, as well as their Category Mask values set in the Attributes Inspector.
Creating the Projectile
At this point, all you can do in the game is watch the cats quietly plotting to take over the world. Scary, right? You need a way to fight back. That way, of course, is zombie goo. :]
In GameScene.swift, add these properties just before didMove(to:)
var pinBeakerToZombieArm: SKPhysicsJointFixed?
var beakerReady = false
Add a method to create the node for your beaker of goo.
func newProjectile () {
let beaker = SKSpriteNode(imageNamed: "beaker")
beaker.name = "beaker"
beaker.zPosition = 5
beaker.position = CGPoint(x: 120, y: 625)
let beakerBody = SKPhysicsBody(rectangleOf: CGSize(width: 40, height: 40))
beakerBody.mass = 1.0
beakerBody.categoryBitMask = PhysicsType.beaker
beakerBody.collisionBitMask = PhysicsType.wall | PhysicsType.cat
beaker.physicsBody = beakerBody
addChild(beaker)
if let armBody = childNode(withName: "player")?.childNode(withName: "arm")?.physicsBody {
pinBeakerToZombieArm = SKPhysicsJointFixed.joint(withBodyA: armBody, bodyB: beakerBody, anchor: CGPoint.zero)
physicsWorld.add(pinBeakerToZombieArm!)
beakerReady = true
}
}
Add the following line to didMove(to:)
:
newProjectile()
This is a fairly standard example of creating a new SKSpriteNode
, setting its properties, adding a SKPhysicsBody
and adding it to the scene. Two properties you might not be familiar with are categoryBitMask
and collisionBitMask
. These mask values are how the physics system identifies which sprites interact with each other.
Each physics body has a categoryBitMask
property you set to one of the values defined in the PhysicsType
struct located at the top of GameScene.swift. Sprites will only collide with or bounce off objects where the categoryBitMask
matches the other object’s collisionBitMask
.
The beaker is attached to the zombie with a SKPhysicsJoint
. A fixed joint keeps two physics bodies in the same relative position. In this case, the beaker will move with the arm body, until the joint is removed.
Note: The physics simulation uses two types of body interactions, collision and contact.
Collision: In this type of interaction, the two sprites bounce off of each other like a ball off a wall. The physics simulation automatically takes care of the collision calculation, so you don’t have to deal with angles or differences in mass.
Contact: This interaction alerts you when two objects touch or overlap. The moving object will continue to move through the other object, unless you change its motion manually. You’d use contacts to be informed when an event happens, such as a ball crossing a goal line, without changing the object’s motion.
Note: The physics simulation uses two types of body interactions, collision and contact.
Collision: In this type of interaction, the two sprites bounce off of each other like a ball off a wall. The physics simulation automatically takes care of the collision calculation, so you don’t have to deal with angles or differences in mass.
Contact: This interaction alerts you when two objects touch or overlap. The moving object will continue to move through the other object, unless you change its motion manually. You’d use contacts to be informed when an event happens, such as a ball crossing a goal line, without changing the object’s motion.
For more details about these interactions, or bit masks in general, the Making Contact section of How To Create a Breakout Game with Sprite Kit and Swift gives a great explanation.
Build and run to see your new beaker of zombie goo. You’re almost ready to attack those cats!
Throwing the Beaker
Now that you’ve got the beaker in the game, you need to be able to use it as a weapon.
To throw the beaker, all you have to do is remove the SKSKPhysicsJointFixed
and give it an impulse in the physics system. An impulse is like a kick, represented by a vector that has both an X and a Y component.
Add the following methods to GameScene.swift:
func tossBeaker(strength: CGVector) {
if beakerReady == true {
if let beaker = childNode(withName: "beaker") {
if let arm = childNode(withName: "player")?.childNode(withName: "arm") {
let toss = SKAction.run() {
self.physicsWorld.remove(self.pinBeakerToZombieArm!)
beaker.physicsBody?.applyImpulse(strength)
beaker.physicsBody?.applyAngularImpulse(0.1125)
self.beakerReady = false
}
let followTrough = SKAction.rotate(byAngle: -6*3.14, duration: 2.0)
arm.run(SKAction.sequence([toss, followTrough]))
}
// explosion added later
}
}
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
tossBeaker(strength: CGVector(dx: 1400, dy: 1150))
}
When using the physics system, you change the motion of a sprite through its physics body, not the sprite itself. SKPhysicsBody
has two methods you could use to throw the beaker, applyForce
and applyImpulse
. Since you want the change to be instantaneous, use applyImpulse
. Usually, thrown objects spin while in the air, and applyAngularImpulse
simulates that. You can adjust the angular impulse to get the desired amount of spin, or even change its direction by using a negative number.
Don’t forget to remove the SKPhysicsJoint
, or the beaker will stay attached to the zombie hand.
Build and run the game. When you tap on the screen, the beaker should fly around. Notice how the beaker bounces off of the walls and cats.
But despite all that spinning and bouncing, there’s no explosion. For that, you need the explosion effect.