summaryrefslogtreecommitdiff
path: root/test-client/movement.ts
diff options
context:
space:
mode:
Diffstat (limited to 'test-client/movement.ts')
-rw-r--r--test-client/movement.ts62
1 files changed, 62 insertions, 0 deletions
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)
+}