🎮ArcadeLab

Chrome Dino Run

by BoldPenguin14
290 lines5.4 KB
▶ Play

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dino Run</title>
<style>
* { box-sizing: border-box; }
body {
  margin: 0;
  background: #f7f7f7;
  color: #535353;
  font-family: monospace;
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  overflow: hidden;
}
.game {
  width: 95%;
  max-width: 850px;
  text-align: center;
}
h1 { font-size: 30px; }
canvas {
  width: 100%;
  background: #f7f7f7;
  border-bottom: 2px solid #535353;
  image-rendering: pixelated;
  touch-action: manipulation;
}
.info {
  display: flex;
  justify-content: space-between;
  font-size: 16px;
  margin: 12px 5px;
}
button {
  background: #535353;
  color: white;
  border: 0;
  padding: 12px 25px;
  font-family: monospace;
  font-size: 16px;
  cursor: pointer;
  border-radius: 5px;
  margin-top: 15px;
}
button:hover { background: #333; }
.hint { color: #888; font-size: 13px; }
</style>
</head>
<body>
<div class="game">
  <h1>🦖 DINO RUN</h1>
  <div class="info">
    <span>SCORE: <b id="score">0</b></span>
    <span>HI: <b id="high">0</b></span>
  </div>
  <canvas id="game" width="850" height="280"></canvas>
  <button id="restart">START / RESTART</button>
  <p class="hint">SPACE / ↑ / TAP TO JUMP</p>
</div>

<script>
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");
const scoreEl = document.getElementById("score");
const highEl = document.getElementById("high");

let dino, obstacles, clouds, score, speed;
let running = false;
let gameOver = false;
let frame = 0;
let high = 0;

try {
  high = Number(localStorage.getItem("dinoHigh") || 0);
} catch(e) {}
highEl.textContent = high;

function reset() {
  dino = {
    x: 65, y: 190, w: 42, h: 48,
    vy: 0, jumping: false
  };
  obstacles = [];
  clouds = [
    {x: 200, y: 45},
    {x: 550, y: 80}
  ];
  score = 0;
  speed = 6;
  frame = 0;
  gameOver = false;
  running = true;
  scoreEl.textContent = 0;
}

function jump() {
  if (!running || gameOver) {
    reset();
    return;
  }
  if (!dino.jumping) {
    dino.vy = -13;
    dino.jumping = true;
  }
}

function drawDino() {
  const x = dino.x;
  const y = dino.y;

  ctx.fillStyle = "#535353";

  // Body
  ctx.fillRect(x+7,y+13,29,29);
  // Head
  ctx.fillRect(x+22,y,24,23);
  // Eye
  ctx.fillStyle = "white";
  ctx.fillRect(x+37,y+5,4,4);
  // Mouth
  ctx.fillStyle = "#535353";
  ctx.fillRect(x+40,y+17,9,3);
  // Tail
  ctx.fillRect(x,y+23,10,7);

  // Legs
  if (dino.jumping) {
    ctx.fillRect(x+12,y+39,8,9);
    ctx.fillRect(x+30,y+39,8,9);
  } else {
    const step = Math.floor(frame/6)%2;
    if (step === 0) {
      ctx.fillRect(x+10,y+39,8,10);
      ctx.fillRect(x+29,y+39,8,5);
    } else {
      ctx.fillRect(x+10,y+39,8,5);
      ctx.fillRect(x+29,y+39,8,10);
    }
  }
}

function drawCactus(o) {
  ctx.fillStyle = "#535353";
  ctx.fillRect(o.x+9,o.y,13,o);
  ctx.fillRect(o.x,o.y+15,10,18);
  ctx.fillRect(o.x-5,o.y+15,9,7);
  ctx.fillRect(o.x+20,o.y+23,10,16);
  ctx.fillRect(o.x+26,o.y+23,9,7);
}

function drawCloud(c) {
  ctx.fillStyle = "#c9c9c9";
  ctx.fillRect(c.x,c.y,45,10);
  ctx.fillRect(c.x+10,c.y-8,20,12);
  ctx.fillRect(c.x+30,c.y-3,15,10);
}

function draw() {
  ctx.clearRect(0,0,850,280);

  // Ground
  ctx.fillStyle = "#777";
  ctx.fillRect(0,238,850,2);

  // Ground dots
  for(let i=0;i<14;i++) {
    let x = (i*85-frame*speed*.7)%850;
    if(x<0)x+=850;
    ctx.fillRect(x,247+(i%3)*4,3,2);
  }

  clouds.forEach(drawCloud);
  drawDino();

  obstacles.forEach(o=>drawCactus(o));

  if (!running) {
    ctx.fillStyle = "#535353";
    ctx.font = "bold 25px monospace";
    ctx.textAlign = "center";
    ctx.fillText("DINO RUN",425,100);
    ctx.font = "15px monospace";
    ctx.fillText("PRESS SPACE OR TAP TO START",425,135);
  }

  if(gameOver) {
    ctx.fillStyle = "#535353";
    ctx.textAlign = "center";
    ctx.font = "bold 30px monospace";
    ctx.fillText("GAME OVER",425,105);
    ctx.font = "16px monospace";
    ctx.fillText("PRESS SPACE OR RESTART",425,140);
  }
}

function update() {
  if(!running || gameOver) return;

  frame++;

  // Physics
  dino.vy += 0.65;
  dino.y += dino.vy;

  if(dino.y>=190) {
    dino.y=190;
    dino.vy=0;
    dino.jumping=false;
  }

  // Obstacles
  if(frame%Math.max(40,Math.floor(95-speed*3))===0) {
    obstacles.push({
      x:870,
      y:198,
      w:30,
      h:40
    });
  }

  obstacles.forEach(o=>o.x-=speed);
  obstacles=obstacles.filter(o=>o.x>-50);

  // Clouds
  clouds.forEach(c=>c.x-=speed*.3);
  clouds.forEach(c=>{
    if(c.x<-60) {
      c.x=900;
      c.y=30+Math.random()*65;
    }
  });

  // Collision
  obstacles.forEach(o=>{
    if(
      dino.x+37>o.x &&
      dino.x+8<o.x+30 &&
      dino.y+dino.h>o.y
    ) {
      gameOver=true;
      running=false;
    }
  });

  // Score and speed
  if(frame%6===0) {
    score++;
    scoreEl.textContent=score;
  }

  if(frame%450===0) speed+=0.5;

  if(score>high) {
    high=score;
    highEl.textContent=high;
    try {
      localStorage.setItem("dinoHigh",high);
    } catch(e) {}
  }
}

function loop() {
  update();
  draw();
  requestAnimationFrame(loop);
}

document.addEventListener("keydown",e=>{
  if(e.code==="Space" || e.code==="ArrowUp") {
    e.preventDefault();
    jump();
  }
});

canvas.addEventListener("pointerdown",jump);
document.getElementById("restart").addEventListener("click",reset);

reset();
running=false;
loop();
</script>
</body>
</html>

Game Source: Chrome Dino Run

Creator: BoldPenguin14

Libraries: none

Complexity: complex (290 lines, 5.4 KB)

The full source code is displayed above on this page.

Remix Instructions

To remix this game, copy the source code above and modify it. Add a ARCADELAB header at the top with "remix_of: chrome-dino-run-boldpenguin14" to link back to the original. Then publish at arcadelab.ai/publish.