diff --git a/src/assets.ts b/src/assets.ts index c6e52f7..c154bd7 100644 --- a/src/assets.ts +++ b/src/assets.ts @@ -13,6 +13,9 @@ import baldosaImg from "./assets/Baldosa.png"; import semillaImg from "./assets/Semilla.png"; import arbol1Img from "./assets/Árbol 1.png"; import arbol2Img from "./assets/Árbol 2.png"; +import ciudadanx1Img from "./assets/Firma 1.png"; +import ciudadanx2Img from "./assets/Firma 2.png"; +import ciudadanx3Img from "./assets/Firma 3.png"; function loadImage(url: string): Promise { return new Promise((resolve, reject) => { @@ -39,6 +42,9 @@ export const assetUrls = { semilla: semillaImg, arbol1: arbol1Img, arbol2: arbol2Img, + ciudadanx1: ciudadanx1Img, + ciudadanx2: ciudadanx2Img, + ciudadanx3: ciudadanx3Img, }; export type Assets = { [key in keyof typeof assetUrls]: HTMLImageElement }; diff --git a/src/assets/Firma 1.png b/src/assets/Firma 1.png new file mode 100644 index 0000000..58dd32e Binary files /dev/null and b/src/assets/Firma 1.png differ diff --git a/src/assets/Firma 2.png b/src/assets/Firma 2.png new file mode 100644 index 0000000..4cf7066 Binary files /dev/null and b/src/assets/Firma 2.png differ diff --git a/src/assets/Firma 3.png b/src/assets/Firma 3.png new file mode 100644 index 0000000..4c38775 Binary files /dev/null and b/src/assets/Firma 3.png differ diff --git a/src/jugando.ts b/src/jugando.ts index e22750f..b5f88dd 100644 --- a/src/jugando.ts +++ b/src/jugando.ts @@ -13,12 +13,15 @@ import { const ENEMIES_NUM = 12; const SEED_COOLDOWN = 300; const MAP_MIN = 1000; -const MAP_MAX = 5000; +const MAP_MAX = 10000; const MAP_SIZE = MAP_MAX - MAP_MIN; -const TREES_TO_WIN = 30; +const SIGNATURES_TO_WIN = 20000; +const CITIZENS = SIGNATURES_TO_WIN / 1000; const TIME = 2 * 60 * 1000; const TIME_LOST_WHEN_HIT = 20 * 1000; +type Citizen = { x: number; sprite: Sprite }; + export type State = { current: "jugando"; pos: { x: number }; @@ -27,19 +30,35 @@ export type State = { enemies: { x: number; sprite: Sprite }[]; seeds: { x: number; velocity: { x: number } }[]; trees: { x: number; sprite: Sprite }[]; + citizens: Citizen[]; + signatures: number; time: number; seedCooldown: number; }; -export function createJugandoState(): State { +export function createJugandoState(juego: Juego): State { + let citizens = []; + for (let i = 0; i < CITIZENS; i++) { + citizens.push({ + x: MAP_MIN + (i + 1) * (MAP_SIZE / CITIZENS), + sprite: randomFromArray([ + juego.sprites.ciudadanx1, + juego.sprites.ciudadanx2, + juego.sprites.ciudadanx3, + ]), + }); + } + console.log(CITIZENS, citizens); return { current: "jugando", - pos: { x: MAP_MIN + MAP_SIZE / 2 }, + pos: { x: MAP_MIN + 100 }, view: { x: 0 }, side: "right", enemies: [], seeds: [], trees: [], + signatures: 0, + citizens, time: TIME, seedCooldown: 0, }; @@ -103,35 +122,33 @@ export function update(juego: Juego, dt: number) { if (juego.state.pos.x > MAP_MAX) juego.state.pos.x = MAP_MAX; juego.state.seedCooldown -= dt; - if ( - (juego.keyboard.keys[" "] || isTouching(juego, center)) && - 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 }, - }); + + const citizen = detectCitizen(juego); + + if (juego.keyboard.keys[" "] || isTouching(juego, center)) { + if (citizen) { + juego.state.signatures += 1000; + juego.state.citizens = juego.state.citizens.filter((c) => c != citizen); + } else { + if (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) - enemy.sprite.getHeight(juego), - width: enemy.sprite.getWidth(juego), - height: enemy.sprite.getHeight(juego), - } + getFlooredBox(juego, juego.sprites.semilla, seed.x), + getFlooredBox(juego, enemy.sprite, enemy.x) ) ) { juego.state.seeds = juego.state.seeds.filter((s) => s.x !== seed.x); @@ -150,7 +167,7 @@ export function update(juego: Juego, dt: number) { ); } - if (juego.state.trees.length >= TREES_TO_WIN) { + if (juego.state.signatures >= SIGNATURES_TO_WIN) { (juego as Juego).state = { current: "win" }; return; } @@ -178,18 +195,8 @@ export function update(juego: Juego, dt: number) { if ( boxCollision( - { - x: juego.state.pos.x, - y: getFloorY(juego) - juego.sprites.jugadorx.getHeight(juego), - width: juego.sprites.jugadorx.getWidth(juego), - height: juego.sprites.jugadorx.getHeight(juego), - }, - { - x: enemy.x, - y: getFloorY(juego) - enemy.sprite.getHeight(juego), - width: enemy.sprite.getWidth(juego), - height: enemy.sprite.getHeight(juego), - } + getFlooredBox(juego, juego.sprites.jugadorx, juego.state.pos.x), + getFlooredBox(juego, enemy.sprite, enemy.x) ) ) { juego.state.enemies = juego.state.enemies.filter((e) => e.x !== enemy.x); @@ -203,6 +210,27 @@ export function update(juego: Juego, dt: number) { juego.sprites.jugadorx.getWidth(juego) / 2; } +function getFlooredBox(juego: Juego, sprite: Sprite, x: number): Box { + const height = sprite.getHeight(juego); + return { + x, + y: getFloorY(juego) - height, + width: sprite.getWidth(juego), + height, + }; +} + +function detectCitizen(juego: Juego): Citizen | undefined { + const jugadorxBox = getFlooredBox( + juego, + juego.sprites.jugadorx, + juego.state.pos.x + ); + return juego.state.citizens.find((c) => + boxCollision(jugadorxBox, getFlooredBox(juego, c.sprite, c.x)) + ); +} + function drawJugadorx(juego: Juego) { const floorY = getFloorY(juego); juego.sprites.jugadorx.draw( @@ -228,6 +256,13 @@ function drawEnemies(juego: Juego) { enemy.sprite.draw(juego, enemy.x + juego.state.view.x, floorY - height); } } +function drawCitizens(juego: Juego) { + const floorY = getFloorY(juego); + for (const citizen of juego.state.citizens) { + const height = citizen.sprite.getHeight(juego); + citizen.sprite.draw(juego, citizen.x + juego.state.view.x, floorY - height); + } +} function drawSeeds(juego: Juego) { const height = juego.sprites.semilla.getHeight(juego); @@ -301,7 +336,7 @@ export function draw(juego: Juego, timestamp: number) { juego.canvas.height, juego.assets.cielo, undefined, - juego.state.trees.length / TREES_TO_WIN + juego.state.signatures / SIGNATURES_TO_WIN ); drawBackground( juego, @@ -309,10 +344,11 @@ export function draw(juego: Juego, timestamp: number) { juego.canvas.height, juego.assets.parquePublicoRio, undefined, - juego.state.trees.length / TREES_TO_WIN + juego.state.signatures / SIGNATURES_TO_WIN ); drawTrees(juego); + drawCitizens(juego); drawEnemies(juego); drawJugadorx(juego); @@ -344,9 +380,9 @@ export function draw(juego: Juego, timestamp: number) { } juego.ctx.fillStyle = "white"; - const arbolesBox = drawText( + const firmasBox = drawText( juego, - `Arboles: ${juego.state.trees.length}/${TREES_TO_WIN}`, + `Firmas: ${juego.state.signatures}/${SIGNATURES_TO_WIN}`, { x: juego.canvas.width - 10, y: 10 }, { bold: true, align: "right" } ); @@ -361,7 +397,7 @@ export function draw(juego: Juego, timestamp: number) { juego.ctx.fillRect( 10, tiempoBox.y + tiempoBox.height, - (juego.canvas.width - arbolesBox.width - 20) * (juego.state.time / TIME), + (juego.canvas.width - firmasBox.width - 20) * (juego.state.time / TIME), 30 ); } diff --git a/src/main.ts b/src/main.ts index fcca70d..9293765 100644 --- a/src/main.ts +++ b/src/main.ts @@ -23,7 +23,10 @@ export type Juego = { | "millonarioMalo" | "semilla" | "arbol1" - | "arbol2"]: Sprite; + | "arbol2" + | "ciudadanx1" + | "ciudadanx2" + | "ciudadanx3"]: Sprite; }; mouse: { x: number; y: number; down: boolean }; touches: TouchList | null; @@ -158,6 +161,24 @@ async function initJuego() { 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 = { diff --git a/src/welcome.ts b/src/welcome.ts index 75015d3..e57d100 100644 --- a/src/welcome.ts +++ b/src/welcome.ts @@ -25,7 +25,7 @@ export function update(juego: Juego, dt: number) { (juego.mouse.down && posInBox(btn, juego.mouse)) || isTouching(juego, btn) ) { - (juego as Juego).state = createJugandoState(); + (juego as Juego).state = createJugandoState(juego); } }