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.

Revisions

  1. samme created this gist Jul 15, 2024.
    282 changes: 282 additions & 0 deletions GameScene.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,282 @@
    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');
    }
    }