From 3eb94f2ef89712588ba181a9cdb743c373690aa7 Mon Sep 17 00:00:00 2001 From: cha0s Date: Wed, 24 Jul 2024 09:28:35 -0500 Subject: [PATCH] refactor: continuous direction --- app/ecs/components/controlled.js | 26 ++++++++++++++++++++++++++ app/ecs/components/direction.js | 13 ++++++++++++- app/ecs/components/emitter.js | 22 +++++++++++----------- app/ecs/components/interacts.js | 13 +++++++------ app/ecs/components/inventory.js | 22 +++++++++++----------- app/ecs/systems/control-direction.js | 9 +++++---- app/ecs/systems/sprite-direction.js | 10 +++++----- app/react/components/pixi/ecs.jsx | 2 +- app/server/create/homestead.js | 2 +- app/server/create/player.js | 2 +- app/util/math.js | 5 +++++ public/assets/hoe/start.js | 2 +- public/assets/kitty/initial.js | 11 ++++++----- public/assets/tomato-seeds/start.js | 7 ++++--- public/assets/watering-can/start.js | 2 +- 15 files changed, 97 insertions(+), 51 deletions(-) diff --git a/app/ecs/components/controlled.js b/app/ecs/components/controlled.js index 6474fff..e1eb807 100644 --- a/app/ecs/components/controlled.js +++ b/app/ecs/components/controlled.js @@ -3,6 +3,32 @@ import Component from '@/ecs/component.js'; export default class Controlled extends Component { instanceFromSchema() { return class ControlledInstance extends super.instanceFromSchema() { + directionMove(direction) { + const x = Math.cos(direction); + if (x > 0) { + this.moveLeft = 0; + this.moveRight = x; + } + else { + this.moveLeft = -x; + this.moveRight = 0; + } + const y = Math.sin(direction); + if (y > 0) { + this.moveUp = 0; + this.moveDown = y; + } + else { + this.moveUp = -y; + this.moveDown = 0; + } + } + stop() { + this.moveRight = 0; + this.moveDown = 0; + this.moveLeft = 0; + this.moveUp = 0; + } toJSON() { return {}; } diff --git a/app/ecs/components/direction.js b/app/ecs/components/direction.js index ce84026..247cdb1 100644 --- a/app/ecs/components/direction.js +++ b/app/ecs/components/direction.js @@ -1,7 +1,18 @@ import Component from '@/ecs/component.js'; +import {HALF_PI, TAU} from '@/util/math.js'; export default class Direction extends Component { + instanceFromSchema() { + return class DirectionInstance extends super.instanceFromSchema() { + static quantize(d, n) { + return Math.floor(((d + (TAU / (n * 2))) % TAU) / (TAU / n)); + } + quantize(n) { + return this.constructor.quantize(this.direction, n); + } + }; + } static properties = { - direction: {type: 'uint8'}, + direction: {defaultValue: HALF_PI, type: 'float32'}, }; } diff --git a/app/ecs/components/emitter.js b/app/ecs/components/emitter.js index a50dbdd..60e07dc 100644 --- a/app/ecs/components/emitter.js +++ b/app/ecs/components/emitter.js @@ -1,16 +1,6 @@ import Component from '@/ecs/component.js'; export default class Emitter extends Component { - mergeDiff(original, update) { - const merged = {}; - if (update.emit) { - merged.emit = { - ...original.emit, - ...update.emit, - } - } - return merged; - } instanceFromSchema() { const Component = this; return class EmitterInstance extends super.instanceFromSchema() { @@ -21,4 +11,14 @@ export default class Emitter extends Component { } }; } -} \ No newline at end of file + mergeDiff(original, update) { + const merged = {}; + if (update.emit) { + merged.emit = { + ...original.emit, + ...update.emit, + } + } + return merged; + } +} diff --git a/app/ecs/components/interacts.js b/app/ecs/components/interacts.js index bdb720f..29033e2 100644 --- a/app/ecs/components/interacts.js +++ b/app/ecs/components/interacts.js @@ -8,18 +8,19 @@ export default class Interacts extends Component { const {Direction, Position} = ecs.get(this.entity); let x0 = Position.x - 8; let y0 = Position.y - 8; - if (0 === Direction.direction) { - y0 -= 12 - } - if (1 === Direction.direction) { + const direction = Direction.quantize(4); + if (0 === direction) { x0 += 12 } - if (2 === Direction.direction) { + if (1 === direction) { y0 += 12 } - if (3 === Direction.direction) { + if (2 === direction) { x0 -= 12 } + if (3 === direction) { + y0 -= 12 + } return {x0, x1: x0 + 15, y0, y1: y0 + 15}; } toJSON() { diff --git a/app/ecs/components/inventory.js b/app/ecs/components/inventory.js index 4694787..a537f85 100644 --- a/app/ecs/components/inventory.js +++ b/app/ecs/components/inventory.js @@ -33,21 +33,21 @@ class ItemProxy { let startY = position.y; switch (direction) { case 0: - startX += projection.distance[1]; - startY -= projection.distance[0]; - break; - case 1: startX += projection.distance[0]; startY += projection.distance[1]; break; - case 2: + case 1: startX -= projection.distance[1]; startY += projection.distance[0]; break; - case 3: + case 2: startX -= projection.distance[0]; startY -= projection.distance[1]; break; + case 3: + startX += projection.distance[1]; + startY -= projection.distance[0]; + break; } const projected = []; for (const row in projection.grid) { @@ -58,17 +58,17 @@ class ItemProxy { let axe; switch (direction) { case 0: - axe = [column, row]; - break; - case 1: axe = [-row, column]; break; - case 2: + case 1: axe = [-column, -row]; break; - case 3: + case 2: axe = [row, -column]; break; + case 3: + axe = [column, row]; + break; } const x = startX + parseInt(axe[0]); const y = startY + parseInt(axe[1]); diff --git a/app/ecs/systems/control-direction.js b/app/ecs/systems/control-direction.js index 067122c..251e8a6 100644 --- a/app/ecs/systems/control-direction.js +++ b/app/ecs/systems/control-direction.js @@ -1,4 +1,5 @@ import {System} from '@/ecs/index.js'; +import {HALF_PI} from '@/util/math.js'; export default class ControlDirection extends System { @@ -9,16 +10,16 @@ export default class ControlDirection extends System { continue; } if (moveUp > 0) { - Direction.direction = 0; + Direction.direction = HALF_PI * 3; } if (moveDown > 0) { - Direction.direction = 2; + Direction.direction = HALF_PI * 1; } if (moveLeft > 0) { - Direction.direction = 3; + Direction.direction = HALF_PI * 2; } if (moveRight > 0) { - Direction.direction = 1; + Direction.direction = HALF_PI * 0; } } } diff --git a/app/ecs/systems/sprite-direction.js b/app/ecs/systems/sprite-direction.js index f3939ac..ccb8f4d 100644 --- a/app/ecs/systems/sprite-direction.js +++ b/app/ecs/systems/sprite-direction.js @@ -25,12 +25,12 @@ export default class SpriteDirection extends System { } if (Direction) { const name = { - 0: 'up', - 1: 'right', - 2: 'down', - 3: 'left', + 0: 'right', + 1: 'down', + 2: 'left', + 3: 'up', }; - parts.push(name[Direction.direction]); + parts.push(name[Direction.quantize(4)]); } if (parts.length > 0) { Sprite.animation = parts.join(':'); diff --git a/app/react/components/pixi/ecs.jsx b/app/react/components/pixi/ecs.jsx index d360e25..399cf4e 100644 --- a/app/react/components/pixi/ecs.jsx +++ b/app/react/components/pixi/ecs.jsx @@ -108,7 +108,7 @@ export default function Ecs({applyFilters, camera, monopolizers, scale}) { if (entity) { const {Direction, Position, Wielder} = entity; setPosition(Position.toJSON()); - setProjected(Wielder.activeItem()?.project(Position.tile, Direction.direction)); + setProjected(Wielder.activeItem()?.project(Position.tile, Direction.quantize(4))); } }, [ecs, mainEntity, scale]); useEffect(() => { diff --git a/app/server/create/homestead.js b/app/server/create/homestead.js index 1b81778..21dd9dd 100644 --- a/app/server/create/homestead.js +++ b/app/server/create/homestead.js @@ -116,7 +116,7 @@ export default async function createHomestead(id) { ], }, Controlled: {}, - Direction: {direction: 2}, + Direction: {}, Emitter: {}, Forces: {}, Interactive: { diff --git a/app/server/create/player.js b/app/server/create/player.js index 504a60c..29d49c1 100644 --- a/app/server/create/player.js +++ b/app/server/create/player.js @@ -14,7 +14,7 @@ export default async function createPlayer(id) { ], }, Controlled: {}, - Direction: {direction: 2}, + Direction: {}, Ecs: {path: ['homesteads', `${id}`].join('/')}, Emitter: {}, Forces: {}, diff --git a/app/util/math.js b/app/util/math.js index 91d6a2a..fd5c254 100644 --- a/app/util/math.js +++ b/app/util/math.js @@ -45,7 +45,12 @@ export const { SQRT2, } = Math; +export const SQRT_2_2 = Math.sqrt(2) / 2; +export const EIGHTH_PI = Math.PI / 8; +export const QUARTER_PI = Math.PI / 4; +export const HALF_PI = Math.PI / 2; export const TAU = Math.PI * 2; +export const PI_180 = Math.PI / 180; export function bresenham({x: x1, y: y1}, {x: x2, y: y2}) { const points = []; diff --git a/public/assets/hoe/start.js b/public/assets/hoe/start.js index 3dc4325..5aab7fa 100644 --- a/public/assets/hoe/start.js +++ b/public/assets/hoe/start.js @@ -1,5 +1,5 @@ const {Direction, Position, Wielder} = wielder -const projected = Wielder.activeItem()?.project(Position.tile, Direction.direction) +const projected = Wielder.activeItem()?.project(Position.tile, Direction.quantize(4)) if (projected?.length > 0) { const {Controlled, Emitter, Sound, Sprite} = wielder diff --git a/public/assets/kitty/initial.js b/public/assets/kitty/initial.js index f930f21..2a9e1d4 100644 --- a/public/assets/kitty/initial.js +++ b/public/assets/kitty/initial.js @@ -1,15 +1,16 @@ -entity.Direction.direction = Math.floor(Math.random() * 4); +entity.Direction.direction = Math.random() * Math.TAU; + +entity.Controlled.directionMove(entity.Direction.direction); -const map = {0: 'moveUp', 1: 'moveRight', 2: 'moveDown', 3: 'moveLeft'}; -entity.Controlled[map[entity.Direction.direction]] = 1; await wait(0.25 + Math.random() * 2.25); -entity.Controlled[map[entity.Direction.direction]] = 0; + +entity.Controlled.stop(); entity.Sprite.isAnimating = 0; await wait(1 + Math.random() * 3); -entity.Direction.direction = Math.floor(Math.random() * 4); +entity.Direction.direction = Math.random() * Math.TAU; await wait(0.5 + Math.random() * 2.5); diff --git a/public/assets/tomato-seeds/start.js b/public/assets/tomato-seeds/start.js index a275f3e..e0010e2 100644 --- a/public/assets/tomato-seeds/start.js +++ b/public/assets/tomato-seeds/start.js @@ -1,5 +1,5 @@ const {Direction, Position, Wielder} = wielder -const projected = Wielder.activeItem()?.project(Position.tile, Direction.direction) +const projected = Wielder.activeItem()?.project(Position.tile, Direction.quantize(4)) if (projected?.length > 0) { const {Controlled, Emitter, Sound, Sprite} = wielder const {TileLayers} = ecs.get(1) @@ -120,9 +120,10 @@ if (projected?.length > 0) { Sound.play('/assets/sow.wav'); Sprite.animation = ['moving', direction].join(':'); + const directionMap = {0: 'right', 1: 'down', 2: 'left', 3: 'up'}; for (let i = 0; i < 6; ++i) { - Direction.direction = Math.floor(Math.random() * 4); - Sprite.animation = ['moving', 0 === Direction.direction ? 'up' : (1 === Direction.direction ? 'right' : (2 === Direction.direction ? 'down' : 'left'))].join(':'); + Direction.direction = Math.HALF_PI * Math.floor(Math.random() * 4); + Sprite.animation = ['moving', directionMap[Direction.quantize(4)]].join(':'); await wait(0.125); } diff --git a/public/assets/watering-can/start.js b/public/assets/watering-can/start.js index d8fddb0..176fc7c 100644 --- a/public/assets/watering-can/start.js +++ b/public/assets/watering-can/start.js @@ -1,5 +1,5 @@ const {Direction, Position, Wielder} = wielder -const projected = Wielder.activeItem()?.project(Position.tile, Direction.direction) +const projected = Wielder.activeItem()?.project(Position.tile, Direction.quantize(4)) if (projected?.length > 0) { const {Controlled, Emitter, Sound, Sprite} = wielder