diff options
Diffstat (limited to 'test-client')
-rw-r--r-- | test-client/main.ts | 47 | ||||
-rw-r--r-- | test-client/movement.ts | 62 | ||||
-rw-r--r-- | test-client/util.ts | 13 | ||||
-rw-r--r-- | test-client/visual.ts | 3 |
4 files changed, 67 insertions, 58 deletions
diff --git a/test-client/main.ts b/test-client/main.ts index 84dfd555..1e6168ed 100644 --- a/test-client/main.ts +++ b/test-client/main.ts @@ -1,11 +1,10 @@ /// <reference lib="dom" /> +import { player_movement_update } from "./movement.ts"; import { Gamedata, ItemIndex, Message, PacketC, PacketS, PlayerID, TileIndex } from "./protocol.ts"; -import { V2, add_v2, length, lerp_exp_v2_mut, normalize, aabb_circle_distance, sub_v2, lerp_exp } from "./util.ts"; +import { V2, add_v2, lerp_exp_v2_mut, normalize, lerp_exp } from "./util.ts"; import { draw_ingame, draw_wait } from "./visual.ts"; -export const PLAYER_SIZE = 0.4; - export let ctx: CanvasRenderingContext2D; export let canvas: HTMLCanvasElement; let ws: WebSocket; @@ -205,14 +204,7 @@ function frame_update(dt: number) { y: (+keys_down.has("KeyS") - +keys_down.has("KeyW")) }) - if (length(input) > 0.1) lerp_exp_v2_mut(p.facing, input, dt * 10.) - p.rot = Math.atan2(p.facing.x, p.facing.y) - p.vel.x += input.x * dt * 0.5 - p.vel.y += input.y * dt * 0.5 - p.x += p.vel.x - p.y += p.vel.y - collide_player(p, dt) - lerp_exp_v2_mut(p.vel, { x: 0, y: 0 }, dt * 5.) + player_movement_update(p, dt, input) const update_item = (item: ItemData) => { if (item.tracking) lerp_exp_v2_mut(item, item.tracking, dt * 10.) @@ -260,36 +252,3 @@ function draw() { else throw new Error(`ws state invalid`); requestAnimationFrame(draw) } - -function collide_player(p: PlayerData, dt: number) { - const tiles_ignored = ["floor", "door", "chair"].map(t => data.tile_names.indexOf(t)) - for (const [_, tile] of tiles) { - if (tiles_ignored.includes(tile.kind)) continue - const d = aabb_circle_distance(tile.x, tile.y, tile.x + 1, tile.y + 1, p.x, p.y) - if (d > PLAYER_SIZE) continue - - const h = 0.01 - const d_sample_x = aabb_circle_distance(tile.x, tile.y, tile.x + 1, tile.y + 1, p.x + h, p.y) - const d_sample_y = aabb_circle_distance(tile.x, tile.y, tile.x + 1, tile.y + 1, p.x, p.y + h) - const grad_x = (d_sample_x - d) / h - const grad_y = (d_sample_y - d) / h - - p.x += (PLAYER_SIZE - d) * grad_x - p.y += (PLAYER_SIZE - d) * grad_y - - const vdotn = (grad_x * p.vel.x) + (grad_y * p.vel.y) - p.vel.x -= grad_x * vdotn - p.vel.y -= grad_y * vdotn - } - - for (const [_, player] of players) { - const diff = sub_v2(p, player) - const d = length(diff) - if (d < 0.01) continue - if (d >= PLAYER_SIZE * 2) continue - const norm = normalize(diff); - const f = 1 / (1 + d) - p.vel.x += norm.x * f * dt - p.vel.y += norm.y * f * dt - } -} diff --git a/test-client/movement.ts b/test-client/movement.ts new file mode 100644 index 00000000..883a64ec --- /dev/null +++ b/test-client/movement.ts @@ -0,0 +1,62 @@ +import { data } from "./main.ts"; +import { tiles, players, PlayerData } from "./main.ts"; +import { V2, normalize, length, sub_v2, lerp_exp_v2_mut } from "./util.ts"; + +export const PLAYER_SIZE = 0.4; + +export function player_movement_update(p: PlayerData, dt: number, input: V2) { + if (length(input) > 0.1) lerp_exp_v2_mut(p.facing, input, dt * 10.) + p.rot = Math.atan2(p.facing.x, p.facing.y) + p.vel.x += input.x * dt * 25 + p.vel.y += input.y * dt * 25 + p.x += p.vel.x * dt + p.y += p.vel.y * dt + collide_player(p, dt) + lerp_exp_v2_mut(p.vel, { x: 0, y: 0 }, dt * 5.) +} + +function collide_player(p: PlayerData, dt: number) { + for (const [_, tile] of tiles) { + if (!data.tile_collide[tile.kind]) continue + + const d = aabb_point_distance(tile.x, tile.y, tile.x + 1, tile.y + 1, p.x, p.y) + if (d > PLAYER_SIZE) continue + + const h = 0.01 + const d_sample_x = aabb_point_distance(tile.x, tile.y, tile.x + 1, tile.y + 1, p.x + h, p.y) + const d_sample_y = aabb_point_distance(tile.x, tile.y, tile.x + 1, tile.y + 1, p.x, p.y + h) + const grad_x = (d_sample_x - d) / h + const grad_y = (d_sample_y - d) / h + + p.x += (PLAYER_SIZE - d) * grad_x + p.y += (PLAYER_SIZE - d) * grad_y + + const vdotn = (grad_x * p.vel.x) + (grad_y * p.vel.y) + p.vel.x -= grad_x * vdotn + p.vel.y -= grad_y * vdotn + } + + for (const [_, player] of players) { + const diff = sub_v2(p, player) + const d = length(diff) + if (d < 0.01) continue + if (d >= PLAYER_SIZE * 2) continue + const norm = normalize(diff); + const f = 1 / (1 + d) + p.vel.x += norm.x * f * dt + p.vel.y += norm.y * f * dt + } +} + +export function aabb_point_distance( + min_x: number, + min_y: number, + max_x: number, + max_y: number, + px: number, + py: number +): number { + const dx = px - Math.max(min_x, Math.min(max_x, px)) + const dy = py - Math.max(min_y, Math.min(max_y, py)) + return Math.sqrt(dx * dx + dy * dy) +} diff --git a/test-client/util.ts b/test-client/util.ts index 1c431411..975a5700 100644 --- a/test-client/util.ts +++ b/test-client/util.ts @@ -22,16 +22,3 @@ export function add_v2(p: V2, o: V2 | number) { else return { x: p.x + o.x, y: p.y + o.y } } export function sub_v2(p: V2, o: V2) { return { x: p.x - o.x, y: p.y - o.y } } - -export function aabb_circle_distance( - min_x: number, - min_y: number, - max_x: number, - max_y: number, - px: number, - py: number -): number { - const dx = px - Math.max(min_x, Math.min(max_x, px)) - const dy = py - Math.max(min_y, Math.min(max_y, py)) - return Math.sqrt(dx * dx + dy * dy) -} diff --git a/test-client/visual.ts b/test-client/visual.ts index 54c979da..cd32b77b 100644 --- a/test-client/visual.ts +++ b/test-client/visual.ts @@ -1,4 +1,5 @@ -import { ItemData, PLAYER_SIZE, camera, canvas, ctx, data, get_interact_target, interact_possible_anim, interact_target_anim, items_removed, keys_down, players, tiles } from "./main.ts"; +import { ItemData, camera, canvas, ctx, data, get_interact_target, interact_possible_anim, interact_target_anim, items_removed, keys_down, players, tiles } from "./main.ts"; +import { PLAYER_SIZE } from "./movement.ts"; import { Message } from "./protocol.ts"; import { FALLBACK_TILE, ITEMS, TILES, FALLBACK_ITEM } from "./tiles.ts"; import { V2, ceil_v2, floor_v2 } from "./util.ts"; |