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>
|
<title>Salvá la costanera</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<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>
|
<canvas id="juego" width="1280" height="720"></canvas>
|
||||||
<script type="module" src="/src/main.ts"></script>
|
<script type="module" src="/src/main.ts"></script>
|
||||||
</body>
|
</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 { Juego } from './main'
|
||||||
import { boxCollision } from './utils'
|
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 ENEMIES_NUM = 20
|
||||||
const ENEMY_SPEED = 40
|
const ENEMY_SPEED = 40
|
||||||
const PLAYER_SPEED = 200
|
const PLAYER_SPEED = 200
|
||||||
|
@ -75,14 +62,14 @@ export function update(juego: Juego<State>, dt: number) {
|
||||||
for (const enemy of juego.state.enemies) {
|
for (const enemy of juego.state.enemies) {
|
||||||
if (boxCollision({
|
if (boxCollision({
|
||||||
x: seed.x,
|
x: seed.x,
|
||||||
y: getFloorY(juego) - semillaSprite.getHeight(juego),
|
y: getFloorY(juego) - juego.sprites.semilla.getHeight(juego),
|
||||||
width: semillaSprite.getWidth(juego),
|
width: juego.sprites.semilla.getWidth(juego),
|
||||||
height: semillaSprite.getHeight(juego),
|
height: juego.sprites.semilla.getHeight(juego),
|
||||||
}, {
|
}, {
|
||||||
x: enemy.x,
|
x: enemy.x,
|
||||||
y: getFloorY(juego) - larretaSprite.getHeight(juego),
|
y: getFloorY(juego) - juego.sprites.larreta.getHeight(juego),
|
||||||
width: larretaSprite.getWidth(juego),
|
width: juego.sprites.larreta.getWidth(juego),
|
||||||
height: larretaSprite.getHeight(juego),
|
height: juego.sprites.larreta.getHeight(juego),
|
||||||
})) {
|
})) {
|
||||||
juego.state.seeds = juego.state.seeds.filter(s => s.x !== seed.x)
|
juego.state.seeds = juego.state.seeds.filter(s => s.x !== seed.x)
|
||||||
juego.state.enemies = juego.state.enemies.filter(e => e.x !== enemy.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(
|
function drawBackground(
|
||||||
|
@ -127,20 +114,20 @@ function drawBackground(
|
||||||
|
|
||||||
function drawJugadorx(juego: Juego<State>) {
|
function drawJugadorx(juego: Juego<State>) {
|
||||||
const floorY = getFloorY(juego)
|
const floorY = getFloorY(juego)
|
||||||
jugadorxSprite.draw(
|
juego.sprites.jugadorx.draw(
|
||||||
juego,
|
juego,
|
||||||
juego.state.pos.x + juego.state.view.x,
|
juego.state.pos.x + juego.state.view.x,
|
||||||
floorY - jugadorxSprite.getHeight(juego),
|
floorY - juego.sprites.jugadorx.getHeight(juego),
|
||||||
0,
|
0,
|
||||||
juego.state.side === "left",
|
juego.state.side === "left",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawTrees(juego: Juego<State>) {
|
function drawTrees(juego: Juego<State>) {
|
||||||
const height = arbolSprite.getHeight(juego)
|
const height = juego.sprites.arbol.getHeight(juego)
|
||||||
const floorY = getFloorY(juego)
|
const floorY = getFloorY(juego)
|
||||||
for (const tree of juego.state.trees) {
|
for (const tree of juego.state.trees) {
|
||||||
arbolSprite.draw(
|
juego.sprites.arbol.draw(
|
||||||
juego,
|
juego,
|
||||||
tree.x + juego.state.view.x,
|
tree.x + juego.state.view.x,
|
||||||
floorY - height,
|
floorY - height,
|
||||||
|
@ -148,10 +135,10 @@ function drawTrees(juego: Juego<State>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function drawEnemies(juego: Juego<State>) {
|
function drawEnemies(juego: Juego<State>) {
|
||||||
const height = larretaSprite.getHeight(juego)
|
const height = juego.sprites.larreta.getHeight(juego)
|
||||||
const floorY = getFloorY(juego)
|
const floorY = getFloorY(juego)
|
||||||
for (const enemy of juego.state.enemies) {
|
for (const enemy of juego.state.enemies) {
|
||||||
larretaSprite.draw(
|
juego.sprites.larreta.draw(
|
||||||
juego,
|
juego,
|
||||||
enemy.x + juego.state.view.x,
|
enemy.x + juego.state.view.x,
|
||||||
floorY - height,
|
floorY - height,
|
||||||
|
@ -160,10 +147,10 @@ function drawEnemies(juego: Juego<State>) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawSeeds(juego: Juego<State>) {
|
function drawSeeds(juego: Juego<State>) {
|
||||||
const height = semillaSprite.getHeight(juego)
|
const height = juego.sprites.semilla.getHeight(juego)
|
||||||
const floorY = getFloorY(juego)
|
const floorY = getFloorY(juego)
|
||||||
for (const seed of juego.state.seeds) {
|
for (const seed of juego.state.seeds) {
|
||||||
semillaSprite.draw(
|
juego.sprites.semilla.draw(
|
||||||
juego,
|
juego,
|
||||||
seed.x + juego.state.view.x,
|
seed.x + juego.state.view.x,
|
||||||
floorY - height,
|
floorY - height,
|
||||||
|
@ -178,8 +165,8 @@ function getFloorY(juego: Juego<State>): number {
|
||||||
export function draw(juego: Juego<State>, timestamp: number) {
|
export function draw(juego: Juego<State>, timestamp: number) {
|
||||||
const { height } = juego.canvas
|
const { height } = juego.canvas
|
||||||
|
|
||||||
drawBackground(juego, 0, (height / 3) * 2, fondoImg)
|
drawBackground(juego, 0, (height / 3) * 2, juego.assets.fondo)
|
||||||
drawBackground(juego, getFloorY(juego), height / 3, veredaImg)
|
drawBackground(juego, getFloorY(juego), height / 3, juego.assets.vereda)
|
||||||
|
|
||||||
drawTrees(juego)
|
drawTrees(juego)
|
||||||
drawEnemies(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 welcome from "./welcome"
|
||||||
import * as jugando from "./jugando"
|
import * as jugando from "./jugando"
|
||||||
|
import { Assets, loadAssets } from './assets'
|
||||||
|
import { loadSprite, Sprite } from './sprite'
|
||||||
|
|
||||||
function update(juego: Juego<any>, dt: number) {
|
function update(juego: Juego<any>, dt: number) {
|
||||||
switch (juego.state.current) {
|
switch (juego.state.current) {
|
||||||
|
@ -38,21 +40,34 @@ export type State = welcome.State | jugando.State
|
||||||
export type Juego<T extends State> = {
|
export type Juego<T extends State> = {
|
||||||
canvas: HTMLCanvasElement
|
canvas: HTMLCanvasElement
|
||||||
ctx: CanvasRenderingContext2D
|
ctx: CanvasRenderingContext2D
|
||||||
|
assets: Assets
|
||||||
|
sprites: { [key in "jugadorx" | "larreta" | "semilla" | "arbol"]: Sprite }
|
||||||
mouse: { x: number; y: number, down: boolean }
|
mouse: { x: number; y: number, down: boolean }
|
||||||
keyboard: { keys: { [key: string]: boolean } }
|
keyboard: { keys: { [key: string]: boolean } }
|
||||||
state: T
|
state: T
|
||||||
}
|
}
|
||||||
|
|
||||||
function initJuego() {
|
async function initJuego() {
|
||||||
const canvas = document.querySelector<HTMLCanvasElement>("#juego")!
|
const canvas = document.querySelector<HTMLCanvasElement>("#juego")!
|
||||||
const ctx = canvas.getContext("2d")!
|
const ctx = canvas.getContext("2d")!
|
||||||
|
|
||||||
window.addEventListener("resize", () => resizeCanvas(canvas), false)
|
window.addEventListener("resize", () => resizeCanvas(canvas), false)
|
||||||
resizeCanvas(canvas)
|
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> = {
|
let juego: Juego<welcome.State> = {
|
||||||
canvas,
|
canvas,
|
||||||
ctx,
|
ctx,
|
||||||
|
assets,
|
||||||
|
sprites,
|
||||||
mouse: { x: 0, y: 0, down: false },
|
mouse: { x: 0, y: 0, down: false },
|
||||||
keyboard: { keys: {} },
|
keyboard: { keys: {} },
|
||||||
state: {
|
state: {
|
||||||
|
|
|
@ -1,5 +1,13 @@
|
||||||
import { Juego } from "./main"
|
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
|
// Sprites are image assets that have a grid of tiles to animate
|
||||||
export function loadSprite(
|
export function loadSprite(
|
||||||
img: HTMLImageElement,
|
img: HTMLImageElement,
|
||||||
|
@ -7,8 +15,7 @@ export function loadSprite(
|
||||||
width: number, height: number,
|
width: number, height: number,
|
||||||
// Calculates the size of the sprite when rendering
|
// Calculates the size of the sprite when rendering
|
||||||
getHeight: (juego: Juego<any>) => number,
|
getHeight: (juego: Juego<any>) => number,
|
||||||
) {
|
): Sprite {
|
||||||
|
|
||||||
const aspect = width / height
|
const aspect = width / height
|
||||||
const rowSize = Math.floor(img.width / width)
|
const rowSize = Math.floor(img.width / width)
|
||||||
if (img.width / width !== rowSize) {
|
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 { createJugandoState } from './jugando'
|
||||||
import { Juego } from './main'
|
import { Juego } from './main'
|
||||||
|
|
||||||
const img = document.getElementById("img-boton-jugar") as HTMLImageElement
|
|
||||||
|
|
||||||
export type State = {
|
export type State = {
|
||||||
current: "welcome"
|
current: "welcome"
|
||||||
}
|
}
|
||||||
|
|
||||||
function startButton(juego: Juego<State>) {
|
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 {
|
return {
|
||||||
x: juego.canvas.width - width - 30,
|
x: juego.canvas.width - width - 30,
|
||||||
y: juego.canvas.height - height - 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) {
|
export function draw(juego: Juego<State>, timestamp: number) {
|
||||||
const btn = startButton(juego)
|
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