commit 2c70605ba18c4b108dc9b96a4a4a978e1d783a5c
Author: Nulo <hi@nulo.in>
Date:   Sun Jun 27 14:49:56 2021 +0000

    Juego base

diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..53f7466
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+node_modules
+.DS_Store
+dist
+dist-ssr
+*.local
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..c1f076b
--- /dev/null
+++ b/index.html
@@ -0,0 +1,21 @@
+<!DOCTYPE html>
+<html lang="es">
+  <head>
+    <meta charset="UTF-8" />
+    <!-- TODO: favicon -->
+    <!-- <link rel="icon" type="image/svg+xml" href="favicon.svg" /> -->
+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
+    <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-larreta" src="/src/assets/larreta.png">
+      <img id="img-vereda" src="/src/assets/piso.png">
+      <img id="img-fondo" src="/src/assets/fondo.png">
+    </div>
+    <canvas id="juego" width="1280" height="720"></canvas>
+    <script type="module" src="/src/main.js"></script>
+  </body>
+</html>
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..2135909
--- /dev/null
+++ b/package.json
@@ -0,0 +1,12 @@
+{
+  "name": "salva-la-costanera",
+  "version": "0.0.0",
+  "scripts": {
+    "dev": "vite",
+    "build": "vite build",
+    "serve": "vite preview"
+  },
+  "devDependencies": {
+    "vite": "^2.3.8"
+  }
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..d044be4
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,95 @@
+lockfileVersion: 5.3
+
+specifiers:
+  vite: ^2.3.8
+
+devDependencies:
+  vite: 2.3.8
+
+packages:
+
+  /colorette/1.2.2:
+    resolution: {integrity: sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==}
+    dev: true
+
+  /esbuild/0.12.9:
+    resolution: {integrity: sha512-MWRhAbMOJ9RJygCrt778rz/qNYgA4ZVj6aXnNPxFjs7PmIpb0fuB9Gmg5uWrr6n++XKwwm/RmSz6RR5JL2Ocsw==}
+    hasBin: true
+    requiresBuild: true
+    dev: true
+
+  /fsevents/2.3.2:
+    resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
+    engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+    os: [darwin]
+    dev: true
+    optional: true
+
+  /function-bind/1.1.1:
+    resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==}
+    dev: true
+
+  /has/1.0.3:
+    resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==}
+    engines: {node: '>= 0.4.0'}
+    dependencies:
+      function-bind: 1.1.1
+    dev: true
+
+  /is-core-module/2.4.0:
+    resolution: {integrity: sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==}
+    dependencies:
+      has: 1.0.3
+    dev: true
+
+  /nanoid/3.1.23:
+    resolution: {integrity: sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==}
+    engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+    hasBin: true
+    dev: true
+
+  /path-parse/1.0.7:
+    resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+    dev: true
+
+  /postcss/8.3.5:
+    resolution: {integrity: sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA==}
+    engines: {node: ^10 || ^12 || >=14}
+    dependencies:
+      colorette: 1.2.2
+      nanoid: 3.1.23
+      source-map-js: 0.6.2
+    dev: true
+
+  /resolve/1.20.0:
+    resolution: {integrity: sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==}
+    dependencies:
+      is-core-module: 2.4.0
+      path-parse: 1.0.7
+    dev: true
+
+  /rollup/2.52.3:
+    resolution: {integrity: sha512-QF3Sju8Kl2z0osI4unyOLyUudyhOMK6G0AeqJWgfiyigqLAlnNrfBcDWDx+f1cqn+JU2iIYVkDrgQ6/KtwEfrg==}
+    engines: {node: '>=10.0.0'}
+    hasBin: true
+    optionalDependencies:
+      fsevents: 2.3.2
+    dev: true
+
+  /source-map-js/0.6.2:
+    resolution: {integrity: sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==}
+    engines: {node: '>=0.10.0'}
+    dev: true
+
+  /vite/2.3.8:
+    resolution: {integrity: sha512-QiEx+iqNnJntSgSF2fWRQvRey9pORIrtNJzNyBJXwc+BdzWs83FQolX84cTBo393cfhObrtWa6180dAa4NLDiQ==}
+    engines: {node: '>=12.0.0'}
+    hasBin: true
+    dependencies:
+      esbuild: 0.12.9
+      postcss: 8.3.5
+      resolve: 1.20.0
+      rollup: 2.52.3
+    optionalDependencies:
+      fsevents: 2.3.2
+    dev: true
diff --git a/src/assets/boton_jugar.png b/src/assets/boton_jugar.png
new file mode 100644
index 0000000..457ad97
Binary files /dev/null and b/src/assets/boton_jugar.png differ
diff --git a/src/assets/fondo.png b/src/assets/fondo.png
new file mode 100644
index 0000000..963ff6b
Binary files /dev/null and b/src/assets/fondo.png differ
diff --git a/src/assets/larreta.png b/src/assets/larreta.png
new file mode 100644
index 0000000..7d5b957
Binary files /dev/null and b/src/assets/larreta.png differ
diff --git a/src/assets/piso.png b/src/assets/piso.png
new file mode 100644
index 0000000..69cb6fb
Binary files /dev/null and b/src/assets/piso.png differ
diff --git a/src/assets/remax.png b/src/assets/remax.png
new file mode 100644
index 0000000..da12847
Binary files /dev/null and b/src/assets/remax.png differ
diff --git a/src/jugando.js b/src/jugando.js
new file mode 100644
index 0000000..7083cf9
--- /dev/null
+++ b/src/jugando.js
@@ -0,0 +1,50 @@
+import { posInBox } from './utils.js'
+
+const larretaImg = document.getElementById("img-larreta")
+const inmobiliariaImg = document.getElementById("img-inmobiliaria")
+const veredaImg = document.getElementById("img-vereda")
+const fondoImg = document.getElementById("img-fondo")
+
+export function createJugandoState() {
+  return {
+    current: 'jugando',
+    pos: { x: 0 },
+    velocity: { x: 0 },
+    // { x }
+    enemies: [{ x: 0 }],
+  }
+}
+
+export function updateJugando(juego, dt) {
+  juego.state.velocity.x = 0
+  if (juego.keyboard.keys.d) {
+    juego.state.velocity.x += 20
+  }
+  if (juego.keyboard.keys.a) {
+    juego.state.velocity.x -= 20
+  }
+  juego.state.pos.x += juego.state.velocity.x
+}
+
+function drawBackground(juego, y, height, img) {
+  const aspect = img.width / img.height
+  const width = height * aspect
+  const realY = typeof y === 'function'
+    ? y(height)
+    : y
+  for (let i = 0; i < 10; i++) {
+    juego.ctx.drawImage(img, i * (width - 1) - juego.state.pos.x, realY, width, height)
+  }
+}
+
+export function drawJugando(juego) {
+  const {width, height} = juego.canvas
+  const {x} = juego.state.pos
+
+  drawBackground(juego, 0, (height / 3) * 2, fondoImg)
+  drawBackground(juego, h => height - h, height / 3, veredaImg)
+
+  for (const enemy of juego.state.enemies) {
+    //juego.ctx.drawImage(larretaImg, enemy.x, btn.y, btn.width, btn.height)
+  }
+}
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 0000000..fb500a8
--- /dev/null
+++ b/src/main.js
@@ -0,0 +1,85 @@
+import './style.css'
+
+import { drawWelcome, updateWelcome } from "./welcome.js"
+import { drawJugando, updateJugando } from "./jugando.js"
+
+function update(juego, dt) {
+  switch (juego.state.current) {
+    case "welcome":
+      updateWelcome(juego, dt)
+      break
+    case "jugando":
+      updateJugando(juego, dt)
+      break
+  }
+}
+
+function draw(juego) {
+  const {width, height} = juego.canvas
+
+  juego.ctx.clearRect(0, 0, width, height)
+  switch (juego.state.current) {
+    case "welcome":
+      drawWelcome(juego)
+      break
+    case "jugando":
+      drawJugando(juego)
+      break
+  }
+}
+
+function resizeCanvas(canvas) {
+  canvas.width = canvas.clientWidth
+  canvas.height = canvas.clientHeight
+}
+
+function initJuego() {
+  const canvas = document.querySelector("#juego")
+  const ctx = canvas.getContext("2d")
+
+  window.addEventListener("resize", () => resizeCanvas(canvas), false)
+  resizeCanvas(canvas)
+
+  let juego = {
+    canvas,
+    ctx,
+    mouse: { x: 0, y: 0, down: false },
+    keyboard: { keys: {} },
+    state: {
+      current: "welcome",
+    },
+  }
+  window.juego = juego
+
+  canvas.addEventListener("mousemove", e => {
+    juego.mouse.x = e.clientX
+    juego.mouse.y = e.clientY
+  }, false)
+  canvas.addEventListener("mousedown", e => {
+    juego.mouse.down = true
+  }, false)
+  canvas.addEventListener("mouseup", e => {
+    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
+  function loop(timestamp) {
+    const progress = timestamp - lastRender
+
+    update(juego, progress)
+    draw(juego)
+
+    lastRender = timestamp
+    window.requestAnimationFrame(loop)
+  }
+
+  window.requestAnimationFrame(loop)
+}
+initJuego()
+document.addEventListener("DOMDocumentLoaded", console.log)
diff --git a/src/style.css b/src/style.css
new file mode 100644
index 0000000..2be616c
--- /dev/null
+++ b/src/style.css
@@ -0,0 +1,17 @@
+html, body {
+  font-family: Avenir, Helvetica, Arial, sans-serif;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+  text-align: center;
+  color: #2c3e50;
+  margin: 0;
+  padding: 0;
+  width: 100%;
+  height: 100%;
+}
+
+#juego {
+  display: block;
+  width: 100%;
+  height: 100%;
+}
diff --git a/src/utils.js b/src/utils.js
new file mode 100644
index 0000000..7747960
--- /dev/null
+++ b/src/utils.js
@@ -0,0 +1,4 @@
+export function posInBox(box, pos) {
+  return pos.x > box.x && pos.x < box.x + box.width
+    && pos.y > box.y && pos.y < box.y + box.height
+}
diff --git a/src/welcome.js b/src/welcome.js
new file mode 100644
index 0000000..4254336
--- /dev/null
+++ b/src/welcome.js
@@ -0,0 +1,27 @@
+import { posInBox } from './utils.js'
+import { createJugandoState } from './jugando.js'
+
+const img = document.getElementById("img-boton-jugar")
+
+function startButton(juego) {
+  const [width, height] = [img.width / 4, img.height / 4]
+  return {
+    x: juego.canvas.width - width - 30,
+    y: juego.canvas.height - height - 30,
+    width,
+    height,
+  }
+}
+
+export function updateWelcome(juego, dt) {
+  const btn = startButton(juego)
+  if (juego.mouse.down && posInBox(btn, juego.mouse)) {
+    juego.state = createJugandoState()
+  }
+}
+
+export function drawWelcome(juego) {
+  const {width, height} = juego.canvas
+  const btn = startButton(juego)
+  juego.ctx.drawImage(img, btn.x, btn.y, btn.width, btn.height)
+}
