🎮ArcadeLab

Jungle Battle Ground

by WildDragon12
403 lines10.8 KB
▶ Play

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Jungle Battle Ground</title>
<style>
*{box-sizing:border-box}
body{margin:0;background:#14251b;color:white;font-family:Arial,sans-serif;text-align:center}
h2{margin:8px}
#game{display:block;width:100%;max-width:960px;height:auto;margin:auto;background:#8bd9ff;border:3px solid #243c29}
#hud{display:flex;justify-content:space-around;gap:6px;flex-wrap:wrap;padding:8px;font-weight:bold}
#controls{display:flex;justify-content:center;gap:12px;padding:12px;flex-wrap:wrap}
button{border:0;border-radius:10px;padding:13px 20px;background:#347b38;color:white;font-weight:bold;font-size:17px;touch-action:none}
button:active{background:#70b84b}
#menu{padding:8px}
#message{min-height:24px;color:#ffe879}
</style>
</head>
<body>
<h2>🌴 Jungle Battle Ground</h2>
<div id="hud">
<span id="level">Level: 1</span>
<span id="score">Score: 0</span>
<span id="hp">❤️ HP: 100</span>
<span id="coins">🪙 Coins: 0</span>
</div>
<canvas id="game" width="960" height="540"></canvas>
<div id="menu">
<button onclick="startGame()">▶ Start / Restart</button>
<button onclick="togglePause()">⏸ Pause</button>
</div>
<div id="message">Jump karke upar wale platforms par kharay ho!</div>
<div id="controls">
<button id="left">⬅ Left</button>
<button id="right">Right ➡</button>
<button onclick="jump()">⬆ Jump</button>
<button onclick="attack()">⚔ Attack</button>
</div>
<script>
const canvas=document.getElementById("game");
const ctx=canvas.getContext("2d");
const W=canvas.width,H=canvas.height;
let keys={},paused=true,gameOver=false;
let level=1,score=0,coins=0,hp=100,camera=0;
let worldWidth=2600,player,platforms=[],pitList=[],coinList=[],enemies=[],goal;

function newPlayer(){
 return {x:70,y:390,w:30,h:44,vx:0,vy:0,onGround:false,face:1,attack:0,invincible:0};
}

function makeLevel(){
 worldWidth=2600+level*100;
 platforms=[];
 pitList=[];
 coinList=[];
 enemies=[];
 camera=0;
 player=newPlayer();

 // Neeche ki zameen ke tukray, darmiyan mein pits
 let groundStart=0;
 for(let x=600;x<worldWidth-250;x+=680){
   const pitWidth=100+(level%3)*15;
   platforms.push({x:groundStart,y:470,w:x-groundStart,h:100,type:"ground"});
   pitList.push({x:x,w:pitWidth});
   groundStart=x+pitWidth;
 }
 platforms.push({x:groundStart,y:470,w:worldWidth-groundStart,h:100,type:"ground"});

 // Upar wale platforms: inke neeche zameen nahi honi zaroori
 const elevated=[
   {x:180,y:375,w:150},
   {x:390,y:310,w:140},
   {x:650,y:350,w:150},
   {x:870,y:285,w:160},
   {x:1120,y:355,w:150},
   {x:1370,y:300,w:170},
   {x:1640,y:350,w:150},
   {x:1880,y:280,w:180},
   {x:2180,y:345,w:170},
   {x:2450,y:300,w:150}
 ];
 elevated.forEach(p=>platforms.push({x:p.x,y:p.y,w:p.w,h:18,type:"upper"}));

 // Coins upar ke platforms ke paas
 elevated.forEach(p=>{
   coinList.push({x:p.x+p.w/2,y:p.y-32,r:10,taken:false});
 });

 for(let i=0;i<Math.min(4+level,12);i++){
   enemies.push({
     x:500+i*170,y:426,w:30,h:40,
     minX:450+i*170,maxX:620+i*170,
     dir:i%2?1:-1,alive:true
   });
 }
 goal={x:worldWidth-100,y:410,w:45,h:60};
}

function startGame(){
 level=1;score=0;coins=0;hp=100;
 gameOver=false;paused=false;
 makeLevel();updateHUD();
 document.getElementById("message").textContent="Platform par jump karo aur coins collect karo!";
}

function togglePause(){
 if(gameOver)return;
 paused=!paused;
 document.getElementById("message").textContent=paused?"Game paused":"Game resumed";
}

function jump(){
 if(paused||gameOver)return;
 if(player.onGround){
   player.vy=-13;
   player.onGround=false;
 }
}

function attack(){
 if(paused||gameOver)return;
 player.attack=12;
 for(const e of enemies){
   if(e.alive&&Math.abs((player.x+player.w/2)-(e.x+e.w/2))<65&&Math.abs(player.y-e.y)<55){
     e.alive=false;
     score+=10;
   }
 }
 updateHUD();
}

function bindHold(id,key){
 const el=document.getElementById(id);
 el.addEventListener("pointerdown",e=>{e.preventDefault();keys[key]=true;});
 el.addEventListener("pointerup",()=>keys[key]=false);
 el.addEventListener("pointerleave",()=>keys[key]=false);
 el.addEventListener("pointercancel",()=>keys[key]=false);
}
bindHold("left","left");
bindHold("right","right");
document.addEventListener("keydown",e=>{
 if(["ArrowLeft","ArrowRight","ArrowUp"," "].includes(e.key))e.preventDefault();
 keys[e.key.toLowerCase()]=true;
 if(e.key==="ArrowUp"||e.key===" ")jump();
 if(e.key.toLowerCase()==="x")attack();
});
document.addEventListener("keyup",e=>keys[e.key.toLowerCase()]=false);

function damage(fall=false){
 if(player.invincible>0)return;
 hp-=25;
 player.invincible=60;
 if(fall){
   // Pit se girne par neeche wale safe ground par wapas
   player.x=Math.max(camera+30,player.x-80);
   player.y=350;
   player.vy=0;
 }else{
   player.vy=-5;
 }
 if(hp<=0){
   hp=0;gameOver=true;paused=true;
   document.getElementById("message").textContent="Game Over! Start / Restart dabao.";
 }
 updateHUD();
}

function update(){
 if(paused||gameOver)return;

 const speed=4;
 player.vx=0;
 if(keys.left||keys.arrowleft||keys.a){player.vx=-speed;player.face=-1;}
 if(keys.right||keys.arrowright||keys.d){player.vx=speed;player.face=1;}

 player.x+=player.vx;
 player.x=Math.max(0,Math.min(worldWidth-player.w,player.x));
 const oldY=player.y;
 player.vy+=0.58;
 if(player.vy>14)player.vy=14;
 player.y+=player.vy;
 player.onGround=false;

 // Platform collision: character sirf platform ke upar se neeche aate waqt land kare
 for(const p of platforms){
   const overlapsX=player.x+player.w>p.x&&player.x<p.x+p.w;
   const oldBottom=oldY+player.h;
   const newBottom=player.y+player.h;
   if(overlapsX&&player.vy>=0&&oldBottom<=p.y&&newBottom>=p.y){
     player.y=p.y-player.h;
     player.vy=0;
     player.onGround=true;
   }
 }

 // Pits ke neeche koi floor nahi: girne par damage
 if(player.y>H+30)damage(true);

 for(const e of enemies){
   if(!e.alive)continue;
   e.x+=e.dir*1.1;
   if(e.x<e.minX)e.dir=1;
   if(e.x>e.maxX)e.dir=-1;
   if(player.invincible<=0&&
      player.x<e.x+e.w&&player.x+player.w>e.x&&
      player.y<e.y+e.h&&player.y+player.h>e.y){
     damage(false);
   }
 }

 for(const c of coinList){
   if(!c.taken&&
      player.x<c.x+c.r&&player.x+player.w>c.x-c.r&&
      player.y<c.y+c.r&&player.y+player.h>c.y-c.r){
     c.taken=true;coins++;score+=5;
   }
 }

 if(player.invincible>0)player.invincible--;
 if(player.attack>0)player.attack--;

 if(player.x>goal.x){
   level++;
   score+=50;
   makeLevel();
   document.getElementById("message").textContent="Level complete! Ab Level "+level;
 }
 camera=Math.max(0,Math.min(worldWidth-W,player.x-W*0.35));
 updateHUD();
}

function drawBackground(){
 const g=ctx.createLinearGradient(0,0,0,H);
 g.addColorStop(0,"#65caff");
 g.addColorStop(1,"#d3f2a3");
 ctx.fillStyle=g;ctx.fillRect(0,0,W,H);

 // Door ke jungle ke darakht
 for(let i=0;i<18;i++){
   let x=((i*180-camera*0.25)%(W+180)+W+180)%(W+180)-50;
   ctx.fillStyle="#2c763b";
   ctx.fillRect(x+20,220,18,250);
   ctx.fillStyle="#3d9845";
   ctx.beginPath();ctx.arc(x+28,210,55,0,Math.PI*2);ctx.fill();
   ctx.fillStyle="#62b54b";
   ctx.beginPath();ctx.arc(x+2,235,35,0,Math.PI*2);ctx.fill();
 }
}

function drawPlatform(p){
 const x=p.x-camera;
 if(x+p.w<0||x>W)return;

 if(p.type==="ground"){
   ctx.fillStyle="#754321";
   ctx.fillRect(x,p.y,p.w,p.h);
   ctx.fillStyle="#48a832";
   ctx.fillRect(x,p.y,p.w,12);
   ctx.fillStyle="#8b5a32";
   for(let i=12;i<p.w;i+=35){
     ctx.fillRect(x+i,p.y+25,18,5);
     ctx.fillRect(x+i+10,p.y+55,12,5);
   }
 }else{
   // Upar wala platform aur uske neeche khaali space
   ctx.fillStyle="#754321";
   ctx.fillRect(x,p.y,p.w,p.h);
   ctx.fillStyle="#50b83b";
   ctx.fillRect(x,p.y,p.w,8);
   ctx.fillStyle="#9b6a3c";
   for(let i=10;i<p.w;i+=30)ctx.fillRect(x+i,p.y+11,12,4);
 }
}

function drawPlayer(){
 const x=player.x-camera,y=player.y;
 ctx.save();
 if(player.invincible>0&&Math.floor(player.invincible/5)%2===0)ctx.globalAlpha=0.45;

 // Legs
 ctx.fillStyle="#243a92";
 ctx.fillRect(x+5,y+29,8,15);
 ctx.fillRect(x+18,y+29,8,15);
 // Boots
 ctx.fillStyle="#30231d";
 ctx.fillRect(x+2,y+40,12,4);
 ctx.fillRect(x+17,y+40,12,4);
 // Body
 ctx.fillStyle="#e64c2f";
 ctx.fillRect(x+3,y+13,24,19);
 // Arms
 ctx.fillStyle="#e9b27b";
 ctx.fillRect(x-2,y+17,6,15);
 ctx.fillRect(x+26,y+17,6,15);
 // Head
 ctx.fillStyle="#e9b27b";
 ctx.fillRect(x+5,y,21,17);
 // Hair
 ctx.fillStyle="#382319";
 ctx.fillRect(x+4,y-2,23,6);
 // Eyes
 ctx.fillStyle="#111";
 ctx.fillRect(x+10,y+7,3,3);
 ctx.fillRect(x+20,y+7,3,3);
 // Attack effect
 if(player.attack>0){
   ctx.strokeStyle="#fff37a";ctx.lineWidth=5;
   ctx.beginPath();
   const ax=player.face===1?x+32:x-12;
   ctx.arc(ax,y+22,15,-1,1);
   ctx.stroke();
 }
 ctx.restore();
}

function draw(){
 drawBackground();

 // Pits are dark gaps; there is no ground under these positions
 for(const pit of pitList){
   const x=pit.x-camera;
   if(x+pit.w>0&&x<W){
     ctx.fillStyle="#173222";
     ctx.fillRect(x,470,pit.w,H-470);
     ctx.fillStyle="#754321";
     ctx.fillRect(x-5,470,5,9);
     ctx.fillRect(x+pit.w,470,5,9);
   }
 }

 platforms.forEach(drawPlatform);

 // Coins
 for(const c of coinList){
   if(c.taken)continue;
   const x=c.x-camera;
   ctx.fillStyle="#ffdb24";
   ctx.beginPath();ctx.arc(x,c.y,c.r,0,Math.PI*2);ctx.fill();
   ctx.strokeStyle="#b77a00";ctx.lineWidth=3;ctx.stroke();
   ctx.fillStyle="#fff6ad";ctx.fillRect(x-2,c.y-6,4,12);
 }

 // Enemies
 for(const e of enemies){
   if(!e.alive)continue;
   const x=e.x-camera;
   ctx.fillStyle="#5a2630";
   ctx.fillRect(x,e.y+9,e.w,e.h-9);
   ctx.fillStyle="#e7ad78";
   ctx.fillRect(x+5,e.y,e.w-10,15);
   ctx.fillStyle="#222";
   ctx.fillRect(x+7,e.y+5,4,3);
   ctx.fillRect(x+19,e.y+5,4,3);
   ctx.fillStyle="#252525";
   ctx.fillRect(x+3,e.y+35,9,5);
   ctx.fillRect(x+19,e.y+35,9,5);
 }

 // Goal
 const gx=goal.x-camera;
 ctx.fillStyle="#694124";
 ctx.fillRect(gx,goal.y,7,60);
 ctx.fillStyle="#ffdf39";
 ctx.beginPath();ctx.moveTo(gx+7,goal.y);ctx.lineTo(gx+50,goal.y+12);ctx.lineTo(gx+7,goal.y+25);ctx.fill();

 drawPlayer();

 if(paused&&!gameOver){
   ctx.fillStyle="rgba(0,0,0,0.42)";
   ctx.fillRect(0,0,W,H);
   ctx.fillStyle="white";ctx.font="bold 34px Arial";ctx.textAlign="center";
   ctx.fillText("JUNGLE BATTLE GROUND",W/2,H/2-12);
   ctx.font="20px Arial";ctx.fillText("Start / Restart dabao",W/2,H/2+28);
 }
 if(gameOver){
   ctx.fillStyle="rgba(0,0,0,0.65)";ctx.fillRect(0,0,W,H);
   ctx.fillStyle="#ff6868";ctx.font="bold 46px Arial";ctx.textAlign="center";
   ctx.fillText("GAME OVER",W/2,H/2);
 }
}

function updateHUD(){
 document.getElementById("level").textContent="Level: "+level;
 document.getElementById("score").textContent="Score: "+score;
 document.getElementById("hp").textContent="❤️ HP: "+hp;
 document.getElementById("coins").textContent="🪙 Coins: "+coins;
}

function loop(){
 update();
 draw();
 requestAnimationFrame(loop);
}
makeLevel();
updateHUD();
loop();
</script>
</body>
</html>

Game Source: Jungle Battle Ground

Creator: WildDragon12

Libraries: none

Complexity: complex (403 lines, 10.8 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: jungle-battle-ground-wilddragon12" to link back to the original. Then publish at arcadelab.ai/publish.