Skip to content

Instantly share code, notes, and snippets.

@samme
Created July 15, 2024 20:10
Show Gist options
  • Save samme/f2683a542c98b4f5010f195ead8a6852 to your computer and use it in GitHub Desktop.
Save samme/f2683a542c98b4f5010f195ead8a6852 to your computer and use it in GitHub Desktop.
import Phaser from 'phaser';
const playerPositions = {
1: { x: 112, y: 112 },
2: { x: 1376, y: 160 },
3: { x: 2000, y: 48 },
4: { x: 2176, y: 144 },
};
export class GameScene extends Phaser.Scene {
constructor() {
super({
key: 'game',
physics: {
arcade: {
debug: false,
fps: 60,
gravity: {
y: 512,
},
},
},
plugins: ['InputPlugin'],
});
}
create() {
const { add, cameras, input, physics } = this;
const { keyboard } = input;
// Bg, Fg
add
.image(-896, 0, 'bg')
.setOrigin(0, 0)
.setAlpha(1)
.setScrollFactor(0.5, 0.5);
add.image(0, 0, 'fg').setOrigin(0, 0).setDepth(2);
// Zones
const zones = [];
for (const [x, y, width, height] of [
[64, 112, 80, 48],
[224, 160, 1184, 80],
[144, 208, 48, 32],
[1536, 256, 496, 48],
[1952, 48, 112, 40],
[2160, 144, 16, 16],
[2256, 144, 32, 16],
]) {
const zone = add.zone(x, y, width, height).setOrigin(0, 0);
physics.add.existing(zone, true);
zones.push(zone);
}
// Player
this.player = this.physics.add
.sprite(560, 120, 'sprites', 'idle1')
.setOrigin(0.5, 1)
.setDepth(1)
.on('animationupdate', this.onPlayerAnimationUpdate, this)
.play('idle');
this.player.body.setSize(16, 32, false).setOffset(56, 16);
// Sword
this.sword = this.add.zone(0, 0, 32, 16).setOrigin(0.5, 1);
this.physics.add.existing(this.sword);
this.sword.body.moves = false;
// Fox
this.fox = this.physics.add
.sprite(1320, 160, 'sprites', 'fox1')
.setOrigin(0.5, 1)
.play('fox');
this.fox.body
.setSize(48, 16, false)
.setOffset(16, 32)
.setCollideWorldBounds(true, 1, 1)
.setBoundsRectangle(new Phaser.Geom.Rectangle(224, 0, 1184, 288))
.setVelocityX(160);
// Guy
this.guy = this.physics.add
.sprite(1784, 256, 'sprites', 'dude1')
.setOrigin(0.5, 1)
.play('dudeIdle')
.setFlipX(true)
.on('animationupdate', this.onDudeAnimationUpdate, this)
.on('animationcomplete', this.onDudeAnimationComplete, this);
this.guy.body.setSize(16, 48, false).setOffset(32, 16);
// Star
this.star = this.physics.add
.sprite(0, 0, 'sprites', 'shuriken1')
.play('shuriken')
.disableBody(true, true);
this.star.body.allowGravity = false;
// Camera
cameras.main.startFollow(this.player, true).setBounds(0, 0, 2512, 304);
// Collisions
this.physics.add.collider([this.player, this.fox, this.guy], zones);
this.physics.add.overlap(this.star, zones, this.onStarHitTerrain);
this.physics.add.overlap(this.star, this.player, this.onStarHitPlayer);
this.physics.add.overlap(this.sword, this.guy, this.onSwordHitGuy);
// Keyboard
this.cursors = keyboard.createCursorKeys();
this.attackKey = keyboard.addKey('Z');
keyboard
.on('keydown-R', this.restart, this)
.on('keydown-T', this.teleport, this)
.on('keydown-ONE', this.teleport, this)
.on('keydown-TWO', this.teleport, this)
.on('keydown-THREE', this.teleport, this)
.on('keydown-FOUR', this.teleport, this);
}
update() {
const { attackKey } = this;
const { left, right, up, down, shift } = this.cursors;
const { anims, body } = this.player;
const { velocity } = this.player.body;
const currentAnim = anims.getName();
this.fox.flipX = this.fox.body.velocity.x < 0;
if (
anims.isPlaying &&
(currentAnim === 'attack' || anims.getName() === 'hurt')
) {
return;
}
if (velocity.x > 0) this.player.flipX = false;
else if (velocity.x < 0) this.player.flipX = true;
if (this.player.body.onFloor()) {
if (attackKey.isDown) {
velocity.x = 0;
anims.play('attack');
return;
}
if (left.isDown) {
velocity.x = -128;
anims.play('run', true);
} else if (right.isDown) {
velocity.x = 128;
anims.play('run', true);
} else {
velocity.x = 0;
anims.play('idle', true);
}
if (up.isDown) {
velocity.y = -256;
}
if (shift.isDown) {
velocity.x *= 1.5;
velocity.y *= 1.5;
}
} else {
if (down.isDown && body.wasTouching.down) {
velocity.x = 0;
velocity.y = 64;
}
if (velocity.y < 0) {
this.player.play('jump', true);
} else {
this.player.play('fall', true);
}
}
}
hurtPlayer() {
this.player.play('hurt').setVelocityX(0);
}
onDudeAnimationComplete(anim, animFrame, sprite, frameName) {
if (anim.key === 'dudeIdle') {
const dx = sprite.x - this.player.x;
const dy = sprite.y - this.player.y;
if (Math.abs(dx) <= 192 && Math.abs(dy) <= 32) {
sprite.flipX = sprite.x < this.player.x;
sprite.play('dudeThrow');
} else {
sprite.play('dudeIdle');
}
} else {
sprite.play('dudeIdle');
}
}
onDudeAnimationUpdate(anim, animFrame, sprite, frameName) {
if (frameName === 'dude6') {
this.throwStar();
}
}
onPlayerAnimationUpdate(anim, animFrame, sprite, frameName) {
if (frameName === 'attack5') {
const x = sprite.x + (sprite.flipX ? -32 : 32);
const y = sprite.y - 16;
this.sword.body.enable = true;
this.sword.body.reset(x, y);
} else if (frameName === 'attack6') {
const x = sprite.x + (sprite.flipX ? 16 : -16);
const y = sprite.y - 32;
this.sword.body.enable = true;
this.sword.body.reset(x, y);
} else {
this.sword.body.enable = false;
}
}
onStarHitTerrain(star) {
star.disableBody(true, true);
}
onStarHitPlayer(star, player) {
player.play('hurt').setVelocityX(0.5 * star.body.velocity.x);
star.disableBody(true, true);
}
onSwordHitGuy(sword, guy) {
guy.active = false;
guy.body.checkCollision.none = true;
}
throwStar() {
const { flipX } = this.guy;
const x = this.guy.x + (flipX ? 32 : -32);
const y = this.guy.y - 32;
this.star
.enableBody(true, x, y, true, true)
.setVelocityX(flipX ? 256 : -256);
}
restart() {
this.scene.restart();
}
teleport(event) {
const { x, y } = playerPositions[event.key];
this.player.enableBody(true, x, y).play('idle');
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment