Usar prettier
This commit is contained in:
parent
b9e404bf29
commit
080513daf6
14 changed files with 594 additions and 445 deletions
6
.prettierignore
Normal file
6
.prettierignore
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
*.local
|
||||||
|
pnpm-lock.yaml
|
1
.prettierrc.json
Normal file
1
.prettierrc.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{}
|
|
@ -4,9 +4,11 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build --base=./",
|
"build": "vite build --base=./",
|
||||||
"serve": "vite preview"
|
"serve": "vite preview",
|
||||||
|
"format": "prettier --write ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"prettier": "2.3.2",
|
||||||
"typescript": "^4.3.4",
|
"typescript": "^4.3.4",
|
||||||
"vite": "^2.3.8"
|
"vite": "^2.3.8"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
lockfileVersion: 5.3
|
lockfileVersion: 5.3
|
||||||
|
|
||||||
specifiers:
|
specifiers:
|
||||||
|
prettier: 2.3.2
|
||||||
typescript: ^4.3.4
|
typescript: ^4.3.4
|
||||||
vite: ^2.3.8
|
vite: ^2.3.8
|
||||||
|
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
prettier: 2.3.2
|
||||||
typescript: 4.3.4
|
typescript: 4.3.4
|
||||||
vite: 2.3.8
|
vite: 2.3.8
|
||||||
|
|
||||||
|
@ -63,6 +65,12 @@ packages:
|
||||||
source-map-js: 0.6.2
|
source-map-js: 0.6.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/prettier/2.3.2:
|
||||||
|
resolution: {integrity: sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==}
|
||||||
|
engines: {node: '>=10.13.0'}
|
||||||
|
hasBin: true
|
||||||
|
dev: true
|
||||||
|
|
||||||
/resolve/1.20.0:
|
/resolve/1.20.0:
|
||||||
resolution: {integrity: sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==}
|
resolution: {integrity: sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==}
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
|
@ -1,38 +1,42 @@
|
||||||
import botonJugarImg from "./assets/boton_jugar.png"
|
import botonJugarImg from "./assets/boton_jugar.png";
|
||||||
import larretaImg from "./assets/Millonario Malo.png"
|
import larretaImg from "./assets/Millonario Malo.png";
|
||||||
import fondoImg from "./assets/CieloRioCalle.png"
|
import fondoImg from "./assets/CieloRioCalle.png";
|
||||||
import edificiosImg from "./assets/Edificios.png"
|
import edificiosImg from "./assets/Edificios.png";
|
||||||
import jugadorxImg from "./assets/ProtagonistaCorriendo_1.png"
|
import jugadorxImg from "./assets/ProtagonistaCorriendo_1.png";
|
||||||
import baldosaImg from "./assets/Baldosa.png"
|
import baldosaImg from "./assets/Baldosa.png";
|
||||||
import semillaImg from "./assets/Semilla.png"
|
import semillaImg from "./assets/Semilla.png";
|
||||||
import arbol1Img from "./assets/Árbol 1.png"
|
import arbol1Img from "./assets/Árbol 1.png";
|
||||||
import arbol2Img from "./assets/Árbol 2.png"
|
import arbol2Img from "./assets/Árbol 2.png";
|
||||||
|
|
||||||
function loadImage(url: string): Promise<HTMLImageElement> {
|
function loadImage(url: string): Promise<HTMLImageElement> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let img = new Image()
|
let img = new Image();
|
||||||
img.onload = () => resolve(img)
|
img.onload = () => resolve(img);
|
||||||
img.onerror = e => reject(e)
|
img.onerror = (e) => reject(e);
|
||||||
img.src = url
|
img.src = url;
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export const assetUrls = {
|
export const assetUrls = {
|
||||||
botonJugar: botonJugarImg,
|
botonJugar: botonJugarImg,
|
||||||
larreta: larretaImg,
|
larreta: larretaImg,
|
||||||
fondo: fondoImg,
|
fondo: fondoImg,
|
||||||
edificios: edificiosImg,
|
edificios: edificiosImg,
|
||||||
jugadorx: jugadorxImg,
|
jugadorx: jugadorxImg,
|
||||||
baldosa: baldosaImg,
|
baldosa: baldosaImg,
|
||||||
semilla: semillaImg,
|
semilla: semillaImg,
|
||||||
arbol1: arbol1Img,
|
arbol1: arbol1Img,
|
||||||
arbol2: arbol2Img,
|
arbol2: arbol2Img,
|
||||||
}
|
};
|
||||||
export type Assets = { [key in keyof typeof assetUrls]: HTMLImageElement }
|
export type Assets = { [key in keyof typeof assetUrls]: HTMLImageElement };
|
||||||
|
|
||||||
const assets = Object.fromEntries(Object.entries(assetUrls).map(([name, url]) => [name, loadImage(url)]))
|
const assets = Object.fromEntries(
|
||||||
|
Object.entries(assetUrls).map(([name, url]) => [name, loadImage(url)])
|
||||||
|
);
|
||||||
|
|
||||||
export async function loadAssets() {
|
export async function loadAssets() {
|
||||||
const imgs = await Promise.all(Object.values(assets))
|
const imgs = await Promise.all(Object.values(assets));
|
||||||
return Object.fromEntries(imgs.map((img, i) => [Object.keys(assetUrls)[i], img])) as Assets
|
return Object.fromEntries(
|
||||||
|
imgs.map((img, i) => [Object.keys(assetUrls)[i], img])
|
||||||
|
) as Assets;
|
||||||
}
|
}
|
||||||
|
|
390
src/jugando.ts
390
src/jugando.ts
|
@ -1,221 +1,255 @@
|
||||||
import { Juego } from './main'
|
import { Juego } from "./main";
|
||||||
import { Sprite } from './sprite'
|
import { Sprite } from "./sprite";
|
||||||
import { Box, boxCollision, drawText, randomFromArray } from './utils'
|
import { Box, boxCollision, drawText, randomFromArray } from "./utils";
|
||||||
|
|
||||||
const ENEMIES_NUM = 12
|
const ENEMIES_NUM = 12;
|
||||||
const SEED_COOLDOWN = 300
|
const SEED_COOLDOWN = 300;
|
||||||
const MAP_MIN = 1000
|
const MAP_MIN = 1000;
|
||||||
const MAP_MAX = 5000
|
const MAP_MAX = 5000;
|
||||||
const MAP_SIZE = MAP_MAX - MAP_MIN
|
const MAP_SIZE = MAP_MAX - MAP_MIN;
|
||||||
const TREES_TO_WIN = 30
|
const TREES_TO_WIN = 30;
|
||||||
const TIME = 2 * 60 * 1000
|
const TIME = 2 * 60 * 1000;
|
||||||
|
|
||||||
export type State = {
|
export type State = {
|
||||||
current: "jugando"
|
current: "jugando";
|
||||||
pos: { x: number }
|
pos: { x: number };
|
||||||
view: { x: number }
|
view: { x: number };
|
||||||
side: "left" | "right"
|
side: "left" | "right";
|
||||||
enemies: { x: number }[]
|
enemies: { x: number }[];
|
||||||
seeds: { x: number; velocity: { x: number } }[]
|
seeds: { x: number; velocity: { x: number } }[];
|
||||||
trees: { x: number, sprite: Sprite }[]
|
trees: { x: number; sprite: Sprite }[];
|
||||||
time: number,
|
time: number;
|
||||||
seedCooldown: number,
|
seedCooldown: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export function createJugandoState(): State {
|
export function createJugandoState(): State {
|
||||||
return {
|
return {
|
||||||
current: "jugando",
|
current: "jugando",
|
||||||
pos: { x: MAP_MIN + MAP_SIZE / 2 },
|
pos: { x: MAP_MIN + MAP_SIZE / 2 },
|
||||||
view: { x: 0 },
|
view: { x: 0 },
|
||||||
side: "right",
|
side: "right",
|
||||||
enemies: [],
|
enemies: [],
|
||||||
seeds: [],
|
seeds: [],
|
||||||
trees: [],
|
trees: [],
|
||||||
time: TIME,
|
time: TIME,
|
||||||
seedCooldown: 0,
|
seedCooldown: 0,
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update(juego: Juego<State>, dt: number) {
|
export function update(juego: Juego<State>, dt: number) {
|
||||||
juego.state.time -= dt
|
juego.state.time -= dt;
|
||||||
if (juego.state.time < 0) {
|
if (juego.state.time < 0) {
|
||||||
(juego as Juego<any>).state = { current: "lose" }
|
(juego as Juego<any>).state = { current: "lose" };
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const playerSpeed = juego.canvas.width * 0.15
|
const playerSpeed = juego.canvas.width * 0.15;
|
||||||
const enemySpeed = juego.canvas.width * 0.05
|
const enemySpeed = juego.canvas.width * 0.05;
|
||||||
if (juego.keyboard.keys.d || juego.keyboard.keys.ArrowRight) {
|
if (juego.keyboard.keys.d || juego.keyboard.keys.ArrowRight) {
|
||||||
juego.state.side = "right"
|
juego.state.side = "right";
|
||||||
juego.state.pos.x += (dt / 1000) * playerSpeed
|
juego.state.pos.x += (dt / 1000) * playerSpeed;
|
||||||
}
|
}
|
||||||
if (juego.keyboard.keys.a || juego.keyboard.keys.ArrowLeft) {
|
if (juego.keyboard.keys.a || juego.keyboard.keys.ArrowLeft) {
|
||||||
juego.state.side = "left"
|
juego.state.side = "left";
|
||||||
juego.state.pos.x -= (dt / 1000) * playerSpeed
|
juego.state.pos.x -= (dt / 1000) * playerSpeed;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (juego.state.pos.x < MAP_MIN) juego.state.pos.x = MAP_MIN
|
if (juego.state.pos.x < MAP_MIN) juego.state.pos.x = MAP_MIN;
|
||||||
if (juego.state.pos.x > MAP_MAX) juego.state.pos.x = MAP_MAX
|
if (juego.state.pos.x > MAP_MAX) juego.state.pos.x = MAP_MAX;
|
||||||
|
|
||||||
juego.state.seedCooldown -= dt
|
|
||||||
if (juego.keyboard.keys[' '] && juego.state.seedCooldown < 0) {
|
|
||||||
const seedSpeed = juego.canvas.width * 0.7
|
|
||||||
juego.state.seeds.push({
|
|
||||||
x: juego.state.pos.x,
|
|
||||||
velocity: { x: juego.state.side === "left" ? -seedSpeed : seedSpeed },
|
|
||||||
})
|
|
||||||
juego.state.seedCooldown = SEED_COOLDOWN
|
|
||||||
}
|
|
||||||
for (const seed of juego.state.seeds) {
|
|
||||||
seed.x += (dt / 1000) * seed.velocity.x
|
|
||||||
seed.velocity.x *= 0.97
|
|
||||||
for (const enemy of juego.state.enemies) {
|
|
||||||
if (boxCollision({
|
|
||||||
x: seed.x,
|
|
||||||
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) - 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)
|
|
||||||
juego.state.trees.push({
|
|
||||||
x: enemy.x,
|
|
||||||
sprite: randomFromArray([juego.sprites.arbol1, juego.sprites.arbol2]),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (Math.abs(seed.velocity.x) < 100)
|
|
||||||
juego.state.seeds = juego.state.seeds.filter(s => s.velocity.x !== seed.velocity.x)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (juego.state.trees.length >= TREES_TO_WIN) {
|
|
||||||
(juego as Juego<any>).state = { current: "win" }
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
while (juego.state.enemies.length < ENEMIES_NUM) {
|
|
||||||
const x = Math.random() * MAP_SIZE + MAP_MIN
|
|
||||||
// Don't spawn enemies too close
|
|
||||||
if (Math.abs(juego.state.pos.x - x) < 300) continue
|
|
||||||
juego.state.enemies.push({ x })
|
|
||||||
}
|
|
||||||
|
|
||||||
|
juego.state.seedCooldown -= dt;
|
||||||
|
if (juego.keyboard.keys[" "] && juego.state.seedCooldown < 0) {
|
||||||
|
const seedSpeed = juego.canvas.width * 0.7;
|
||||||
|
juego.state.seeds.push({
|
||||||
|
x: juego.state.pos.x,
|
||||||
|
velocity: { x: juego.state.side === "left" ? -seedSpeed : seedSpeed },
|
||||||
|
});
|
||||||
|
juego.state.seedCooldown = SEED_COOLDOWN;
|
||||||
|
}
|
||||||
|
for (const seed of juego.state.seeds) {
|
||||||
|
seed.x += (dt / 1000) * seed.velocity.x;
|
||||||
|
seed.velocity.x *= 0.97;
|
||||||
for (const enemy of juego.state.enemies) {
|
for (const enemy of juego.state.enemies) {
|
||||||
const distance = enemy.x - juego.state.pos.x
|
if (
|
||||||
if (distance < 0) {
|
boxCollision(
|
||||||
enemy.x += (dt / 1000) * enemySpeed
|
{
|
||||||
} else {
|
x: seed.x,
|
||||||
enemy.x -= (dt / 1000) * enemySpeed
|
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) - 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
|
||||||
|
);
|
||||||
|
juego.state.trees.push({
|
||||||
|
x: enemy.x,
|
||||||
|
sprite: randomFromArray([juego.sprites.arbol1, juego.sprites.arbol2]),
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (Math.abs(seed.velocity.x) < 100)
|
||||||
|
juego.state.seeds = juego.state.seeds.filter(
|
||||||
|
(s) => s.velocity.x !== seed.velocity.x
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
juego.state.view.x = -juego.state.pos.x + juego.canvas.width / 2 - juego.sprites.jugadorx.getWidth(juego) / 2
|
if (juego.state.trees.length >= TREES_TO_WIN) {
|
||||||
|
(juego as Juego<any>).state = { current: "win" };
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (juego.state.enemies.length < ENEMIES_NUM) {
|
||||||
|
const x = Math.random() * MAP_SIZE + MAP_MIN;
|
||||||
|
// Don't spawn enemies too close
|
||||||
|
if (Math.abs(juego.state.pos.x - x) < 300) continue;
|
||||||
|
juego.state.enemies.push({ x });
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const enemy of juego.state.enemies) {
|
||||||
|
const distance = enemy.x - juego.state.pos.x;
|
||||||
|
if (distance < 0) {
|
||||||
|
enemy.x += (dt / 1000) * enemySpeed;
|
||||||
|
} else {
|
||||||
|
enemy.x -= (dt / 1000) * enemySpeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
juego.state.view.x =
|
||||||
|
-juego.state.pos.x +
|
||||||
|
juego.canvas.width / 2 -
|
||||||
|
juego.sprites.jugadorx.getWidth(juego) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawJugadorx(juego: Juego<State>) {
|
function drawJugadorx(juego: Juego<State>) {
|
||||||
const floorY = getFloorY(juego)
|
const floorY = getFloorY(juego);
|
||||||
juego.sprites.jugadorx.draw(
|
juego.sprites.jugadorx.draw(
|
||||||
juego,
|
juego,
|
||||||
juego.state.pos.x + juego.state.view.x,
|
juego.state.pos.x + juego.state.view.x,
|
||||||
floorY - juego.sprites.jugadorx.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 floorY = getFloorY(juego)
|
const floorY = getFloorY(juego);
|
||||||
for (const tree of juego.state.trees) {
|
for (const tree of juego.state.trees) {
|
||||||
const height = tree.sprite.getHeight(juego)
|
const height = tree.sprite.getHeight(juego);
|
||||||
tree.sprite.draw(
|
tree.sprite.draw(juego, tree.x + juego.state.view.x, floorY - height);
|
||||||
juego,
|
}
|
||||||
tree.x + juego.state.view.x,
|
|
||||||
floorY - height,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
function drawEnemies(juego: Juego<State>) {
|
function drawEnemies(juego: Juego<State>) {
|
||||||
const height = juego.sprites.larreta.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) {
|
||||||
juego.sprites.larreta.draw(
|
juego.sprites.larreta.draw(
|
||||||
juego,
|
juego,
|
||||||
enemy.x + juego.state.view.x,
|
enemy.x + juego.state.view.x,
|
||||||
floorY - height,
|
floorY - height
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawSeeds(juego: Juego<State>) {
|
function drawSeeds(juego: Juego<State>) {
|
||||||
const height = juego.sprites.semilla.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) {
|
||||||
juego.sprites.semilla.draw(
|
juego.sprites.semilla.draw(
|
||||||
juego,
|
juego,
|
||||||
seed.x + juego.state.view.x,
|
seed.x + juego.state.view.x,
|
||||||
floorY - height,
|
floorY - height
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFloorY(juego: Juego<State>): number {
|
function getFloorY(juego: Juego<State>): number {
|
||||||
return juego.canvas.height * 65 / 96
|
return (juego.canvas.height * 65) / 96;
|
||||||
}
|
}
|
||||||
|
|
||||||
function drawBackground(
|
function drawBackground(
|
||||||
juego: Juego<State>,
|
juego: Juego<State>,
|
||||||
y: number,
|
y: number,
|
||||||
height: number,
|
height: number,
|
||||||
img: HTMLImageElement,
|
img: HTMLImageElement,
|
||||||
sourceBox?: Box,
|
sourceBox?: Box
|
||||||
) {
|
) {
|
||||||
const aspect = img.width / img.height
|
const aspect = img.width / img.height;
|
||||||
const width = height * aspect
|
const width = height * aspect;
|
||||||
for (let i = 0; i < 10; i++) {
|
for (let i = 0; i < 10; i++) {
|
||||||
if (sourceBox) {
|
if (sourceBox) {
|
||||||
juego.ctx.drawImage(
|
juego.ctx.drawImage(
|
||||||
img,
|
img,
|
||||||
sourceBox.x, sourceBox.y, sourceBox.width, sourceBox.height,
|
sourceBox.x,
|
||||||
i * (width - 1) + juego.state.view.x, y, width, height,
|
sourceBox.y,
|
||||||
)
|
sourceBox.width,
|
||||||
} else {
|
sourceBox.height,
|
||||||
juego.ctx.drawImage(img, i * (width - 1) + juego.state.view.x, y, width, height)
|
i * (width - 1) + juego.state.view.x,
|
||||||
}
|
y,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
juego.ctx.drawImage(
|
||||||
|
img,
|
||||||
|
i * (width - 1) + juego.state.view.x,
|
||||||
|
y,
|
||||||
|
width,
|
||||||
|
height
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function draw(juego: Juego<State>, timestamp: number) {
|
export function draw(juego: Juego<State>, timestamp: number) {
|
||||||
drawBackground(juego, 0, juego.canvas.height, juego.assets.fondo)
|
drawBackground(juego, 0, juego.canvas.height, juego.assets.fondo);
|
||||||
drawBackground(
|
drawBackground(juego, 0, getFloorY(juego), juego.assets.edificios, {
|
||||||
juego, 0, getFloorY(juego), juego.assets.edificios,
|
x: 0,
|
||||||
{ x: 0, y: 0, width: 89, height: 48 })
|
y: 0,
|
||||||
|
width: 89,
|
||||||
|
height: 48,
|
||||||
|
});
|
||||||
|
|
||||||
drawTrees(juego)
|
drawTrees(juego);
|
||||||
drawEnemies(juego)
|
drawEnemies(juego);
|
||||||
|
|
||||||
drawJugadorx(juego)
|
drawJugadorx(juego);
|
||||||
drawSeeds(juego)
|
drawSeeds(juego);
|
||||||
|
|
||||||
juego.ctx.fillStyle = "white"
|
juego.ctx.fillStyle = "white";
|
||||||
drawText(juego, 'Usá las flechitas para moverte, y espacio para "disparar" semillas.', { x: 0, y: 100 }, {})
|
drawText(
|
||||||
|
juego,
|
||||||
|
'Usá las flechitas para moverte, y espacio para "disparar" semillas.',
|
||||||
|
{ x: 0, y: 100 },
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
const arbolesBox = drawText(
|
const arbolesBox = drawText(
|
||||||
juego, `Arboles: ${juego.state.trees.length}/${TREES_TO_WIN}`,
|
juego,
|
||||||
{ x: juego.canvas.width - 10, y: 10 },
|
`Arboles: ${juego.state.trees.length}/${TREES_TO_WIN}`,
|
||||||
{ bold: true, align: 'right' })
|
{ x: juego.canvas.width - 10, y: 10 },
|
||||||
|
{ bold: true, align: "right" }
|
||||||
|
);
|
||||||
|
|
||||||
const tiempoBox = drawText(
|
const tiempoBox = drawText(
|
||||||
juego, `Tiempo restante`,
|
juego,
|
||||||
{ x: 10, y: 10 },
|
`Tiempo restante`,
|
||||||
{ bold: false, align: 'left' })
|
{ x: 10, y: 10 },
|
||||||
|
{ bold: false, align: "left" }
|
||||||
|
);
|
||||||
|
|
||||||
juego.ctx.fillRect(
|
juego.ctx.fillRect(
|
||||||
10, tiempoBox.y + tiempoBox.height,
|
10,
|
||||||
(juego.canvas.width - arbolesBox.width - 20) * (juego.state.time / TIME),
|
tiempoBox.y + tiempoBox.height,
|
||||||
30)
|
(juego.canvas.width - arbolesBox.width - 20) * (juego.state.time / TIME),
|
||||||
|
30
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
24
src/lose.ts
24
src/lose.ts
|
@ -1,18 +1,20 @@
|
||||||
import { Juego } from './main'
|
import { Juego } from "./main";
|
||||||
import { drawText } from './utils'
|
import { drawText } from "./utils";
|
||||||
|
|
||||||
export type State = {
|
export type State = {
|
||||||
current: "lose"
|
current: "lose";
|
||||||
}
|
};
|
||||||
|
|
||||||
export function update(juego: Juego<State>, dt: number) {
|
export function update(juego: Juego<State>, dt: number) {}
|
||||||
}
|
|
||||||
|
|
||||||
export function draw(juego: Juego<State>, timestamp: number) {
|
export function draw(juego: Juego<State>, timestamp: number) {
|
||||||
drawText(juego, '¡Te convirtieron en baldosa!',
|
drawText(
|
||||||
{ x: juego.canvas.width / 2, y: 100 },
|
juego,
|
||||||
{ bold: true, size: 3, align: 'center' })
|
"¡Te convirtieron en baldosa!",
|
||||||
|
{ x: juego.canvas.width / 2, y: 100 },
|
||||||
|
{ bold: true, size: 3, align: "center" }
|
||||||
|
);
|
||||||
|
|
||||||
const width = juego.sprites.baldosa.getWidth(juego)
|
const width = juego.sprites.baldosa.getWidth(juego);
|
||||||
juego.sprites.baldosa.draw(juego, juego.canvas.width / 2 - width / 2, 100)
|
juego.sprites.baldosa.draw(juego, juego.canvas.width / 2 - width / 2, 100);
|
||||||
}
|
}
|
||||||
|
|
260
src/main.ts
260
src/main.ts
|
@ -1,131 +1,181 @@
|
||||||
import './style.css'
|
import "./style.css";
|
||||||
|
|
||||||
import * as welcome from "./welcome"
|
import * as welcome from "./welcome";
|
||||||
import * as jugando from "./jugando"
|
import * as jugando from "./jugando";
|
||||||
import * as win from "./win"
|
import * as win from "./win";
|
||||||
import * as lose from "./lose"
|
import * as lose from "./lose";
|
||||||
import { Assets, loadAssets } from './assets'
|
import { Assets, loadAssets } from "./assets";
|
||||||
import { loadSprite, Sprite } from './sprite'
|
import { loadSprite, Sprite } from "./sprite";
|
||||||
|
|
||||||
export type State = welcome.State | jugando.State | win.State | lose.State
|
export type State = welcome.State | jugando.State | win.State | lose.State;
|
||||||
|
|
||||||
export type Juego<T extends State> = {
|
export type Juego<T extends State> = {
|
||||||
canvas: HTMLCanvasElement
|
canvas: HTMLCanvasElement;
|
||||||
ctx: CanvasRenderingContext2D
|
ctx: CanvasRenderingContext2D;
|
||||||
assets: Assets
|
assets: Assets;
|
||||||
sprites: { [key in "jugadorx" | "baldosa" | "larreta" | "semilla" | "arbol1" | "arbol2"]: Sprite }
|
sprites: {
|
||||||
mouse: { x: number; y: number, down: boolean }
|
[key in
|
||||||
keyboard: { keys: { [key: string]: boolean } }
|
| "jugadorx"
|
||||||
state: T
|
| "baldosa"
|
||||||
}
|
| "larreta"
|
||||||
|
| "semilla"
|
||||||
|
| "arbol1"
|
||||||
|
| "arbol2"]: Sprite;
|
||||||
|
};
|
||||||
|
mouse: { x: number; y: number; down: boolean };
|
||||||
|
keyboard: { keys: { [key: string]: boolean } };
|
||||||
|
state: T;
|
||||||
|
};
|
||||||
|
|
||||||
function update(juego: Juego<any>, dt: number) {
|
function update(juego: Juego<any>, dt: number) {
|
||||||
switch (juego.state.current) {
|
switch (juego.state.current) {
|
||||||
case "welcome":
|
case "welcome":
|
||||||
welcome.update(juego, dt)
|
welcome.update(juego, dt);
|
||||||
break
|
break;
|
||||||
case "jugando":
|
case "jugando":
|
||||||
jugando.update(juego, dt)
|
jugando.update(juego, dt);
|
||||||
break
|
break;
|
||||||
case "win":
|
case "win":
|
||||||
win.update(juego, dt)
|
win.update(juego, dt);
|
||||||
break
|
break;
|
||||||
case "lose":
|
case "lose":
|
||||||
lose.update(juego, dt)
|
lose.update(juego, dt);
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw(juego: Juego<any>, timestamp: number) {
|
function draw(juego: Juego<any>, timestamp: number) {
|
||||||
const { width, height } = juego.canvas
|
const { width, height } = juego.canvas;
|
||||||
|
|
||||||
juego.ctx.fillStyle = "white"
|
juego.ctx.fillStyle = "white";
|
||||||
juego.ctx.fillRect(0, 0, width, height)
|
juego.ctx.fillRect(0, 0, width, height);
|
||||||
juego.ctx.fillStyle = "black"
|
juego.ctx.fillStyle = "black";
|
||||||
switch (juego.state.current) {
|
switch (juego.state.current) {
|
||||||
case "welcome":
|
case "welcome":
|
||||||
welcome.draw(juego, timestamp)
|
welcome.draw(juego, timestamp);
|
||||||
break
|
break;
|
||||||
case "jugando":
|
case "jugando":
|
||||||
jugando.draw(juego, timestamp)
|
jugando.draw(juego, timestamp);
|
||||||
break
|
break;
|
||||||
case "win":
|
case "win":
|
||||||
win.draw(juego, timestamp)
|
win.draw(juego, timestamp);
|
||||||
break
|
break;
|
||||||
case "lose":
|
case "lose":
|
||||||
lose.draw(juego, timestamp)
|
lose.draw(juego, timestamp);
|
||||||
break
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function resizeCanvas(canvas: HTMLCanvasElement) {
|
function resizeCanvas(canvas: HTMLCanvasElement) {
|
||||||
canvas.width = canvas.clientWidth
|
canvas.width = canvas.clientWidth;
|
||||||
canvas.height = canvas.clientHeight
|
canvas.height = canvas.clientHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
async 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", {
|
||||||
alpha: false,
|
alpha: false,
|
||||||
desynchronized: true,
|
desynchronized: true,
|
||||||
})!
|
})!;
|
||||||
|
|
||||||
window.addEventListener("resize", () => resizeCanvas(canvas), false)
|
window.addEventListener("resize", () => resizeCanvas(canvas), false);
|
||||||
resizeCanvas(canvas)
|
resizeCanvas(canvas);
|
||||||
|
|
||||||
const assets = await loadAssets()
|
const assets = await loadAssets();
|
||||||
|
|
||||||
const sprites = {
|
const sprites = {
|
||||||
jugadorx: loadSprite(assets.jugadorx, 65, 94, juego => juego.canvas.height / 4),
|
jugadorx: loadSprite(
|
||||||
baldosa: loadSprite(assets.baldosa, 72, 72, juego => juego.canvas.height * 0.8),
|
assets.jugadorx,
|
||||||
larreta: loadSprite(assets.larreta, 50, 71, juego => juego.canvas.height / 4),
|
65,
|
||||||
semilla: loadSprite(assets.semilla, 72, 73, juego => juego.canvas.height / 8),
|
94,
|
||||||
arbol1: loadSprite(assets.arbol1, 72, 68, juego => juego.canvas.height / 3),
|
(juego) => juego.canvas.height / 4
|
||||||
arbol2: loadSprite(assets.arbol2, 72, 56, juego => juego.canvas.height / 4),
|
),
|
||||||
}
|
baldosa: loadSprite(
|
||||||
|
assets.baldosa,
|
||||||
|
72,
|
||||||
|
72,
|
||||||
|
(juego) => juego.canvas.height * 0.8
|
||||||
|
),
|
||||||
|
larreta: loadSprite(
|
||||||
|
assets.larreta,
|
||||||
|
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
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
let juego: Juego<welcome.State> = {
|
let juego: Juego<welcome.State> = {
|
||||||
canvas,
|
canvas,
|
||||||
ctx,
|
ctx,
|
||||||
assets,
|
assets,
|
||||||
sprites,
|
sprites,
|
||||||
mouse: { x: 0, y: 0, down: false },
|
mouse: { x: 0, y: 0, down: false },
|
||||||
keyboard: { keys: {} },
|
keyboard: { keys: {} },
|
||||||
state: {
|
state: {
|
||||||
current: "welcome",
|
current: "welcome",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
(window as any).juego = juego
|
(window as any).juego = juego;
|
||||||
juego.ctx.imageSmoothingEnabled = false
|
juego.ctx.imageSmoothingEnabled = false;
|
||||||
|
|
||||||
canvas.addEventListener("mousemove", e => {
|
canvas.addEventListener(
|
||||||
juego.mouse.x = e.clientX
|
"mousemove",
|
||||||
juego.mouse.y = e.clientY
|
(e) => {
|
||||||
}, false)
|
juego.mouse.x = e.clientX;
|
||||||
canvas.addEventListener("mousedown", () => {
|
juego.mouse.y = e.clientY;
|
||||||
juego.mouse.down = true
|
},
|
||||||
}, false)
|
false
|
||||||
canvas.addEventListener("mouseup", () => {
|
);
|
||||||
juego.mouse.down = false
|
canvas.addEventListener(
|
||||||
}, false)
|
"mousedown",
|
||||||
window.addEventListener("keydown", e => {
|
() => {
|
||||||
juego.keyboard.keys[e.key] = true
|
juego.mouse.down = true;
|
||||||
})
|
},
|
||||||
window.addEventListener("keyup", e => {
|
false
|
||||||
juego.keyboard.keys[e.key] = 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;
|
||||||
|
});
|
||||||
|
|
||||||
let lastRender = 0
|
let lastRender = 0;
|
||||||
const loop: FrameRequestCallback = timestamp => {
|
const loop: FrameRequestCallback = (timestamp) => {
|
||||||
const progress = timestamp - lastRender
|
const progress = timestamp - lastRender;
|
||||||
|
|
||||||
update(juego, progress)
|
update(juego, progress);
|
||||||
draw(juego, timestamp)
|
draw(juego, timestamp);
|
||||||
|
|
||||||
lastRender = timestamp
|
lastRender = timestamp;
|
||||||
window.requestAnimationFrame(loop)
|
window.requestAnimationFrame(loop);
|
||||||
}
|
};
|
||||||
|
|
||||||
window.requestAnimationFrame(loop)
|
window.requestAnimationFrame(loop);
|
||||||
}
|
}
|
||||||
initJuego()
|
initJuego();
|
||||||
|
|
123
src/sprite.ts
123
src/sprite.ts
|
@ -1,65 +1,80 @@
|
||||||
import { Juego } from "./main"
|
import { Juego } from "./main";
|
||||||
|
|
||||||
export type Sprite = {
|
export type Sprite = {
|
||||||
getWidth: (juego: Juego<any>) => number;
|
getWidth: (juego: Juego<any>) => number;
|
||||||
getHeight: (juego: Juego<any>) => number;
|
getHeight: (juego: Juego<any>) => number;
|
||||||
draw: (juego: Juego<any>, x: number, y: number, spriteIndex?: number, flipped?: boolean) => void;
|
draw: (
|
||||||
width: number;
|
juego: Juego<any>,
|
||||||
height: number;
|
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,
|
||||||
// The size of each tile
|
// The size of each tile
|
||||||
width: number, height: number,
|
width: number,
|
||||||
// Calculates the size of the sprite when rendering
|
height: number,
|
||||||
getHeight: (juego: Juego<any>) => number,
|
// Calculates the size of the sprite when rendering
|
||||||
|
getHeight: (juego: Juego<any>) => number
|
||||||
): Sprite {
|
): 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) {
|
||||||
console.warn(`The sprite grid for ${img.src} has extra space after rows, are you sure the width/height of each tile is right?`)
|
console.warn(
|
||||||
}
|
`The sprite grid for ${img.src} has extra space after rows, are you sure the width/height of each tile is right?`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function getWidth(juego: Juego<any>) {
|
function getWidth(juego: Juego<any>) {
|
||||||
return getHeight(juego) * aspect
|
return getHeight(juego) * aspect;
|
||||||
}
|
}
|
||||||
|
|
||||||
function draw(juego: Juego<any>, x: number, y: number, spriteIndex = 0, flipped = false) {
|
function draw(
|
||||||
const drawHeight = getHeight(juego)
|
juego: Juego<any>,
|
||||||
const drawWidth = getWidth(juego)
|
x: number,
|
||||||
const tileX = spriteIndex % rowSize
|
y: number,
|
||||||
const tileY = Math.floor(spriteIndex / rowSize)
|
spriteIndex = 0,
|
||||||
if (flipped) {
|
flipped = false
|
||||||
juego.ctx.save()
|
) {
|
||||||
juego.ctx.scale(-1, 1)
|
const drawHeight = getHeight(juego);
|
||||||
juego.ctx.drawImage(
|
const drawWidth = getWidth(juego);
|
||||||
img,
|
const tileX = spriteIndex % rowSize;
|
||||||
tileX * width,
|
const tileY = Math.floor(spriteIndex / rowSize);
|
||||||
tileY * height,
|
if (flipped) {
|
||||||
width,
|
juego.ctx.save();
|
||||||
height,
|
juego.ctx.scale(-1, 1);
|
||||||
-x - drawWidth,
|
juego.ctx.drawImage(
|
||||||
y,
|
img,
|
||||||
drawWidth,
|
tileX * width,
|
||||||
drawHeight,
|
tileY * height,
|
||||||
)
|
width,
|
||||||
juego.ctx.restore()
|
height,
|
||||||
} else {
|
-x - drawWidth,
|
||||||
juego.ctx.drawImage(
|
y,
|
||||||
img,
|
drawWidth,
|
||||||
tileX * width,
|
drawHeight
|
||||||
tileY * height,
|
);
|
||||||
width,
|
juego.ctx.restore();
|
||||||
height,
|
} else {
|
||||||
x,
|
juego.ctx.drawImage(
|
||||||
y,
|
img,
|
||||||
drawWidth,
|
tileX * width,
|
||||||
drawHeight,
|
tileY * height,
|
||||||
)
|
width,
|
||||||
}
|
height,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
drawWidth,
|
||||||
|
drawHeight
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return { getWidth, getHeight, draw, width, height }
|
return { getWidth, getHeight, draw, width, height };
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
html, body {
|
html,
|
||||||
|
body {
|
||||||
font-family: Avenir, Helvetica, Arial, sans-serif;
|
font-family: Avenir, Helvetica, Arial, sans-serif;
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
|
|
67
src/utils.ts
67
src/utils.ts
|
@ -1,47 +1,62 @@
|
||||||
import { Juego } from "./main";
|
import { Juego } from "./main";
|
||||||
|
|
||||||
export type Pos = {
|
export type Pos = {
|
||||||
x: number, y: number,
|
x: number;
|
||||||
|
y: number;
|
||||||
};
|
};
|
||||||
export type Box = Pos & {
|
export type Box = Pos & {
|
||||||
width: number, height: number,
|
width: number;
|
||||||
}
|
height: number;
|
||||||
|
};
|
||||||
|
|
||||||
export function posInBox(box: Box, pos: Pos) {
|
export function posInBox(box: Box, pos: Pos) {
|
||||||
return pos.x > box.x && pos.x < box.x + box.width
|
return (
|
||||||
&& pos.y > box.y && pos.y < box.y + box.height
|
pos.x > box.x &&
|
||||||
|
pos.x < box.x + box.width &&
|
||||||
|
pos.y > box.y &&
|
||||||
|
pos.y < box.y + box.height
|
||||||
|
);
|
||||||
}
|
}
|
||||||
export function boxCollision(box1: Box, box2: Box) {
|
export function boxCollision(box1: Box, box2: Box) {
|
||||||
// http://stackoverflow.com/questions/2440377/ddg#7301852
|
// http://stackoverflow.com/questions/2440377/ddg#7301852
|
||||||
return !(
|
return !(
|
||||||
((box1.y + box1.height) < (box2.y)) ||
|
box1.y + box1.height < box2.y ||
|
||||||
(box1.y > (box2.y + box2.height)) ||
|
box1.y > box2.y + box2.height ||
|
||||||
((box1.x + box1.width) < box2.x) ||
|
box1.x + box1.width < box2.x ||
|
||||||
(box1.x > (box2.x + box2.width))
|
box1.x > box2.x + box2.width
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function drawText(juego: Juego<any>, text: string, pos: Pos, {
|
export function drawText(
|
||||||
|
juego: Juego<any>,
|
||||||
|
text: string,
|
||||||
|
pos: Pos,
|
||||||
|
{
|
||||||
bold = false,
|
bold = false,
|
||||||
size = 2,
|
size = 2,
|
||||||
align = "left",
|
align = "left",
|
||||||
baseline = "top",
|
baseline = "top",
|
||||||
}: {
|
}: {
|
||||||
align?: CanvasTextAlign,
|
align?: CanvasTextAlign;
|
||||||
baseline?: CanvasTextBaseline,
|
baseline?: CanvasTextBaseline;
|
||||||
bold?: boolean,
|
bold?: boolean;
|
||||||
// in rem
|
// in rem
|
||||||
size?: number,
|
size?: number;
|
||||||
}): Box {
|
}
|
||||||
juego.ctx.font = `${bold ? 'bold ' : ''}${size}rem sans-serif`
|
): Box {
|
||||||
juego.ctx.textAlign = align
|
juego.ctx.font = `${bold ? "bold " : ""}${size}rem sans-serif`;
|
||||||
juego.ctx.textBaseline = baseline
|
juego.ctx.textAlign = align;
|
||||||
juego.ctx.fillText(text, pos.x, pos.y)
|
juego.ctx.textBaseline = baseline;
|
||||||
|
juego.ctx.fillText(text, pos.x, pos.y);
|
||||||
|
|
||||||
const measure = juego.ctx.measureText(text)
|
const measure = juego.ctx.measureText(text);
|
||||||
return { ...pos, width: measure.width, height: measure.actualBoundingBoxDescent }
|
return {
|
||||||
|
...pos,
|
||||||
|
width: measure.width,
|
||||||
|
height: measure.actualBoundingBoxDescent,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function randomFromArray<T>(array: T[]): T {
|
export function randomFromArray<T>(array: T[]): T {
|
||||||
return array[Math.floor(Math.random() * array.length)]
|
return array[Math.floor(Math.random() * array.length)];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,29 +1,38 @@
|
||||||
import { posInBox } from './utils'
|
import { posInBox } from "./utils";
|
||||||
import { createJugandoState } from './jugando'
|
import { createJugandoState } from "./jugando";
|
||||||
import { Juego } from './main'
|
import { Juego } from "./main";
|
||||||
|
|
||||||
export type State = {
|
export type State = {
|
||||||
current: "welcome"
|
current: "welcome";
|
||||||
}
|
};
|
||||||
|
|
||||||
function startButton(juego: Juego<State>) {
|
function startButton(juego: Juego<State>) {
|
||||||
const [width, height] = [juego.assets.botonJugar.width / 4, juego.assets.botonJugar.height / 4]
|
const [width, height] = [
|
||||||
return {
|
juego.assets.botonJugar.width / 4,
|
||||||
x: juego.canvas.width - width - 30,
|
juego.assets.botonJugar.height / 4,
|
||||||
y: juego.canvas.height - height - 30,
|
];
|
||||||
width,
|
return {
|
||||||
height,
|
x: juego.canvas.width - width - 30,
|
||||||
}
|
y: juego.canvas.height - height - 30,
|
||||||
|
width,
|
||||||
|
height,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function update(juego: Juego<State>, dt: number) {
|
export function update(juego: Juego<State>, dt: number) {
|
||||||
const btn = startButton(juego)
|
const btn = startButton(juego);
|
||||||
if (juego.mouse.down && posInBox(btn, juego.mouse)) {
|
if (juego.mouse.down && posInBox(btn, juego.mouse)) {
|
||||||
(juego as Juego<any>).state = createJugandoState()
|
(juego as Juego<any>).state = createJugandoState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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(juego.assets.botonJugar, btn.x, btn.y, btn.width, btn.height)
|
juego.ctx.drawImage(
|
||||||
|
juego.assets.botonJugar,
|
||||||
|
btn.x,
|
||||||
|
btn.y,
|
||||||
|
btn.width,
|
||||||
|
btn.height
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
20
src/win.ts
20
src/win.ts
|
@ -1,15 +1,17 @@
|
||||||
import { Juego } from './main'
|
import { Juego } from "./main";
|
||||||
import { drawText } from './utils'
|
import { drawText } from "./utils";
|
||||||
|
|
||||||
export type State = {
|
export type State = {
|
||||||
current: "win"
|
current: "win";
|
||||||
}
|
};
|
||||||
|
|
||||||
export function update(juego: Juego<State>, dt: number) {
|
export function update(juego: Juego<State>, dt: number) {}
|
||||||
}
|
|
||||||
|
|
||||||
export function draw(juego: Juego<State>, timestamp: number) {
|
export function draw(juego: Juego<State>, timestamp: number) {
|
||||||
drawText(juego, '¡Salvaste la costanera!',
|
drawText(
|
||||||
{ x: juego.canvas.width / 2, y: 100 },
|
juego,
|
||||||
{ bold: true, size: 3, align: 'center' })
|
"¡Salvaste la costanera!",
|
||||||
|
{ x: juego.canvas.width / 2, y: 100 },
|
||||||
|
{ bold: true, size: 3, align: "center" }
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "ESNext",
|
"target": "ESNext",
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"lib": ["ESNext", "DOM"],
|
"lib": ["ESNext", "DOM"],
|
||||||
"moduleResolution": "Node",
|
"moduleResolution": "Node",
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"noImplicitReturns": true
|
"noImplicitReturns": true
|
||||||
},
|
},
|
||||||
"include": ["./src"]
|
"include": ["./src"]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue