import { FiniteStateMachine } from './FSM.js'; import { LoadingState } from './states/LoadingState.js'; import { MenuState } from './states/MenuState.js'; import { GameState } from './states/GameState.js'; import { ExploreMapState } from './states/ExploreMapState.js'; import { Logger } from './Logger.js'; export var canvas; var context; var lastTime; var updateIntervalId; export const StateKey = { Loading: 1, MainMenu: 2, Game: 3, Map: 4, }; export var fsm = new FiniteStateMachine(); fsm.addState(StateKey.Loading, new LoadingState()); fsm.addState(StateKey.MainMenu, new MenuState()); fsm.addState(StateKey.Game, new GameState()); fsm.addState(StateKey.Map, new ExploreMapState()); fsm.initialLoad(StateKey.Loading); function animate() { clearFrame(context); fsm.drawCurrentState(context); requestAnimationFrame(animate); } function clearFrame(context) { context.clearRect(0, 0, canvas.width, canvas.height); } function init() { lastTime = new Date().getUTCMilliseconds(); context = canvas.getContext('2d'); onResize(); } function tick(delta) { fsm.updateCurrentState(delta); } function getPixelRatio(context) { let dpr = window.devicePixelRatio || 1; let bsr = context.webkitBackingStorePixelRatio || context.mozBackingStorePixelRatio || context.msBackingStorePixelRatio || context.oBackingStorePixelRatio || context.backingStorePixelRatio || 1; return dpr / bsr; } function onResize() { let ratio = getPixelRatio(context); let canvasBounds = canvas.getBoundingClientRect(); canvas.width = canvasBounds.width * ratio; canvas.height = canvasBounds.height * ratio; context.scale(ratio, ratio); fsm.onResize(); } export var webSocket; var keepAliveTimerId; export function websocketReconnect() { webSocket = new WebSocket(`ws://${location.hostname + (location.port ? ':' + location.port : '')}/ws`); webSocket.onmessage = function (event) { fsm.websocketMessage(webSocket, event); }; webSocket.onopen = function (event) { fsm.websocketConnect(webSocket, event); }; webSocket.onerror = function (event) { fsm.websocketError(webSocket, event); }; webSocket.onclose = function (event) { fsm.websocketClose(webSocket, event); }; clearInterval(keepAliveTimerId); keepAliveTimerId = setInterval(() => { Logger.info("Websocket send: ping"); webSocket.send("ping"); }, 30000); } document.addEventListener("DOMContentLoaded", event => { canvas = document.createElement("canvas"); document.getElementById("game").appendChild(canvas); init(); animate(); updateIntervalId = setInterval(() => { let currentTime = new Date().getUTCMilliseconds(); tick(1 + ((currentTime - lastTime) / 1000)); lastTime = currentTime; }, 16); websocketReconnect(); }); window.addEventListener("resize", onResize); window.addEventListener("mousedown", fsm.onMouseDown); window.addEventListener("mousemove", fsm.onMouseMove); window.addEventListener("mouseup", fsm.onMouseUp); window.addEventListener("contextmenu", fsm.onRightClick); window.addEventListener("touchstart", fsm.onTouchStart); window.addEventListener("touchmove", fsm.onTouchMove); window.addEventListener("touchend", fsm.onTouchEnd); window.addEventListener("popstate", fsm.onPopState);