base2020/src/game/Message.ts

71 lines
2.4 KiB
TypeScript

import { DrawSet } from "../applet/Render";
import { Floor } from "../ecs/Components";
import { Join, Remove } from "../ecs/Data";
import { TransformCx } from "../ecs/Location";
import { Data, GamePhase, World } from "./GameComponents";
/*export function SpawnMessage(color: string, text: string) {
return function(data: Data, world: World, x: number, timeoutDelta = 0): Id {
return Create(data, {
location: new Location({
X: -world.width,
Y: world.height/2,
VX: world.width
}),
message: new Message(world.cloudLayer, color, text, 3 + timeoutDelta)
});
}
}*/
const FONT_SIZE = 16;
const ADVANCE = 20;
export function ArrangeMessages(data: Data, world: World, interval: number) {
const messages = Join(data, "message", "location");
messages.sort(([{timeout: timeoutA}, {}], [{timeout: timeoutB}, {}]) => timeoutA - timeoutB);
let y = Floor(world.height / 3);
messages.forEach(([message, location]) => {
message.targetY = y;
y = Floor(y + ADVANCE);
const delta = message.targetY - location.Y;
if(Math.abs(delta) < 100 * interval) {
location.Y = message.targetY;
location.VY = Floor(0);
} else {
location.VY = Floor(Math.sign(delta) * 100);
}
if(location.X >= world.width / 2 && message.timeout >= 0) {
location.X = Floor(world.width / 2);
message.timeout -= interval;
location.VX = Floor(0);
} else if(world.phase == GamePhase.PLAYING) {
location.VX = world.width;
}
});
}
export function ReapMessages(data: Data, {width, height, debug}: World) {
let count = 0;
Join(data, "message", "location", "id").forEach(([_message, {X}, id]) => {
count++;
if(X > width * 2) {
Remove(data, id);
}
});
}
export function RenderMessages(data: Data, drawSet: DrawSet) {
drawSet.queue(...Join(data, "message", "location").map(
([{layer, color, message}, location]) => data.layers[layer].toRender((cx, dt) => {
TransformCx(cx, location, dt);
cx.font = `${FONT_SIZE}px monospace`;
cx.fillStyle = color;
cx.textAlign = "center";
cx.textBaseline = "middle";
cx.fillText(message, 0, 0);
}))
);
}