Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
bb6e329
Update lesson 1 "Initialize the framework" to Phaser 3.90 (except for…
igrep Jul 13, 2025
ccb6b7f
Forgot to update the URL to the example
igrep Jul 13, 2025
d3ae4c6
Update lesson 2 "Scaling" to Phaser 3.90 (except for the live sample)
igrep Jul 13, 2025
4064490
Update lesson 3 "Load the assets and print them on screen" to Phaser …
igrep Jul 15, 2025
d3e834a
Update lesson 4 "Move the ball" to Phaser 3.90 (except for the live s…
igrep Jul 16, 2025
6c4d861
Update lesson 5 "Physics" to Phaser 3.90 (except for the live sample)
igrep Jul 17, 2025
cda4007
Update lesson 6 "Bounce off the walls" to Phaser 3.90 (except for the…
igrep Jul 19, 2025
3a1c01e
(WIP) Update lesson 7 "Player paddle and controls" to Phaser 3.90
igrep Jul 20, 2025
3deac1b
Update lesson 7 "Player paddle and controls" to Phaser 3.90 except fo…
igrep Jul 21, 2025
19a5a93
Update the live sample in lesson 7 "Player paddle and controls" to Ph…
igrep Jul 21, 2025
5eadc1e
Correct the path to the assets in the live sample
igrep Jul 23, 2025
753cf50
Update lesson 8 "Game over" to Phaser 3.90
igrep Jul 23, 2025
0ce3ffd
Update lesson 9 "Build the brick field" to Phaser 3.90
igrep Jul 26, 2025
083a83a
Update lesson 10 "Collision detection" to Phaser 3.90
igrep Jul 26, 2025
a557f4b
Update lesson 11 "The score" to Phaser 3.90
igrep Jul 26, 2025
3014535
Modify lesson 11 "The score" to Phaser 3.90
igrep Jul 26, 2025
32d2919
Modify lesson 11 "The score" to Phaser 3.90
igrep Jul 26, 2025
6429f21
Modify lesson 12 "Win the game" to Phaser 3.90
igrep Jul 26, 2025
14b3dcd
(WIP) Modify lesson 13 "Extra lives" to Phaser 3.90
igrep Jul 27, 2025
5b37cab
Modify lesson 13 "Extra lives" to Phaser 3.90
igrep Jul 28, 2025
e40e328
Modify lesson 14 "Extra lives" to Phaser 3.90
igrep Jul 28, 2025
b3e64ab
(WIP) Modify lesson 15 "Buttons" to Phaser 3.90
igrep Jul 29, 2025
59be5d9
Modify lesson 15 "Buttons" to Phaser 3.90
igrep Jul 31, 2025
26ec9c4
Modify lesson 16 "Randomizing gameplay" to Phaser 3.90
igrep Jul 31, 2025
4ef696f
Migrate all the lessons to live sample from JSFiddle
igrep Jul 31, 2025
a5e4b71
Fix syntax errors in the example code and several parts I forgot to fix
igrep Aug 1, 2025
854560b
Apply formatter
igrep Aug 2, 2025
a186193
Updates
Josh-Cena Aug 2, 2025
16fdcc0
Fix grammar
Josh-Cena Aug 2, 2025
3287b45
Final tweaks
Josh-Cena Aug 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Fix syntax errors in the example code and several parts I forgot to fix
  • Loading branch information
igrep committed Aug 1, 2025
commit a5e4b714a1f67c69345763d0828e9da331a577f5
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,26 @@ To add an animation to the object we use the `anims.create` method, which receiv
In the `physics.collide` method call that handles the collision between the ball and the paddle (the first line inside `update`, see below), we can add an extra parameter that specifies a function to be executed every time the collision happens, in the same fashion as the `hitBrick` method. Update the first line inside `update()` as shown below:

```js
update () {
this.physics.collide(this.ball, this.paddle, this.hitPaddle.bind(this));
this.physics.collide(this.ball, this.bricks, this.hitBrick.bind(this));
this.paddle.x = this.input.x || this.scale.width * 0.5;
class Example extends Phaser.Scene {
// ...
update() {
this.physics.collide(this.ball, this.paddle, this.hitPaddle.bind(this));
this.physics.collide(this.ball, this.bricks, this.hitBrick.bind(this));
this.paddle.x = this.input.x || this.scale.width * 0.5;
}
// ...
}
```

Then, we can create the `hitPaddle` method (having `ball` and `paddle` as default parameters), playing the wobble animation when it is called. Add the following method just before your closing brace `}` of the `Example` class:

```js
hitPaddle (ball, paddle) {
this.ball.anims.play('wobble');
class Example extends Phaser.Scene {
// ...
hitPaddle(ball, paddle) {
this.ball.anims.play("wobble");
}
// ...
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@ The `bricks` property will be used to create a group of bricks, which will make
Next, let's load the image of the brick — add the following `load.image()` call just below the others:

```js
preload () {
class Example extends Phaser.Scene {
// ...
preload() {
// ...
this.load.image("brick", "img/brick.png");
}
// ...
this.load.image('brick', 'img/brick.png');
}
```

Expand All @@ -43,29 +47,37 @@ You also need to [grab the brick image from GitHub](https://github.com/igrep/2D_
We will place all the code for drawing the bricks inside an `initBricks` method to keep it separated from the rest of the code. Add a call to `initBricks` at the end of the `create` method:

```js
create () {
class Example extends Phaser.Scene {
// ...
create() {
// ...
this.initBricks();
}
// ...
this.initBricks();
}
```

Now onto the method itself. Add the `initBricks` method at the end of the `Example` class, just before the closing brace `}`, as shown below. To begin with, we add the `bricksLayout` object, as this will come in handy very soon:

```js
initBricks () {
const bricksLayout = {
width: 50,
height: 20,
count: {
row: 3,
col: 7,
},
offset: {
top: 50,
left: 60,
},
padding: 10,
};
class Example extends Phaser.Scene {
// ...
initBricks() {
const bricksLayout = {
width: 50,
height: 20,
count: {
row: 3,
col: 7,
},
offset: {
top: 50,
left: 60,
},
padding: 10,
};
}
// ...
}
```

Expand Down Expand Up @@ -121,35 +133,41 @@ Each `brickX` position is worked out as `bricksLayout.width` plus `bricksLayout.
Here is the complete code for the `initBricks()` function:

```js
initBricks () {
const bricksLayout = {
width: 50,
height: 20,
count: {
row: 3,
col: 7,
},
offset: {
top: 50,
left: 60,
},
padding: 10,
};

this.bricks = this.add.group();
for (let c = 0; c < bricksLayout.count.col; c++) {
for (let r = 0; r < bricksLayout.count.row; r++) {
const brickX =
c * (bricksLayout.width + bricksLayout.padding) + bricksLayout.offset.left;
const brickY =
r * (bricksLayout.height + bricksLayout.padding) + bricksLayout.offset.top;

const newBrick = this.add.sprite(brickX, brickY, "brick");
this.physics.add.existing(newBrick);
newBrick.body.setImmovable(true);
this.bricks.add(newBrick);
class Example extends Phaser.Scene {
// ...
initBricks() {
const bricksLayout = {
width: 50,
height: 20,
count: {
row: 3,
col: 7,
},
offset: {
top: 50,
left: 60,
},
padding: 10,
};

this.bricks = this.add.group();
for (let c = 0; c < bricksLayout.count.col; c++) {
for (let r = 0; r < bricksLayout.count.row; r++) {
const brickX =
c * (bricksLayout.width + bricksLayout.padding) +
bricksLayout.offset.left;
const brickY =
r * (bricksLayout.height + bricksLayout.padding) +
bricksLayout.offset.top;

const newBrick = this.add.sprite(brickX, brickY, "brick");
this.physics.add.existing(newBrick);
newBrick.body.setImmovable(true);
this.bricks.add(newBrick);
}
}
}
// ...
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,14 @@ First, we call `setInteractive` on the button to make it respond to pointer even
Now, we need to define the `startGame` method referenced in the code above:

```js
startGame () {
this.startButton.destroy();
this.ball.body.setVelocity(150, -150);
this.playing = true;
class Example extends Phaser.Scene {
// ...
startGame() {
this.startButton.destroy();
this.ball.body.setVelocity(150, -150);
this.playing = true;
}
// ...
}
```

Expand All @@ -117,10 +121,14 @@ Finally for this section, go back into your `create` method, find the `this.ball
It works as expected, but we can still move the paddle when the game hasn't started yet, which looks a bit silly. To stop this, we can take advantage of the `playing` variable and make the paddle movable only when the game has started. To do that, adjust the `update` function like so:

```js
update () {
class Example extends Phaser.Scene {
// ...
if (this.playing) {
this.paddle.x = this.input.x || this.scale.width * 0.5;
update() {
// ...
if (this.playing) {
this.paddle.x = this.input.x || this.scale.width * 0.5;
}
// ...
}
// ...
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,26 @@ Now onto the next challenge — the collision detection between the ball and the
The physics engine makes everything a lot easier — we just need to add two simple pieces of code. First, add a new line inside your `update` method that detects a collision between the ball and bricks, as shown below:

```js
function update() {
this.physics.collide(this.ball, this.paddle);
this.physics.collide(this.ball, this.bricks, this.hitBrick);
paddle.x = game.input.x || game.world.width * 0.5;
class Example extends Phaser.Scene {
// ...
update() {
this.physics.collide(this.ball, this.paddle);
this.physics.collide(this.ball, this.bricks, this.hitBrick);
paddle.x = game.input.x || game.world.width * 0.5;
}
// ...
}
```

The ball's position is calculated against the positions of all the bricks in the group. The third, optional parameter is the function executed when a collision occurs — `hitBrick`. Create this new function as the last method of the `Example` class, just before the closing brace `}`, as follows:

```js
hitBrick (ball, brick) {
brick.destroy();
class Example extends Phaser.Scene {
// ...
hitBrick(ball, brick) {
brick.destroy();
}
// ...
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,20 +115,28 @@ if (ballIsOutOfBounds) {
We want to decrease the number of lives every time the ball leaves the canvas. Add the `ballLeaveScreen()` method definition at the end of the `Example` class:

```js
ballLeaveScreen () {
this.lives--;
if (this.lives > 0) {
this.livesText.setText(`Lives: ${this.lives}`);
this.lifeLostText.visible = true;
this.ball.body.reset(this.scale.width * 0.5, this.scale.height - 25);
this.input.once("pointerdown", () => {
this.lifeLostText.visible = false;
this.ball.body.setVelocity(150, -150);
}, this);
} else {
alert("Game over!");
location.reload();
class Example extends Phaser.Scene {
// ...
ballLeaveScreen() {
this.lives--;
if (this.lives > 0) {
this.livesText.setText(`Lives: ${this.lives}`);
this.lifeLostText.visible = true;
this.ball.body.reset(this.scale.width * 0.5, this.scale.height - 25);
this.input.once(
"pointerdown",
() => {
this.lifeLostText.visible = false;
this.ball.body.setVelocity(150, -150);
},
this,
);
} else {
alert("Game over!");
location.reload();
}
}
// ...
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ ball;
Loading images and printing them on our canvas is a lot easier using Phaser than using pure JavaScript. To load the asset, we will use the `Phaser.Scene`'s `load.image` method, available as `this.load.image`. Add the following new line just the `preload()` method:

```js
preload () {
this.load.image('ball', 'img/ball.png');
class Example extends Phaser.Scene {
// ...
preload() {
this.load.image("ball", "img/ball.png");
}
// ...
}
```

Expand All @@ -36,8 +40,12 @@ Of course, to load the image, it must be available in our code directory. [Grab
Now, to show it on the screen we will use another `Phaser.Scene`'s method called `add.sprite`; add the following new line inside the `create()` method:

```js
create () {
this.ball = this.add.sprite(50, 50, 'ball');
class Example extends Phaser.Scene {
// ...
create() {
this.ball = this.add.sprite(50, 50, "ball");
}
// ...
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,13 @@ this.ball.body.setVelocity(150, 150);
Remember to remove our old method of adding values to `x` and `y` from the `update` method:

```js
update () {
ball.x += 1;
ball.y += 1;
class Example extends Phaser.Scene {
// ...
update() {
ball.x += 1;
ball.y += 1;
}
// ...
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,23 @@ From the framework point of view the paddle is very similar to the ball — we n
First, add the `paddle` property we will be using in our game, right after the `ball` property:

```js
paddle;
class Example extends Phaser.Scene {
ball;
paddle;
// ...
}
```

Then, in the `preload` function, load the `paddle` image by adding the following new `load.image()` call:
Then, in the `preload` method, load the `paddle` image by adding the following new `load.image()` call:

```js
function preload() {
// …
this.load.image("ball", "img/ball.png");
this.load.image("paddle", "img/paddle.png");
class Example extends Phaser.Scene {
// ...
preload() {
this.load.image("ball", "img/ball.png");
this.load.image("paddle", "img/paddle.png");
}
// ...
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,13 @@ Our game appears to be completed, but if you look close enough you'll notice tha
We can change the ball's velocity depending on the exact spot it hits the paddle, by modifying the `x` velocity each time the `hitPaddle` method is run using a line along the lines of the below. Add this new line to your code now, and try it out.

```js
hitPaddle (ball, paddle) {
this.ball.anims.play('wobble');
ball.body.velocity.x = -5 * (paddle.x - ball.x);
class Example extends Phaser.Scene {
// ...
hitPaddle (ball, paddle) {
this.ball.anims.play('wobble');
ball.body.velocity.x = -5 * (paddle.x - ball.x);
}
// ...
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,14 @@ The last parameter looks very similar to CSS styling. In our case the score text
We will increase the number of points every time the ball hits a brick and update the `scoreText` to display the current score. This can be done using the `setText` method — add the two new lines seen below to the `hitBrick` method:

```js
hitBrick (ball, brick) {
brick.destroy();
this.score += 10;
this.scoreText.setText(`Points: ${this.score}`);
class Example extends Phaser.Scene {
// ...
hitBrick (ball, brick) {
brick.destroy();
this.score += 10;
this.scoreText.setText(`Points: ${this.score}`);
}
// ...
}
```

Expand Down
Loading
Loading