refactor enemy behaviour code.

This commit is contained in:
trans_soup 2023-10-25 21:33:24 +02:00
parent 3c8954ad4e
commit 6c9199923e
4 changed files with 101 additions and 19 deletions

25
js/behaviours/main.mjs Normal file
View file

@ -0,0 +1,25 @@
import * as entity from "../entity.mjs";
export const behaviours = new Map();
export function exists (name) {
return behaviours.has(name);
}
export function get_tick (name) {
return behaviours.get(name).tick;
}
export function init (enemy, name, params) {
entity.get_meta(enemy).set("behaviour", name);
const behaviour = behaviours.get(name);
if (behaviour.hasOwnProperty("init")) {
behaviour.init(enemy, params);
}
}
import sine_x from "./sine_x.mjs";
behaviours.set("sine_x", sine_x);

34
js/behaviours/sine_x.mjs Normal file
View file

@ -0,0 +1,34 @@
import * as entity from "../entity.mjs";
import { underride } from "../underride.mjs";
export default {
tick: (enemy, deltatime) => {
const {y} = entity.get_pos(enemy);
const meta = entity.get_meta(enemy);
const age = meta.get("age");
// `movement_speed` is in hertz and `Math.sin` input is in radians.
const age_factor = meta.get("movement_speed") * Math.PI * 2;
const x = meta.get("center_x") + Math.sin(age * age_factor) * meta.get("movement_scale");
entity.set_pos(enemy, x, y);
},
init: (enemy, params = {}) => {
params = underride(params, {
movement_scale: 100,
movement_speed: 1/4,
});
const {x} = entity.get_pos(enemy);
const meta = entity.get_meta(enemy);
meta.set("center_x", x);
meta.set("movement_scale", params.movement_scale);
meta.set("movement_speed", params.movement_speed);
},
};

View file

@ -1,14 +1,11 @@
import { assert } from "./test.mjs";
import * as entity from "./entity.mjs";
import { register_tick } from "./tick.mjs";
import * as behaviours from "./behaviours/main.mjs";
const enemies = [];
const behaviours = new Map();
function tick_enemy (enemy, deltatime) {
const meta = entity.get_meta(enemy);
const age = meta.get("age") + deltatime;
@ -16,8 +13,9 @@ function tick_enemy (enemy, deltatime) {
if (meta.has("behaviour")) {
const b = meta.get("behaviour");
if (behaviours.has(b)) {
behaviours.get(b)(enemy, deltatime)
if (behaviours.exists(b)) {
const callback = behaviours.get_tick(b);
callback(enemy, deltatime);
}
}
}
@ -32,8 +30,8 @@ export function get_all () {
return enemies;
}
function create () {
const enemy = entity.create(100, 100, 40, 40);
function create (...args) {
const enemy = entity.create(...args);
const meta = entity.get_meta(enemy);
meta.set("age", 0);
@ -41,15 +39,10 @@ function create () {
return enemy;
}
const e = create();
function set_behaviour (enemy, behaviour, params) {
behaviours.init(enemy, behaviour, params);
}
const e = create(300, 100, 40, 40);
set_behaviour(e, "sine_x");
enemies.push(e);
entity.get_meta(e).set("behaviour", "sine_x");
behaviours.set("sine_x", (enemy, deltatime) => {
const {x, y} = entity.get_pos(enemy);
const meta = entity.get_meta(enemy);
const age = meta.get("age");
entity.set_pos(enemy, 100 + Math.sin(age) * 80, y);
});

30
js/underride.mjs Normal file
View file

@ -0,0 +1,30 @@
import { assert } from "./test.mjs";
function shallow_mutable_copy (source, target) {
for (const [key, value] of Object.entries(source)) {
target[key] = value;
}
}
export function underride (object, template) {
const result = {};
shallow_mutable_copy(template, result);
shallow_mutable_copy(object, result);
return result;
}
assert("underriding works.", _ => {
const object = underride({
gay: true,
trans: true,
}, {
trans: false,
invisible: false,
});
return object.gay && object.trans && (object.invisible === false);
});