Meta Description" name="description" />
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Parkour Adventure</title>
<style>
body{margin:0;overflow:hidden}
canvas{display:block}
#ui{
position:fixed;
top:10px;
left:10px;
font-family:Arial;
font-size:20px;
color:white;
text-shadow:2px 2px 4px black;
}
</style>
</head>
<body>
<div id="ui">
Score: <span id="score">0</span>
</div>
<canvas id="game"></canvas>
<script>
const canvas = document.getElementById("game");
const ctx = canvas.getContext("2d");
canvas.width = innerWidth;
canvas.height = innerHeight;
const scoreText = document.getElementById("score");
let score = 0;
const player = {
x:100,
y:300,
w:40,
h:50,
vx:0,
vy:0,
ground:false
};
const checkpoint = {x:100,y:300};
const keys = {};
addEventListener("keydown",e=>{
keys[e.key.toLowerCase()] = true;
});
addEventListener("keyup",e=>{
keys[e.key.toLowerCase()] = false;
});
const platforms = [
{x:0,y:400,w:600,h:80},
{x:700,y:350,w:200,h:30},
{x:1000,y:300,w:200,h:30},
{x:1300,y:250,w:200,h:30},
{x:1700,y:220,w:250,h:30},
{x:2100,y:180,w:250,h:30}
];
const enemies = [
{x:780,y:310,w:30,h:40,dir:1,min:730,max:860},
{x:1750,y:180,w:30,h:40,dir:1,min:1720,max:1900}
];
const coins = [
{x:760,y:300,r:12,taken:false},
{x:1060,y:250,r:12,taken:false},
{x:1360,y:200,r:12,taken:false},
{x:1800,y:170,r:12,taken:false}
];
const finish = {
x:2300,
y:100,
w:40,
h:80
};
let cameraX = 0;
function collide(a,b){
return (
a.x < b.x+b.w &&
a.x+a.w > b.x &&
a.y < b.y+b.h &&
a.y+a.h > b.y
);
}
function update(){
player.vx = 0;
if(keys["a"]) player.vx = -5;
if(keys["d"]) player.vx = 5;
if((keys["w"] || keys[" "]) && player.ground){
player.vy = -15;
player.ground = false;
}
player.vy += 0.8;
player.x += player.vx;
player.y += player.vy;
player.ground = false;
for(const p of platforms){
if(
player.x + player.w > p.x &&
player.x < p.x+p.w &&
player.y + player.h > p.y &&
player.y + player.h < p.y+20 &&
player.vy > 0
){
player.y = p.y-player.h;
player.vy = 0;
player.ground = true;
}
}
for(const e of enemies){
e.x += e.dir*2;
if(e.x < e.min) e.dir = 1;
if(e.x > e.max) e.dir = -1;
if(collide(player,e)){
player.x = checkpoint.x;
player.y = checkpoint.y;
player.vx = 0;
player.vy = 0;
}
}
for(const c of coins){
if(c.taken) continue;
const dx = (player.x+20)-c.x;
const dy = (player.y+20)-c.y;
if(Math.sqrt(dx*dx+dy*dy)<30){
c.taken=true;
score+=10;
scoreText.textContent=score;
}
}
if(collide(player,finish)){
alert("LEVEL COMPLETE! SCORE: "+score);
location.reload();
}
if(player.y > 900){
player.x = checkpoint.x;
player.y = checkpoint.y;
player.vy = 0;
}
cameraX = player.x - canvas.width/3;
}
function drawSky(){
const g = ctx.createLinearGradient(0,0,0,canvas.height);
g.addColorStop(0,"#5cc8ff");
g.addColorStop(1,"#d7f4ff");
ctx.fillStyle = g;
ctx.fillRect(0,0,canvas.width,canvas.height);
}
function draw(){
drawSky();
ctx.save();
ctx.translate(-cameraX,0);
for(const p of platforms){
ctx.fillStyle="#4CAF50";
ctx.fillRect(p.x,p.y,p.w,p.h);
}
for(const c of coins){
if(c.taken) continue;
ctx.beginPath();
ctx.fillStyle="gold";
ctx.arc(c.x,c.y,c.r,0,Math.PI*2);
ctx.fill();
}
for(const e of enemies){
ctx.fillStyle="crimson";
ctx.fillRect(e.x,e.y,e.w,e.h);
}
ctx.fillStyle="orange";
ctx.fillRect(finish.x,finish.y,finish.w,finish.h);
ctx.fillStyle="blue";
ctx.fillRect(player.x,player.y,player.w,player.h);
ctx.restore();
}
function loop(){
update();
draw();
requestAnimationFrame(loop);
}
loop();
onresize=()=>{
canvas.width=innerWidth;
canvas.height=innerHeight;
};
</script>
</body>
</html>1
1
4KB
4KB
132.0ms
192.0ms
132.0ms