Files
giochino/index.html
T

175 lines
5.2 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Windjammers</title>
<style>
body{background:#1a1a2e;display:flex;justify-content:center;align-items:center;min-height:100vh;margin:0;font-family:Courier}
#gc{width:900px;height:500px;border:3px solid #e94560;border-radius:8px;position:relative;overflow:hidden;background:#000}
canvas{width:100%;height:100%}
#ui{position:absolute;top:10px;left:50%;transform:translateX(-50%);display:flex;gap:20px;pointer-events:none}
.sb{background:rgba(0,0,0,.7);padding:8px 16px;border-radius:4px;border:2px solid #e94560;color:#fff;font-size:18px;font-weight:bold}
</style>
</head>
<body>
<div id="gc">
<canvas id="c" width="900" height="500"></canvas>
<div id="ui">
<div class="sb" id="s1">P1: 0</div>
<div class="sb" id="st">SET 1</div>
<div class="sb" id="s2">CPU: 0</div>
</div>
</div>
<script>
var C=document.getElementById('c');
var X=C.getContext('2d');
var W=C.width,H=C.height;
var keys={};
var game=null;
document.addEventListener('keydown',function(e){keys[e.code]=true;});
document.addEventListener('keyup',function(e){keys[e.code]=false;});
function initGame(){
game={
p1:{x:150,y:250,vx:0,vy:0,has:false,tc:0,score:0,color:'#E74C3C'},
p2:{x:750,y:250,vx:0,vy:0,has:false,tc:0,score:0,color:'#3498DB'},
disc:{x:450,y:250,vx:0,vy:0,owner:null,inPlay:false},
mode:'menu'
};
}
function drawField(){
// Sky
var g=X.createLinearGradient(0,0,0,80);g.addColorStop(0,'#4A90D9');g.addColorStop(1,'#87CEEB');
X.fillStyle=g;X.fillRect(0,0,W,80);
// Court
X.fillStyle='#7DCEA0';X.fillRect(50,80,W-100,H-160);
X.strokeStyle='#fff';X.lineWidth=3;X.strokeRect(50,80,W-100,H-160);
// Net
X.fillStyle='#fff';X.fillRect(446,80,8,H-160);
// Goals
X.fillStyle='#E74C3C';X.globalAlpha=0.6;X.fillRect(15,180,35,140);X.globalAlpha=1;
X.fillStyle='#3498DB';X.globalAlpha=0.6;X.fillRect(850,180,35,140);X.globalAlpha=1;
}
function drawPlayer(p){
// Body
X.fillStyle=p.color;X.beginPath();X.ellipse(p.x,p.y,18,25,0,0,Math.PI*2);X.fill();
// Head
X.fillStyle='#FDBCB4';X.beginPath();X.arc(p.x,p.y-15,12,0,Math.PI*2);X.fill();
// Arms if has disc
if(p.has){X.strokeStyle=p.color;X.lineWidth=5;X.beginPath();X.moveTo(p.x,p.y);X.lineTo(p.x+(p.x<450?25:-25),p.y-10);X.stroke();}
}
function drawDisc(){
if(game.disc.owner)return; // hidden when held
X.fillStyle='#F39C12';X.beginPath();X.ellipse(game.disc.x,game.disc.y,14,6,0,0,Math.PI*2);X.fill();
X.strokeStyle='#B7950B';X.lineWidth=2;X.stroke();
}
function updatePlayer(p,speed){
p.vx=0;p.vy=0;
if(speed===undefined)speed=4;
if(p===game.p1){
if(keys['KeyW'])p.vy=-speed;
if(keys['KeyS'])p.vy=speed;
if(keys['KeyA'])p.vx=-speed;
if(keys['KeyD'])p.vx=speed;
if(keys['KeyF']&&p.has&&p.tc<=0){throwDisc(p,850);p.tc=30;}
}else{
// AI
if(p.has&&Math.random()<0.02){throwDisc(p,50);}
else if(game.disc.inPlay){var dx=game.disc.x-p.x,dy=game.disc.y-p.y,d=Math.hypot(dx,dy);if(d>40){p.vx=dx/d*3.5;p.vy=dy/d*3.5;}}
else{p.vx*=0.9;p.vy*=0.9;}
}
p.x+=p.vx;p.y+=p.vy;
p.x=Math.max(60,Math.min(840,p.x));
p.y=Math.max(90,Math.min(410,p.y));
// Keep in own half
if(p===game.p1&&p.x>430)p.x=430;
if(p===game.p2&&p.x<470)p.x=470;
if(p.tc>0)p.tc--;
}
function throwDisc(p,targetX){
var tx=targetX+(Math.random()-0.5)*150;
var ty=100+Math.random()*300;
game.disc.owner=null;
game.disc.inPlay=true;
var dx=tx-p.x,dy=ty-p.y,d=Math.hypot(dx,dy);
game.disc.vx=dx/d*8;
game.disc.vy=dy/d*8;
game.disc.x=p.x;
game.disc.y=p.y;
p.has=false;
}
function updateDisc(){
var d=game.disc;
if(d.owner){d.x=d.owner.x+(d.owner===game.p1?20:-20);d.y=d.owner.y;return;}
if(!d.inPlay)return;
d.x+=d.vx;d.y+=d.vy;
// Bounce walls
if(d.x<60||d.x>840)d.vx*=-0.8;
if(d.y<90||d.y>410)d.vy*=-0.8;
// Net
if(Math.abs(d.x-450)<10)d.vx*=-0.7;
// Catch
[game.p1,game.p2].forEach(function(p){
if(p.has||p.tc>0)return;
var dist=Math.hypot(d.x-p.x,d.y-p.y);
if(dist<35){p.has=true;d.inPlay=false;d.owner=p;}
});
// Goals
if(d.x<50){game.p2.score++;resetPoint();}
if(d.x>850){game.p1.score++;resetPoint();}
}
function resetPoint(){
game.disc.inPlay=false;
game.disc.owner=null;
game.disc.x=450;game.disc.y=250;
game.disc.vx=0;game.disc.vy=0;
game.p1.x=150;game.p1.y=250;game.p1.has=false;
game.p2.x=750;game.p2.y=250;game.p2.has=false;
// Serve to random player
if(Math.random()<0.5)game.p1.has=true;
else game.p2.has=true;
}
function loop(){
X.clearRect(0,0,W,H);
drawField();
if(game===null){
initGame();
X.fillStyle='#e94560';X.font='bold 40px Courier';X.textAlign='center';
X.fillText('WINDJAMMERS',W/2,150);
X.fillStyle='#F39C12';X.font='16px Courier';
X.fillText('FLYING DISC ARCADE',W/2,190);
X.fillStyle='#fff';X.font='14px Courier';
X.fillText('Premi SPAZIO per iniziare',W/2,300);
if(keys['Space']){game.p1.has=true;game.mode='playing';}
}else if(game.mode==='playing'){
updatePlayer(game.p1);
updatePlayer(game.p2);
updateDisc();
drawPlayer(game.p1);
drawPlayer(game.p2);
drawDisc();
}
// UI
if(game){
document.getElementById('s1').textContent='P1: '+game.p1.score;
document.getElementById('s2').textContent='CPU: '+game.p2.score;
}
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>