# Popfizz Week5 exploring Phaser.io example1
New example for next week research
https://mozdevs.github.io/html5-games-workshop/en/guides/platformer/start-here/
## Main concepts
### Javascript
#### - Basic tag(h1, div, p)
#### - Script tag
#### - JS classes(&keyword this)
#### - Function/method
#### - If else condition
#### - A little bit of DOM/ styling
#### - Concept of Framework
### Phaser
#### - Create scene
#### - Sprite
#### - Add a player
#### - Text(score)
#### - Keyboard control
#### - Collision
#### - Tween
## INSTRUCTIONS
Based on tutorial by Lesscake.com
(https://www.lesscake.com/phaser-game-tutorial)
### Setup
* Add "index.html". This will display our game.
* Add "game.js". This will have our Javascript code.
~~* Make a directory called "assets" containing 2 sprites.~~
- [ ] (---> Is adding assets possible in our editor?)

### Display the game
* Let's start with the index.html file.

* Add title, h1 and p tag.
```
<h1>My First Phaser Game</h1>
<p>Direction: Use the arrow keys to move around and collect the coins.</p>
```
* Then, let's add script tag to load Phraser.io framework inside `<head>` tag.
```
<script src="https://cdn.jsdelivr.net/npm/phaser@3.14.0/dist/phaser.min.js"></script>
```
* Add another script tag, `game.js` (our file).
```
<script src="game.js"></script>
```
* Lastly, add `<div id="game">` element inside the `<body>` tag, that's where the game will appear.
---
#### Final display for HTML
```
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>My First Phaser Game</title>
<script src="https://cdn.jsdelivr.net/npm/phaser@3.14.0/dist/phaser.min.js"></script>
<script src="game.js"></script>
</head>
<body>
<h1>My First Phaser Game</h1>
<div id="game"></div>
<p>Use the arrow keys to move around and collect the coins.</p>
</body>
</html>
```
---
### Create a scene
* Create our scene called mainScene, in the game.js file.
```
class mainScene {
}
```
Inside, we will add 3 methods. They are key to how Phaser works.
* Add `preload(){}` inside the `class`. This method is called once at the beginning and it will load all the assets, like sprites and sounds.
* Add `create(){}` inside the `class`. This method is called once, just after `preload(){}`. It will initialize our scene, like the positions of the sprites.
* Add `update(){}` inside the `class`. This method is called 60 times per second after create(){}. It will handle all the game's logic, like movements.
Eventually, it will look like this.
```
class mainScene {
preload() {
}
create() {
}
update() {
}
}
```
To summarize, these 3 methods will be called in this order: preload() → create() → update() → update() → update() → etc.
---
#### Final display for Create a scene
```
class mainScene {
preload() {
}
create() {
}
update() {
}
}
```
---
### Start the game
Now that our scene is created, it's time to start the game. For that we call `Phaser.Game()` at the end of the Javascript file. There are a lot of optional parameters available, but here are the main ones.
* Let's pass width and height property as a parameter. `width`, `height` property assign the size of the scene. `backgroundColor` property is the background color of the game scene.
```
new Phaser.game({
width: 700,
height: 400,
backgroundColor: '#3498db'
});
```
You can try different size/color by chaning these properties' values.
* Now, we will include `scene` property as a parameter which refers to the `class mainScene {}` we just created for our game.
```
new Phaser.Game({
width: 700,
height: 400,
backgroundColor: '#3498db',
scene: mainScene
});
```
* Add `physics` property as a parameter. Although we are not going to use physics in this project, it is a great method we can use in Phraser.io framework in the future. For now, we will leave it as 'arcade'.
```
new Phaser.Game({
width: 700,
height: 400,
backgroundColor: '#3498db',
scene: mainScene,
physics: { default: 'arcade' }
});
```
* Lastly, `parent` property will create the game inside the `<div id="game">`, the element we wrote inside `index.html` previously.
```
new Phaser.Game({
width: 700,
height: 400,
backgroundColor: '#3498db',
scene: mainScene,
physics: { default: 'arcade' },
parent: 'game'
});
```
---
#### Final display for Start the game
```
new Phaser.Game({
width: 700,
height: 400,
backgroundColor: '#3498db',
scene: mainScene,
physics: { default: 'arcade' },
parent: 'game'
});
```
---
### Test the game
It's a good time to test what we did so far. Click 'Open new brower' and check our scene we just created.

### Add the player
Let's add the player in the game scene.

First, we should load the player sprite. Since we are loading an asset, we have to do it in the preload() method.
* Add this element inside `preload()` method.
```
this.load.image('player', 'assets/player.png');
```
We use two parameters here. Name of the sprite, `'player'` and `'assets/player.png'`as a path of the image.
Now that we load the sprite, it is time to show the sprite on the screen. This is part of the initialization of the scene, not the preloading our assets. So we do that in the `create()` method.
* Let's place player element in `create()` method.
```
this.player = this.physics.add.sprite(100, 100, 'player');`
```
Here, we used three parameters to place the sprite. x position `100`, y position `100`, name of the sprite `'player'`.
There are 3 interesting things to mention here:
1. The player is stored in the this.player variable, which is accessible in all methods of the class.
1. We typed this.physics to create the player. It means that we are using the physics engine on the sprite, and that will make handling collisions super easy later on.
1. If we set the player's position to x = 0 and y = 0, then it would have been displayed in the top left corner of the screen.
Let's run the code and check whether it is placed.
### Add the coin

Next, we will add a yellow coin that the player can catch. The process is going to be very similar to what we did previously.
* First let's load the image of the coin inside `preload()`.
```
this.load.image('coin', 'assets/coin.png');
```
* Then, we show the coin on the screen inside `create()`
```
this.coin = this.physics.add.sprite(300, 300, 'coin');
```
---
#### Final display for `preload()`
```
preload() {
this.load.image('player', 'https://lh3.googleusercontent.com/mDLdWcNTAWvwl9FE6sFfy0Vs13qshqpc64e8WX2dcXBLHa_hvdMhYBuwTYcyz497fiOm9A=s25');
this.load.image('coin', 'https://lh3.googleusercontent.com/U316QAhyimg-17B09dO_Ybnde1GlGIVenMM8fSkc7asjEB7DMzxrB7ELsKXjBEkYKxoB61w=s15')
}
```
---
### Add the score

The last element that is missing from our game is a score. Since there are no assets to load, we put this code directly in the `create()` method.
* Let's store the score in a variable, initialized at 0
```
this.score = 0;
```
* Let's change the style of the text. We will create a style variable, and assign font size, font-family and color of the sprite.
```
let style = { font: '20px Arial', fill: '#fff' };
```
* Now, let place the score in the top left corner
```
this.scoreText = this.add.text(20, 20, 'score: ' + this.score, style);
```
Let's look at parameter inside this `scoreText` element closely.
> x position `20`
y position `20`
text `'score: ' + this.score`
style: As we declare variable `let style = { font: '20px Arial', fill: '#fff' }`
, this parameter points to the `style` variable that we created beforehand.
#### Final display for `create()`
```
create() {
//Add player
this.player = this.physics.add.sprite(100, 100, 'player');
this.coin = this.physics.add.sprite(300, 300, 'coin');
//Add the score
this.score = 0;
let style = { font: '20px arial', fill: '#fff'};
this.scoreText= this.add.text(20, 20, 'score: ' + this.score, style);
}
```
Now all the elements of the game are here, but the player is stuck on the screen. How can we make the player move around?
### Move the player
In order to move the player around, we have to tell Phaser that we want the arrow keys as inputs. For that, we type this line in the `create()` method.
```
this.arrow = this.input.keyboard.createCursorKeys();
```
With this new variable we can check which arrow key is pressed, and change the player's position accordingly.
To be able to move the player at any time, we put the following code in the `update()` method that is called 60 times per second.
* Add this code to Handle horizontal movements
```
if (this.arrow.right.isDown) {
// if arrow right key is isDown(pressed), move +3
this.player.x += 3;
} else if (this.arrow.left.isDown) {
// if arrow right key is isDown(pressed), move -3
this.player.x -= 3;
}
```
* Do the same for vertical movements
```
if (this.arrow.down.isDown) {
this.player.y += 3;
} else if (this.arrow.up.isDown) {
this.player.y -= 3;
}
```
---
#### Final display
```
create() {
//Add player
this.player = this.physics.add.sprite(100, 100, 'player');
this.coin = this.physics.add.sprite(300, 300, 'coin');
//Add the score
this.score = 0;
let style = { font: '20px arial', fill: '#fff'};
this.scoreText= this.add.text(20, 20, 'score: ' + this.score, style);
// Handle movements
this.arrow = this.input.keyboard.createCursorKeys();
}
update() {
//Keyboard controll
if (this.arrow.right.isDown) {
this.player.x += 3;
} else if (this.arrow.left.isDown) {
this.player.x -= 3;
}
if (this.arrow.down.isDown) {
this.player.y += 3;
} else if (this.arrow.up.isDown) {
this.player.y -= 3;
}
}
```
---
### Handle collisions
Every time the player touches the coin, we would like to move the coin to a random position and increment the score by 10. So let's code all of that in a new method called `hit()`.
* Let's creat new method `hit()` below the `update()` method.
```
hit() {
}
```
Whenever the player touches the coin, we want the other coin is generated in a random position. In this case, we can use `Phaser.Math.Between(x position, y position)`.
* So we will add this element inside the `hit()` method.
```
this.coin.x = Phaser.Math.Between(100, 600);
this.coin.y = Phaser.Math.Between(100, 300);
```
* Also, we want to increment score by 10. This will be acheived by += operators.
```
this.score += 10;
```
* Lastly, incremented score will be updated on the screen by adding `this.scoreText.setText()`
```
this.scoreText.setText('score: ' + this.score);
```
Finally, we will see the method hit() looks like this.
```
hit() {
this.coin.x = Phaser.Math.Between(100, 600);
this.coin.y = Phaser.Math.Between(100, 300);
this.score += 10;
this.scoreText.setText('score: ' + this.score);
}
```
We need to call `hit()` whenever the player and the coin overlap. But how do we know when that happens? It's very simple with Phaser's built in physics engine, we just put this code at the beginning of `update()`.
```
// If the player is overlapping with the coin
if (this.physics.overlap(this.player, this.coin)) {
// Call the new hit() method
this.hit();
}
```
---
#### Final display for `update()/hit()`
```
update() {
//Keyboard controll
if (this.arrow.right.isDown) {
this.player.x += 3;
} else if (this.arrow.left.isDown) {
this.player.x -= 3;
}
if (this.arrow.down.isDown) {
this.player.y += 3;
} else if (this.arrow.up.isDown) {
this.player.y -= 3;
}
//Handle collisions
if (this.physics.overlap(this.player, this.coin)) {
this.hit();
}
}
hit() {
// Change the position x and y of the coin randomly
this.coin.x = Phaser.Math.Between(100, 600);
this.coin.y = Phaser.Math.Between(100, 300);
// Increment the score by 10
this.score += 10;
// Display the updated score on the screen
this.scoreText.setText('score: ' + this.score);
// Create a new tween
this.tweens.add({
targets: this.player,
duration: 500,
scaleX: 1.2,
scaleY: 1.2,
yoyo: true,
});
}
```
---
### Advanced collisions with a tween
Right now when grabbing a coin, the only thing that changes is the score. How about to make the player temporary grow when he takes a coin? This can be done with a tween in the `hit()` method. Tweens helps to animate properties of an sprite in the game such as width or opacity.
* Let's add a tween inside the `hit()`, and choose the target. In this case, the target is the player we created in this game.
```
this.tweens.add({
targets: this.player
});
```
* Now, we will change the scale of the player, whenever it takes a coin. Adding `scale` and `duration` property, we can achieve this easily.
```
this.tweens.add({
targets: this.player
duration: 300, // for 300ms
scaleX: 1.2, // that scale vertically by 20%
scaleY: 1.2, // and scale horizontally by 20%
});
```
* Lastly, we want to make the player go back to the origianl scale. Adding `yoyo` property with value of `true`, it will become an original scale.
```
this.tweens.add({
targets: this.player
duration: 300,
scaleX: 1.2,
scaleY: 1.2,
yoyo: true // at the end, go back to original scale
});
```
Well done! Here's the final result.

You can check the full source code from our course, Phaser Test Course(Unit 3)
Full source code from original tuturial
https://github.com/lesscake/phaser-game-tutorial