Build games as easily as you play them — join the Phaser Beam waitlist for Early Access.
export default class Boot extends Phaser.Scene { constructor () { super('Boot'); } preload () { this.load.setBaseURL('https://cdn.phaserfiles.com/v355'); this.load.image('loading', 'assets/games/bank-panic/loading.png'); } create () { this.scene.start('Preloader'); } }
export default class MainMenu extends Phaser.Scene { constructor () { super('MainMenu'); } create () { this.add.image(512, 384, 'title'); let sign = this.add.image(512, -400, 'logo'); this.tweens.add({ targets: sign, y: 180, ease: 'Bounce.easeOut', duration: 2000 }); let cactus1 = this.add.image(150, 680, 'https://labs.phaser.io/assets', 'cactus'); let cactus2 = this.add.image(880, 680, 'https://labs.phaser.io/assets', 'cactus').setFlipX(true); this.tweens.add({ targets: cactus1, props: { scaleX: { value: 0.9, duration: 250 }, scaleY: { value: 1.1, duration: 250 }, angle: { value: -20, duration: 500, delay: 250 }, y: { value: 660, duration: 250 } }, ease: 'Sine.easeInOut', repeat: -1, yoyo: true }); this.tweens.add({ targets: cactus2, props: { scaleX: { value: 0.9, duration: 250 }, scaleY: { value: 1.1, duration: 250 }, angle: { value: 20, duration: 500, delay: 250 }, y: { value: 660, duration: 250 } }, ease: 'Sine.easeInOut', repeat: -1, yoyo: true }); this.music = this.sound.play('music', { loop: true }); this.input.once('pointerdown', () => { this.sound.stopAll(); this.sound.play('shot'); this.scene.start('MainGame'); }); } }
export default class Preloader extends Phaser.Scene { constructor () { super('Preloader'); } preload () { this.load.setBaseURL('https://cdn.phaserfiles.com/v355'); this.loading = this.add.image(512, 384, 'loading'); this.load.setPath('assets/games/bank-panic/'); this.load.image('start'); this.load.image('title'); this.load.image('logo'); this.load.image('background'); this.load.image('bulletHole', 'bullet-hole.png'); this.load.atlas('https://labs.phaser.io/assets', 'bank-panic.png', 'bank-panic.json'); this.load.audio('shot', [ 'shot.ogg', 'shot.m4a', 'shot.mp3' ]); this.load.audio('banditShot', [ '50cal.ogg', '50cal.m4a', '50cal.mp3' ]); this.load.audio('money', [ 'money.ogg', 'money.m4a', 'money.mp3' ]); this.load.audio('levelComplete', [ 'complete.ogg', 'complete.m4a', 'complete.mp3' ]); this.load.audio('gameOver', [ 'gameover.ogg', 'gameover.m4a', 'gameover.mp3' ]); this.load.audio('music', [ 'music.ogg', 'music.m4a', 'music.mp3' ]); this.load.audio('door', [ 'door.ogg', 'door.m4a', 'door.mp3' ]); this.load.audio('scream1', [ 'scream1.ogg', 'scream1.m4a', 'scream1.mp3' ]); this.load.audio('scream2', [ 'scream2.ogg', 'scream2.m4a', 'scream2.mp3' ]); this.load.audio('scream3', [ 'scream3.ogg', 'scream3.m4a', 'scream3.mp3' ]); } create () { // Create our global animations this.anims.create({ key: 'doorOpen', frames: this.anims.generateFrameNames('https://labs.phaser.io/assets', { prefix: 'door', start: 1, end: 5 }), frameRate: 20 }); this.anims.create({ key: 'doorClose', frames: this.anims.generateFrameNames('https://labs.phaser.io/assets', { prefix: 'door', start: 5, end: 1 }), frameRate: 20 }); this.loading.setTexture('start'); this.loading.setInteractive(); this.loading.once('pointerdown', () => { this.scene.start('MainMenu'); }); } }
import Door from './Door.js'; export default class MainGame extends Phaser.Scene { constructor () { super('MainGame'); this.hats; this.goals; this.gold; this.doors; this.isPaused = false; this.goalsComplete = 0; this.sign; this.level = 1; this.levelImage; this.killDelay = 0.7; this.closeDurationLow = 2000; this.closeDurationHigh = 4000; } create () { this.add.image(512, 384, 'background'); // Level text this.add.image(450, 650, 'https://labs.phaser.io/assets', 'levelText'); this.levelImage = this.add.image(600, 650, 'https://labs.phaser.io/assets', '1'); this.createGoals(); this.createDoors(); this.hats = this.add.group({ defaultKey: 'https://labs.phaser.io/assets', defaultFrame: 'hat', key: 'https://labs.phaser.io/assets', frame: 'hat', active: false, visible: false, repeat: 32, maxSize: 32 }); this.gold = this.add.group({ defaultKey: 'https://labs.phaser.io/assets', defaultFrame: 'gold', key: 'https://labs.phaser.io/assets', frame: 'gold', active: false, visible: false, repeat: 11, maxSize: 12 }); this.isPaused = false; this.level = 1; this.killDelay = 0.8; this.closeDurationLow = 2000; this.closeDurationHigh = 4000; this.doors.forEach((door) => { door.start(this.game.getTime()); }); } createGoals () { this.goals = []; this.goalsComplete = 0; for (let i = 1; i <= 12; i++) { this.goals.push(this.add.image(0, 0, 'https://labs.phaser.io/assets', i)); } Phaser.Actions.GridAlign(this.goals, { width: 12, height: 1, cellWidth: 80, cellHeight: 36, x: 80, y: 86 }); } createDoors () { this.doors = []; let doorWidth = 200; let doorSpace = Math.floor((1024 - (doorWidth * 4)) / 5); let x = 100 + doorSpace; let y = 352; for (let i = 1; i <= 4; i++) { this.doors.push(new Door('Door' + i, this, x, y)) x += doorWidth + doorSpace; } } addGold (x, y) { let target = this.goals[this.goalsComplete]; let gold = this.gold.get(x + 50, y + 100); gold.setActive(true).setVisible(true); this.sound.play('money'); this.tweens.add({ targets: gold, x: target.x, y: target.y, duration: 600, ease: 'Quad.easeOut', onComplete: () => { target.setVisible(false); } }); this.goalsComplete++; if (this.goalsComplete === 12) { this.levelComplete(); } } addHat (x, y, stackPosition) { y = 180 + (30 * (5 - stackPosition)); let hat = this.hats.get(x, y); hat.setActive(true).setVisible(true); hat.setScale(1).setAlpha(1); const destX = Phaser.Math.RND.between(x - 400, x + 400); const destY = y - 400; this.tweens.add({ targets: hat, x: destX, y: destY, angle: 960, duration: 1000, ease: 'Quad.easeOut', onComplete: () => { hat.setActive(false); hat.setVisible(false); } }); } levelFail () { this.isPaused = true; this.sign = this.add.image(512, -200, 'https://labs.phaser.io/assets', 'gameOver'); this.sound.play('gameOver'); this.tweens.add({ targets: this.sign, y: 384, ease: 'Bounce.easeOut', duration: 1500, onComplete: () => { this.input.once('pointerdown', () => this.scene.start('MainMenu')); } }); } levelComplete () { this.isPaused = true; this.sign = this.add.image(512, -200, 'https://labs.phaser.io/assets', 'levelComplete'); this.sound.play('levelComplete'); this.tweens.add({ targets: this.sign, y: 384, ease: 'Bounce.easeOut', duration: 1500, onComplete: () => { this.input.once('pointerdown', () => this.nextLevel()); } }); } nextLevel () { this.goals.forEach((goal, index) => { goal.setFrame((index + 1).toString()); goal.setVisible(true); }); this.gold.getChildren().forEach((gold) => { gold.setVisible(false); gold.setActive(false); }); // Reset everything this.doors.forEach((door) => { door.reset(this.game.getTime()); }); this.goalsComplete = 0; // Change difficulty if (this.level < 5) { this.killDelay -= 0.1; } if (this.level < 10) { this.closeDurationLow -= 100; this.closeDurationHigh -= 200; } // Change level counter this.level++; this.levelImage.setFrame(this.level); this.sign.setVisible(false); this.isPaused = false; } killed (x, y) { // Bullet holes on the screen let offsetX = 100; for (let i = 0; i < 3; i++) { let x = Phaser.Math.RND.between(offsetX, offsetX + 200); let y = Phaser.Math.RND.between(200, 600); let hole = this.add.image(x, y, 'bulletHole').setAlpha(0); this.tweens.add({ targets: hole, alpha: 1, duration: 30, delay: 200 * i }); offsetX += 340; } this.levelFail(); } update (time) { if (!this.isPaused) { this.doors.forEach((door) => { door.update(time); }); } } }
import Boot from './Boot.js'; import Preloader from './Preloader.js'; import MainMenu from './MainMenu.js'; import MainGame from './Game.js'; const config = { type: Phaser.AUTO, width: 1024, height: 768, backgroundColor: '#2e91f3', parent: 'phaser-example', scene: [ Boot, Preloader, MainMenu, MainGame ] }; let game = new Phaser.Game(config);
export default class Door extends Phaser.GameObjects.Container { constructor (name, scene, x, y) { super(scene, x, y); this.name = name; this.background = scene.add.image(0, 0, 'https://labs.phaser.io/assets', 'doorBackground'); this.door = scene.add.sprite(0, 0, 'https://labs.phaser.io/assets', 'door1'); this.character = scene.add.image(0, 0, 'https://labs.phaser.io/assets', 'bandit1'); this.characterFrame = 'bandit1'; this.isOpen = false; this.isBandit = false; this.isHats = false; this.isDead = false; this.wasBandit = (scene.doors.length % 2) ? true : false; this.hats = 0; this.timeToOpen = Number.MAX_SAFE_INTEGER; this.timeToClose = Number.MAX_SAFE_INTEGER; this.timeToKill = 0; this.characters = [ 'bandit1', 'bandit2', 'cowboy1', 'cowboy2', 'hat' ]; this.add([ this.background, this.character, this.door ]); this.setSize(200, 400); this.setInteractive(); this.on('pointerup', this.shoot, this); scene.add.existing(this); } destroy () { this.off('pointerup'); } start (time) { this.timeToOpen = time + Phaser.Math.RND.between(500, 4000); } reset (time) { this.isOpen = false; this.isBandit = false; this.isHats = false; this.isDead = false; this.door.play('doorClose'); this.timeToOpen = time + Phaser.Math.RND.between(500, 4000); } openDoor (time) { this.isOpen = true; this.isBandit = false; this.isHats = false; this.isDead = false; this.characterFrame = Phaser.Utils.Array.GetRandom(this.characters); // When should this door close again? const duration = Phaser.Math.RND.between(this.scene.closeDurationLow, this.scene.closeDurationHigh); this.timeToClose = time + duration; if (this.characterFrame === 'bandit1' || this.characterFrame === 'bandit2') { this.isBandit = true; } else if (this.characterFrame === 'hat') { this.isHats = true; // Pick random number of hats this.hats = Phaser.Math.RND.between(2, 5); this.characterFrame += this.hats.toString(); } else { this.timeToClose = time + (duration / 2); } // If we had a citizen or hats on our last go, we have to have a bandit now if (!this.wasBandit && !this.isBandit) { this.isHats = false; this.hats = 0; this.isBandit = true; this.characterFrame = (Math.random() > 0.5) ? 'bandit1' : 'bandit2'; this.timeToClose = time + duration; } this.character.setFrame(this.characterFrame); this.character.setScale(1).setAlpha(1); if (this.isBandit) { this.timeToKill = time + (duration * this.scene.killDelay); } this.scene.sound.play('door'); this.door.play('doorOpen'); } closeDoor (time) { this.door.play('doorClose'); this.isOpen = false; this.wasBandit = this.isBandit; if (!this.isBandit && !this.isHats && !this.isDead) { this.scene.addGold(this.x, this.y); } // When should this door open again? this.timeToOpen = time + Phaser.Math.RND.between(2000, 4000); } shoot () { if (!this.isOpen || this.scene.isPaused) { return; } this.scene.sound.play('shot'); if (this.isDead) { // We will want to hear the gunshot, but not actually do anything with it return; } if (this.isBandit) { this.shootCharacter(true); } else { if (this.isHats) { this.shootHat(); } else { this.shootCharacter(false); } } } shootCharacter (closeDoor) { this.isDead = true; this.characterFrame += 'Dead'; this.character.setFrame(this.characterFrame); this.scene.sound.play('scream' + Phaser.Math.RND.between(1, 3)); this.scene.tweens.add({ targets: this.character, scaleX: 0.5, scaleY: 0.5, duration: 300, onComplete: () => { if (closeDoor) { this.closeDoor(this.scene.game.getTime()); } else { this.scene.levelFail(); } } }); // No more shots at this door if (!closeDoor) { this.off('pointerup'); this.scene.isPaused = true; } } shootHat () { if (this.hats > 0) { this.scene.addHat(this.x, this.y, this.hats); this.hats--; this.characterFrame = 'hat' + this.hats; } this.character.setFrame(this.characterFrame); } shootYou () { this.off('pointerup'); this.scene.isPaused = true; // Shots let shot1 = this.scene.add.image(this.x, this.y, 'https://labs.phaser.io/assets', this.characterFrame + 'shot1'); let shot2 = this.scene.add.image(this.x, this.y, 'https://labs.phaser.io/assets', this.characterFrame + 'shot2'); this.scene.sound.play('banditShot'); this.scene.sound.play('banditShot', { delay: 0.25 }); this.scene.sound.play('banditShot', { delay: 0.5 }); this.scene.tweens.add({ targets: shot1, alpha: 0, duration: 200, ease: 'Power2' }); this.scene.tweens.add({ targets: shot2, alpha: 0, duration: 200, delay: 200, ease: 'Power2', onComplete: () => { this.scene.killed(this.x, this.y); } }); // Gun smoke rising from the bandit let smoke1 = this.scene.add.image(this.x, this.y, 'https://labs.phaser.io/assets', this.characterFrame + 'smoke1'); let smoke2 = this.scene.add.image(this.x, this.y, 'https://labs.phaser.io/assets', this.characterFrame + 'smoke2'); this.scene.tweens.add({ targets: smoke1, props: { y: { value: 150, duration: 1000, ease: 'Sine.easeInOut' }, alpha: { value: 0, duration: 250, ease: 'Power2', delay: 750 } } }); this.scene.tweens.add({ targets: smoke2, props: { y: { value: 150, duration: 1000, ease: 'Sine.easeInOut', delay: 500 }, alpha: { value: 0, duration: 250, ease: 'Power2', delay: 1250 } } }); } update (time) { if (!this.isOpen && time >= this.timeToOpen) { this.openDoor(time); } else if (this.isOpen && time >= this.timeToClose) { this.closeDoor(time); } else if (this.isOpen && this.isBandit && !this.isDead && time >= this.timeToKill) { this.shootYou(); } } }
export default class Boot extends Phaser.Scene
{
constructor ()
{
super('Boot');
}
preload ()
{
this.load.setBaseURL('https://cdn.phaserfiles.com/v355');
this.load.image('loading', 'assets/games/bank-panic/loading.png');
}
create ()
{
this.scene.start('Preloader');
}
}
export default class MainMenu extends Phaser.Scene
{
constructor ()
{
super('MainMenu');
}
create ()
{
this.add.image(512, 384, 'title');
let sign = this.add.image(512, -400, 'logo');
this.tweens.add({
targets: sign,
y: 180,
ease: 'Bounce.easeOut',
duration: 2000
});
let cactus1 = this.add.image(150, 680, 'https://labs.phaser.io/assets', 'cactus');
let cactus2 = this.add.image(880, 680, 'https://labs.phaser.io/assets', 'cactus').setFlipX(true);
this.tweens.add({
targets: cactus1,
props: {
scaleX: { value: 0.9, duration: 250 },
scaleY: { value: 1.1, duration: 250 },
angle: { value: -20, duration: 500, delay: 250 },
y: { value: 660, duration: 250 }
},
ease: 'Sine.easeInOut',
repeat: -1,
yoyo: true
});
this.tweens.add({
targets: cactus2,
props: {
scaleX: { value: 0.9, duration: 250 },
scaleY: { value: 1.1, duration: 250 },
angle: { value: 20, duration: 500, delay: 250 },
y: { value: 660, duration: 250 }
},
ease: 'Sine.easeInOut',
repeat: -1,
yoyo: true
});
this.music = this.sound.play('music', { loop: true });
this.input.once('pointerdown', () => {
this.sound.stopAll();
this.sound.play('shot');
this.scene.start('MainGame');
});
}
}
export default class Preloader extends Phaser.Scene
{
constructor ()
{
super('Preloader');
}
preload ()
{
this.load.setBaseURL('https://cdn.phaserfiles.com/v355');
this.loading = this.add.image(512, 384, 'loading');
this.load.setPath('assets/games/bank-panic/');
this.load.image('start');
this.load.image('title');
this.load.image('logo');
this.load.image('background');
this.load.image('bulletHole', 'bullet-hole.png');
this.load.atlas('https://labs.phaser.io/assets', 'bank-panic.png', 'bank-panic.json');
this.load.audio('shot', [ 'shot.ogg', 'shot.m4a', 'shot.mp3' ]);
this.load.audio('banditShot', [ '50cal.ogg', '50cal.m4a', '50cal.mp3' ]);
this.load.audio('money', [ 'money.ogg', 'money.m4a', 'money.mp3' ]);
this.load.audio('levelComplete', [ 'complete.ogg', 'complete.m4a', 'complete.mp3' ]);
this.load.audio('gameOver', [ 'gameover.ogg', 'gameover.m4a', 'gameover.mp3' ]);
this.load.audio('music', [ 'music.ogg', 'music.m4a', 'music.mp3' ]);
this.load.audio('door', [ 'door.ogg', 'door.m4a', 'door.mp3' ]);
this.load.audio('scream1', [ 'scream1.ogg', 'scream1.m4a', 'scream1.mp3' ]);
this.load.audio('scream2', [ 'scream2.ogg', 'scream2.m4a', 'scream2.mp3' ]);
this.load.audio('scream3', [ 'scream3.ogg', 'scream3.m4a', 'scream3.mp3' ]);
}
create ()
{
// Create our global animations
this.anims.create({
key: 'doorOpen',
frames: this.anims.generateFrameNames('https://labs.phaser.io/assets', { prefix: 'door', start: 1, end: 5 }),
frameRate: 20
});
this.anims.create({
key: 'doorClose',
frames: this.anims.generateFrameNames('https://labs.phaser.io/assets', { prefix: 'door', start: 5, end: 1 }),
frameRate: 20
});
this.loading.setTexture('start');
this.loading.setInteractive();
this.loading.once('pointerdown', () => {
this.scene.start('MainMenu');
});
}
}
import Door from './Door.js';
export default class MainGame extends Phaser.Scene
{
constructor ()
{
super('MainGame');
this.hats;
this.goals;
this.gold;
this.doors;
this.isPaused = false;
this.goalsComplete = 0;
this.sign;
this.level = 1;
this.levelImage;
this.killDelay = 0.7;
this.closeDurationLow = 2000;
this.closeDurationHigh = 4000;
}
create ()
{
this.add.image(512, 384, 'background');
// Level text
this.add.image(450, 650, 'https://labs.phaser.io/assets', 'levelText');
this.levelImage = this.add.image(600, 650, 'https://labs.phaser.io/assets', '1');
this.createGoals();
this.createDoors();
this.hats = this.add.group({
defaultKey: 'https://labs.phaser.io/assets',
defaultFrame: 'hat',
key: 'https://labs.phaser.io/assets',
frame: 'hat',
active: false,
visible: false,
repeat: 32,
maxSize: 32
});
this.gold = this.add.group({
defaultKey: 'https://labs.phaser.io/assets',
defaultFrame: 'gold',
key: 'https://labs.phaser.io/assets',
frame: 'gold',
active: false,
visible: false,
repeat: 11,
maxSize: 12
});
this.isPaused = false;
this.level = 1;
this.killDelay = 0.8;
this.closeDurationLow = 2000;
this.closeDurationHigh = 4000;
this.doors.forEach((door) => {
door.start(this.game.getTime());
});
}
createGoals ()
{
this.goals = [];
this.goalsComplete = 0;
for (let i = 1; i <= 12; i++)
{
this.goals.push(this.add.image(0, 0, 'https://labs.phaser.io/assets', i));
}
Phaser.Actions.GridAlign(this.goals, {
width: 12,
height: 1,
cellWidth: 80,
cellHeight: 36,
x: 80,
y: 86
});
}
createDoors ()
{
this.doors = [];
let doorWidth = 200;
let doorSpace = Math.floor((1024 - (doorWidth * 4)) / 5);
let x = 100 + doorSpace;
let y = 352;
for (let i = 1; i <= 4; i++)
{
this.doors.push(new Door('Door' + i, this, x, y))
x += doorWidth + doorSpace;
}
}
addGold (x, y)
{
let target = this.goals[this.goalsComplete];
let gold = this.gold.get(x + 50, y + 100);
gold.setActive(true).setVisible(true);
this.sound.play('money');
this.tweens.add({
targets: gold,
x: target.x,
y: target.y,
duration: 600,
ease: 'Quad.easeOut',
onComplete: () => {
target.setVisible(false);
}
});
this.goalsComplete++;
if (this.goalsComplete === 12)
{
this.levelComplete();
}
}
addHat (x, y, stackPosition)
{
y = 180 + (30 * (5 - stackPosition));
let hat = this.hats.get(x, y);
hat.setActive(true).setVisible(true);
hat.setScale(1).setAlpha(1);
const destX = Phaser.Math.RND.between(x - 400, x + 400);
const destY = y - 400;
this.tweens.add({
targets: hat,
x: destX,
y: destY,
angle: 960,
duration: 1000,
ease: 'Quad.easeOut',
onComplete: () => {
hat.setActive(false);
hat.setVisible(false);
}
});
}
levelFail ()
{
this.isPaused = true;
this.sign = this.add.image(512, -200, 'https://labs.phaser.io/assets', 'gameOver');
this.sound.play('gameOver');
this.tweens.add({
targets: this.sign,
y: 384,
ease: 'Bounce.easeOut',
duration: 1500,
onComplete: () => {
this.input.once('pointerdown', () => this.scene.start('MainMenu'));
}
});
}
levelComplete ()
{
this.isPaused = true;
this.sign = this.add.image(512, -200, 'https://labs.phaser.io/assets', 'levelComplete');
this.sound.play('levelComplete');
this.tweens.add({
targets: this.sign,
y: 384,
ease: 'Bounce.easeOut',
duration: 1500,
onComplete: () => {
this.input.once('pointerdown', () => this.nextLevel());
}
});
}
nextLevel ()
{
this.goals.forEach((goal, index) => {
goal.setFrame((index + 1).toString());
goal.setVisible(true);
});
this.gold.getChildren().forEach((gold) => {
gold.setVisible(false);
gold.setActive(false);
});
// Reset everything
this.doors.forEach((door) => {
door.reset(this.game.getTime());
});
this.goalsComplete = 0;
// Change difficulty
if (this.level < 5)
{
this.killDelay -= 0.1;
}
if (this.level < 10)
{
this.closeDurationLow -= 100;
this.closeDurationHigh -= 200;
}
// Change level counter
this.level++;
this.levelImage.setFrame(this.level);
this.sign.setVisible(false);
this.isPaused = false;
}
killed (x, y)
{
// Bullet holes on the screen
let offsetX = 100;
for (let i = 0; i < 3; i++)
{
let x = Phaser.Math.RND.between(offsetX, offsetX + 200);
let y = Phaser.Math.RND.between(200, 600);
let hole = this.add.image(x, y, 'bulletHole').setAlpha(0);
this.tweens.add({
targets: hole,
alpha: 1,
duration: 30,
delay: 200 * i
});
offsetX += 340;
}
this.levelFail();
}
update (time)
{
if (!this.isPaused)
{
this.doors.forEach((door) => {
door.update(time);
});
}
}
}
import Boot from './Boot.js';
import Preloader from './Preloader.js';
import MainMenu from './MainMenu.js';
import MainGame from './Game.js';
const config = {
type: Phaser.AUTO,
width: 1024,
height: 768,
backgroundColor: '#2e91f3',
parent: 'phaser-example',
scene: [ Boot, Preloader, MainMenu, MainGame ]
};
let game = new Phaser.Game(config);
export default class Door extends Phaser.GameObjects.Container
{
constructor (name, scene, x, y)
{
super(scene, x, y);
this.name = name;
this.background = scene.add.image(0, 0, 'https://labs.phaser.io/assets', 'doorBackground');
this.door = scene.add.sprite(0, 0, 'https://labs.phaser.io/assets', 'door1');
this.character = scene.add.image(0, 0, 'https://labs.phaser.io/assets', 'bandit1');
this.characterFrame = 'bandit1';
this.isOpen = false;
this.isBandit = false;
this.isHats = false;
this.isDead = false;
this.wasBandit = (scene.doors.length % 2) ? true : false;
this.hats = 0;
this.timeToOpen = Number.MAX_SAFE_INTEGER;
this.timeToClose = Number.MAX_SAFE_INTEGER;
this.timeToKill = 0;
this.characters = [
'bandit1',
'bandit2',
'cowboy1',
'cowboy2',
'hat'
];
this.add([ this.background, this.character, this.door ]);
this.setSize(200, 400);
this.setInteractive();
this.on('pointerup', this.shoot, this);
scene.add.existing(this);
}
destroy ()
{
this.off('pointerup');
}
start (time)
{
this.timeToOpen = time + Phaser.Math.RND.between(500, 4000);
}
reset (time)
{
this.isOpen = false;
this.isBandit = false;
this.isHats = false;
this.isDead = false;
this.door.play('doorClose');
this.timeToOpen = time + Phaser.Math.RND.between(500, 4000);
}
openDoor (time)
{
this.isOpen = true;
this.isBandit = false;
this.isHats = false;
this.isDead = false;
this.characterFrame = Phaser.Utils.Array.GetRandom(this.characters);
// When should this door close again?
const duration = Phaser.Math.RND.between(this.scene.closeDurationLow, this.scene.closeDurationHigh);
this.timeToClose = time + duration;
if (this.characterFrame === 'bandit1' || this.characterFrame === 'bandit2')
{
this.isBandit = true;
}
else if (this.characterFrame === 'hat')
{
this.isHats = true;
// Pick random number of hats
this.hats = Phaser.Math.RND.between(2, 5);
this.characterFrame += this.hats.toString();
}
else
{
this.timeToClose = time + (duration / 2);
}
// If we had a citizen or hats on our last go, we have to have a bandit now
if (!this.wasBandit && !this.isBandit)
{
this.isHats = false;
this.hats = 0;
this.isBandit = true;
this.characterFrame = (Math.random() > 0.5) ? 'bandit1' : 'bandit2';
this.timeToClose = time + duration;
}
this.character.setFrame(this.characterFrame);
this.character.setScale(1).setAlpha(1);
if (this.isBandit)
{
this.timeToKill = time + (duration * this.scene.killDelay);
}
this.scene.sound.play('door');
this.door.play('doorOpen');
}
closeDoor (time)
{
this.door.play('doorClose');
this.isOpen = false;
this.wasBandit = this.isBandit;
if (!this.isBandit && !this.isHats && !this.isDead)
{
this.scene.addGold(this.x, this.y);
}
// When should this door open again?
this.timeToOpen = time + Phaser.Math.RND.between(2000, 4000);
}
shoot ()
{
if (!this.isOpen || this.scene.isPaused)
{
return;
}
this.scene.sound.play('shot');
if (this.isDead)
{
// We will want to hear the gunshot, but not actually do anything with it
return;
}
if (this.isBandit)
{
this.shootCharacter(true);
}
else
{
if (this.isHats)
{
this.shootHat();
}
else
{
this.shootCharacter(false);
}
}
}
shootCharacter (closeDoor)
{
this.isDead = true;
this.characterFrame += 'Dead';
this.character.setFrame(this.characterFrame);
this.scene.sound.play('scream' + Phaser.Math.RND.between(1, 3));
this.scene.tweens.add({
targets: this.character,
scaleX: 0.5,
scaleY: 0.5,
duration: 300,
onComplete: () => {
if (closeDoor)
{
this.closeDoor(this.scene.game.getTime());
}
else
{
this.scene.levelFail();
}
}
});
// No more shots at this door
if (!closeDoor)
{
this.off('pointerup');
this.scene.isPaused = true;
}
}
shootHat ()
{
if (this.hats > 0)
{
this.scene.addHat(this.x, this.y, this.hats);
this.hats--;
this.characterFrame = 'hat' + this.hats;
}
this.character.setFrame(this.characterFrame);
}
shootYou ()
{
this.off('pointerup');
this.scene.isPaused = true;
// Shots
let shot1 = this.scene.add.image(this.x, this.y, 'https://labs.phaser.io/assets', this.characterFrame + 'shot1');
let shot2 = this.scene.add.image(this.x, this.y, 'https://labs.phaser.io/assets', this.characterFrame + 'shot2');
this.scene.sound.play('banditShot');
this.scene.sound.play('banditShot', { delay: 0.25 });
this.scene.sound.play('banditShot', { delay: 0.5 });
this.scene.tweens.add({
targets: shot1,
alpha: 0,
duration: 200,
ease: 'Power2'
});
this.scene.tweens.add({
targets: shot2,
alpha: 0,
duration: 200,
delay: 200,
ease: 'Power2',
onComplete: () => {
this.scene.killed(this.x, this.y);
}
});
// Gun smoke rising from the bandit
let smoke1 = this.scene.add.image(this.x, this.y, 'https://labs.phaser.io/assets', this.characterFrame + 'smoke1');
let smoke2 = this.scene.add.image(this.x, this.y, 'https://labs.phaser.io/assets', this.characterFrame + 'smoke2');
this.scene.tweens.add({
targets: smoke1,
props: {
y: { value: 150, duration: 1000, ease: 'Sine.easeInOut' },
alpha: { value: 0, duration: 250, ease: 'Power2', delay: 750 }
}
});
this.scene.tweens.add({
targets: smoke2,
props: {
y: { value: 150, duration: 1000, ease: 'Sine.easeInOut', delay: 500 },
alpha: { value: 0, duration: 250, ease: 'Power2', delay: 1250 }
}
});
}
update (time)
{
if (!this.isOpen && time >= this.timeToOpen)
{
this.openDoor(time);
}
else if (this.isOpen && time >= this.timeToClose)
{
this.closeDoor(time);
}
else if (this.isOpen && this.isBandit && !this.isDead && time >= this.timeToKill)
{
this.shootYou();
}
}
}