diff --git a/frontend/src/js/fight_scene.ts b/frontend/src/js/fight_scene.ts index 786eb9fd0537e1043c4a475c32698dd1120b7339..b6e0e6459428aed296b6fee5782dc5d86d62fff4 100644 --- a/frontend/src/js/fight_scene.ts +++ b/frontend/src/js/fight_scene.ts @@ -194,7 +194,7 @@ export default class FightScene extends Phaser.Scene { scene.foes.splice(scene.foes.indexOf(enemy), 1); // FIXME } - new Spear(this, this.player, enemy); + new Spear(this, this.player, hit ? enemy : undefined); } } diff --git a/frontend/src/js/main.ts b/frontend/src/js/main.ts index cadc4607889263c35cf796f7693da1391959c05c..3e0695f00df0e8782d16a9935b4f06d9e42ceb9d 100644 --- a/frontend/src/js/main.ts +++ b/frontend/src/js/main.ts @@ -15,7 +15,7 @@ const config = { default: "arcade", arcade: { gravity: { y: GRAVITY_Y }, - debug: true, + // debug: true, }, }, scene: FightScene, diff --git a/frontend/src/js/spear.ts b/frontend/src/js/spear.ts index c017b72cd495f6e502426204f10c68916989e56f..74ca7ac4e8e6b0923cd15ff7268a0ec50f425f55 100644 --- a/frontend/src/js/spear.ts +++ b/frontend/src/js/spear.ts @@ -8,15 +8,16 @@ const SPEED = 450; class Spear extends Phaser.Physics.Arcade.Sprite { source: Phaser.GameObjects.Sprite; - target: Phaser.GameObjects.Sprite; + target: Phaser.GameObjects.Sprite | undefined; body: Phaser.Physics.Arcade.Body; constructor( scene: FightScene, source: Phaser.GameObjects.Sprite, - target: Phaser.GameObjects.Sprite, + target: Phaser.GameObjects.Sprite | undefined, ) { super(scene, scene.player.x, scene.player.y, "spear"); + this.play({ key: "spearAni", repeat: -1 }); scene.add.existing(this); this.setScale(3); @@ -27,27 +28,63 @@ class Spear extends Phaser.Physics.Arcade.Sprite { //scene.physics.world.enableBody(this, Phaser.Physics.Arcade.DYNAMIC_BODY); this.body = new Phaser.Physics.Arcade.Body(scene.physics.world, this); scene.physics.world.add(this.body); - scene.physics.add.collider(this, scene.ground); + scene.physics.add.collider(this, scene.ground, this.hitGround.bind(this)); this.body.setBounce(0, 0.2); // TODO: bounce only at small angles - const theta = this.calculateSuccessfulLaunchAngle(source, target); + if (this.target) { + this.shootTarget(); + } else { + this.shootGround(); + } + } + shootTarget() { + const theta = this.calculateSuccessfulLaunchAngle(this.source, this.target); if (theta) { this.body.setVelocity(SPEED * Math.cos(theta), SPEED * Math.sin(theta)); + this.scene.physics.add.overlap( + this, + this.target, + this.hitTarget.bind(this), + ); } else { - console.error("Cannot hit foe."); + console.error("Cannot hit foe. :("); } + } - scene.physics.add.overlap(this, this.target, (_, hitTarget) => { - scene.physics.world.removeCollider(this); - this.destroy(); - hitTarget.flee(); + hitTarget() { + this.scene.physics.world.removeCollider(this); + // TODO: bounce? + this.destroy(); + this.target.flee(); + } + + shootGround() { + const theta = Math.random() * 2 * Math.PI; + this.body.setVelocity(SPEED * Math.cos(theta), SPEED * Math.sin(theta)); + } + + hitGround() { + // this.scene.physics.world.remove(this.body); + this.body.setEnable(false); + this.play({ key: "spearHitAni", repeat: -1, frameRate: 48 }); + this.setRotation(this.rotation - Math.PI / 2); + this.scene.tweens.add({ + targets: this, + alpha: 0, + ease: "Linear", + delay: 500, + duration: 1500, + onComplete: this.destroy.bind(this), }); + } - // this.anims.play("spearAni"); + preUpdate(time, delta): void { + super.preUpdate(time, delta); // NOTE: this preserves sprite animations + if (this.body.enable) this.alignToVelocity(); } - preUpdate(): void { + alignToVelocity() { const velocity = this.body.velocity as Phaser.Math.Vector2; this.setRotation(velocity.angle()); }