diff options
Diffstat (limited to 'test-client/movement.ts')
| -rw-r--r-- | test-client/movement.ts | 62 | 
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) +} | 
