Dupa ce in articolul acesta ti-am aratat primul pas pentru a programa un joc de Tetris, iar in al doilea articol din serie am schitat “scheletul” programului, in acest articol voi pune un pic de “carne” pe “schelet” :-).
In ciuda exprimarii, n-a iesit nimic “monstruos”, ci dimpotriva — rezultatul e chiar simpatic. Apasa butonul “Reseteaza…” din simulatorul de mai jos ca sa vezi in stanga codul sursa al programului.
Vei vedea ca fata de programul din articolul trecut am mai adaugat sapte functii (GenereazaPiesa(), PunePiesa(), RidicaPiesa(), CoboaraPiesa(), AfiseazaTabla(), LaStanga() si LaDreapta()), precum si apelurile catre ele acolo unde a fost cazul.
Ordinea in care noile functii sunt definite nu este neaparat cea mai logica, ci este ordinea in care le-am construit (pe masura ce am avut nevoie de ele). Ideea a fost sa aduc jocul la “viata” intr-o forma cat mai simpla cu putinta, urmand ca apoi sa-l imbunatatesc “milimetru” cu “milimetru”.
Acum te las sa te distrezi un pic:
// +--------+
// | TETRIS |
// +--------+
// CONSTANTELE:
// Piesele:
var piesa1 = Matrice(4, 4);
piesa1[0][0] = 0; piesa1[0][1] = 0; piesa1[0][2] = 1; piesa1[0][3] = 0;
piesa1[1][0] = 0; piesa1[1][1] = 0; piesa1[1][2] = 1; piesa1[1][3] = 0;
piesa1[2][0] = 0; piesa1[2][1] = 0; piesa1[2][2] = 1; piesa1[2][3] = 0;
piesa1[3][0] = 0; piesa1[3][1] = 0; piesa1[3][2] = 1; piesa1[3][3] = 0;
var piesa2 = Matrice(4, 4);
piesa2[0][0] = 0; piesa2[0][1] = 0; piesa2[0][2] = 0; piesa2[0][3] = 0;
piesa2[1][0] = 0; piesa2[1][1] = 1; piesa2[1][2] = 0; piesa2[1][3] = 0;
piesa2[2][0] = 0; piesa2[2][1] = 1; piesa2[2][2] = 1; piesa2[2][3] = 0;
piesa2[3][0] = 0; piesa2[3][1] = 1; piesa2[3][2] = 0; piesa2[3][3] = 0;
var piesa3 = Matrice(4, 4);
piesa3[0][0] = 0; piesa3[0][1] = 0; piesa3[0][2] = 0; piesa3[0][3] = 0;
piesa3[1][0] = 0; piesa3[1][1] = 0; piesa3[1][2] = 0; piesa3[1][3] = 0;
piesa3[2][0] = 0; piesa3[2][1] = 1; piesa3[2][2] = 1; piesa3[2][3] = 0;
piesa3[3][0] = 0; piesa3[3][1] = 1; piesa3[3][2] = 1; piesa3[3][3] = 0;
var piesa4 = Matrice(4, 4);
piesa4[0][0] = 0; piesa4[0][1] = 0; piesa4[0][2] = 0; piesa4[0][3] = 0;
piesa4[1][0] = 0; piesa4[1][1] = 1; piesa4[1][2] = 0; piesa4[1][3] = 0;
piesa4[2][0] = 0; piesa4[2][1] = 1; piesa4[2][2] = 0; piesa4[2][3] = 0;
piesa4[3][0] = 0; piesa4[3][1] = 1; piesa4[3][2] = 1; piesa4[3][3] = 0;
var piesa5 = Matrice(4, 4);
piesa5[0][0] = 0; piesa5[0][1] = 0; piesa5[0][2] = 0; piesa5[0][3] = 0;
piesa5[1][0] = 0; piesa5[1][1] = 1; piesa5[1][2] = 0; piesa5[1][3] = 0;
piesa5[2][0] = 0; piesa5[2][1] = 1; piesa5[2][2] = 1; piesa5[2][3] = 0;
piesa5[3][0] = 0; piesa5[3][1] = 0; piesa5[3][2] = 1; piesa5[3][3] = 0;
// Starile jocului:
var JOC_OPRIT = 0;
var GENEREAZA_PIESA = 1;
var COBOARA_PIESA = 2;
var JOC_TERMINAT = -1;
// VARIABILELE:
// Variabile ajutatoare:
var l;
var c;
// Tabla de joc:
var t = Matrice(17, 16);
l = 0;
while (l<17)
{
c = 0;
while (c<16)
{
if ( (c<3) || (c>12) || (l>13) )
{
t[l][c] = -1; // unde nu se poate gasi piesa
}
else
{
t[l][c] = 0;
}
c = c+1;
}
l = l+1;
}
// Piesa curenta:
var p = Matrice(4, 4);
p[0][0] = 0; p[0][1] = 0; p[0][2] = 0; p[0][3] = 0;
p[1][0] = 0; p[1][1] = 0; p[1][2] = 0; p[1][3] = 0;
p[2][0] = 0; p[2][1] = 0; p[2][2] = 0; p[2][3] = 0;
p[3][0] = 0; p[3][1] = 0; p[3][2] = 0; p[3][3] = 0;
// Coordonatele piesei:
var pl;
var pc;
// Starea jocului:
var stare_joc;
// FUNCTIILE
function FunctieTaste(ev)
{
var tasta = TastaApasata(ev);
if (tasta == 'a') // deplasare la stanga
{
if (stare_joc == COBOARA_PIESA)
{
LaStanga();
}
}
else if (tasta == 'd') // deplasare la dreapta
{
if (stare_joc == COBOARA_PIESA)
{
LaDreapta();
}
}
else if (tasta == 'o') // rotatie la stanga
{
if (stare_joc == COBOARA_PIESA)
{
//...
}
}
else if (tasta == 'p') //rotatie la dreapta
{
if (stare_joc == COBOARA_PIESA)
{
//...
}
}
else if (tasta == 'z') // pauza/repornire
{
if (stare_joc == COBOARA_PIESA)
{
Aprinde(0, 0, ALBASTRU);
stare_joc = JOC_OPRIT;
}
else if (stare_joc == JOC_OPRIT)
{
Aprinde(0, 0, ALB);
stare_joc = COBOARA_PIESA;
}
}
}
function FunctieDesenare()
{
if (TimpScurs(1000/4) == 1)
{
if (stare_joc == JOC_TERMINAT)
{
// Incheie programul:
Aprinde(0, 0, ROSU);
AscultaTaste();
StartAnimatie();
}
else if (stare_joc == JOC_OPRIT)
{
// Nu face nimic.
}
else if (stare_joc == COBOARA_PIESA)
{
CoboaraPiesa();
AfiseazaTabla();
}
else if (stare_joc == GENEREAZA_PIESA)
{
GenereazaPiesa();
}
}
Animeaza(FunctieDesenare);
}
function GenereazaPiesa()
{
// Alege aleator o piesa:
var aleator = NrAleator(4);
// Si pune-o in matricea "piesa":
var i = 0;
var j;
while (i<4)
{
j = 0;
while (j<4)
{
if (aleator == 0) p[i][j] = piesa1[i][j];
else if (aleator == 1) p[i][j] = piesa2[i][j];
else if (aleator == 2) p[i][j] = piesa3[i][j];
else if (aleator == 3) p[i][j] = piesa4[i][j];
else p[i][j] = piesa5[i][j];
j = j+1;
}
i = i+1;
}
// Si apoi pozitioneaz-o sus de tot:
pl = 0;
pc = 6;
// Pune piesa "piesa" pe tabla "t" la poztia ("pl", "pc"):
var ok = PunePiesa();
// Daca se suprapune, termina jocul:
if (ok == 0)
stare_joc = JOC_TERMINAT;
else
stare_joc = COBOARA_PIESA;
}
function PunePiesa()
{
// Intai verifica daca sunt suprapuneri:
var ok = 1;
var i = 0;
var j;
while (i<4)
{
j = 0;
while (j<4)
{
if ( (p[i][j] != 0) && (t[pl+i][pc+j] != 0) )
{
ok = 0;
}
j = j+1;
}
i = i+1;
}
// Daca sunt suprapuneri, returneaza ca e eroare -- 0:
if (ok == 0)
{
return 0;
}
// Altfel, pune piesa si returneaza ca e OK -- 1:
i = 0;
while (i<4)
{
j = 0;
while (j<4)
{
if (p[i][j] != 0)
{
t[pl+i][pc+j] = p[i][j];
}
j = j+1;
}
i = i+1;
}
return 1;
}
function RidicaPiesa()
{
var i = 0;
var j;
while (i<4)
{
j = 0;
while (j<4)
{
if (p[i][j] != 0)
{
t[pl+i][pc+j] = 0;
}
j = j+1;
}
i = i+1;
}
}
function CoboaraPiesa()
{
// Ridica piesa:
RidicaPiesa();
// Coboar-o cu o linie:
pl = pl+1;
var ok = PunePiesa();
// Daca se suprapune sau iese in afara:
if (ok == 0)
{
// Pune-o la loc:
pl = pl-1;
PunePiesa();
// Si genereaza o noua piesa:
stare_joc = GENEREAZA_PIESA;
}
}
function AfiseazaTabla()
{
var y = 1;
var x;
while (y <= 10)
{
x = 1;
while (x <= 10)
{
AprindeNrCul(x, y, t[14-y][2+x]);
x = x+1;
}
y = y+1;
}
}
function LaStanga()
{
// Ridica piesa:
RidicaPiesa();
// Mut-o la stanga cu o coloana:
pc = pc-1;
var ok = PunePiesa();
// Daca se suprapune sau iese in afara:
if (ok == 0)
{
// Pune-o la loc:
pc = pc+1;
PunePiesa();
}
else
{
AfiseazaTabla();
}
}
function LaDreapta()
{
// Ridica piesa:
RidicaPiesa();
// Mut-o la dreapta cu o coloana:
pc = pc+1;
var ok = PunePiesa();
// Daca se suprapune sau iese in afara:
if (ok == 0)
{
// Pune-o la loc:
pc = pc-1;
PunePiesa();
}
else
{
AfiseazaTabla();
}
}
// PROGRAMUL:
Aprinde(0, 0, ALB);
stare_joc = GENEREAZA_PIESA;
AscultaTaste(FunctieTaste);
StartAnimatie(FunctieDesenare);
Dupa cum poti vedea (daca apesi butonul “Reseteaza…” si apoi butonul “Executa…”), jocul nostru de Tetris a inceput sa prinda viata. 🙂
Momentan iti permite doar sa deplasezi piesa curenta la stanga (prin apasarea tastei ‘a’) sau la dreapta (prin apasarea tastei ‘d’) si piesele doar se aduna una peste alta pana cand se incheie jocul. (De asemenea, poti pune pauza prin apasarea tastei ‘z’.)
Mai e de lucru pana la a termina de programat un joc de Tetris valabil, dar am avansat mult in directia asta, nu crezi? Ce zici, te-ai incumeta sa faci liniile completate sa dispara? 🙂
Alatura-te celor peste 2000 de oameni din armata noastra de creiere cu muschi si vei primi testul care iti va spune daca ai sau nu minte de programator:
Cu drag,
Florin