diff --git a/index.html b/index.html index 4e70ef3..46dccad 100644 --- a/index.html +++ b/index.html @@ -8,16 +8,6 @@ Salvá la costanera -
- - - - - - - - -
diff --git a/src/assets.ts b/src/assets.ts new file mode 100644 index 0000000..50f82cd --- /dev/null +++ b/src/assets.ts @@ -0,0 +1,34 @@ +import botonJugarImg from "./assets/boton_jugar.png" +import larretaImg from "./assets/larreta.png" +import veredaImg from "./assets/piso.png" +import fondoImg from "./assets/fondo.png" +import jugadorxImg from "./assets/eli.png" +import semillaImg from "./assets/semilla.png" +import arbolImg from "./assets/arbol.png" + +function loadImage(url: string): Promise { + return new Promise((resolve, reject) => { + let img = new Image() + img.onload = () => resolve(img) + img.onerror = e => reject(e) + img.src = url + }) +} + +export const assetUrls = { + botonJugar: botonJugarImg, + larreta: larretaImg, + vereda: veredaImg, + fondo: fondoImg, + jugadorx: jugadorxImg, + semilla: semillaImg, + arbol: arbolImg, +} +export type Assets = { [key in keyof typeof assetUrls]: HTMLImageElement } + +const assets = Object.fromEntries(Object.entries(assetUrls).map(([name, url]) => [name, loadImage(url)])) + +export async function loadAssets() { + const imgs = await Promise.all(Object.values(assets)) + return Object.fromEntries(imgs.map((img, i) => [Object.keys(assetUrls)[i], img])) as Assets +} diff --git a/src/jugando.ts b/src/jugando.ts index 3898716..7800ebf 100644 --- a/src/jugando.ts +++ b/src/jugando.ts @@ -2,19 +2,6 @@ import { loadSprite } from './sprite' import { Juego } from './main' import { boxCollision } from './utils' -const larretaImg = document.getElementById("img-larreta") as HTMLImageElement -const inmobiliariaImg = document.getElementById("img-inmobiliaria") as HTMLImageElement -const veredaImg = document.getElementById("img-vereda") as HTMLImageElement -const fondoImg = document.getElementById("img-fondo") as HTMLImageElement -const jugadorxImg = document.getElementById("img-jugadorx") as HTMLImageElement -const semillaImg = document.getElementById("img-semilla") as HTMLImageElement -const arbolImg = document.getElementById("img-arbol") as HTMLImageElement - -const jugadorxSprite = loadSprite(jugadorxImg, 133, 266, juego => juego.canvas.height / 4) -const larretaSprite = loadSprite(larretaImg, 800, 1069, juego => juego.canvas.height / 4) -const semillaSprite = loadSprite(semillaImg, 480, 640, juego => juego.canvas.height / 8) -const arbolSprite = loadSprite(arbolImg, 80, 150, juego => juego.canvas.height / 4) - const ENEMIES_NUM = 20 const ENEMY_SPEED = 40 const PLAYER_SPEED = 200 @@ -75,14 +62,14 @@ export function update(juego: Juego, dt: number) { for (const enemy of juego.state.enemies) { if (boxCollision({ x: seed.x, - y: getFloorY(juego) - semillaSprite.getHeight(juego), - width: semillaSprite.getWidth(juego), - height: semillaSprite.getHeight(juego), + y: getFloorY(juego) - juego.sprites.semilla.getHeight(juego), + width: juego.sprites.semilla.getWidth(juego), + height: juego.sprites.semilla.getHeight(juego), }, { x: enemy.x, - y: getFloorY(juego) - larretaSprite.getHeight(juego), - width: larretaSprite.getWidth(juego), - height: larretaSprite.getHeight(juego), + y: getFloorY(juego) - juego.sprites.larreta.getHeight(juego), + width: juego.sprites.larreta.getWidth(juego), + height: juego.sprites.larreta.getHeight(juego), })) { juego.state.seeds = juego.state.seeds.filter(s => s.x !== seed.x) juego.state.enemies = juego.state.enemies.filter(e => e.x !== enemy.x) @@ -109,7 +96,7 @@ export function update(juego: Juego, dt: number) { } } - juego.state.view.x = -juego.state.pos.x + juego.canvas.width / 2 - jugadorxSprite.getWidth(juego) / 2 + juego.state.view.x = -juego.state.pos.x + juego.canvas.width / 2 - juego.sprites.jugadorx.getWidth(juego) / 2 } function drawBackground( @@ -127,20 +114,20 @@ function drawBackground( function drawJugadorx(juego: Juego) { const floorY = getFloorY(juego) - jugadorxSprite.draw( + juego.sprites.jugadorx.draw( juego, juego.state.pos.x + juego.state.view.x, - floorY - jugadorxSprite.getHeight(juego), + floorY - juego.sprites.jugadorx.getHeight(juego), 0, juego.state.side === "left", ) } function drawTrees(juego: Juego) { - const height = arbolSprite.getHeight(juego) + const height = juego.sprites.arbol.getHeight(juego) const floorY = getFloorY(juego) for (const tree of juego.state.trees) { - arbolSprite.draw( + juego.sprites.arbol.draw( juego, tree.x + juego.state.view.x, floorY - height, @@ -148,10 +135,10 @@ function drawTrees(juego: Juego) { } } function drawEnemies(juego: Juego) { - const height = larretaSprite.getHeight(juego) + const height = juego.sprites.larreta.getHeight(juego) const floorY = getFloorY(juego) for (const enemy of juego.state.enemies) { - larretaSprite.draw( + juego.sprites.larreta.draw( juego, enemy.x + juego.state.view.x, floorY - height, @@ -160,10 +147,10 @@ function drawEnemies(juego: Juego) { } function drawSeeds(juego: Juego) { - const height = semillaSprite.getHeight(juego) + const height = juego.sprites.semilla.getHeight(juego) const floorY = getFloorY(juego) for (const seed of juego.state.seeds) { - semillaSprite.draw( + juego.sprites.semilla.draw( juego, seed.x + juego.state.view.x, floorY - height, @@ -178,8 +165,8 @@ function getFloorY(juego: Juego): number { export function draw(juego: Juego, timestamp: number) { const { height } = juego.canvas - drawBackground(juego, 0, (height / 3) * 2, fondoImg) - drawBackground(juego, getFloorY(juego), height / 3, veredaImg) + drawBackground(juego, 0, (height / 3) * 2, juego.assets.fondo) + drawBackground(juego, getFloorY(juego), height / 3, juego.assets.vereda) drawTrees(juego) drawEnemies(juego) diff --git a/src/main.ts b/src/main.ts index d32aaba..8d2ddb1 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,6 +2,8 @@ import './style.css' import * as welcome from "./welcome" import * as jugando from "./jugando" +import { Assets, loadAssets } from './assets' +import { loadSprite, Sprite } from './sprite' function update(juego: Juego, dt: number) { switch (juego.state.current) { @@ -38,21 +40,34 @@ export type State = welcome.State | jugando.State export type Juego = { canvas: HTMLCanvasElement ctx: CanvasRenderingContext2D + assets: Assets + sprites: { [key in "jugadorx" | "larreta" | "semilla" | "arbol"]: Sprite } mouse: { x: number; y: number, down: boolean } keyboard: { keys: { [key: string]: boolean } } state: T } -function initJuego() { +async function initJuego() { const canvas = document.querySelector("#juego")! const ctx = canvas.getContext("2d")! window.addEventListener("resize", () => resizeCanvas(canvas), false) resizeCanvas(canvas) + const assets = await loadAssets() + + const sprites = { + jugadorx: loadSprite(assets.jugadorx, 133, 266, juego => juego.canvas.height / 4), + larreta: loadSprite(assets.larreta, 800, 1069, juego => juego.canvas.height / 4), + semilla: loadSprite(assets.semilla, 480, 640, juego => juego.canvas.height / 8), + arbol: loadSprite(assets.arbol, 80, 150, juego => juego.canvas.height / 4), + } + let juego: Juego = { canvas, ctx, + assets, + sprites, mouse: { x: 0, y: 0, down: false }, keyboard: { keys: {} }, state: { diff --git a/src/sprite.ts b/src/sprite.ts index d6d9005..3debc1e 100644 --- a/src/sprite.ts +++ b/src/sprite.ts @@ -1,5 +1,13 @@ import { Juego } from "./main" +export type Sprite = { + getWidth: (juego: Juego) => number; + getHeight: (juego: Juego) => number; + draw: (juego: Juego, x: number, y: number, spriteIndex?: number, flipped?: boolean) => void; + width: number; + height: number; +} + // Sprites are image assets that have a grid of tiles to animate export function loadSprite( img: HTMLImageElement, @@ -7,8 +15,7 @@ export function loadSprite( width: number, height: number, // Calculates the size of the sprite when rendering getHeight: (juego: Juego) => number, -) { - +): Sprite { const aspect = width / height const rowSize = Math.floor(img.width / width) if (img.width / width !== rowSize) { diff --git a/src/vite-env.d.ts b/src/vite-env.d.ts new file mode 100644 index 0000000..11f02fe --- /dev/null +++ b/src/vite-env.d.ts @@ -0,0 +1 @@ +/// diff --git a/src/welcome.ts b/src/welcome.ts index 7cb44bf..195df1c 100644 --- a/src/welcome.ts +++ b/src/welcome.ts @@ -2,14 +2,12 @@ import { posInBox } from './utils' import { createJugandoState } from './jugando' import { Juego } from './main' -const img = document.getElementById("img-boton-jugar") as HTMLImageElement - export type State = { current: "welcome" } function startButton(juego: Juego) { - const [width, height] = [img.width / 4, img.height / 4] + const [width, height] = [juego.assets.botonJugar.width / 4, juego.assets.botonJugar.height / 4] return { x: juego.canvas.width - width - 30, y: juego.canvas.height - height - 30, @@ -27,5 +25,5 @@ export function update(juego: Juego, dt: number) { export function draw(juego: Juego, timestamp: number) { const btn = startButton(juego) - juego.ctx.drawImage(img, btn.x, btn.y, btn.width, btn.height) + juego.ctx.drawImage(juego.assets.botonJugar, btn.x, btn.y, btn.width, btn.height) }