MiniRun
Desarrollo de videojuegos
Phaser3
- JavaScript
- ES6 Support
- Desktop & Mobile
- Free Software (MIT)
Set up
npm install phaser
Parcel support
npm install parcel-bundler
parcel index.html
index.html
<html>
<head>
<title>Phaser mini run</title>
</head>
<body>
<script src="src/game.js"></script>
</body>
</html>
src/game.js
import Phaser from 'phaser'
import config from './config'
new Phaser.Game(config)
src/config.js
import Phaser from 'phaser'
export default {
type: Phaser.auto,
title: 'Game',
width: 800,
height: 600,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 1200 }
}
},
scene: [
]
}
Start your game
npm start
Creating our first scene
Download the assets
https://github.com/photonstorm/phaser-examples
Put them on `src/assets`
Add the scene
import Phaser from 'phaser'
+import FirstScene from './scenes/FirstScene'
+
export default {
type: Phaser.auto,
title: 'Game',
width: 800,
height: 600,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 1200 }
}
},
scene: [
+ FirstScene,
]
}
src/scenes/FirstScene.js
import Phaser from 'phaser'
import space from '../assets/space3.png'
import logo from '../assets/phaser.png'
export default class FirstScene extends Phaser.Scene {
preload() {
this.load.image('space', space);
this.load.image('logo', logo);
}
create() {
this.add.image(400, 300, 'space');
var logo = this.physics.add.image(400, 100, 'logo');
logo.setVelocity(100, 200);
logo.setBounce(1, 1);
logo.setCollideWorldBounds(true);
}
}
Components of a Scene
Preload
Used to load all the media files (assets) that will be used:
- Images
- Audio
- Sprites
- Videos
You can add a scene to preload the most common files of your game.
Create
Places assets and configures what will be used in the scene.
Update
Is called with every `click` of the game, to update whatever is necessary of the scene.
Our first game
Flappy Bird!
Preparing the assets
Game images
https://github.com/sourabhv/FlapPyBird
Aseprite
Asset types
// Import the image and give it a js name.
import background from '../assets/background-day.png'
// Load the image into the game and give it an ID.
this.load.image('background', background)
// Add the image to the scene.
// The position coordinates are based on the center of the image.
this.add.image(144, 256, 'background');
Image
// Import the sprite and give it a js name.
import bird from '../assets/bird.png'
// Load the sprite into the game and give it an ID.
const frameSize = { frameWidth: 34, frameHeight: 24 }
this.load.spritesheet('bird', bird, frameSize)
// Add the spri to the scene.
this.bird = this.add.sprite(144, 256, 'bird')
// Animate it.
this.anims.create({
key: 'fly',
frames: this.anims.generateFrameNumbers('bird', { start: 0, end: 3 }),
frameRate: 10,
repeat: -1
})
this.bird.anims.play('fly', true)
Sprite
Preloading our assets
src/scenes/Preload.js
import Phaser from 'phaser'
import background from '../assets/background-day.png'
import logo from '../assets/logo.png'
import bird from '../assets/bird.png'
import pipe from '../assets/pipe-green.png'
export default class Preload extends Phaser.Scene {
preload() {
const bg = this.add.rectangle(144, 256, 200, 40, 0x666666)
const bar = this.add.rectangle(
bg.x, bg.y, bg.width, bg.height, 0xffffff
).setScale(0, 1)
this.load.image('background', background)
this.load.image('logo', logo)
const frameSize = { frameWidth: 34, frameHeight: 24 }
this.load.spritesheet('bird', bird, frameSize)
this.load.image('pipe', pipe)
this.load.on('progress', progress => bar.setScale(progress, 1))
}
}
src/config.js
import Phaser from 'phaser'
import Preload from './scenes/Preload'
export default {
type: Phaser.auto,
title: 'Game',
width: 288,
height: 512,
physics: {
default: 'arcade',
arcade: {
gravity: { y: 1200 }
}
},
scene: [
Preload,
]
}
Add our menu
src/scenes/Menu.js
import Phaser from 'phaser'
export default class Menu extends Phaser.Scene {
constructor() {
super({ key: 'menu' })
}
create() {
this.add.image(144, 256, 'background');
this.add.image(144, 200, 'logo');
this.bird = this.add.sprite(144, 256, 'bird')
this.anims.create({
key: 'fly',
frames: this.anims.generateFrameNumbers('bird', { start: 0, end: 3 }),
frameRate: 10,
repeat: -1
})
this.bird.anims.play('fly', true)
}
}
Configure it
Add the transition
export default class Preload extends Phaser.Scene {
// ...
update() {
this.scene.start('menu')
}
}
Designing our level
Add physics to the bird
import Phaser from 'phaser'
export default class Level extends Phaser.Scene {
constructor() {
super({ key: 'level' })
}
create() {
this.add.image(144, 256, 'background');
this.bird = this.physics.add.sprite(144, 256, 'bird')
this.anims.create({
key: 'fly',
frames: this.anims.generateFrameNumbers('bird',
{ start: 0, end: 3 }),
frameRate: 10,
repeat: -1
})
this.bird.anims.play('fly', true)
}
}
Add transition on click
import Phaser from 'phaser'
export default class Menu extends Phaser.Scene {
// ...
create() {
// ...
this.input.on('pointerup', () => this.scene.start('level'))
}
}
Make the bird die
import Phaser from 'phaser'
export default class Level extends Phaser.Scene {
// ...
update() {
const position = this.bird.body.position
if (position.y > 512) {
this.scene.start('menu')
}
}
}
Make the bird fly
import Phaser from 'phaser'
export default class Level extends Phaser.Scene {
// ...
create() {
// ...
this.bird.setCollideWorldBounds(true)
this.input.on('pointerup', () => this.fly())
this.fly()
}
fly() {
this.bird.setVelocityY(-500)
}
}
Let's add pipes!
export default class Level extends Phaser.Scene {
create() {
// ...
const config = {velocityX: -100, gravityY: -1200}
this.pipes = this.physics.add.group(config)
this.createPipe()
}
// ...
createPipe() {
const topPosition = Math.random() * (160 + 120) - 120
const bottomPosition = topPosition + 440
const topPipe = this.add.image(288, topPosition, 'pipe')
topPipe.setFlipY(true)
const bottomPipe = this.add.image(288, bottomPosition, 'pipe')
this.pipes.add(topPipe)
this.pipes.add(bottomPipe)
}
}
Moar pipes!
export default class Level extends Phaser.Scene {
create() {
// ...
- this.createPipe()
+ this.this.time.delayedCall(3000, this.createPipe, [], this)
}
// ...
createPipe() {
// ...
+ this.time.delayedCall(3000, this.createPipe, [], this)
}
}
Add collisions
export default class Level extends Phaser.Scene {
create() {
// ...
const config = {velocityX: -100, gravityY: -1200, immovable: true}
this.pipes = this.physics.add.group(config)
this.time.delayedCall(3000, this.createPipe, [], this)
this.physics.add.collider(this.bird, this.pipes, () => this.die())
}
die() {
this.scene.start('menu')
}
// ...
}
Let's add sound
Load the assets
import wingOgg from '../assets/wing.ogg'
import wingWav from '../assets/wing.wav'
export default class Preload extends Phaser.Scene {
preload() {
this.load.audio('wing', [wingOgg, wingWav])
}
}
Add the sound to the scene
export default class Level extends Phaser.Scene {
create() {
this.wing = this.sound.add('wing')
}
}
Add them when flying
export default class Level extends Phaser.Scene {
fly() {
this.bird.setVelocityY(-500)
this.sound.stopAll()
this.wing.play()
}
}
Resources
Sample repository
Assets:
MiniRunDesarrollo de videojuegos
By david_hernandez
MiniRunDesarrollo de videojuegos
- 1,073