Moving Platforms with Matter Physics in Phaser 3

Learn how to create this popular feature of platformers

by on 5 minute read


Are you working on a side-scrolling platformer in Phaser 3 using Matter Physics?

And are you having trouble implementing moving platforms? Ones that can be used as elevators or add some extra challenge to horizontal jumps?

Matter has some quirks that can make creating moving platforms a frustrating experience.

That's where this article comes in! We'll show you how to create moving platforms that can carry the player up and down or across pits.

Example Set-Up

We'll be using modern JavaScript in this example as well as platformer assets from Kenney.

If you are not familiar with using modern JavaScript with Phaser 3 then we have a free book to help you get started!

Learn to make an Infinite Jumper in Phaser 3 with modern JavaScript!

Drop your email into the box below to get this free 60+ page book and join our newsletter.

Learn more about the book here.

Our focus will be on implementing a MovingPlatform class that can move vertically or horizontally. We assume that you already have a working player character that can run and jump.

The MovingPlatform Class

First, let's create a barebones MovingPlatform class that extends from Phaser.Physics.Matter.Image:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
import Phaser from 'phaser'

export default class MovingPlatform extends Phaser.Physics.Matter.Image
{
	/**
	 * 
	 * @param {Phaser.Scene} scene 
	 * @param {number} x 
	 * @param {number} y 
	 * @param {string} texture 
	 * @param {Phaser.Types.Physics.Matter.MatterBodyConfig} options 
	 */
	constructor(scene, x, y, texture, options)
	{
		super(scene.matter.world, x, y, texture, 0, options)

		scene.add.existing(this)
	}
}

Next, let's create an instance of this class in our Scene.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// import the class at the top
import MovingPlatform from './MovingPlatform'

// Scene's create method
create()
{
	// other code...

	this.platform = new MovingPlatform(this, 500, 500, 'platform', {
		isStatic: true
	})
}

The key here is that we need to make the platform static by passing in isStatic: true as the MatterBodyConfig.

A static body will not move or be affected by gravity but it will collide with other non-static bodies in the world. This will allow us to manually move the platform up and down or left and right.

In most platformers, a moving platform travels a predefined distance and then returns. It is much simpler to control the platform's movement manually than to adjust the velocity depending on where the platform should travel to.

Moving the Platform Vertically

Phaser comes with a tween system that can be used to move our platform up and down over time with easing.

Let's add the logic by creating this moveVertically() method to the MovingPlatform class:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
moveVertically()
{
	this.scene.tweens.addCounter({
		from: 0,
		to: -300,
		duration: 1500,
		ease: Phaser.Math.Easing.Sine.InOut,
		repeat: -1,
		yoyo: true,
		onUpdate: (tween, target) => {
			const y = this.startY + target.value
			const dy = y - this.y
			this.y = y
			this.setVelocityY(dy)
		}
	})
}

Notice that we are using addCounter(). This will tween a number from 0 to -300 as specified on lines 4 and 5. We then use the tweened value in the onUpdate callback.

Setting this.y and then setting the y velocity is important. Other bodies on the platform will not move with it unless the velocity is set.

We also set yoyo to true and repeat to -1 so that it will move up then back down and loop forever.

An additional class property named startY was created and it should be set to the initial y value in the constructor:

1
2
3
4
5
6
7
8
constructor(scene, x, y, texture, options)
{
	super(scene.matter.world, x, y, texture, 0, options)

	scene.add.existing(this)
	
	this.startY = y
}

Try out the vertically moving platform by calling moveVertically() after creating the platform.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// Scene's create method
create()
{
	// other code...

	this.platform = new MovingPlatform(this, 500, 500, 'platform', {
		isStatic: true
	})

	this.platform.moveVertically()
}

You should get something that works like this:

Moving the Platform Horizontally

Now that we have vertical movement, let's implement horizontal movement.

The basic concepts will be the same except we have to adjust the platform's friction or bodies on the platform may not stay there as it moves.

Adjust the platform's friction in the constructor:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
constructor(scene, x, y, texture, options)
{
	super(scene.matter.world, x, y, texture, 0, options)

	scene.add.existing(this)

	this.setFriction(1, 0, Infinity)

	this.startX = x
	this.startY = y
}

Notice the call to setFriction() where we pass in Infinity for the staticFriction argument.

We also created a class property named startX to store the initial x value on line 9.

Next, let's add a moveHorizontally() method:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
moveHorizontally()
{
	this.scene.tweens.addCounter({
		from: 0,
		to: -300,
		duration: 1500,
		ease: Phaser.Math.Easing.Sine.InOut,
		repeat: -1,
		yoyo: true,
		onUpdate: (tween, target) => {
			const x = this.startX + target.value
			const dx = x - this.x
			this.x = x
			this.setVelocityX(dx)
		}
	})
}

This method is almost identical to moveVertically() except we adjust this.x and the x velocity for horizontal movement.

Try it out by calling moveHorizontally() after creating the platform.

Next Steps

You can add duration or distance parameters to the moveVertically() and moveHorizontally() methods to allow different platforms to move at different speeds and distances.

Feel free to play with the ease property to get a different type of movement.

With the techniques from this article, you should be able to make diagonally moving platforms as well!

Be sure to sign up for our newsletter so you don't miss any future Phaser 3 game development tips and techniques!

Drop your email into the box below.

Don't miss any Phaser 3 game development content

Subscribers get exclusive tips & techniques not found on the blog!

Join our newsletter. It's free. We don't spam. Spamming is for jerks.

Phaser 3 physics matter matterjs matter physics platformer platforms

Want tips and techniques more suited for you?


You may also like...


Video Guides


Beginner Guides


Articles Recommended For You

How to Load Images Dynamically in Phaser 3

by on

Does your game have a lot of images that not every player sees? Maybe a collectible card game? Loading those images …

6 minute read

Fix Stretched Image Distortions in Phaser 3 with 9-Slice Scaling

by on

Are you having image distortion problems when scaling to make a button or panel graphic bigger? Multiple versions of the …

5 minute read

Command Pattern to Undo Player Actions

by on

Are you looking for a clean and reusable way to implement undo for player actions? Perhaps you are making a turn-based …

15 minute read

Advanced Logging with the Strategy Pattern

by on

Have you ever tried debugging a problem with your game that only seems to happen in production? The Developer Tools …

7 minute read

Didn't find what you were looking for?


comments powered by Disqus