Files
giochino/index.html
T

288 lines
23 KiB
HTML

<!DOCTYPE html>
<html lang='it'><head><meta charset='UTF-8'>
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
<title>Windjammers Arcade</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{background:#1a1a2e;display:flex;justify-content:center;align-items:center;min-height:100vh;font-family:'Courier New',monospace;overflow:hidden}
#gc{position:relative;border:4px solid #e94560;border-radius:8px;box-shadow:0 0 40px rgba(233,69,96,.3)}
canvas{display:block;border-radius:4px}
#ui{position:absolute;top:10px;left:50%;transform:translateX(-50%);display:flex;gap:20px;color:#fff;font-size:18px;font-weight:bold;text-shadow:2px 2px 4px rgba(0,0,0,.8);pointer-events:none}
.sb{background:rgba(0,0,0,.6);padding:8px 16px;border-radius:4px;border:2px solid #e94560}
#msg{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);color:#fff;font-size:32px;font-weight:bold;text-shadow:3px 3px 6px rgba(0,0,0,.9);pointer-events:none;text-align:center;opacity:0;transition:opacity .3s}
#ctr{position:absolute;bottom:10px;left:50%;transform:translateX(-50%);color:#fff;font-size:11px;text-align:center;opacity:.7;pointer-events:none;width:95%}
</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 id="msg"></div>
<div id="ctr">P1: W/A/S/D</div></div>
<script>
"use strict";
var C=document.getElementById("c"),X=C.getContext("2d"),W=C.width,H=C.height;
var K={sky:"#87CEEB",skyT:"#4A90D9",sand:"#F4D03F",sandD:"#D4AC0D",gr:"#7DCEA0",net:"#FFF",p1:"#E74C3C",p1d:"#C0392B",p2:"#3498DB",p2d:"#2980B9",disc:"#F39C12",glow:"#F1C40F",g5:"#E74C3C",g3:"#F39C12"};
var court={x:50,y:80,w:W-100,h:H-160,nx:W/2,nw:8,gd:40};
var DEF={p1:{up:"KeyW",down:"KeyS",left:"KeyA",right:"KeyD",thr:"KeyF",lob:"KeyG",sli:"KeyH"},p2:{up:"ArrowUp",down:"ArrowDown",left:"ArrowLeft",right:"ArrowRight",thr:"KeyK",lob:"KeyL",sli:"Semicolon"}};
var CTRL={p1:{},p2:{}};
var LB={up:"SU",down:"GIU",left:"SINISTRA",right:"DESTRA",thr:"TIRO",lob:"LOB",sli:"SLIDE"};
var KD={Space:"SPC",ArrowUp:"UP",ArrowDown:"DW",ArrowLeft:"LF",ArrowRight:"RT",Semicolon:";"};
var menu={screen:"main",mode:"ai",diff:"normal",sel:0};
var G={state:"menu",set:1,score:[0,0],sets:[0,0],time:3600,msg:"",mt:0,rally:0,serve:0,ai:null,cd:0,pp:0,pt:null};
var keys={},listening=null,p1,p2,disc,P=[];
function initCtrl(){
var s=localStorage.getItem("wj_c");
if(s){try{var p=JSON.parse(s);if(p.p1)Object.assign(CTRL.p1,p.p1);if(p.p2)Object.assign(CTRL.p2,p.p2);}catch(e){}}
for(var k in DEF.p1)if(!CTRL.p1[k])CTRL.p1[k]=DEF.p1[k];
for(var k in DEF.p2)if(!CTRL.p2[k])CTRL.p2[k]=DEF.p2[k];
}
function saveCtrl(){try{localStorage.setItem("wj_c",JSON.stringify(CTRL))}catch(e){}}
function resetCtrl(){Object.assign(CTRL.p1,JSON.parse(JSON.stringify(DEF.p1)));Object.assign(CTRL.p2,JSON.parse(JSON.stringify(DEF.p2)));saveCtrl();}
function kd(c){return KD[c]?KD[c]:c.replace("Key","").replace("Digit","").substring(0,6).toUpperCase()}
addEventListener("keydown",function(e){
keys[e.code]=true;
if(listening){e.preventDefault();listening.obj[listening.prop]=e.code;listening=null;saveCtrl();return}
if(["Space","ArrowUp","ArrowDown","ArrowLeft","ArrowRight"].includes(e.code))e.preventDefault();
});
addEventListener("keyup",function(e){keys[e.code]=false});
function Player(x,c,dc,s,n){
this.x=x;this.y=court.y+court.h/2;this.w=40;this.h=60;this.c=c;this.dc=dc;this.s=s;this.n=n;
this.vx=0;this.vy=0;this.sp=4;this.has=false;this.sl=false;this.st=0;this.sd=0;
this.ch=false;this.ct=0;this.af=0;this.fr=s===0;this.tc=0;this.cc=0;this.sup=false;
}
Player.prototype.up=function(){
if(!this.sl){var l=Math.hypot(this.vx,this.vy);if(l>.1){this.x+=this.vx;this.y+=this.vy;if(this.vx!==0)this.fr=this.vx>0;}}
if(this.sl){this.st--;this.x+=this.vx;this.y+=this.vy;if(this.st<=0){this.sl=false;this.vx*=.3;this.vy*=.3;}}
this.x=Math.max(court.x+20,Math.min(court.x+court.w-20,this.x));
this.y=Math.max(court.y+20,Math.min(court.y+court.h-20,this.y));
if(this.s===0&&this.x>court.nx-court.nw/2-20)this.x=court.nx-court.nw/2-20;
if(this.s===1&&this.x<court.nx+court.nw/2+20)this.x=court.nx+court.nw/2+20;
if(this.tc>0)this.tc--;if(this.cc>0)this.cc--;
if(this.ct>0){this.ct--;if(this.ct<=0){this.ch=false;this.sup=true;}}
this.af+=.15;
};
Player.prototype.slide=function(d){if(this.sl)return;this.sl=true;this.sd=d;this.st=16;this.vx=d*8;this.vy=0;};
Player.prototype.draw=function(){
X.save();X.fillStyle="rgba(0,0,0,.3)";X.beginPath();X.ellipse(this.x,this.y+this.h/2+5,this.w/2,8,0,0,Math.PI*2);X.fill();
var b=Math.sin(this.af)*3;X.strokeStyle=this.dc;X.lineWidth=6;X.lineCap="round";X.beginPath();
if(this.sl){X.moveTo(this.x-10,this.y+10);X.lineTo(this.x-25,this.y+25);X.moveTo(this.x+10,this.y+10);X.lineTo(this.x+25,this.y+25);}
else{X.moveTo(this.x-8,this.y+15);X.lineTo(this.x-12,this.y+this.h/2+b);X.moveTo(this.x+8,this.y+15);X.lineTo(this.x+12,this.y+this.h/2-b);}
X.stroke();X.fillStyle=this.c;X.beginPath();X.ellipse(this.x,this.y+5,this.w/2-5,this.h/2-10,0,0,Math.PI*2);X.fill();
X.strokeStyle=this.dc;X.lineWidth=2;X.stroke();X.strokeStyle=this.c;X.lineWidth=5;X.beginPath();
if(this.has){var a=this.fr?0:Math.PI;X.moveTo(this.x,this.y);X.lineTo(this.x+Math.cos(a)*25,this.y+Math.sin(a)*10);X.moveTo(this.x,this.y);X.lineTo(this.x+Math.cos(a)*20,this.y-15);}
else{X.moveTo(this.x,this.y);X.lineTo(this.x-15,this.y+10+b);X.moveTo(this.x,this.y);X.lineTo(this.x+15,this.y+10-b);}
X.stroke();X.fillStyle="#FDBCB4";X.beginPath();X.arc(this.x,this.y-15,12,0,Math.PI*2);X.fill();
X.strokeStyle=this.dc;X.lineWidth=2;X.stroke();X.fillStyle=this.dc;X.beginPath();X.arc(this.x,this.y-20,10,Math.PI,0);X.fill();
X.fillStyle="#000";X.beginPath();X.arc(this.x-4,this.y-15,2,0,Math.PI*2);X.arc(this.x+4,this.y-15,2,0,Math.PI*2);X.fill();
X.strokeStyle="#000";X.lineWidth=1.5;X.beginPath();X.arc(this.x,this.y-10,4,.1*Math.PI,.9*Math.PI);X.stroke();
if(this.ch){X.strokeStyle=K.glow;X.lineWidth=3;X.beginPath();X.arc(this.x,this.y,35+Math.sin(Date.now()/100)*5,0,Math.PI*2);X.stroke();}
if(this.sup){X.fillStyle=K.glow;X.beginPath();X.arc(this.x,this.y-35,5+Math.sin(Date.now()/50)*2,0,Math.PI*2);X.fill();}
X.restore();
};
function Disc(){this.x=W/2;this.y=H/2;this.vx=0;this.vy=0;this.r=15;this.rot=0;this.ow=null;this.ip=false;this.tr=[];this.lob=false;this.lh=0;this.sp=8;this.sup=false;}
Disc.prototype.throw=function(tx,ty,lob){var dx=tx-this.x,dy=ty-this.y,d=Math.hypot(dx,dy);this.vx=dx/d*this.sp;this.vy=dy/d*this.sp;this.lob=lob;this.ip=true;this.ow=null;if(lob){this.lh=0;this.vx*=.6;this.vy*=.6;}if(this.sup)this.vx*=1.5,this.vy*=1.5;};
Disc.prototype.up=function(){
if(!this.ip)return;
if(this.lob){this.lh+=.5;if(this.lh>100)this.lob=false;}
this.x+=this.vx;this.y+=this.vy;this.rot+=.3;
if(this.x-this.r<court.x){this.x=court.x+this.r;this.vx*=-.8;}
if(this.x+this.r>court.x+court.w){this.x=court.x+court.w-this.r;this.vx*=-.8;}
if(this.y-this.r<court.y){this.y=court.y+this.r;this.vy*=-.8;}
if(this.y+this.r>court.y+court.h){this.y=court.y+court.h-this.r;this.vy*=-.8;}
if(Math.abs(this.x-court.nx)<court.nw/2+this.r&&this.y>court.y+20&&this.y<court.y+court.h-20){this.vx*=-.7;this.x=court.nx+(this.x<court.nx?-1:1)*(court.nw/2+this.r);}
this.tr.push({x:this.x,y:this.y});if(this.tr.length>12)this.tr.shift();
this.vx*=.995;this.vy*=.995;
};
Disc.prototype.draw=function(){
X.save();
if(this.tr.length>1){X.beginPath();X.moveTo(this.tr[0].x,this.tr[0].y);for(var i=0;i<this.tr.length;i++)X.lineTo(this.tr[i].x,this.tr[i].y);X.strokeStyle="rgba(243,156,18,.4)";X.lineWidth=this.r;X.lineCap="round";X.stroke();}
var s=this.lob?1+this.lh/200:1,r=this.r*s;
if(this.sup){X.shadowColor=K.glow;X.shadowBlur=20;}
X.fillStyle=K.disc;X.beginPath();X.ellipse(this.x,this.y,r,r*.4,this.rot,0,Math.PI*2);X.fill();
X.strokeStyle="#D68910";X.lineWidth=2;X.beginPath();X.ellipse(this.x,this.y,r*.7,r*.25,this.rot,0,Math.PI*2);X.stroke();
X.fillStyle="rgba(255,255,255,.4)";X.beginPath();X.ellipse(this.x-r*.3,this.y-r*.15,r*.3,r*.15,this.rot,0,Math.PI*2);X.fill();
X.restore();
};
function Particle(x,y,c,t){this.x=x;this.y=y;this.vx=(Math.random()-.5)*8;this.vy=(Math.random()-.5)*8-2;this.lf=1;this.c=c;this.type=t||"dust";this.s=this.type==="conf"?8:4;this.rot=Math.random()*Math.PI*2;}
Particle.prototype.up=function(){this.x+=this.vx;this.y+=this.vy;this.vy+=.2;this.lf-=.02;this.rot+=.1;};
Particle.prototype.draw=function(){X.save();X.globalAlpha=this.lf;X.fillStyle=this.c;if(this.type==="conf"){X.translate(this.x,this.y);X.rotate(this.rot);X.fillRect(-this.s/2,-this.s/4,this.s,this.s/2);}else{X.beginPath();X.arc(this.x,this.y,this.s*this.lf,0,Math.PI*2);X.fill();}X.restore();};
function AI(p,d){this.p=p;this.td=0;this.st=0;this.setDiff(d);}
AI.prototype.setDiff=function(d){var a={easy:[25,.5,.3,.2,40,.005],normal:[12,.75,.6,.55,20,.015],hard:[5,.95,.9,.85,10,.03]}[d];this.rf=a[0];this.acc=a[1];this.agg=a[2];this.pred=a[3];this.td=a[4];this.sf=a[5];};
AI.prototype.up=function(d,opp){this.p.cc=Math.max(0,this.p.cc-1);this.st=Math.max(0,this.st-1);var f=15+(1-this.pred)*20;this.px=d.x+d.vx*f;this.py=d.y+d.vy*f;if(this.p.has)this.atk(opp);else if(d.ip&&!d.ow)this.def(d);else this.idle();};
AI.prototype.atk=function(opp){if(this.st>0)return;if(Math.random()<this.agg||this.st<-this.td*2){var ty=this.tgt();ty+=(1-this.acc)*(Math.random()-.5)*100;ty=Math.max(court.y+30,Math.min(court.y+court.h-30,ty));var lob=Math.random()<.2*this.agg;var sup=this.p.sup&&Math.random()<this.agg;d.throw(court.x,ty,lob);this.p.has=false;this.p.tc=30;this.p.sup=false;this.st=this.td;}};
AI.prototype.tgt=function(){var r=Math.random();if(this.acc>.8&&r<.4)return court.y+court.h/2+(Math.random()-.5)*30;if(r<.6)return court.y+court.h/6+(Math.random()-.5)*20;return court.y+court.h*5/6+(Math.random()-.5)*20;};
AI.prototype.def=function(d){var tx=this.px,ty=this.py,dx=tx-this.p.x,dy=ty-this.p.y,dist=Math.hypot(dx,dy);if(dist>50){if(Math.random()<this.sf&&dist>100){this.p.slide(dx>0?1:-1);this.st=25;}else{var s=this.p.sp*(1+this.agg*.5);this.p.vx=dx/dist*s;this.p.vy=dy/dist*s;if(dx!==0)this.p.fr=dx>0;}}else{this.p.vx*=.5;this.p.vy*=.5;}};
AI.prototype.idle=function(){var cx=court.nx+150,cy=court.y+court.h/2,dx=cx-this.p.x,dy=cy-this.p.y,d=Math.hypot(dx,dy);if(d>30){var s=this.p.sp*.7;this.p.vx=dx/d*s;this.p.vy=dy/d*s;if(dx!==0)this.p.fr=dx>0;}else{this.p.vx*=.8;this.vy*=.8;}};
function initGame(){
p1=new Player(court.x+100,K.p1,K.p1d,0,"P1");p2=new Player(court.x+court.w-100,K.p2,K.p2d,1,"CPU");
disc=new Disc();P=[];G.score=[0,0];G.sets=[0,0];G.set=1;G.time=3600;G.rally=0;G.serve=0;G.pp=0;G.pt=null;G.cd=120;
if(G.aiMode)G.ai=new AI(p2,G.diff);serve();updateCtrUI();
}
function serve(){var s=G.serve===0?p1:p2;s.has=true;disc.ow=s;disc.ip=false;disc.x=s.x+(s.fr?25:-25);disc.y=s.y;}
function updateUI(){document.getElementById("s1").textContent="P1: "+G.score[0];document.getElementById("s2").textContent=(G.aiMode?"CPU":"P2")+": "+G.score[1];document.getElementById("st").textContent="SET "+G.set;}
function updateCtrUI(){document.getElementById("ctr").textContent="P1: "+kd(CTRL.p1.up)+"/"+kd(CTRL.p1.left)+"/"+kd(CTRL.p1.down)+"/"+kd(CTRL.p1.right)+" + "+kd(CTRL.p1.thr)+"(tiro) "+kd(CTRL.p1.lob)+"(lob) "+kd(CTRL.p1.sli)+"(slide)";}
function showMsg(t){G.msg=t;G.mt=120;document.getElementById("msg").textContent=t;document.getElementById("msg").style.opacity=1;}
function scorePoint(pl,pts){G.score[pl]+=pts;G.rally=0;for(var i=0;i<30;i++)P.push(new Particle(pl===0?court.x+court.w:court.x,disc.y,"hsl("+Math.random()*360+",70%,60%)","conf"));updateUI();showMsg("+pts+" PUNTI!");G.pp=90;G.pt=pl;}
function checkGoal(){if(!disc.ip)return;if(disc.x-disc.r<court.x){var z=Math.floor((disc.y-court.y)/(court.h/3));scorePoint(1,z===1?5:3);}if(disc.x+disc.r>court.x+court.w){var z=Math.floor((disc.y-court.y)/(court.h/3));scorePoint(0,z===1?5:3);}}
function checkCatch(){if(!disc.ip)return;[p1,p2].forEach(function(p){if(p.cc>0||p.has)return;var d=Math.hypot(disc.x-p.x,disc.y-p.y);if(d<45){p.has=true;disc.ow=p;disc.ip=false;disc.vx=0;disc.vy=0;p.cc=30;G.rally++;for(var i=0;i<5;i++)P.push(new Particle(p.x,p.y+20,K.sand));}});}
function handleP1(){var c=CTRL.p1;if(keys[c.thr]&&p1.has&&p1.tc===0){disc.throw(court.x+court.w,court.y+Math.random()*court.h,false);p1.has=false;p1.tc=30;p1.sup=false;}if(keys[c.lob]&&p1.has&&p1.tc===0){disc.throw(court.x+court.w,court.y+Math.random()*court.h,true);p1.has=false;p1.tc=40;}if(keys[c.sli]&&!p1.has&&!p1.sl)p1.slide(p1.fr?1:-1);}
function handleP2(){if(G.aiMode)return;var c=CTRL.p2;if(keys[c.thr]&&p2.has&&p2.tc===0){disc.throw(court.x,court.y+Math.random()*court.h,false);p2.has=false;p2.tc=30;p2.sup=false;}if(keys[c.lob]&&p2.has&&p2.tc===0){disc.throw(court.x,court.y+Math.random()*court.h,true);p2.has=false;p2.tc=40;}if(keys[c.sli]&&!p2.has&&!p2.sl)p2.slide(p2.fr?1:-1);}
function checkSetEnd(){if(G.sets[0]>=2||G.sets[1]>=2){G.state="end";return;}G.score=[0,0];G.time=3600;updateUI();G.pp=60;}
function drawBg(){
var s=X.createLinearGradient(0,0,0,court.y);s.addColorStop(0,K.skyT);s.addColorStop(1,K.sky);X.fillStyle=s;X.fillRect(0,0,W,court.y);
X.fillStyle="rgba(255,255,255,.8)";[[100,30,40],[300,50,30],[600,25,50],[800,45,35]].forEach(function(c){X.beginPath();X.arc(c[0],c[1],c[2],0,Math.PI*2);X.arc(c[0]+c[2]*.8,c[1]-c[2]*.2,c[2]*.7,0,Math.PI*2);X.arc(c[0]+c[2]*1.5,c[1],c[2]*.8,0,Math.PI*2);X.fill();});
X.fillStyle="#5DADE2";X.fillRect(0,court.y-20,W,20);X.fillStyle="#3498DB";X.fillRect(0,court.y-20,W,2);X.fillRect(0,court.y-12,W,2);X.fillRect(0,court.y-4,W,2);
var sd=X.createLinearGradient(0,court.y+court.h,0,H);sd.addColorStop(0,K.sand);sd.addColorStop(1,K.sandD);X.fillStyle=sd;X.fillRect(0,court.y+court.h,W,H-court.y-court.h);
X.fillStyle=K.gr;X.fillRect(court.x,court.y,court.w,court.h);X.strokeStyle="#FFF";X.lineWidth=3;X.strokeRect(court.x,court.y,court.w,court.h);
X.setLineDash([10,10]);X.beginPath();X.moveTo(court.nx,court.y);X.lineTo(court.nx,court.y+court.h);X.stroke();X.setLineDash([]);
drawGoal(court.x,0);drawGoal(court.x+court.w,1);
X.fillStyle=K.net;X.fillRect(court.nx-court.nw/2,court.y,court.nw,court.h);
for(var y=court.y;y<court.y+court.h;y+=12)X.fillRect(court.nx-court.nw/2,y,court.nw,3);
}
function drawGoal(x,side){
var gx=side===0?x-court.gd:x,zw=court.gd,zh=court.h/3;
X.fillStyle=K.g5;X.globalAlpha=.7;X.fillRect(gx,court.y+zh,zw,zh);
X.fillStyle=K.g3;X.fillRect(gx,court.y,zw,zh);X.fillRect(gx,court.y+zh*2,zw,zh);X.globalAlpha=1;
X.strokeStyle="#000";X.lineWidth=2;X.strokeRect(gx,court.y,zw,court.h);
X.beginPath();X.moveTo(gx,court.y+zh);X.lineTo(gx+zw,court.y+zh);X.moveTo(gx,court.y+zh*2);X.lineTo(gx+zw,court.y+zh*2);X.stroke();
X.fillStyle="#FFF";X.font="bold 16px Courier New";X.textAlign="center";
X.fillText("3",gx+zw/2,court.y+zh/2+5);X.fillText("5",gx+zw/2,court.y+zh+zh/2+5);X.fillText("3",gx+zw/2,court.y+zh*2+zh/2+5);
}
function drawHUD(){X.fillStyle="rgba(0,0,0,.5)";X.fillRect(court.x,court.y-25,180,20);X.fillStyle="#fff";X.font="14px Courier New";X.textAlign="left";X.fillText("Rally: "+G.rally,court.x+10,court.y-10);X.fillStyle="rgba(0,0,0,.5)";X.fillRect(court.x+court.w-180,court.y-25,180,20);X.fillStyle="#F39C12";X.font="bold 14px Courier New";X.textAlign="right";X.fillText("Tempo: "+Math.ceil(G.time/60)+"s",court.x+court.w-10,court.y-10);}
function drawMenu(){
X.fillStyle="rgba(0,0,0,.92)";X.fillRect(0,0,W,H);X.textAlign="center";
if(menu.screen==="main"){
X.fillStyle="#e94560";X.font="bold 50px Courier New";X.fillText("WINDJAMMERS",W/2,85);
X.fillStyle="#F39C12";X.font="bold 20px Courier New";X.fillText("FLYING DISC ARCADE",W/2,125);
X.fillStyle="#666";X.font="15px Courier New";X.fillText("- menu -",W/2,165);
var opt=["VS CPU (Intelligenza Artificiale)","2 GIOCATORI (locale)","IMPOSTAZIONI (configura tasti)"];
for(var i=0;i<opt.length;i++){X.fillStyle=i===menu.sel?"#F39C12":"#777";X.font=i===menu.sel?"bold 22px Courier New":"18px Courier New";X.fillText((i===menu.sel?" >> ":" ")+opt[i]+" "+(i===menu.sel?"<<":""),W/2,260+i*50);}
X.fillStyle="#444";X.font="13px Courier New";X.fillText("FRECCE = scegli INVIO = conferma",W/2,460);
}else if(menu.screen==="diff"){
X.fillStyle="#3498DB";X.font="bold 38px Courier New";X.fillText("VS CPU",W/2,90);
X.fillStyle="#fff";X.font="20px Courier New";X.fillText("Scegli la difficolta:",W/2,150);
var opt=["FACILE Lento e impreciso","NORMARE Equilibrato","DIFFICILE Veloce, preciso, aggressivo"];
for(var i=0;i<opt.length;i++){X.fillStyle=i===menu.sel?"#F39C12":"#777";X.font=i===menu.sel?"bold 22px Courier New":"17px Courier New";X.fillText((i===menu.sel?" >> ":" ")+opt[i]+" "+(i===menu.sel?"<<":""),W/2,250+i*50);}
X.fillStyle="#444";X.font="13px Courier New";X.fillText("FRECCE = scegli INVIO = conferma ESC = indietro",W/2,440);
}else if(menu.screen==="settings"){
X.fillStyle="#9b59b6";X.font="bold 28px Courier New";X.fillText("IMPOSTAZIONI",W/2,40);
var whichP=menu.sel<7?1:2;
var ck=whichP===1?"p1":"p2";
var cp=CTRL[ck];
var k=["up","down","left","right","thr","lob","sli"];
if(whichP===1){
X.fillStyle="#e74c3c";X.font="bold 16px Courier New";X.fillText("<<< P1 (rosso) ||| P2 (blu) >>>",W/2,70);
}else{
X.fillStyle="#3498db";X.font="bold 16px Courier New";X.fillText("<<< P1 (rosso) ||| P2 (blu) >>>",W/2,70);
}
X.fillStyle="#fff";X.font="14px Courier New";X.fillText("Scorri fino a P2 per configurarne i tasti",W/2,95);
for(var i=0;i<k.length;i++){
var idx=whichP===1?i:i+7;
var y=125+i*32;
var isL=listening&&listening.obj===cp&&listening.prop===k[i];
var isSel=(whichP===1&&menu.sel===i)||(whichP===2&&menu.sel===i+7);
X.fillStyle=isL?"#F39C12":(isSel?"#fff":"#777");
X.font=isL?"bold 17px Courier New":(isSel?"bold 15px Courier New":"14px Courier New");
var val=isL?"... PREMI UN TASTO ...":kd(cp[k[i]]);
X.fillText((isL?" > ":isSel?" > ":" ")+LB[k[i]]+" : "+val+" "+(isL||isSel?"<":""),W/2,y);
}
X.fillStyle="#555";X.font="11px Courier New";
X.fillText("FRECCE SU/GIU = cambia azione FRECCE SIN/DEST = cambia giocatore",W/2,385);
X.fillText("INVIO/SPAZIO = cambia tasto (premi il nuovo tasto)",W/2,405);
X.fillText("R = reset predefiniti ESC = torna al menu",W/2,425);
if(listening){X.fillStyle="#F39C12";X.font="bold 18px Courier New";X.fillText(">> PREMI IL NUOVO TASTO ORA <<",W/2,475);}
}else if(menu.screen==="ready"){
X.fillStyle="#e94560";X.font="bold 44px Courier New";X.fillText("PRONTO!",W/2,115);
X.fillStyle="#fff";X.font="18px Courier New";X.fillText("Modalita: "+(G.aiMode?"VS CPU ("+G.diff.toUpperCase()+")":"2 GIOCATORI"),W/2,180);
X.fillStyle="#F39C12";X.font="bold 24px Courier New";X.fillText("Premi SPAZIO per iniziare!",W/2,245);
X.fillStyle="#aaa";X.font="13px Courier New";
X.fillText("P1: "+kd(CTRL.p1.thr)+"=tiro "+kd(CTRL.p1.lob)+"=lob "+kd(CTRL.p1.sli)+"=slide",W/2,340);
X.fillText((G.aiMode?"CPU controlla P2":"P2: "+kd(CTRL.p2.thr)+"=tiro "+kd(CTRL.p2.lob)+"=lob "+kd(CTRL.p2.sli)+"=slide"),W/2,370);
X.fillStyle="#666";X.font="11px Courier New";X.fillText("Vai in IMPOSTAZIONI per cambiare tasti",W/2,420);
}
}
function handleMenuInput(){
if(listening)return;
if(keys["ArrowUp"]){keys["ArrowUp"]=false;var mx=menu.screen==="main"?2:(menu.screen==="diff"?2:13);menu.sel=Math.max(0,menu.sel-1);}
if(keys["ArrowDown"]){keys["ArrowDown"]=false;var mx=menu.screen==="main"?2:(menu.screen==="diff"?2:13);menu.sel=Math.min(mx,menu.sel+1);}
if(keys["Enter"]||keys["Space"]){
keys["Enter"]=false;keys["Space"]=false;
if(menu.screen==="main"){
if(menu.sel===0){menu.screen="diff";menu.sel=1;}
else if(menu.sel===1){G.aiMode=false;menu.screen="ready";G.state="ready";}
else{menu.screen="settings";menu.sel=0;}
}else if(menu.screen==="diff"){G.aiMode=true;G.diff=["easy","normal","hard"][menu.sel];menu.screen="ready";G.state="ready";}
else if(menu.screen==="settings"){var k=["up","down","left","right","thr","lob","sli"];if(menu.sel>=0&&menu.sel<=6){listening={obj:CTRL.p1,prop:k[menu.sel]};}else if(menu.sel>=7&&menu.sel<=13){listening={obj:CTRL.p2,prop:k[menu.sel-7]};}}
}
if(keys["Escape"]){keys["Escape"]=false;if(menu.screen==="diff"||menu.screen==="settings"){menu.screen="main";menu.sel=0;}}
if(keys["KeyR"]&&menu.screen==="settings"){keys["KeyR"]=false;resetCtrl();}
if((keys["Space"]||keys["Enter"])&&menu.screen==="ready"&&G.state==="ready"){G.state="countdown";G.cd=120;keys["Space"]=false;keys["Enter"]=false;}
}
function loop(){
X.clearRect(0,0,W,H);
if(G.state==="menu"||G.state==="ready"||G.state==="countdown"){
drawBg();
if(G.state==="menu"||G.state==="ready")handleMenuInput();
if(G.state==="countdown"){
G.cd--;
if(!p1){p1=new Player(court.x+100,K.p1,K.p1d,0,"P1");p2=new Player(court.x+court.w-100,K.p2,K.p2d,1,"CPU");}
p1.up();p2.up();p1.draw();p2.draw();
X.fillStyle="#fff";X.font="bold 60px Courier New";X.textAlign="center";X.fillText(Math.ceil(G.cd/60),W/2,H/2+20);
X.fillStyle="#F39C12";X.font="bold 20px Courier New";X.fillText("GET READY!",W/2,H/2-60);
if(G.cd<=0){G.state="playing";serve();}
}
drawMenu();
}else if(G.state==="playing"){
drawBg();
if(G.pp>0){G.pp--;if(G.pp<=0){if(G.pt!==null){checkSetEnd();G.pt=null;}}}
if(G.pp<=0){
handleP1();handleP2();
if(G.aiMode)G.ai.up(disc,p1);
p1.up();p2.up();disc.up();
if(disc.ow){disc.x=disc.ow.x+(disc.ow.fr?25:-25);disc.y=disc.ow.y;}
checkCatch();checkGoal();G.time--;
if(G.time<=0){
if(G.score[0]>G.score[1]){G.sets[0]++;showMsg("P1 VINCE IL SET!");}
else if(G.score[1]>G.score[0]){G.sets[1]++;showMsg("CPU VINCE IL SET!");}
else{G.sets[0]++;G.sets[1]++;showMsg("PAREGGIO!");}
G.set++;checkSetEnd();
}
}
p1.draw();p2.draw();
if(disc.ip||disc.ow)disc.draw();
P=P.filter(function(p){return p.lf>0;});
P.forEach(function(p){p.up();p.draw();});
if(G.mt>0){G.mt--;if(G.mt<=0)document.getElementById("msg").style.opacity=0;}
drawHUD();
}else if(G.state==="end"){
drawBg();p1.draw();p2.draw();
X.fillStyle="rgba(0,0,0,.75)";X.fillRect(0,0,W,H);X.textAlign="center";
X.fillStyle="#e94560";X.font="bold 44px Courier New";
var w=G.sets[0]>G.sets[1]?"P1 VINCE!":(G.sets[1]>G.sets[0]?"CPU VINCE!":"PAREGGIO!");
X.fillText(w,W/2,H/2-20);
X.fillStyle="#fff";X.font="18px Courier New";X.fillText("Premi R per rigiocare o ESC per il menu",W/2,H/2+40);
if(keys["KeyR"]){keys["KeyR"]=false;initGame();G.state="countdown";G.cd=120;}
if(keys["Escape"]){keys["Escape"]=false;G.state="menu";menu.screen="main";menu.sel=0;p1.x=court.x+100;p2.x=court.x+court.w-100;}
}
updateUI();
requestAnimationFrame(loop);
}
initCtrl();
loop();
</script>
</body>
</html>