salva-la-costanera/src/jugando.ts

175 lines
5.6 KiB
TypeScript
Raw Normal View History

2021-06-28 18:01:45 +00:00
import { loadSprite } from './sprite'
import { Juego } from './main'
2021-06-28 19:02:12 +00:00
import { boxCollision } from './utils'
2021-06-28 18:01:45 +00:00
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
2021-06-28 19:02:12 +00:00
const semillaImg = document.getElementById("img-semilla") as HTMLImageElement
2021-06-28 18:01:45 +00:00
const jugadorxSprite = loadSprite(jugadorxImg, 133, 266, juego => juego.canvas.height / 4)
const larretaSprite = loadSprite(larretaImg, 800, 1069, juego => juego.canvas.height / 4)
2021-06-28 19:02:12 +00:00
const semillaSprite = loadSprite(semillaImg, 480, 640, juego => juego.canvas.height / 8)
2021-06-28 18:01:45 +00:00
const ENEMIES_NUM = 20
const ENEMY_SPEED = 40
const PLAYER_SPEED = 200
const SEED_SPEED = 1000
const SEED_COOLDOWN = 300
const MAP_MIN = 1000
const MAP_MAX = 5000
const MAP_SIZE = MAP_MAX - MAP_MIN
2021-06-28 18:01:45 +00:00
export type State = {
current: "jugando"
pos: { x: number }
view: { x: number }
2021-06-28 19:02:12 +00:00
side: "left" | "right"
2021-06-28 18:01:45 +00:00
enemies: { x: number }[]
2021-06-28 19:02:12 +00:00
seeds: { x: number; velocity: { x: number } }[]
seedCooldown: number,
2021-06-28 18:01:45 +00:00
}
export function createJugandoState(): State {
return {
current: "jugando",
pos: { x: MAP_MIN + MAP_SIZE / 2 },
2021-06-28 18:01:45 +00:00
view: { x: 0 },
2021-06-28 19:02:12 +00:00
side: "right",
enemies: [],
2021-06-28 19:02:12 +00:00
seeds: [],
seedCooldown: 0,
2021-06-28 18:01:45 +00:00
}
}
export function update(juego: Juego<State>, dt: number) {
2021-06-28 19:02:12 +00:00
if (juego.keyboard.keys.d || juego.keyboard.keys.ArrowRight) {
juego.state.side = "right"
juego.state.pos.x += (dt / 1000) * PLAYER_SPEED
2021-06-28 18:01:45 +00:00
}
2021-06-28 19:02:12 +00:00
if (juego.keyboard.keys.a || juego.keyboard.keys.ArrowLeft) {
juego.state.side = "left"
juego.state.pos.x -= (dt / 1000) * PLAYER_SPEED
2021-06-28 18:01:45 +00:00
}
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
2021-06-28 18:01:45 +00:00
2021-06-28 19:02:12 +00:00
juego.state.seedCooldown -= dt
if (juego.keyboard.keys[' '] && juego.state.seedCooldown < 0) {
juego.state.seeds.push({
x: juego.state.pos.x,
velocity: { x: juego.state.side === "left" ? -SEED_SPEED : SEED_SPEED },
2021-06-28 19:02:12 +00:00
})
juego.state.seedCooldown = SEED_COOLDOWN
2021-06-28 19:02:12 +00:00
}
for (const seed of juego.state.seeds) {
seed.x += (dt / 1000) * seed.velocity.x
seed.velocity.x *= 0.9
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),
}, {
x: enemy.x,
y: getFloorY(juego) - larretaSprite.getHeight(juego),
width: larretaSprite.getWidth(juego),
height: larretaSprite.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)
}
}
2021-06-28 19:20:54 +00:00
if (Math.abs(seed.velocity.x) < 100)
juego.state.seeds = juego.state.seeds.filter(s => s.velocity.x !== seed.velocity.x)
2021-06-28 19:02:12 +00:00
}
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) * ENEMY_SPEED
} else {
enemy.x -= (dt / 1000) * ENEMY_SPEED
}
}
2021-06-28 18:01:45 +00:00
juego.state.view.x = -juego.state.pos.x + juego.canvas.width / 2 - jugadorxSprite.getWidth(juego) / 2
}
function drawBackground(
juego: Juego<State>,
2021-06-28 19:02:12 +00:00
y: number,
2021-06-28 18:01:45 +00:00
height: number,
img: HTMLImageElement,
) {
const aspect = img.width / img.height
const width = height * aspect
for (let i = 0; i < 10; i++) {
2021-06-28 19:02:12 +00:00
juego.ctx.drawImage(img, i * (width - 1) + juego.state.view.x, y, width, height)
2021-06-28 18:01:45 +00:00
}
}
2021-06-28 19:02:12 +00:00
function drawJugadorx(juego: Juego<State>) {
const floorY = getFloorY(juego)
2021-06-28 18:01:45 +00:00
jugadorxSprite.draw(
juego,
juego.state.pos.x + juego.state.view.x,
2021-06-28 19:02:12 +00:00
floorY - jugadorxSprite.getHeight(juego),
0,
juego.state.side === "left",
2021-06-28 18:01:45 +00:00
)
}
2021-06-28 19:02:12 +00:00
function drawEnemies(juego: Juego<State>) {
2021-06-28 18:01:45 +00:00
const height = larretaSprite.getHeight(juego)
2021-06-28 19:02:12 +00:00
const floorY = getFloorY(juego)
2021-06-28 18:01:45 +00:00
for (const enemy of juego.state.enemies) {
larretaSprite.draw(
juego,
enemy.x + juego.state.view.x,
floorY - height,
)
}
}
2021-06-28 19:02:12 +00:00
function drawSeeds(juego: Juego<State>) {
const height = semillaSprite.getHeight(juego)
const floorY = getFloorY(juego)
for (const seed of juego.state.seeds) {
semillaSprite.draw(
juego,
seed.x + juego.state.view.x,
floorY - height,
)
}
}
function getFloorY(juego: Juego<State>): number {
return (juego.canvas.height / 3) * 2
}
2021-06-28 18:01:45 +00:00
export function draw(juego: Juego<State>, timestamp: number) {
const { height } = juego.canvas
drawBackground(juego, 0, (height / 3) * 2, fondoImg)
2021-06-28 19:02:12 +00:00
drawBackground(juego, getFloorY(juego), height / 3, veredaImg)
2021-06-28 18:01:45 +00:00
2021-06-28 19:02:12 +00:00
drawEnemies(juego)
2021-06-28 18:01:45 +00:00
2021-06-28 19:02:12 +00:00
drawJugadorx(juego)
drawSeeds(juego)
juego.ctx.fillText('Usá las flechitas para moverte, y espacio para "disparar" semillas.', 100, 100)
2021-06-28 18:01:45 +00:00
}