🎮ArcadeLab

Captain Run

by LaserHawk84
162 lines5.7 KB
▶ Play

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Captain Run</title>
<style>
*{box-sizing:border-box}
body{margin:0;background:#101827;color:white;font-family:Arial;text-align:center}
h2{color:#ffd54a}
canvas{width:100%;max-width:850px;background:#8bd9ff;border:3px solid white;border-radius:10px;touch-action:manipulation}
button{padding:13px 24px;margin:8px;border:0;border-radius:10px;background:#ffd54a;font-size:17px;font-weight:bold}
</style>
</head>
<body>
<h2>🏏 CAPTAIN RUN</h2>
<p>Score: <span id="score">0</span> | 🪙 Coins: <span id="coins">0</span></p>
<canvas id="game" width="850" height="400"></canvas><br>
<button onclick="jump()">⬆ JUMP</button>
<button onclick="reset()">↻ RESTART</button>
<p>Tap to jump • Collect coins • Avoid obstacles</p>
<script>
const c=document.getElementById('game'),ctx=c.getContext('2d');
let p,obs,cs,score,coinCount,frame,speed,over;
const ground=325;
let audio;
function initAudio(){
 if(!audio){
  const AC=window.AudioContext||window.webkitAudioContext;
  if(AC)audio=new AC();
 }
 if(audio&&audio.state==='suspended')audio.resume();
}
function tone(freq,duration,type='sine',volume=.08,endFreq=null){
 if(!audio)return;
 const o=audio.createOscillator(),g=audio.createGain();
 o.type=type;o.frequency.setValueAtTime(freq,audio.currentTime);
 if(endFreq)o.frequency.exponentialRampToValueAtTime(endFreq,audio.currentTime+duration);
 g.gain.setValueAtTime(volume,audio.currentTime);
 g.gain.exponentialRampToValueAtTime(.001,audio.currentTime+duration);
 o.connect(g);g.connect(audio.destination);
 o.start();o.stop(audio.currentTime+duration);
}
function coinSound(){
 tone(880,.09,'sine',.09);
 setTimeout(()=>tone(1320,.15,'sine',.07),65);
}
function hitSound(){
 tone(180,.25,'sawtooth',.12,65);
}
function jumpSound(){
 tone(300,.16,'sine',.07,600);
}
function reset(){
 initAudio();
 p={x:100,y:260,vy:0,grounded:true,run:0};
 obs=[];cs=[];score=0;coinCount=0;frame=0;speed=4;over=false;
 document.getElementById('score').textContent=0;
 document.getElementById('coins').textContent=0;
}
function jump(){
 initAudio();
 if(over){reset();return}
 if(p.grounded){p.vy=-13;p.grounded=false;jumpSound()}
}
c.addEventListener('pointerdown',jump);
document.addEventListener('keydown',e=>{
 if(e.code==='Space'||e.code==='ArrowUp'){e.preventDefault();jump()}
});
function circle(x,y,r,color){
 ctx.fillStyle=color;ctx.beginPath();ctx.arc(x,y,r,0,Math.PI*2);ctx.fill()
}
function background(){
 let g=ctx.createLinearGradient(0,0,0,ground);
 g.addColorStop(0,'#56c5ff');g.addColorStop(1,'#e4f8ff');
 ctx.fillStyle=g;ctx.fillRect(0,0,850,400);
 circle(735,60,30,'#ffe05a');
 ctx.fillStyle='#84c96b';
 ctx.beginPath();ctx.moveTo(0,270);
 for(let x=0;x<=850;x+=50)ctx.lineTo(x,240+Math.sin(x/40)*15);
 ctx.lineTo(850,ground);ctx.lineTo(0,ground);ctx.fill();
 ctx.fillStyle='#37a64c';ctx.fillRect(0,ground,850,75);
 ctx.fillStyle='#caa16c';ctx.fillRect(0,ground+38,850,37);
 ctx.fillStyle='white';
 for(let i=0;i<12;i++){
 let x=((i*100-frame*speed)%1000+1000)%1000;
 ctx.fillRect(x,ground+55,35,4);
 }
}
function player(){
 let x=p.x,y=p.y,sw=p.grounded?Math.sin(p.run)*9:0;
 circle(x+20,ground+4,22,'#26733a');
 ctx.strokeStyle='#1d2638';ctx.lineWidth=9;ctx.lineCap='round';
 ctx.beginPath();ctx.moveTo(x+15,y+44);ctx.lineTo(x+12+sw,y+62);ctx.stroke();
 ctx.beginPath();ctx.moveTo(x+25,y+44);ctx.lineTo(x+29-sw,y+62);ctx.stroke();
 ctx.fillStyle='#fff';ctx.fillRect(x+3+sw,y+61,12,5);ctx.fillRect(x+27-sw,y+61,12,5);
 ctx.fillStyle='#dca078';ctx.fillRect(x+16,y+13,10,12);
 circle(x+21,y+10,13,'#dca078');
 ctx.fillStyle='#24202a';ctx.beginPath();ctx.arc(x+21,y+7,13,Math.PI,Math.PI*2);ctx.fill();
 ctx.fillStyle='#1674dc';ctx.beginPath();ctx.roundRect(x+6,y+22,29,27,5);ctx.fill();
 ctx.fillStyle='#ffcf42';ctx.fillRect(x+8,y+28,25,3);
 ctx.fillStyle='white';ctx.font='bold 12px Arial';ctx.fillText('7',x+17,y+42);
 ctx.strokeStyle='#dca078';ctx.lineWidth=7;
 ctx.beginPath();ctx.moveTo(x+8,y+28);ctx.lineTo(x+2,y+38);ctx.stroke();
 ctx.beginPath();ctx.moveTo(x+33,y+28);ctx.lineTo(x+39,y+37);ctx.stroke();
}
function draw(){
 background();
 if(!over){
  frame++;score++;
  speed=4+Math.min(score/600,4);
  if(frame%90===0)obs.push({x:870,y:ground-35,w:28,h:35});
  if(frame%48===0){
   let yy=ground-65-Math.random()*65;
   for(let i=0;i<3;i++)cs.push({x:870+i*28,y:yy,t:false});
  }
  p.vy+=.58;p.y+=p.vy;
  if(p.y>=ground-65){p.y=ground-65;p.vy=0;p.grounded=true}
  p.run+=.22;
  for(let o of obs)o.x-=speed;
  for(let a of cs)a.x-=speed;
  obs=obs.filter(o=>o.x>-50);
  cs=cs.filter(a=>a.x>-30&&!a.t);
  for(let o of obs){
   if(p.x+30>o.x+3&&p.x+8<o.x+o.w&&p.y+60>o.y){
    over=true;hitSound();break;
   }
  }
  for(let a of cs){
   if(!a.t&&Math.abs(p.x+20-a.x)<23&&Math.abs(p.y+28-a.y)<35){
    a.t=true;coinCount++;coinSound();
   }
  }
  document.getElementById('score').textContent=score;
  document.getElementById('coins').textContent=coinCount;
 }
 for(let o of obs){
  ctx.fillStyle='#fff';ctx.fillRect(o.x,o.y,5,o.h);
  ctx.fillRect(o.x+11,o.y,5,o.h);ctx.fillRect(o.x+22,o.y,5,o.h);
  ctx.fillStyle='#e5bd54';ctx.fillRect(o.x-3,o.y,32,5);
 }
 for(let a of cs)if(!a.t){
  circle(a.x,a.y,11,'#e5a500');circle(a.x,a.y,8,'#ffdf43');
  ctx.fillStyle='#9c6200';ctx.font='bold 13px Arial';ctx.fillText('$',a.x-4,a.y+5);
 }
 player();
 if(over){
  ctx.fillStyle='rgba(0,0,0,.72)';ctx.fillRect(0,0,850,400);
  ctx.textAlign='center';ctx.fillStyle='#ffd54a';ctx.font='bold 42px Arial';
  ctx.fillText('GAME OVER',425,175);
  ctx.fillStyle='white';ctx.font='24px Arial';
  ctx.fillText('Score: '+score+' Coins: '+coinCount,425,220);
  ctx.font='20px Arial';ctx.fillText('Tap JUMP or RESTART',425,265);
  ctx.textAlign='left';
 }
 requestAnimationFrame(draw);
}
reset();draw();
</script>
</body>
</html>

Game Source: Captain Run

Creator: LaserHawk84

Libraries: none

Complexity: moderate (162 lines, 5.7 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: captain-run-laserhawk84" to link back to the original. Then publish at arcadelab.ai/publish.