forked from StrafesNET/roblox-bot-player
128 lines
3.7 KiB
JavaScript
128 lines
3.7 KiB
JavaScript
import init, {
|
|
setup_graphics,
|
|
CompleteBot,
|
|
CompleteMap,
|
|
PlaybackHead,
|
|
} from "./pkg/strafesnet_roblox_bot_player_wasm_module.js";
|
|
|
|
// Loading
|
|
await init(); // load the wasm module
|
|
|
|
const b = await fetch("bhop_marble_7cf33a64-7120-4514-b9fa-4fe29d9523d.qbot");
|
|
const m = await fetch("bhop_marble_5692093612.snfm");
|
|
|
|
const canvas = document.getElementById("viewport");
|
|
|
|
const graphics = await setup_graphics(canvas);
|
|
const bot = new CompleteBot(new Uint8Array(await b.arrayBuffer()));
|
|
const map = new CompleteMap(new Uint8Array(await m.arrayBuffer()));
|
|
const playback = new PlaybackHead(bot, 0);
|
|
|
|
graphics.change_map(map);
|
|
|
|
// HUD
|
|
const hud_timer = document.getElementById("hud_timer");
|
|
const hud_duration = document.getElementById("hud_duration");
|
|
const MODE_MAIN = 0;
|
|
|
|
function timer_text(t) {
|
|
const h = Math.floor(t / 3600);
|
|
const m = Math.floor((t % 3600) / 60);
|
|
const s = Math.floor(t % 60);
|
|
const ms = Math.floor((t % 1) * 1000);
|
|
return `${String(h).padStart(2, "0")}:${String(m).padStart(2, "0")}:${String(s).padStart(2, "0")}.${String(ms).padStart(3, "0")}`;
|
|
}
|
|
|
|
hud_duration.textContent = timer_text(bot.run_duration(MODE_MAIN));
|
|
|
|
// Stuff
|
|
const startTime = document.timeline.currentTime;
|
|
function elapsed() {
|
|
return (document.timeline.currentTime - startTime) / 1000;
|
|
}
|
|
|
|
const control_speed = document.getElementById("control_speed");
|
|
|
|
var paused = false;
|
|
var scale = 1;
|
|
function set_scale(new_scale) {
|
|
scale = new_scale;
|
|
playback.set_scale(elapsed(), scale);
|
|
control_speed.value = `${scale.toPrecision(3)}x`;
|
|
}
|
|
|
|
const SEEK_DURATION = 1.0;
|
|
|
|
// Controls
|
|
document.getElementById("control_reset").addEventListener("click", (e) => {
|
|
playback.set_head_time(bot, elapsed(), 0.0);
|
|
});
|
|
document.getElementById("control_pause").addEventListener("click", (e) => {
|
|
paused = !paused;
|
|
playback.set_paused(elapsed(), paused);
|
|
});
|
|
document.getElementById("control_forward").addEventListener("click", (e) => {
|
|
const time_now = elapsed();
|
|
const playback_time = playback.get_head_time(time_now);
|
|
const time_offset = playback.get_scale() * SEEK_DURATION;
|
|
playback.set_head_time(bot, time_now, playback_time + time_offset);
|
|
});
|
|
document.getElementById("control_backward").addEventListener("click", (e) => {
|
|
const time_now = elapsed();
|
|
const playback_time = playback.get_head_time(time_now);
|
|
const time_offset = playback.get_scale() * SEEK_DURATION;
|
|
playback.set_head_time(bot, time_now, playback_time - time_offset);
|
|
});
|
|
document.getElementById("control_slower").addEventListener("click", (e) => {
|
|
set_scale((scale * 4) / 5);
|
|
});
|
|
const regex = new RegExp("^([^x]*)x?$");
|
|
control_speed.addEventListener("change", (e) => {
|
|
const parsed = regex.exec(e.target.value);
|
|
if (!parsed) {
|
|
set_scale(1);
|
|
return;
|
|
}
|
|
const input = Number(parsed.at(1));
|
|
if (Number.isNaN(input)) {
|
|
set_scale(1);
|
|
return;
|
|
}
|
|
set_scale(input);
|
|
});
|
|
document.getElementById("control_faster").addEventListener("click", (e) => {
|
|
set_scale((scale * 5) / 4);
|
|
});
|
|
|
|
// Rendering
|
|
function animate(now) {
|
|
const elapsedMs = now - startTime;
|
|
const elapsedSec = elapsedMs / 1000; // wasm expects seconds
|
|
|
|
// Advance the playback head to the current time
|
|
playback.advance_time(bot, elapsedSec);
|
|
|
|
// update the timer text
|
|
const time = playback.get_run_time(bot, elapsedSec, MODE_MAIN);
|
|
hud_timer.textContent = timer_text(time);
|
|
|
|
// Render the frame that the bot is at that time
|
|
graphics.render(bot, playback, elapsedSec);
|
|
|
|
// Keep the loop going
|
|
requestAnimationFrame(animate);
|
|
}
|
|
|
|
requestAnimationFrame(animate);
|
|
|
|
// Resizing
|
|
function resize() {
|
|
canvas.width = canvas.clientWidth;
|
|
canvas.height = canvas.clientHeight;
|
|
const fov_y = playback.get_fov_slope_y();
|
|
const fov_x = (fov_y * canvas.width) / canvas.height;
|
|
graphics.resize(canvas.width, canvas.height, fov_x, fov_y);
|
|
}
|
|
window.addEventListener("resize", resize);
|
|
resize();
|