Ecco, seguendo un tutorial ho realizzato l'abbozzo del videogiochino della pallina che deve rompere i mattoncini.
Per il momento ho realizzato solo la pallina e la racchetta.
Ora mi analizzo la struttura del giochino...
Abbiamo alcune funzioni semplici che potrebbero essere anche messe su un file a parte.
Ho già linkato un file di codice Javascript per la sola funzione $ che evita di dover scrivere
document.getElementById, e potrei linkare anche un altro file con queste funzioni.
Ma vediamo se sono "isolabili"...
Il codice intero è questo:
<!DOCTYPE html>
<html>
<head>
<script src="funzioni2.js"></script>
<script>
var canvas;
var ctx;
x=150;
y=150;
var dx=2;
var dy=4;
var WIDTH;
var HEIGHT;
var paddlex;
var paddlew;
var paddleh;
var rightDown=false;
var leftDown=false;
var intervallo;
function inizia(){
//creiamo la base del contesto.
canvas=$("canvas");
ctx=canvas.getContext("2d");
WIDTH=canvas.width;
HEIGHT=canvas.height;
paddlex=WIDTH/2-100;
paddleh=10;
paddlew=75;
//funzione setInterval
intervallo=setInterval(draw,15);
}
document.onkeydown=OnKeyDown;
document.onkeyup=OnKeyUp;
function OnKeyDown(evt){
if (evt.keyCode==39) rightDown=true;
else if(evt.keyCode==37) leftDown=true;
}
function OnKeyUp(evt){
if (evt.keyCode==39) rightDown=false;
else if (evt.keyCode==37) leftDown=false;
}
function circle(x,y,r){
ctx.fillStyle="red";
ctx.beginPath();
ctx.arc(x,y,r,0,Math.PI*2,true);
ctx.closePath();
ctx.fill();
}
function rect(x,y,w,h){
ctx.beginPath();
ctx.rect(x,y,w,h);
ctx.closePath();
}
function clear(){
ctx.clearRect(0,0,WIDTH,HEIGHT);
}
function draw() {
clear();
circle(x,y,10);
if(rightDown) paddlex+=5;
if(leftDown) paddlex-=5;
ctx.fillStyle="blue";
rect(paddlex,HEIGHT-paddleh,paddlew,paddleh);
if(x+dx<0 || x+dx>WIDTH)
dx=-dx;
if(y+dy<0)
dy=-dy;
else if(y+dy>HEIGHT){
if(x>paddlex && x<(paddlex+paddlew))
dy=-dy;
else{
clearInterval(intervallo);
alert("Game over!");
window.location.reload();
}
}
ctx.fill();
x+=dx;
y+=dy;
}
window.addEventListener("load",inizia);
</script>
</head>
<body>
<canvas id="canvas" width="800" height="500" style="border:3px solid maroon"></canvas>
</body>
</html>
Abbiamo:
Funzione
circle che traccia un cerchio:
function circle(x,y,r){
ctx.fillStyle="red";
ctx.beginPath();
ctx.arc(x,y,r,0,Math.PI*2,true);
ctx.closePath();
ctx.fill();
}
Ecco, qui c'è un elemento che imposta il
fillStyle e che va eliminato dalla funzione, oppure va compreso mettendo il colore come parametro.
Scegliamo la seconda e riscriviamo:
function circle(x,y,r,colore){
ctx.fillStyle=colore;
ctx.beginPath();
ctx.arc(x,y,r,0,Math.PI*2,true);
ctx.closePath();
ctx.fill();
}
Provandola, con l'accortezza di aggiungere il colore fra i parametri quando si chiama la funzione,
function draw() {
clear();
circle(x,y,10,"green");
if(rightDown) paddlex+=5;
if(leftDown) paddlex-=5;
....
....
(ho cambiato colore per verificare bene il funzionamento) funziona!
La possiamo togliere dal codice e immettere in un file a parte, che va linkato al codice della pagina.
Lo chiamo "funzioniCanvas.js" e lo linko:
<!DOCTYPE html>
<html>
<head>
<script src="funzioni2.js"></script>
<script src="funzioniCanvas.js"></script>
Stessa cosa posso fare con la funzione
rect che traccia un rettangolo:
function rect(x,y,w,h){
ctx.beginPath();
ctx.rect(x,y,w,h);
ctx.closePath();
}
In questo caso il codice per il colore non è incluso nella funzione, ma è scritto a parte prima di chiamare la funzione.
Potrei fare la stessa scelta che per la funzione che traccia un cerchio, e includere il colore come parametro...
function rect(x,y,w,h,colore){
ctx.fillStyle=colore;
ctx.beginPath();
ctx.rect(x,y,w,h);
ctx.closePath();
ctx.fill();
}
e funziona.
Tolgo questa funzione e la metto nel file di codice a parte.
E funziona!
La funzione
clear che ripulisce il canvas consentendo l'effetto di animazione, posso portarla nel file di codice.
Questa però usa due variabili, che porto anch'esse nel file a parte:
function clear(){
ctx.clearRect(0,0,WIDTH,HEIGHT);
}
E funziona ancora tutto.
Ora ci sono le funzioni che stabiliscono se sia stato premuto il tasto destra o sinistra. Queste mi sembrano sufficientemente generalizzabili da poterle portare nel file a parte: settano delle variabili booleane a seconda che sia stato premuto il tasto freccia destra o freccia sinistra, e affidano queste funzioni agli eventi onkeydown del documento HTML.
Fanno uso di due variabili booleane, che porto anch'esse sul file di codice.
var rightDown=false;
var leftDown=false;
document.onkeydown=OnKeyDown;
document.onkeyup=OnKeyUp;
function OnKeyDown(evt){
if (evt.keyCode==39) rightDown=true;
else if(evt.keyCode==37) leftDown=true;
}
function OnKeyUp(evt){
if (evt.keyCode==39) rightDown=false;
else if (evt.keyCode==37) leftDown=false;
}
Ho ridotto quasi all'osso la cosa.
Ma potrei anche portare nel codice le procedure che "prendono possesso" del canvas e del contesto, tanto più che anch'esse usano variabili che vi ho già portato:
function inizia(){
//creiamo la base del contesto.
canvas=$("canvas");
ctx=canvas.getContext("2d");
WIDTH=canvas.width;
HEIGHT=canvas.height;
....
La riscrivo come InitContext...
function initContext(nome){
canvas=$(nome);
ctx=canvas.getContext("2d");
WIDTH=canvas.width;
HEIGHT=canvas.height;
}
richiamandola dalla funzione iniziale:
function inizia(){
initContext("canvas");
paddlex=WIDTH/2-100;
paddleh=10;
paddlew=75;
//funzione setInterval
intervallo=setInterval(draw,15);
}
E quindi la porto sul file di codice insieme alle variabili che usa:
var canvas;
var ctx;
function initContext(nome){
canvas=$(nome);
ctx=canvas.getContext("2d");
WIDTH=canvas.width;
HEIGHT=canvas.height;
}
e funziona!
Io metterei anche una routine che inizializza tutte le variabili.
Prima dichiaro tutte le variabili, quindi le inizializzo in una funzione apposita:
//coordinate della palla
var x;
var y;
var dx;
var dy;
//coordinate della racchetta
var paddlex;
var paddlew;
var paddleh;
var intervallo;
function initVariables(){
x=100;
y=100;
dx=2;
dy=4;
paddlew=75;
paddleh=10;
paddlex=WIDTH/2-120;
}