From db1baa5db4d532827ba6c44c0a6abb0f9cdd920c Mon Sep 17 00:00:00 2001 From: cha0s Date: Sun, 23 Jun 2024 02:45:05 -0500 Subject: [PATCH] polish: smooth camera --- app/ecs-systems/follow-camera.js | 42 ++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/app/ecs-systems/follow-camera.js b/app/ecs-systems/follow-camera.js index f9cad61..9276612 100644 --- a/app/ecs-systems/follow-camera.js +++ b/app/ecs-systems/follow-camera.js @@ -1,28 +1,54 @@ import {RESOLUTION} from '@/constants.js' import {System} from '@/ecs/index.js'; +const [hx, hy] = [RESOLUTION.x / 2, RESOLUTION.y / 2]; + export default class FollowCamera extends System { + static queries() { + return { + default: ['Camera', 'Position'], + }; + } + reindex(entities) { super.reindex(entities); for (const id of entities) { - this.updateCamera(this.ecs.get(id)); + this.updateCamera(1, this.ecs.get(id)); } } - tick() { - for (const entity of this.ecs.changed(['Position'])) { - this.updateCamera(entity); + tick(elapsed) { + for (const [, , entityId] of this.select('default')) { + this.updateCamera(elapsed * 3, this.ecs.get(entityId)); } } - updateCamera(entity) { + updateCamera(portion, entity) { const {Camera, Position} = entity; if (Camera && Position) { const {AreaSize: {x, y}} = this.ecs.get(1); - const [hx, hy] = [RESOLUTION.x / 2, RESOLUTION.y / 2]; - Camera.x = Math.max(hx, Math.min(Position.x, x - hx)); - Camera.y = Math.max(hy, Math.min(Position.y, y - hy)); + const [px, py] = [ + Math.max(hx, Math.min(Math.round(Position.x), x - hx)), + Math.max(hy, Math.min(Math.round(Position.y), y - hy)), + ]; + if (Camera.x === px && Camera.y === py) { + return; + } + if (Math.abs(Camera.x - px) < 0.1) { + Camera.x = px; + } + if (Math.abs(Camera.y - py) < 0.1) { + Camera.y = py; + } + const [dx, dy] = [ + (px - Camera.x) * portion, + (py - Camera.y) * portion, + ]; + [Camera.x, Camera.y] = [ + Camera.x + (Math.sign(dx) * Math.max(0.1, Math.abs(dx))), + Camera.y + (Math.sign(dy) * Math.max(0.1, Math.abs(dy))), + ]; } }