diff --git a/app/ecs/components/arbitrary.js b/app/ecs/components/arbitrary.js new file mode 100644 index 0000000..ce0a86a --- /dev/null +++ b/app/ecs/components/arbitrary.js @@ -0,0 +1,20 @@ +import Component from '@/ecs/component.js'; + +export default class Arbitrary extends Component { + instanceFromSchema() { + return class ArbitraryInstance extends super.instanceFromSchema() { + bag = {}; + toFullJSON() { + return { + blob: JSON.stringify(this.bag), + }; + } + }; + } + load(instance) { + instance.bag = JSON.parse(instance.blob); + } + static properties = { + blob: {type: 'string'}, + }; +} diff --git a/app/ecs/components/behaving.js b/app/ecs/components/behaving.js index 337ffb4..ac3c64a 100644 --- a/app/ecs/components/behaving.js +++ b/app/ecs/components/behaving.js @@ -8,6 +8,7 @@ export default class Behaving extends Component { tick(elapsed) { const routine = this.$$routineInstances[this.currentRoutine]; if (routine) { + routine.locals.ecs = ecs; routine.locals.entity = ecs.get(this.entity); routine.tick(elapsed); } diff --git a/app/util/script.js b/app/util/script.js index 3e2a994..2fbff58 100644 --- a/app/util/script.js +++ b/app/util/script.js @@ -68,7 +68,7 @@ export default class Script { } let result; do { - result = this.iterator.next(); + result = this.iterator.next(this.locals.elapsed); if (result.value instanceof Ticker) { this.$$ticker = result.value; const tickerResult = this.$$ticker.tick(elapsed); diff --git a/resources/kitty/initial.js b/resources/kitty/initial.js index 490c5db..38a93d9 100644 --- a/resources/kitty/initial.js +++ b/resources/kitty/initial.js @@ -1,7 +1,8 @@ import * as Math from '@/util/math.js'; import Ticker from '@/util/ticker.js'; -export default function*({entity: {Controlled, Direction, Sprite}}) { +export default function*({entity}) { + const {Controlled, Direction, Sprite} = entity; Direction.direction = Math.random() * Math.TAU; Controlled.directionMove(Direction.direction); yield Ticker.wait(0.25 + Math.random() * 2.25); diff --git a/resources/magic-swords/initial.js b/resources/magic-swords/initial.js new file mode 100644 index 0000000..ced8a22 --- /dev/null +++ b/resources/magic-swords/initial.js @@ -0,0 +1,22 @@ +import * as Math from '@/util/math.js'; +import Ticker from '@/util/ticker.js'; + +const SPREAD = 0.5; + +export default function*({ecs, entity}) { + const {Arbitrary, Controlled, Direction, id, Position, Speed, Sprite} = entity; + let accumulated = 0; + Controlled.directionMove(Direction.direction); + while (accumulated <= SPREAD) { + accumulated += yield Ticker.wait(); + Speed.speed = 100 * (1 - (accumulated / SPREAD)); + } + const {where: {x, y}} = Arbitrary.bag; + const toward = Math.atan2(y - Position.y, x - Position.x); + Direction.direction = (Math.TAU + toward) % Math.TAU; + Controlled.directionMove(Direction.direction); + Speed.speed = 400; + yield Ticker.wait(0.5); + Sprite.alpha = 0; + ecs.destroy(id); +} diff --git a/resources/magic-swords/start.js b/resources/magic-swords/start.js index c0b59c3..1117ef8 100644 --- a/resources/magic-swords/start.js +++ b/resources/magic-swords/start.js @@ -1,20 +1,22 @@ import * as Math from '@/util/math.js'; import Ticker from '@/util/ticker.js'; -export default function*(locals) { - const {ecs, where, wielder} = locals; - const {Player, Position} = wielder; - - const EVERY = 0.03; - const N = 14; - const SPREAD = 1; +const SHOTS = 14; +function createShots(where, wielder) { const offset = Math.random() * Math.TAU; - - const specs = []; - - for (let i = 0; i < N; ++i) { - specs.push({ + const {Player, Position} = wielder; + const shots = []; + for (let i = 0; i < SHOTS; ++i) { + shots.push({ + Arbitrary: { + blob: JSON.stringify({where}), + }, + Behaving: { + routines: { + initial: '/resources/magic-swords/initial.js', + }, + }, Collider: { bodies: [ { @@ -30,7 +32,7 @@ export default function*(locals) { ], }, Controlled: {}, - Direction: {direction: offset + Math.TAU * (i / N)}, + Direction: {direction: offset + Math.TAU * (i / SHOTS)}, Forces: {}, Harmful: { harmScript: '/resources/magic-swords/harm.js', @@ -40,61 +42,19 @@ export default function*(locals) { Position: {x: Position.x, y: Position.y}, Speed: {}, Sprite: { - alpha: 0, source: '/resources/magic-swords/magic-sword-shot.json', }, Ticking: {}, VisibleAabb: {}, }); } - - const creating = Array.from(ecs.createMany(specs)).map((entityId) => ecs.get(entityId)); - - const shot = creating.shift(); - shot.Sprite.alpha = 1; - const shots = [ - { - accumulated: 0, - entity: shot, - }, - ]; - - let spawner = 0; - while (shots.length > 0) { - spawner += locals.elapsed; - if (creating.length > 0 && spawner >= EVERY) { - const entity = creating.shift(); - entity.Sprite.alpha = 1; - shots.push({accumulated: 0, entity}) - spawner -= EVERY; - } - const destroying = []; - for (const shot of shots) { - shot.accumulated += locals.elapsed; - if (shot.accumulated <= SPREAD) { - shot.entity.Speed.speed = 100 * (1 - (shot.accumulated / SPREAD)) - } - else { - if (!shot.oriented) { - const toward = Math.atan2( - where.y - shot.entity.Position.y, - where.x - shot.entity.Position.x, - ) - shot.entity.Speed.speed = 400; - shot.entity.Direction.direction = (Math.TAU + toward) % Math.TAU; - shot.oriented = true; - } - if (shot.accumulated > 1.5) { - shot.entity.Sprite.alpha = 0; - ecs.destroy(shot.entity.id); - destroying.push(shot); - } - } - shot.entity.Controlled.directionMove(shot.entity.Direction.direction); - } - for (let i = 0; i < destroying.length; ++i) { - shots.splice(shots.indexOf(destroying[i]), 1); - } - yield Ticker.wait(); - } + return shots; +} + +export default function*({ecs, where, wielder}) { + const shots = createShots(where, wielder); + do { + ecs.create(shots.shift()); + yield Ticker.wait(0.03); + } while (shots.length > 0); }