<footer><div id=version></div></footer>
html, body {
height: 100%;
}
body {
margin: 0;
padding: 0;
background: #111;
color: #eee;
font: caption;
}
#version {
position: absolute;
left: 0;
top: 0;
padding: 0;
background: rgba(0, 0, 0, 0.5)
}
/* global colors, Phaser */
let bulletPlasma;
let bullets;
let enemy;
let enemyBullets;
let enemyFiring;
let enemyMoving;
let player;
let stars;
let text;
const config = {
width: 512,
height: 512,
pixelArt: true,
scene: {
preload: preload,
create: create,
update: update
},
physics: {
default: "arcade",
arcade: {
debug: false
}
},
loader: {
baseURL: "https://labs.phaser.io",
crossOrigin: "anonymous"
}
};
function preload() {
this.load.image("bullet", "assets/sprites/bullets/bullet7.png");
this.load.image("enemyBullet", "assets/sprites/bullets/bullet6.png");
this.load.image("ship", "assets/sprites/bsquadron1.png");
this.load.image("starfield", "assets/skies/starfield.png");
this.load.spritesheet("enemy", "assets/sprites/bsquadron-enemies.png", {
frameWidth: 192,
frameHeight: 160
});
}
function create() {
stars = this.add.blitter(0, 0, "starfield");
stars.create(0, 0);
stars.create(0, -512);
bullets = this.physics.add.group({
name: "bullets",
collideWorldBounds: true,
enable: false
});
bullets.createMultiple({
key: "bullet",
quantity: 5,
active: false,
visible: false
});
enemyBullets = this.physics.add.group({
name: "enemyBullets",
collideWorldBounds: true,
enable: false
});
enemyBullets.createMultiple({
quantity: 5,
key: "enemyBullet",
active: false,
visible: false
});
enemy = this.physics.add.sprite(256, 128, "enemy", 1);
enemy.body.setSize(160, 64);
enemy.state = 10;
enemyMoving = this.tweens.add({
targets: enemy.body.velocity,
props: {
x: { from: 150, to: -150, duration: 4000 },
y: { from: 50, to: -50, duration: 2000 }
},
ease: "Sine.easeInOut",
yoyo: true,
repeat: -1
});
enemyFiring = this.time.addEvent({
delay: 750,
loop: true,
callback: fireBulletFromEnemy
});
player = this.physics.add.image(256, 448, "ship");
bulletPlasma = this.add.particles("bullet").createEmitter({
alpha: { start: 1, end: 0, ease: "Cubic.easeIn" },
blendMode: 3,
frequency: -1,
lifespan: 500,
radial: false,
scale: { start: 1, end: 5, ease: "Cubic.easeOut" }
});
text = this.add.text(0, 32, "", { font: "16px monospace", fill: colors.cssColors.lime });
this.physics.add.overlap(enemy, bullets, overlapEnemyWithBullet);
this.physics.add.overlap(player, enemyBullets, overlapPlayerWithBullet);
this.physics.world.on("worldstep", worldStep, this);
this.input.on("pointermove", movePlayerFromPointer);
this.input.on("pointerdown", fireBulletFromPlayer);
}
function update() {
stars.y += 1;
stars.y %= 512;
text.setText([poolInfo(bullets), poolInfo(enemyBullets)]);
}
function worldStep() {
bullets.getChildren().forEach(updateBullet, this);
enemyBullets.getChildren().forEach(updateBullet, this);
}
function updateBullet(bullet) {
bullet.state -= bullet.body.newVelocity.length();
if (bullet.state <= 0) {
bullet.disableBody(true, true);
}
}
function movePlayerFromPointer(pointer) {
player.x = pointer.worldX;
}
function fireBulletFromEnemy() {
fireBulletFromGroup(enemyBullets, enemy.x, enemy.y + 32, 0, 150);
}
function fireBulletFromPlayer() {
fireBulletFromGroup(bullets, player.x, player.y, 0, -300);
}
function fireBulletFromGroup(group, x, y, vx, vy) {
const bullet = group.getFirstDead(false);
if (bullet) {
fireBullet(bullet, x, y, vx, vy);
}
}
function fireBullet(bullet, x, y, vx, vy) {
bullet.enableBody(true, x, y, true, true);
bullet.setVelocity(vx, vy);
// Range (px)
bullet.state = 300;
}
function overlapEnemyWithBullet(_enemy, bullet) {
const { x, y } = bullet.body.center;
_enemy.state -= 1;
bullet.disableBody(true, true);
bulletPlasma.setSpeedY(0.2 * bullet.body.velocity.y).emitParticleAt(x, y);
if (_enemy.state <= 0) {
_enemy.setFrame(3);
_enemy.body.checkCollision.none = true;
enemyFiring.remove();
enemyMoving.stop();
}
}
function overlapPlayerWithBullet(_player, bullet) {
const { x, y } = bullet.body.center;
bullet.disableBody(true, true);
bulletPlasma.setSpeedY(0.2 * bullet.body.velocity.y).emitParticleAt(x, y);
}
function poolInfo(group) {
return `${group.name} ${group.getLength()} (${group.countActive(
true
)}:${group.countActive(false)})`;
}
document.getElementById("version").textContent = "Phaser v" + Phaser.VERSION;
new Phaser.Game(config);
This Pen doesn't use any external CSS resources.