No al cierre de webs
ShareCode
Permalink: http://www.treeweb.es/u/974/ 01/02/2011

ShareCode

1 <!DOCTYPE html>2 <html lang="es">3 <head>4 <meta charset="UTF-8" />5 <title>Elastic Ball Platformer</title>6 <style>7  body {8  margin: 0;9  background: #111;10  overflow: hidden;11  font-family: sans-serif;12  }13  canvas {14  display: block;15  margin: auto;16  background: linear-gradient(#87ceeb, #d0f4f7);17  }18 </style>19 </head>20 <body>21 22 <canvas id="game" width="900" height="500"></canvas>23 24 <script>25 const canvas = document.getElementById("game");26 const ctx = canvas.getContext("2d");27 28 const GRAVITY = 0.6;29 const FRICTION = 0.8;30 const JUMP_FORCE = -13;31 32 let keys = {};33 let lives = 3;34 let dead = false;35 36 document.addEventListener("keydown", e => keys[e.code] = true);37 document.addEventListener("keyup", e => keys[e.code] = false);38 39 const player = {40  x: 100,41  y: 100,42  r: 18,43  vx: 0,44  vy: 0,45  onGround: false,46  squashX: 1,47  squashY: 1,48 49  reset() {50  this.x = 100;51  this.y = 100;52  this.vx = 0;53  this.vy = 0;54  }55 };56 57 const platforms = [58  { x: 0, y: 460, w: 900, h: 40 },59  { x: 200, y: 360, w: 120, h: 20 },60  { x: 400, y: 300, w: 120, h: 20, move: true, dir: 1 },61  { x: 600, y: 260, w: 120, h: 20 }62 ];63 64 const holes = [65  { x: 150, y: 460, w: 80, h: 40 },66  { x: 500, y: 460, w: 100, h: 40 }67 ];68 69 function updatePlatforms() {70  for (let p of platforms) {71  if (p.move) {72  p.x += p.dir * 1.2;73  if (p.x < 350 || p.x > 500) p.dir *= -1;74  }75  }76 }77 78 function updatePlayer() {79  // Input80  if (keys["ArrowLeft"]) player.vx -= 0.6;81  if (keys["ArrowRight"]) player.vx += 0.6;82  if (keys["Space"] && player.onGround) {83  player.vy = JUMP_FORCE;84  player.onGround = false;85  }86 87  // Physics88  player.vy += GRAVITY;89  player.x += player.vx;90  player.y += player.vy;91  player.vx *= FRICTION;92 93  // Deformación elástica94  if (!player.onGround) {95  player.squashX = 0.9;96  player.squashY = 1.1;97  } else {98  player.squashX = 1.15;99  player.squashY = 0.85;100  }101 102  // Colisiones plataformas (solo desde arriba)103  player.onGround = false;104  for (let p of platforms) {105  if (106  player.x + player.r > p.x &&107  player.x - player.r < p.x + p.w &&108  player.y + player.r > p.y &&109  player.y + player.r < p.y + p.h &&110  player.vy >= 0111  ) {112  player.y = p.y - player.r;113  player.vy = 0;114  player.onGround = true;115  }116  }117 118  // Agujeros = muerte119  for (let h of holes) {120  if (121  player.x > h.x &&122  player.x < h.x + h.w &&123  player.y + player.r > h.y124  ) {125  killPlayer();126  }127  }128 129  // Caer fuera del mundo130  if (player.y > canvas.height + 100) {131  killPlayer();132  }133 134  // Suavizado deformación135  player.squashX += (1 - player.squashX) * 0.2;136  player.squashY += (1 - player.squashY) * 0.2;137 }138 139 function killPlayer() {140  if (dead) return;141  dead = true;142  lives--;143  setTimeout(() => {144  dead = false;145  if (lives <= 0) {146  lives = 3;147  }148  player.reset();149  }, 700);150 }151 152 function drawPlayer() {153  ctx.save();154  ctx.translate(player.x, player.y);155  ctx.scale(player.squashX, player.squashY);156  ctx.beginPath();157  ctx.arc(0, 0, player.r, 0, Math.PI * 2);158  ctx.fillStyle = "#ff4d4d";159  ctx.fill();160  ctx.restore();161 }162 163 function draw() {164  ctx.clearRect(0, 0, canvas.width, canvas.height);165 166  // Plataformas167  ctx.fillStyle = "#444";168  for (let p of platforms) {169  ctx.fillRect(p.x, p.y, p.w, p.h);170  }171 172  // Agujeros173  ctx.fillStyle = "#000";174  for (let h of holes) {175  ctx.fillRect(h.x, h.y, h.w, h.h);176  }177 178  drawPlayer();179 180  // HUD181  ctx.fillStyle = "#000";182  ctx.font = "18px sans-serif";183  ctx.fillText(`Vidas: ${lives}`, 20, 30);184 }185 186 function loop() {187  updatePlatforms();188  updatePlayer();189  draw();190  requestAnimationFrame(loop);191 }192 193 loop();194 </script>195 </body>196 </html>197 
Enlace
El enlace para compartir es: