import "./style.css"; import * as welcome from "./welcome"; import * as jugando from "./jugando"; import * as win from "./win"; import * as lose from "./lose"; import { Assets, loadAssets } from "./assets"; import { loadSprite, Sprite } from "./sprite"; import { drawText, isMobile } from "./utils"; export type State = welcome.State | jugando.State | win.State | lose.State; export type Juego = { canvas: HTMLCanvasElement; ctx: CanvasRenderingContext2D; assets: Assets; sprites: { [key in | "flecha" | "jugadorx" | "baldosa" | "larreta" | "millonarioMalo" | "semilla" | "arbol1" | "arbol2" | "ciudadanx1" | "ciudadanx2" | "ciudadanx3"]: Sprite; }; mouse: { x: number; y: number; down: boolean }; touches: TouchList | null; keyboard: { keys: { [key: string]: boolean } }; state: T; }; function needsRotation(juego: Juego): boolean { return juego.canvas.width < juego.canvas.height; } function update(juego: Juego, dt: number) { if (needsRotation(juego)) return; switch (juego.state.current) { case "welcome": welcome.update(juego, dt); break; case "jugando": jugando.update(juego, dt); break; case "win": win.update(juego, dt); break; case "lose": lose.update(juego, dt); break; } } function draw(juego: Juego, timestamp: number) { const { width, height } = juego.canvas; juego.ctx.imageSmoothingEnabled = false; juego.ctx.fillStyle = "white"; juego.ctx.fillRect(0, 0, width, height); juego.ctx.fillStyle = "black"; if (needsRotation(juego)) { drawText( juego, "¡Por favor rotá el dispositivo!", { x: juego.canvas.width / 2, y: juego.canvas.height / 2 }, { align: "center", maxWidth: juego.canvas.width } ); return; } switch (juego.state.current) { case "welcome": welcome.draw(juego, timestamp); break; case "jugando": jugando.draw(juego, timestamp); break; case "win": win.draw(juego, timestamp); break; case "lose": lose.draw(juego, timestamp); break; } } function resizeCanvas(canvas: HTMLCanvasElement) { canvas.width = canvas.clientWidth; canvas.height = canvas.clientHeight; } function touchListener(juego: Juego, event: TouchEvent) { juego.touches = event.touches; } async function initJuego() { const canvas = document.querySelector("#juego")!; const ctx = canvas.getContext("2d", { alpha: false, desynchronized: true, })!; window.addEventListener("resize", () => resizeCanvas(canvas), false); resizeCanvas(canvas); const assets = await loadAssets(); const sprites = { flecha: loadSprite( assets.flecha, 11, 9, (juego) => juego.canvas.height / 6 ), jugadorx: loadSprite( assets.jugadorx, 65, 94, (juego) => juego.canvas.height / 4 ), baldosa: loadSprite( assets.baldosa, 72, 72, (juego) => juego.canvas.height * 0.8 ), larreta: loadSprite( assets.larreta, 83, 131, (juego) => juego.canvas.height / 4 ), millonarioMalo: loadSprite( assets.millonarioMalo, 50, 71, (juego) => juego.canvas.height / 4 ), semilla: loadSprite( assets.semilla, 72, 73, (juego) => juego.canvas.height / 8 ), arbol1: loadSprite( assets.arbol1, 72, 68, (juego) => juego.canvas.height / 3 ), arbol2: loadSprite( assets.arbol2, 72, 56, (juego) => juego.canvas.height / 4 ), ciudadanx1: loadSprite( assets.ciudadanx1, 45, 88, (juego) => juego.canvas.height / 4 ), ciudadanx2: loadSprite( assets.ciudadanx2, 45, 88, (juego) => juego.canvas.height / 4 ), ciudadanx3: loadSprite( assets.ciudadanx3, 45, 88, (juego) => juego.canvas.height / 4 ), }; let juego: Juego = { canvas, ctx, assets, sprites, mouse: { x: 0, y: 0, down: false }, touches: null, keyboard: { keys: {} }, state: { current: "welcome", }, }; (window as any).juego = juego; juego.ctx.imageSmoothingEnabled = false; canvas.addEventListener( "mousemove", (e) => { juego.mouse.x = e.clientX; juego.mouse.y = e.clientY; }, false ); canvas.addEventListener( "mousedown", () => { juego.mouse.down = true; }, false ); canvas.addEventListener( "mouseup", () => { juego.mouse.down = false; }, false ); window.addEventListener("keydown", (e) => { juego.keyboard.keys[e.key] = true; }); window.addEventListener("keyup", (e) => { juego.keyboard.keys[e.key] = false; }); window.addEventListener("touchstart", (e) => touchListener(juego, e)); window.addEventListener("touchend", (e) => touchListener(juego, e)); window.addEventListener("touchcancel", (e) => touchListener(juego, e)); window.addEventListener("touchmove", (e) => touchListener(juego, e)); let lastRender = 0; const loop: FrameRequestCallback = (timestamp) => { const progress = timestamp - lastRender; update(juego, progress); draw(juego, timestamp); lastRender = timestamp; window.requestAnimationFrame(loop); }; window.requestAnimationFrame(loop); } document.getElementById("full-screen")!.addEventListener("click", async () => { document.documentElement.requestFullscreen && (await document.documentElement.requestFullscreen({ navigationUI: "hide", })); await screen.orientation.lock("landscape"); }); initJuego();