Skip to content
Snippets Groups Projects
Commit 3e5dbb04 authored by Paolo.Brasolin's avatar Paolo.Brasolin
Browse files

feat: #fe spears have actual physics now

parent ef12c91e
No related branches found
No related tags found
No related merge requests found
......@@ -11,6 +11,7 @@
"dependencies": {
"axios": "^0.26.0",
"damerau-levenshtein": "^1.0.8",
"newton-raphson-method": "^1.0.2",
"phaser": "^3.55.2"
},
"devDependencies": {
......@@ -9222,6 +9223,11 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
"node_modules/newton-raphson-method": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/newton-raphson-method/-/newton-raphson-method-1.0.2.tgz",
"integrity": "sha512-UoBJJxNVVQhviRvled1bL76IjmPls4dNLPeF661FW2eNrv/pKKfRDpOdlN+vo9XamZvj8OMt/KtjOBTFN6I0gw=="
},
"node_modules/nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
......@@ -21973,6 +21979,11 @@
"integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
"dev": true
},
"newton-raphson-method": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/newton-raphson-method/-/newton-raphson-method-1.0.2.tgz",
"integrity": "sha512-UoBJJxNVVQhviRvled1bL76IjmPls4dNLPeF661FW2eNrv/pKKfRDpOdlN+vo9XamZvj8OMt/KtjOBTFN6I0gw=="
},
"nice-try": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
......
......@@ -19,6 +19,7 @@
"dependencies": {
"axios": "^0.26.0",
"damerau-levenshtein": "^1.0.8",
"newton-raphson-method": "^1.0.2",
"phaser": "^3.55.2"
},
"devDependencies": {
......
import Phaser from "phaser";
import nr from "newton-raphson-method";
import Foe from "./foe";
import backend from "./backend";
......@@ -8,8 +10,10 @@ import levenshtein from "damerau-levenshtein";
const fightScene = new Phaser.Scene("fight");
fightScene.foes = [];
fightScene.spears = [];
fightScene.preload = preload;
fightScene.create = create;
fightScene.update = update;
function setAnimation(obj, idleKey) {
obj.play({ key: idleKey, repeat: -1 });
......@@ -222,23 +226,11 @@ function initAndBindGuessPreview(scene) {
}
function shootSpear(enemy, hit, scene = fightScene) {
let startPoint = new Phaser.Math.Vector2(scene.player.x, scene.player.y);
let controlPoint1 = new Phaser.Math.Vector2(
enemy.x + (scene.player.x - enemy.x) / 2,
scene.cameras.main.height - (scene.player.x - enemy.x),
);
let endPoint = new Phaser.Math.Vector2(
enemy.x + enemy.width * 1.6,
scene.cameras.main.height - 60,
);
let message = scene.add
.sprite(scene.cameras.main.width / 2, scene.cameras.main.height / 2)
.setScale(1);
// hit / missing <--- message
if (!hit) {
endPoint = new Phaser.Math.Vector2(-500, scene.cameras.main.height - 60);
message.play({ key: "missing", repeat: 1 });
message.on("animationcomplete", () => {
message.anims.remove("miss");
......@@ -257,70 +249,47 @@ function shootSpear(enemy, hit, scene = fightScene) {
scene.foes.splice(scene.foes.indexOf(enemy), 1);
}
let curve = new Phaser.Curves.QuadraticBezier(
startPoint,
controlPoint1,
endPoint,
);
let spear = scene.add.sprite(scene.player.x, scene.player.y, "spear");
scene.spears.push(spear);
scene.physics.world.enable(spear);
scene.physics.add.collider(spear, scene.ground);
spear.body.setBounce(0.2);
const dx = scene.player.x - enemy.x;
const dy = 0;
const v = 450; // MAGIC NUMBER
const w = 100;
const g = 200;
// TODO: maybe introduce damping
// TODO: expand and use analytic derivative
const f = (theta) =>
2 * dy * Math.pow(w - v * Math.cos(theta), 2) +
2 * v * Math.sin(theta) * (w - v * Math.cos(theta)) * dx +
g * Math.pow(dx, 2);
const theta = nr(f, Math.PI, {
verbose: true,
maxIterations: 100,
});
let graphics = scene.add.graphics();
graphics.lineStyle(1, 0xff00ff, 1);
// curve.draw(graphics); // decomment to see the trajectory
let spear = scene.add.follower(curve);
// console.log(player.x + " " + enemy.x);
if (hit) {
spear.startFollow({
positionOnPath: true,
duration: (scene.cameras.main.width - enemy.x) * 3,
rotateToPath: true,
verticalAdjust: true,
scale: 3,
onComplete: (x, y) => {
let spearHitObj = scene.add
.sprite(
enemy.x + enemy.width * 1.6 - 10,
scene.cameras.main.height - 60,
)
.setScale(2);
setAnimation(spearHitObj, "spearHitAni");
spear.anims.stop("spearAni");
spear.anims.remove("spearAni");
spear.destroy();
setTimeout(() => {
enemy.flipX = false;
setAnimation(enemy, enemy.typeName + "_run");
enemy.movement.stop();
scene.tweens.add({
targets: enemy,
x: -500,
duration: 5000,
onComplete: function () {
enemy.destroy();
//callback(enemy); // ???
},
});
}, 3000);
setTimeout(() => {
spearHitObj.destroy();
}, 4000);
},
});
} else {
enemy.setInteractive();
enemy.movement.resume();
setAnimation(enemy, enemy.typeName + "_walk");
spear.startFollow({
positionOnPath: true,
duration: 3000,
rotateToPath: true,
verticalAdjust: true,
scale: 3,
});
const t = dx / (w - v * Math.cos(theta));
if (theta) {
spear.body.setVelocity(v * Math.cos(theta), v * Math.sin(theta));
}
scene.physics.add.overlap(spear, enemy, (player, nemico) => {
scene.physics.world.removeCollider(this);
// TODO: fancy bounce
scene.spears.splice(scene.spears.indexOf(spear), 1);
spear.destroy();
// TODO: refactor into flee method
nemico.play(nemico.species + "_run");
nemico.flipX = false;
nemico.body.setVelocity(-200, 0);
setTimeout(() => nemico.destroy(), 2000);
});
spear.scale = 2;
spear.anims.play("spearAni");
}
......@@ -346,16 +315,8 @@ function submitTranscription(transcription, scene) {
// TODO: we can have near misses depending on similarity!
let hit = similarity >= 0.9;
let enemy = match;
enemy.sprite.disableInteractive();
// here invoke image
enemy.sprite.movement.pause();
setAnimation(enemy.sprite, enemy.sprite.typeName + "_idle");
// let beginTime = new Date().getTime();
// let endTime = new Date().getTime();
// let deltaTime = endTime - beginTime;
shootSpear(enemy.sprite, hit);
shootSpear(enemy.animalSprite, hit);
}
function gameStart(scene) {
......@@ -371,4 +332,10 @@ function dispatchEnemy(scene) {
});
}
function update() {
this.spears.forEach((spear) => {
spear.setRotation(spear.body.velocity.angle());
});
}
export default fightScene;
......@@ -35,8 +35,9 @@ class Foe {
this.animalSprite = this.scene.physics.add
.sprite(-100, this.scene.cameras.main.height - 100, this.species)
.setScale(-1 * scale, scale)
.setScale(scale)
.setInteractive();
this.animalSprite.flipX = true;
this.scene.physics.add.collider(this.animalSprite, this.scene.ground);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment