Revamp sistema de assets para que cargue imagenes antes de iniciar el juego
This commit is contained in:
parent
da92f24ca6
commit
0a20e26554
7 changed files with 79 additions and 47 deletions
10
index.html
10
index.html
|
@ -8,16 +8,6 @@
|
|||
<title>Salvá la costanera</title>
|
||||
</head>
|
||||
<body>
|
||||
<div style="display: none">
|
||||
<!-- Cargar imágenes -->
|
||||
<img id="img-boton-jugar" src="./src/assets/boton_jugar.png">
|
||||
<img id="img-vereda" src="./src/assets/piso.png">
|
||||
<img id="img-fondo" src="./src/assets/fondo.png">
|
||||
<img id="img-larreta" src="./src/assets/larreta.png">
|
||||
<img id="img-jugadorx" src="./src/assets/eli.png">
|
||||
<img id="img-semilla" src="./src/assets/semilla.png">
|
||||
<img id="img-arbol" src="./src/assets/arbol.png">
|
||||
</div>
|
||||
<canvas id="juego" width="1280" height="720"></canvas>
|
||||
<script type="module" src="/src/main.ts"></script>
|
||||
</body>
|
||||
|
|
34
src/assets.ts
Normal file
34
src/assets.ts
Normal file
|
@ -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<HTMLImageElement> {
|
||||
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
|
||||
}
|
|
@ -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<State>, 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<State>, 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<State>) {
|
||||
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<State>) {
|
||||
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<State>) {
|
|||
}
|
||||
}
|
||||
function drawEnemies(juego: Juego<State>) {
|
||||
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<State>) {
|
|||
}
|
||||
|
||||
function drawSeeds(juego: Juego<State>) {
|
||||
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<State>): number {
|
|||
export function draw(juego: Juego<State>, 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)
|
||||
|
|
17
src/main.ts
17
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<any>, dt: number) {
|
||||
switch (juego.state.current) {
|
||||
|
@ -38,21 +40,34 @@ export type State = welcome.State | jugando.State
|
|||
export type Juego<T extends State> = {
|
||||
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<HTMLCanvasElement>("#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<welcome.State> = {
|
||||
canvas,
|
||||
ctx,
|
||||
assets,
|
||||
sprites,
|
||||
mouse: { x: 0, y: 0, down: false },
|
||||
keyboard: { keys: {} },
|
||||
state: {
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
import { Juego } from "./main"
|
||||
|
||||
export type Sprite = {
|
||||
getWidth: (juego: Juego<any>) => number;
|
||||
getHeight: (juego: Juego<any>) => number;
|
||||
draw: (juego: Juego<any>, 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<any>) => number,
|
||||
) {
|
||||
|
||||
): Sprite {
|
||||
const aspect = width / height
|
||||
const rowSize = Math.floor(img.width / width)
|
||||
if (img.width / width !== rowSize) {
|
||||
|
|
1
src/vite-env.d.ts
vendored
Normal file
1
src/vite-env.d.ts
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
/// <reference types="vite/client" />
|
|
@ -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<State>) {
|
||||
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<State>, dt: number) {
|
|||
|
||||
export function draw(juego: Juego<State>, 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)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue