diff options
Diffstat (limited to 'test-client')
-rw-r--r-- | test-client/main.ts | 42 | ||||
-rw-r--r-- | test-client/movement.ts | 55 |
2 files changed, 58 insertions, 39 deletions
diff --git a/test-client/main.ts b/test-client/main.ts index 42c1a3e0..831513fc 100644 --- a/test-client/main.ts +++ b/test-client/main.ts @@ -17,7 +17,7 @@ */ /// <reference lib="dom" /> -import { player_movement_update } from "./movement.ts"; +import { MovementBase, update_movement } from "./movement.ts"; import { Gamedata, ItemIndex, Message, PacketC, PacketS, PlayerID, TileIndex } from "./protocol.ts"; import { V2, add_v2, lerp_exp_v2_mut, normalize, lerp_exp, sub_v2, length } from "./util.ts"; import { draw_ingame, draw_wait } from "./visual.ts"; @@ -62,18 +62,14 @@ export interface ItemData { progress_warn?: boolean remove_anim?: number } -export interface PlayerData { - x: number, - y: number, +export interface PlayerData extends MovementBase { name: string, - rot: number, item?: ItemData, - facing: V2, character: number, anim_position: V2, - vel: V2, message?: MessageData, } + export interface TileData { x: number y: number @@ -112,14 +108,18 @@ function packet(p: PacketC) { break; case "add_player": { players.set(p.id, { - x: p.position[0], - y: p.position[1], + position: { + x: p.position[0], + y: p.position[1], + }, character: p.character, name: p.name, rot: 0, anim_position: { x: 0, y: 1 }, facing: { x: 0, y: 1 }, vel: { x: 0, y: 0 }, + stamina: 0, + boosting: false, }) break; } @@ -129,10 +129,10 @@ function packet(p: PacketC) { case "position": { const pl = players.get(p.player)! const pos = { x: p.pos[0], y: p.pos[1] } - const dist = length(sub_v2(pl, pos)); + const dist = length(sub_v2(pl.position, pos)); if (p.player == my_id && dist < 3) return; // we know better where we are - pl.x = pos.x - pl.y = pos.y + pl.position.x = pos.x + pl.position.y = pos.y pl.rot = p.rot break; } @@ -140,7 +140,7 @@ function packet(p: PacketC) { const player = players.get(p.player)! const tile = tiles.get(p.tile.toString())! player.item = tile.item; - player.item!.tracking = player + player.item!.tracking = player.position tile.item = undefined break; } @@ -163,7 +163,7 @@ function packet(p: PacketC) { const player = players.get(p.player)! if (player.item !== undefined && player.item !== null) items_removed.add(player.item) player.item = undefined - if (p.item !== undefined && p.item !== null) player.item = { kind: p.item, x: player.x + 0.5, y: player.y + 0.5 } + if (p.item !== undefined && p.item !== null) player.item = { kind: p.item, x: player.position.x + 0.5, y: player.position.y + 0.5 } break; } case "set_active": { @@ -234,8 +234,8 @@ export function get_interact_target(): V2 | undefined { const me = players.get(my_id) if (!me) return return { - x: Math.floor(me.x + Math.sin(me.rot)), - y: Math.floor(me.y + Math.cos(me.rot)) + x: Math.floor(me.position.x + Math.sin(me.rot)), + y: Math.floor(me.position.y + Math.cos(me.rot)) } } @@ -248,7 +248,7 @@ function set_interact(edge: boolean) { function tick_update() { const p = players.get(my_id) if (!p) return - send({ type: "position", pos: [p.x, p.y], rot: p.rot }) + send({ type: "position", pos: [p.position.x, p.position.y], rot: p.rot }) } function frame_update(dt: number) { @@ -260,14 +260,14 @@ function frame_update(dt: number) { y: (+keys_down.has("KeyS") - +keys_down.has("KeyW")) }) if (interacting) input.x *= 0, input.y *= 0 - player_movement_update(p, dt, input) + update_movement(p, dt, input, keys_down.has("KeyN")) const update_item = (item: ItemData) => { if (item.tracking) lerp_exp_v2_mut(item, item.tracking, dt * 10.) } for (const [pid, player] of players) { - if (pid == my_id) player.anim_position.x = player.x, player.anim_position.y = player.y - else lerp_exp_v2_mut(player.anim_position, player, dt * 15) + if (pid == my_id) player.anim_position.x = player.position.x, player.anim_position.y = player.position.y + else lerp_exp_v2_mut(player.anim_position, player.position, dt * 15) if (player.item !== undefined && player.item !== null) update_item(player.item) if (player.message) player.message.anim_size = lerp_exp(player.message.anim_size, 1, dt * 3) } @@ -284,7 +284,7 @@ function frame_update(dt: number) { } remove.forEach(i => items_removed.delete(i)) - lerp_exp_v2_mut(camera, p, dt * 10.) + lerp_exp_v2_mut(camera, p.position, dt * 10.) const it = get_interact_target() ?? { x: 0, y: 0 }; const possible = data.tile_interact[tiles.get([it.x, it.y].toString())?.kind ?? 0] ?? false diff --git a/test-client/movement.ts b/test-client/movement.ts index 38f4b47b..933b6af5 100644 --- a/test-client/movement.ts +++ b/test-client/movement.ts @@ -16,43 +16,62 @@ */ import { data } from "./main.ts"; -import { tiles, players, PlayerData } from "./main.ts"; +import { tiles, players } from "./main.ts"; import { V2, normalize, length, sub_v2, lerp_exp_v2_mut } from "./util.ts"; -export const PLAYER_SIZE = 0.4; -export const PLAYER_SPEED = 65; +export const PLAYER_SIZE = 0.4 +export const PLAYER_FRICTION = 10 +export const PLAYER_SPEED = 40 +export const BOOST_FACTOR = 3 +export const BOOST_DURATION = 0.3 +export const BOOST_RESTORE = 0.5 -export function player_movement_update(p: PlayerData, dt: number, input: V2) { +export interface MovementBase { + position: V2, + vel: V2, + facing: V2, + rot: number, + boosting: boolean, + stamina: number +} + +export function update_movement(p: MovementBase, dt: number, input: V2, boost: boolean) { 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 * PLAYER_SPEED - p.vel.y += input.y * dt * PLAYER_SPEED - p.x += p.vel.x * dt - p.y += p.vel.y * dt + boost &&= length(input) > 0.1 + p.boosting = boost && (p.boosting || p.stamina >= 1) && p.stamina > 0 + if (p.boosting) p.stamina -= dt / BOOST_DURATION + else p.stamina += dt / BOOST_RESTORE + p.stamina = Math.max(Math.min(p.stamina, 1), 0) + const speed = PLAYER_SPEED * (p.boosting ? BOOST_FACTOR : 1) + p.vel.x += input.x * dt * speed + p.vel.y += input.y * dt * speed + p.position.x += p.vel.x * dt + p.position.y += p.vel.y * dt collide_player(p, dt) - lerp_exp_v2_mut(p.vel, { x: 0, y: 0 }, dt * 15.) + lerp_exp_v2_mut(p.vel, { x: 0, y: 0 }, dt * PLAYER_FRICTION) } -function collide_player(p: PlayerData, dt: number) { +function collide_player(p: MovementBase, dt: number) { for (let xo = -1; xo <= 1; xo++) { for (let yo = -1; yo <= 1; yo++) { - const x = Math.floor(p.x) + xo - const y = Math.floor(p.y) + yo + const x = Math.floor(p.position.x) + xo + const y = Math.floor(p.position.y) + yo const tile = tiles.get([x, y].toString()) if (tile && !data.tile_collide[tile.kind]) continue - const d = aabb_point_distance(x, y, x + 1, y + 1, p.x, p.y) + const d = aabb_point_distance(x, y, x + 1, y + 1, p.position.x, p.position.y) if (d > PLAYER_SIZE) continue const h = 0.01 - const d_sample_x = aabb_point_distance(x, y, x + 1, y + 1, p.x + h, p.y) - const d_sample_y = aabb_point_distance(x, y, x + 1, y + 1, p.x, p.y + h) + const d_sample_x = aabb_point_distance(x, y, x + 1, y + 1, p.position.x + h, p.position.y) + const d_sample_y = aabb_point_distance(x, y, x + 1, y + 1, p.position.x, p.position.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 + p.position.x += (PLAYER_SIZE - d) * grad_x + p.position.y += (PLAYER_SIZE - d) * grad_y const vdotn = (grad_x * p.vel.x) + (grad_y * p.vel.y) p.vel.x -= grad_x * vdotn @@ -61,7 +80,7 @@ function collide_player(p: PlayerData, dt: number) { } for (const [_, player] of players) { - const diff = sub_v2(p, player) + const diff = sub_v2(p.position, player.position) const d = length(diff) if (d < 0.01) continue if (d >= PLAYER_SIZE * 2) continue |