diff options
Diffstat (limited to 'test-client')
-rw-r--r-- | test-client/main.ts | 67 | ||||
-rw-r--r-- | test-client/tiles.ts | 4 | ||||
-rw-r--r-- | test-client/util.ts | 15 |
3 files changed, 72 insertions, 14 deletions
diff --git a/test-client/main.ts b/test-client/main.ts index 3c1285a4..009b1705 100644 --- a/test-client/main.ts +++ b/test-client/main.ts @@ -1,8 +1,8 @@ /// <reference lib="dom" /> -import { ID, Item, PacketC, PacketS, Tile } from "./protocol.ts"; +import { ID, Item, PacketC, PacketS, Tile, Vec2 } from "./protocol.ts"; import { FALLBACK_TILE, TILES } from "./tiles.ts"; -import { V2, ceil_v2, floor_v2, lerp_v2_mut, normalize } from "./util.ts"; +import { V2, add_v2, ceil_v2, floor_v2, lerp_exp_v2_mut, normalize } from "./util.ts"; let ctx: CanvasRenderingContext2D; let canvas: HTMLCanvasElement; @@ -34,9 +34,9 @@ document.addEventListener("DOMContentLoaded", () => { interface PlayerData { x: number; y: number, name: string, rot: number, hand?: ID } const players = new Map<number, PlayerData>() -interface ItemData { x: number; y: number, kind: Item } +interface ItemData { kind: Item, tile?: V2, player?: ID, tracking_player: boolean, x: number, y: number } const items = new Map<number, ItemData>() -interface TileData { x: number; y: number, kind: Tile } +interface TileData { x: number; y: number, kind: Tile, items: ID[], active: boolean } const tiles = new Map<string, TileData>() let my_id: number = -1 @@ -49,7 +49,7 @@ function packet(p: PacketC) { if ("joined" in p) { my_id = p.joined.id } else if ("add_player" in p) { - if (p.add_player.hand) items.set(p.add_player.hand[0], { kind: p.add_player.hand[1], x: 0, y: 0 }) + if (p.add_player.hand) items.set(p.add_player.hand[0], { kind: p.add_player.hand[1], player: p.add_player.id, tracking_player: true, x: 0, y: 0 }) players.set(p.add_player.id, { x: 0, y: 0, name: p.add_player.name, rot: 0, hand: p.add_player.hand?.[0] }) } else if ("remove_player" in p) { players.delete(p.remove_player.id) @@ -60,17 +60,22 @@ function packet(p: PacketC) { pl.y = p.position.pos[1] pl.rot = p.position.rot } else if ("take_item" in p) { - // TODO + const item = items.get(p.take_item.item)! + item.tracking_player = true + item.player = p.take_item.player } else if ("put_item" in p) { - // TODO + const item = items.get(p.put_item.item)! + item.tracking_player = false + item.tile = { x: p.put_item.pos[0], y: p.put_item.pos[1] } } else if ("produce_item" in p) { - // TODO + items.set(p.produce_item.id, { kind: p.produce_item.kind, x: p.produce_item.pos[0] + 0.5, y: p.produce_item.pos[1] + 0.5, tracking_player: false, tile: { x: p.produce_item.pos[0], y: p.produce_item.pos[1] } }) + tiles.get(p.produce_item.pos.toString())!.items.push(p.produce_item.id) } else if ("consume_item" in p) { // TODO } else if ("set_active" in p) { // TODO } else if ("update_map" in p) { - tiles.set(p.update_map.pos.toString(), { x: p.update_map.pos[0], y: p.update_map.pos[1], kind: p.update_map.tile }) + tiles.set(p.update_map.pos.toString(), { x: p.update_map.pos[0], y: p.update_map.pos[1], kind: p.update_map.tile, active: false, items: [] }) } else console.warn("unknown packet", p); } @@ -78,13 +83,22 @@ const keys_down = new Set(); const HANDLED_KEYS = ["KeyW", "KeyA", "KeyS", "KeyD", "Space"] function keyboard(ev: KeyboardEvent, down: boolean) { if (HANDLED_KEYS.includes(ev.code)) ev.preventDefault() - if (ev.code == "Space") interact() + if (ev.code == "Space" && down) interact() if (down) keys_down.add(ev.code) else keys_down.delete(ev.code) } -function interact() { +function get_interact_target(): Vec2 | undefined { + const me = players.get(my_id) + if (!me) return + return [ + Math.floor(me.x + Math.sin(me.rot)), + Math.floor(me.y + Math.cos(me.rot)) + ] +} +function interact() { + send({ interact: { pos: get_interact_target()! } }) } function tick_update() { @@ -105,7 +119,11 @@ function frame_update(dt: number) { p.x += input.x * dt * 5 p.y += input.y * dt * 5 - lerp_v2_mut(camera, p, dt * 10.) + for (const [_, i] of items) { + lerp_exp_v2_mut(i, i.tracking_player ? players.get(i.player!)! : add_v2(i.tile!, 0.5), dt * 10.) + } + + lerp_exp_v2_mut(camera, p, dt * 10.) } function resize() { @@ -181,6 +199,31 @@ function draw_ingame() { ctx.restore() } + for (const [_, item] of items) { + ctx.save() + + ctx.translate(item.x, item.y) + ctx.fillStyle = "rgb(252, 19, 19)" + ctx.fillRect(-0.1, -0.1, 0.2, 0.2) + ctx.restore() + } + + draw_interact_target() + + ctx.restore() +} + +function draw_interact_target() { + const [x, y] = get_interact_target() ?? [0, 0] + ctx.save() + ctx.translate(x, y) + + ctx.lineCap = "round" + ctx.lineJoin = "round" + ctx.lineWidth = 0.06 + 0.03 * Math.sin(Date.now() / 100) + ctx.strokeStyle = "rgb(84, 122, 236)" + ctx.strokeRect(0, 0, 1, 1) + ctx.restore() } diff --git a/test-client/tiles.ts b/test-client/tiles.ts index 3b15385c..6eb1dc29 100644 --- a/test-client/tiles.ts +++ b/test-client/tiles.ts @@ -24,10 +24,12 @@ function circle(radius: number, fill: string, stroke?: string, stroke_width?: nu } const table = [base("rgb(133, 76, 38)")]; +const floor = [base("#333", "#222", 0.05)]; export const FALLBACK_TILE: Component[] = [base("#f0f")]; export const TILES: { [key: string]: Component[] } = { - "floor": [base("#333", "#222", 0.05)], + "floor": floor, "table": table, "pan": [...table, circle(0.4, "#444", "#999")], + "flour_bag": [...floor, circle(0.5, "#fff", "#ddd")], } diff --git a/test-client/util.ts b/test-client/util.ts index 99f0c013..6febac37 100644 --- a/test-client/util.ts +++ b/test-client/util.ts @@ -2,9 +2,22 @@ export interface V2 { x: number, y: number } export function length(p: V2): number { return Math.sqrt(p.x * p.x + p.y * p.y) } export function normalize_mut(p: V2) { const l = length(p); if (l == 0) return; p.x /= l; p.y /= l } export function normalize(p: V2): V2 { let l = length(p); if (l == 0) l = 1; return { x: p.x / l, y: p.y / l } } -export function lerp_v2_mut(current: V2, target: V2, dt: number) { +export function lerp_exp(current: number, target: number, dt: number): number { + return target + (current - target) * Math.exp(-dt) +} +export function lerp_v2(a: V2, b: V2, t: number): V2 { + return { + x: a.x * (1 - t) + b.x * t, + y: a.y * (1 - t) + b.y * t, + } +} +export function lerp_exp_v2_mut(current: V2, target: V2, dt: number) { current.x = target.x + (current.x - target.x) * Math.exp(-dt) current.y = target.y + (current.y - target.y) * Math.exp(-dt) } export function floor_v2(p: V2): V2 { return { x: Math.floor(p.x), y: Math.floor(p.y) } } export function ceil_v2(p: V2): V2 { return { x: Math.ceil(p.x), y: Math.ceil(p.y) } } +export function add_v2(p: V2, o: V2 | number) { + if (typeof o == "number") return { x: p.x + o, y: p.y + o } + else return { x: p.x + o.x, y: p.y + o.y } +}
\ No newline at end of file |