Tetris v HTML5 – II. Herná logika 1/4
V druhom diely tohto seriálu začneme s implementáciou hernej logiky.
Keďže nemá zmysel opätovne „objavovať koleso“, tak určitá časť hernej logiky bude prevzatá z predchádzajúceho seriálu o hre Snake (> link <), keďže technické riešenie oboch hier veľmi podobné. V oboch hrách je herné pole zložené z určitého počtu pozícii, ktoré môžu mať vopred určené stavy a herná logika sa odvíja od týchto stavov. V hre Snake boli tieto stavy 3: prázdne pole, časť hada a potrava, no v Tetrise si vystačíme so stavom prázdne pole a pole s dielikom. Teoreticky by na tieto stavy stačilo použiť boolean ( true/false, 1/0), avšak takto sa dá herná logika rozšíriť o ďalšie možnosti (napríklad nejaké špeciálne typy dielikov a pod).Nasledujúce úpravy budeme robiť v súbore main.js.Začneme definovaním enumerátov pred objekt Game.
Kód zabezpečí vytvorenie hracej plochy a jej následné nakreslenie. V úvode si poznačíme aktuálny dátum a čas do premennej LastUpdate. Tento údaj budeme neskôr potrebovať na výpočet času na aktualizáciu hry.Pre kontrolu si projekt uložíme a spustíme v prehliadači. V prípade, ak sme sa nikde nepomýlili by ste mali vidieť prázdnu hraciu plochu.Na prázdnej hracej ploche si veľa nezahráme, čiže nastal čas pridať hracie kocky. Hraciu kocku nám bude reprezentovať objekt Piece, ktorý bude obsahovať informáciu o jej šírke, dĺžke, pozícii na hracej ploche, farbe (resp o obrázku z ktorého je poskladaná) a o jednotlivých dielikoch, ktoré hraciu kocku tvoria. Na vytvorenie všeobecného objektu Piece vytvoríme funkciu CreatePiece.
Pokračujeme pridaním funkcií DrawPiece, PlacePiece, a NewPiece. DrawPiece bude slúžiť na vykreslenie objektu Piece na hernú plochu. Na základe pozície kocky vyráta pozície jej jednotlivých dielikov a vyplní ich príslušnou farbou, resp. jej obrázkom. PlacePiece sa postará o dátové umiestnenie kocky do hry, konkrétne výpočet jej úvodnej pozície, priradenie referencie do premennej ActivePiece a zavolanie DrawPiece). Tretia v poradí NewPiece bude volaná zo všetkých miest v programe, kde bude požadované vloženie ďalšej kocky do hry. Vyberie náhodnú kocku a pomocou PlacePiece ju umiestni na plochu (Neskôr si jej funkčnosť ešte rozšírime). Volanie funkcie NewPiece vložíme aj na koniec NewGame
Po uložení projektu a zobrazení stránky v prehliadači, by sa v hornej časti hracej plochy mala objaviť náhodná kocka náhodnej farby. Funkčnost náhodnosti môžeme vyskúšať aj viacnásobným refresh-om stránky.V nasledujúcom diely seriálu budeme pokračovať s hernou logikou, rozpohybujeme kocky, pridáme detekciu kolízie a rotáciu kocky.
Ostatné texty v seriály
Zdrojový kód:
var FieldStates = {
fs_Empty: 0,
fs_Block: 1
};var GameStates = {
gs_Stop: 0,
gs_Play: 1,
gs_Loading: 2
};var Game = {
...
}
FieldStates reprezentuje stavy políčka a GameStates zase stavy hry, pričom gs_Loading bude použitý len pri prvotnom nahrávaní hry.Pre lepšiu prehľadnosť kódu, si objekte Game vytvoríme 3 skupiny premenných (pomocou komentárov „Nastavenia“, „Herne premenne“, „Obrazky“), do ktorých budeme vkladať jednotlivé premenné, podľa skupiny do ktorej patria.fs_Empty: 0,
fs_Block: 1
};var GameStates = {
gs_Stop: 0,
gs_Play: 1,
gs_Loading: 2
};var Game = {
...
}
Zdrojový kód:
var Game = { /* Nastavenia */ //Rozmery hracieho pola (pocet policok, nie px)
GameArrayWidth: 10,
GameArrayHeight: 20, GameFieldWidth: 25, //Velkost jedneho policka
BorderWidth: 2, //Hrubka oramovania hracieho pola BackColor: '#000000', //Farba pozadia
BorderColor: '#303030', //Farba oramovania //Rozmery hracej plochy (v px)
GameAreaWidth: 263,
GameAreaHeight: 523,
/* / Nastavenia */ /* Herne premenne */
Canvas: null,
Context: null, //Kresliaca plocha
ActivePiece: null, //Aktivna kocka
NextPiece: null, //Nasledujuca kocka
LastUpdate: null, //Cas poslednej aktualizacie hry
LastRandomNumber: -1, //Posledne vratene nahodne cislo //Rozmery kresliacej plochy
ContextWidth: 0,
ContextHeight: 0, Status: GameStates.gs_Loading, //Status hry
GameArray: null, //Herne pole
ItemsToLoad: 0, //Pocet poloziek, ktore sa este nacitavaju
/* /Herne premenne */ /* Obrazky */
img_empty: null, //Prazde policko
img_colors: [], //Farebne kocky
/* /Obrazky */
...
}
V predchádzajúcom kóde sme si už zadefinovali niektoré z premenných, ktoré budeme ďalej používať. Ku každej premennej je pridaný aj komentár, čiže zatiaľ ich bližšie popisovať netreba. Ďalej si zadefinujeme funkciu KeyDown, ktorá bude slúžiť ako event handler na stlačené klávesy. V jej tele bude switch, ktorým si odchytíme len nami požadované klávesy (šípky, medzerník a enter) a zablokujeme ich ďalšie spracovanie v prehliadači cez funkciu preventDefault.GameArrayWidth: 10,
GameArrayHeight: 20, GameFieldWidth: 25, //Velkost jedneho policka
BorderWidth: 2, //Hrubka oramovania hracieho pola BackColor: '#000000', //Farba pozadia
BorderColor: '#303030', //Farba oramovania //Rozmery hracej plochy (v px)
GameAreaWidth: 263,
GameAreaHeight: 523,
/* / Nastavenia */ /* Herne premenne */
Canvas: null,
Context: null, //Kresliaca plocha
ActivePiece: null, //Aktivna kocka
NextPiece: null, //Nasledujuca kocka
LastUpdate: null, //Cas poslednej aktualizacie hry
LastRandomNumber: -1, //Posledne vratene nahodne cislo //Rozmery kresliacej plochy
ContextWidth: 0,
ContextHeight: 0, Status: GameStates.gs_Loading, //Status hry
GameArray: null, //Herne pole
ItemsToLoad: 0, //Pocet poloziek, ktore sa este nacitavaju
/* /Herne premenne */ /* Obrazky */
img_empty: null, //Prazde policko
img_colors: [], //Farebne kocky
/* /Obrazky */
...
}
Zdrojový kód:
var Game = {
...
KeyDown: function (e)
{
switch (e.keyCode)
{
case 13: //Enter - Restart game
{
e.preventDefault();
}
break;
case 38: //Up - Rotate
{
e.preventDefault();
}
break;
case 40: //Down
{
e.preventDefault();
}
break;
case 37: //Left
{
e.preventDefault();
}
break;
case 39: //Right
{
e.preventDefault();
}
break;
case 32: //SpaceBar
{
e.preventDefault();
}
break;
}
}
}
Z projektu Snake si požičiame funkcie CreateImage, ImageLoaded a CheckLoadedFiles, ktoré nám slúžia na načítanie obrázkov do projektu. CreateImage túto akciu inicializuje a ImageLoaded je volaná po jej úspešnom dokončení, pričom zvyšujú a znižujú hodnotu premennej ItemsToLoad v objekte Game, ktorá slúži ako indikátor načítania všetkých súborov do hry. Funkcia CheckLoadedFiles nakoniec skontroluje, či je všetko už načítané a ak áno, hra sa spustí cez funkciu NewGame ktorá bude zatiaľ obsahovať len jednoduchý alert....
KeyDown: function (e)
{
switch (e.keyCode)
{
case 13: //Enter - Restart game
{
e.preventDefault();
}
break;
case 38: //Up - Rotate
{
e.preventDefault();
}
break;
case 40: //Down
{
e.preventDefault();
}
break;
case 37: //Left
{
e.preventDefault();
}
break;
case 39: //Right
{
e.preventDefault();
}
break;
case 32: //SpaceBar
{
e.preventDefault();
}
break;
}
}
}
Zdrojový kód:
CreateImage: function (FileName)
{
var img = new Image();
this.ItemsToLoad++;
img.src = "imgs/" + FileName + ".png";
img.onload = this.ImageLoaded;
return img; },
ImageLoaded: function ()
{
this.onload = null;
Game.ItemsToLoad--;
Game.CheckLoadedFiles();
},
CheckLoadedFiles: function ()
{
if (Game.ItemsToLoad <= 0)
{
this.NewGame();
}
},
NewGame: function ()
{
alert('New game');
},
Funkcie na načítanie obrázkov do hry už máme, môžeme ich teda do hry pridať. Z nasledujúcej linky > link < si môžete stiahnuť potrebné obrázky a rozbaliť ich do priečinka imgs v našom projekte. Jedná sa o obrázky políčka hracej plochy. Konkrétne empty.png reprezentuje prázdne políčko a ostatné (blue, brown, green, purple, red a yellow) sú znakom plného políčka.Určite ste si všimli, že podľa obrázkov môže byť políčko vykreslené až siedmimi obrázkami, no v enumeráte FieldStates sú len 2 možné hodnoty. Nie je to chyba, keďže z pohľadu hernej logiky je nepodstatné akou farbou je políčko vyplnené. Dôležitá je len informácia, či je políčko vyplnené alebo nie.Na načítanie jednotlivých obrázkov pridáme funkciu LoadImages{
var img = new Image();
this.ItemsToLoad++;
img.src = "imgs/" + FileName + ".png";
img.onload = this.ImageLoaded;
return img; },
ImageLoaded: function ()
{
this.onload = null;
Game.ItemsToLoad--;
Game.CheckLoadedFiles();
},
CheckLoadedFiles: function ()
{
if (Game.ItemsToLoad <= 0)
{
this.NewGame();
}
},
NewGame: function ()
{
alert('New game');
},
Zdrojový kód:
LoadImages: function ()
{
this.img_empty = this.CreateImage("empty"); //Nacitanie farebnych kociek
this.img_colors[0] = this.CreateImage("blue");
this.img_colors[1] = this.CreateImage("brown");
this.img_colors[2] = this.CreateImage("green");
this.img_colors[3] = this.CreateImage("purple");
this.img_colors[4] = this.CreateImage("red");
this.img_colors[5] = this.CreateImage("yellow"); },
Obrázky už máme načítane, no nemáme ich ešte kde vykresľovať. Pridáme preto funkciu LoadCanvas v ktorej si načítame objekt canvasu, vytvoríme kresliaci context a odpamätáme ich rozmery.{
this.img_empty = this.CreateImage("empty"); //Nacitanie farebnych kociek
this.img_colors[0] = this.CreateImage("blue");
this.img_colors[1] = this.CreateImage("brown");
this.img_colors[2] = this.CreateImage("green");
this.img_colors[3] = this.CreateImage("purple");
this.img_colors[4] = this.CreateImage("red");
this.img_colors[5] = this.CreateImage("yellow"); },
Zdrojový kód:
LoadCanvas: function ()
{
this.Canvas = document.getElementById('gamecanvas');
this.Context = this.Canvas.getContext("2d"); // Odpamatame si rozmery kresliacej plochy
this.ContextWidth = this.Canvas.offsetWidth;
this.ContextHeight = this.Canvas.offsetHeight;
},
Vrátime sa na moment k funkcii LoadGame kde nahradíme alert za volania doteraz vytvorených funkcii:{
this.Canvas = document.getElementById('gamecanvas');
this.Context = this.Canvas.getContext("2d"); // Odpamatame si rozmery kresliacej plochy
this.ContextWidth = this.Canvas.offsetWidth;
this.ContextHeight = this.Canvas.offsetHeight;
},
Zdrojový kód:
LoadGame: function ()
{
//Event listener na stlacene klavesy
window.addEventListener('keydown', this.KeyDown); //Nacitanie obrazkov
this.LoadImages(); //Inicializacia kresliaceho prostredia
this.LoadCanvas(); //Skontrolujeme ci uz nebolo vsetko nahrate
this.CheckLoadedFiles();
}
Súbor game.js môžeme uložiť a stránku index.html môžeme spustiť v prehliadači. Ak sme urobili všetko správne, malo by sa nám po spustení stránky zobraziť hlásenie „New game“. Týmto sme si potvrdili že skript funguje a obrázky sa podarilo načítať.Nasleduje inicializácia herného pola, ktoré nám reprezentuje premenná GameArray. Vytvoríme si funkcie CreateGameArray a CreateEmptyLine.{
//Event listener na stlacene klavesy
window.addEventListener('keydown', this.KeyDown); //Nacitanie obrazkov
this.LoadImages(); //Inicializacia kresliaceho prostredia
this.LoadCanvas(); //Skontrolujeme ci uz nebolo vsetko nahrate
this.CheckLoadedFiles();
}
Zdrojový kód:
CreateGameArray: function ()
{
var i, j; this.GameArray = [];
for (i = 0; i < this.GameArrayHeight; i++)
{
this.GameArray[i] = this.CreateEmptyLine();
}
},
CreateEmptyLine: function ()
{
var ret = [];
for (var j = 0; j < this.GameArrayWidth; j++)
{
ret[j] = FieldStates.fs_Empty;
} return ret;
}
Kód funkcie CreateEmptyLine budeme potrebovať aj na iných miestach, preto je definovaná samostatne.Hracie pole máme definované, teraz si ho musíme aj nakresliť. Nakreslíme ho pomocou funkcie DrawGameField, ktorá najskôr vyčistí kresliacu plochu, farebne oddelí hraciu plochu (vytvorí obdĺžnik hernej plochy, ktorý bude neskôr slúžiť aj ako orámovanie) a nakoniec nakreslí samotné políčka. Na nakreslenie jednotlivých políčok bude slúžiť funkcia DrawBlock, ktorú použijeme aj všade tam, kde bude potrebné políčka aktualizovať. Na výpočet vizuálnej pozície políčka na kresliacej ploche použijeme vzorec: [Reálna pozícia] = [Šírka orámovania] + [pozícia v GameArray] * [Vizuálna šírka hracieho políčka] + [pozícia v GameArray] . Pozícia v GameArray je vo vzorci 2x, nakoľko medzi jednolivými políčkami nechávame 1px medzeru. Tento vzorec zapíšeme do funkcie GetRealPosition.{
var i, j; this.GameArray = [];
for (i = 0; i < this.GameArrayHeight; i++)
{
this.GameArray[i] = this.CreateEmptyLine();
}
},
CreateEmptyLine: function ()
{
var ret = [];
for (var j = 0; j < this.GameArrayWidth; j++)
{
ret[j] = FieldStates.fs_Empty;
} return ret;
}
Zdrojový kód:
DrawGameField: function ()
{
//Vyplnenie celej plochy farbou pozadia
this.Context.fillStyle = this.BackColor;
this.Context.fillRect(0, 0, this.ContextWidth, this.ContextHeight); //Vyplnenie hernej plochy farbou oramovania
this.Context.fillStyle = this.BorderColor;
this.Context.fillRect(0, 0, this.GameAreaWidth, this.GameAreaHeight); //Nakreslenie jednotlivych policok
for (var i = 0; i < this.GameArrayHeight; i++)
{
for (var j = 0; j < this.GameArrayWidth; j++)
{
this.DrawBlock(i, j, this.img_empty);
}
}
},
GetRealPosition: function (pos)
{
return this.BorderWidth + pos * this.GameFieldWidth + pos;
},
DrawBlock: function (top, left, color)
{
var RealLeft = this.GetRealPosition(left);
var RealTop = this.GetRealPosition(top);
this.Context.drawImage(color, RealLeft, RealTop);
},
Na moment sa vrátime k funkcii NewGame do ktorej pridáme nasledujúci kód.{
//Vyplnenie celej plochy farbou pozadia
this.Context.fillStyle = this.BackColor;
this.Context.fillRect(0, 0, this.ContextWidth, this.ContextHeight); //Vyplnenie hernej plochy farbou oramovania
this.Context.fillStyle = this.BorderColor;
this.Context.fillRect(0, 0, this.GameAreaWidth, this.GameAreaHeight); //Nakreslenie jednotlivych policok
for (var i = 0; i < this.GameArrayHeight; i++)
{
for (var j = 0; j < this.GameArrayWidth; j++)
{
this.DrawBlock(i, j, this.img_empty);
}
}
},
GetRealPosition: function (pos)
{
return this.BorderWidth + pos * this.GameFieldWidth + pos;
},
DrawBlock: function (top, left, color)
{
var RealLeft = this.GetRealPosition(left);
var RealTop = this.GetRealPosition(top);
this.Context.drawImage(color, RealLeft, RealTop);
},
Zdrojový kód:
NewGame: function ()
{
this.LastUpdate = new Date(); //Vycistit hracie pole
this.CreateGameArray(); //Nakreslit hracie pole
this.DrawGameField();
},
{
this.LastUpdate = new Date(); //Vycistit hracie pole
this.CreateGameArray(); //Nakreslit hracie pole
this.DrawGameField();
},
Prázdna hracia plocha
Zdrojový kód:
CreatePiece: function (width, height, color)
{
var Ret = {Left: 0, Top: 0, Width: width, Height: height, Color: color, Blocks: []}; Ret.Blocks = [];
for (var i = 0; i < height; i++)
{
Ret.Blocks[i] = [];
for (var j = 0; j < width; j++)
{
Ret.Blocks[i][j] = FieldStates.fs_Empty;
}
} return Ret;
},
Kocka vytvorená touto funkciou má informáciu o svojich rozmeroch a farbe. Ostatné jej vlastnosti je potrebné zadefinovať pre každý typ kocky zvlášť. Preto vytvoríme pre každý typ kocky samostatnú inicializačnú funkciu, ktorá bude volať CreatePiece a následne doplní informáciu o rozmiestnení dielikov. Údaje o pozícii sa budú dynamicky meniť, preto sa budú nastavovať v menej všeobecných funkciách.{
var Ret = {Left: 0, Top: 0, Width: width, Height: height, Color: color, Blocks: []}; Ret.Blocks = [];
for (var i = 0; i < height; i++)
{
Ret.Blocks[i] = [];
for (var j = 0; j < width; j++)
{
Ret.Blocks[i][j] = FieldStates.fs_Empty;
}
} return Ret;
},
Zdrojový kód:
Create_L_Piece: function (color)
{
var piece = this.CreatePiece(3, 2, color);
piece.Blocks[0][0] = FieldStates.fs_Block;
piece.Blocks[0][1] = FieldStates.fs_Block;
piece.Blocks[0][2] = FieldStates.fs_Block;
piece.Blocks[1][0] = FieldStates.fs_Block;
return piece;
},
Create_J_Piece: function (color)
{
var piece = this.CreatePiece(3, 2, color);
piece.Blocks[0][0] = FieldStates.fs_Block;
piece.Blocks[0][1] = FieldStates.fs_Block;
piece.Blocks[0][2] = FieldStates.fs_Block;
piece.Blocks[1][2] = FieldStates.fs_Block;
return piece;
},
Create_T_Piece: function (color)
{
var piece = this.CreatePiece(3, 2, color);
piece.Blocks[0][0] = FieldStates.fs_Block;
piece.Blocks[0][1] = FieldStates.fs_Block;
piece.Blocks[0][2] = FieldStates.fs_Block;
piece.Blocks[1][1] = FieldStates.fs_Block;
return piece;
},
Create_O_Piece: function (color)
{
var piece = this.CreatePiece(2, 2, color);
piece.Blocks[0][0] = FieldStates.fs_Block;
piece.Blocks[0][1] = FieldStates.fs_Block;
piece.Blocks[1][0] = FieldStates.fs_Block;
piece.Blocks[1][1] = FieldStates.fs_Block;
return piece;
},
Create_I_Piece: function (color)
{
var piece = this.CreatePiece(4, 1, color);
piece.Blocks[0][0] = FieldStates.fs_Block;
piece.Blocks[0][1] = FieldStates.fs_Block;
piece.Blocks[0][2] = FieldStates.fs_Block;
piece.Blocks[0][3] = FieldStates.fs_Block;
return piece;
},
Create_S_Piece: function (color)
{
var piece = this.CreatePiece(3, 2, color);
piece.Blocks[0][1] = FieldStates.fs_Block;
piece.Blocks[0][2] = FieldStates.fs_Block;
piece.Blocks[1][0] = FieldStates.fs_Block;
piece.Blocks[1][1] = FieldStates.fs_Block;
return piece;
},
Create_Z_Piece: function (color)
{
var piece = this.CreatePiece(3, 2, color);
piece.Blocks[0][0] = FieldStates.fs_Block;
piece.Blocks[0][1] = FieldStates.fs_Block;
piece.Blocks[1][1] = FieldStates.fs_Block;
piece.Blocks[1][2] = FieldStates.fs_Block;
return piece;
},
Funkcie na vytvorenie kociek máme, potrebujeme ešte zabezpečiť, aby nám ich hra vytvárala v náhodnom poradí a v náhodnej farbe. JavaScript poskytuje funkciu Math.random(), ktorá vygeneruje náhodné desatinné číslo od 0 (vrátane) do 1. Čiže vrátené číslo môže byť napríklad 0,56934718. V prípade, ak potrebujeme náhodné číslo bez desatinných miest (Integer) a v nejakom vopred určenom rozsahu, môžeme použiť vzorec: [Náhodné číslo] = [Minimálna hodnota] + Math.floor(Math.random() * ([Maximálna hodnota] + 1)) .Avšak, tu som narazil na problém… Hodnoty, ktoré boli vrátené týmto spôsobom sa veľmi často opakovali. Preto si poslednú vrátenú hodnotu budeme pamätať a nedovolíme ju opäť vrátiť.Na výber náhodného čísla vytvoríme funkciu Random a použijeme ju vo funkcii Create_Random_Piece ktorá nám pomocou nej vytvorí náhodný typ kocky v náhodnej farbe.{
var piece = this.CreatePiece(3, 2, color);
piece.Blocks[0][0] = FieldStates.fs_Block;
piece.Blocks[0][1] = FieldStates.fs_Block;
piece.Blocks[0][2] = FieldStates.fs_Block;
piece.Blocks[1][0] = FieldStates.fs_Block;
return piece;
},
Create_J_Piece: function (color)
{
var piece = this.CreatePiece(3, 2, color);
piece.Blocks[0][0] = FieldStates.fs_Block;
piece.Blocks[0][1] = FieldStates.fs_Block;
piece.Blocks[0][2] = FieldStates.fs_Block;
piece.Blocks[1][2] = FieldStates.fs_Block;
return piece;
},
Create_T_Piece: function (color)
{
var piece = this.CreatePiece(3, 2, color);
piece.Blocks[0][0] = FieldStates.fs_Block;
piece.Blocks[0][1] = FieldStates.fs_Block;
piece.Blocks[0][2] = FieldStates.fs_Block;
piece.Blocks[1][1] = FieldStates.fs_Block;
return piece;
},
Create_O_Piece: function (color)
{
var piece = this.CreatePiece(2, 2, color);
piece.Blocks[0][0] = FieldStates.fs_Block;
piece.Blocks[0][1] = FieldStates.fs_Block;
piece.Blocks[1][0] = FieldStates.fs_Block;
piece.Blocks[1][1] = FieldStates.fs_Block;
return piece;
},
Create_I_Piece: function (color)
{
var piece = this.CreatePiece(4, 1, color);
piece.Blocks[0][0] = FieldStates.fs_Block;
piece.Blocks[0][1] = FieldStates.fs_Block;
piece.Blocks[0][2] = FieldStates.fs_Block;
piece.Blocks[0][3] = FieldStates.fs_Block;
return piece;
},
Create_S_Piece: function (color)
{
var piece = this.CreatePiece(3, 2, color);
piece.Blocks[0][1] = FieldStates.fs_Block;
piece.Blocks[0][2] = FieldStates.fs_Block;
piece.Blocks[1][0] = FieldStates.fs_Block;
piece.Blocks[1][1] = FieldStates.fs_Block;
return piece;
},
Create_Z_Piece: function (color)
{
var piece = this.CreatePiece(3, 2, color);
piece.Blocks[0][0] = FieldStates.fs_Block;
piece.Blocks[0][1] = FieldStates.fs_Block;
piece.Blocks[1][1] = FieldStates.fs_Block;
piece.Blocks[1][2] = FieldStates.fs_Block;
return piece;
},
Zdrojový kód:
Random: function (min, max)
{
var Ret = -1;
do
{
Ret = min + Math.floor(Math.random() * (max + 1));
} while (Ret === this.LastRandomNumber) this.LastRandomNumber = Ret; return Ret;
},
//Vygenerovat nahodnu kocku s nahodnou farbou
Create_Random_Piece: function ()
{
//Typ kocky
var pType = this.Random(0, 6);
//Index farby
var pColor = this.img_colors[this.Random(0, this.img_colors.length - 1)]; switch (pType)
{
default:
case 0:
{
return this.Create_L_Piece(pColor);
}
break;
case 1:
{
return this.Create_J_Piece(pColor);
}
break;
case 2:
{
return this.Create_T_Piece(pColor);
}
break;
case 3:
{
return this.Create_O_Piece(pColor);
}
break;
case 4:
{
return this.Create_I_Piece(pColor);
}
break;
case 5:
{
return this.Create_S_Piece(pColor);
}
break;
case 6:
{
return this.Create_Z_Piece(pColor);
}
break;
}
},
{
var Ret = -1;
do
{
Ret = min + Math.floor(Math.random() * (max + 1));
} while (Ret === this.LastRandomNumber) this.LastRandomNumber = Ret; return Ret;
},
//Vygenerovat nahodnu kocku s nahodnou farbou
Create_Random_Piece: function ()
{
//Typ kocky
var pType = this.Random(0, 6);
//Index farby
var pColor = this.img_colors[this.Random(0, this.img_colors.length - 1)]; switch (pType)
{
default:
case 0:
{
return this.Create_L_Piece(pColor);
}
break;
case 1:
{
return this.Create_J_Piece(pColor);
}
break;
case 2:
{
return this.Create_T_Piece(pColor);
}
break;
case 3:
{
return this.Create_O_Piece(pColor);
}
break;
case 4:
{
return this.Create_I_Piece(pColor);
}
break;
case 5:
{
return this.Create_S_Piece(pColor);
}
break;
case 6:
{
return this.Create_Z_Piece(pColor);
}
break;
}
},
Pokračujeme pridaním funkcií DrawPiece, PlacePiece, a NewPiece. DrawPiece bude slúžiť na vykreslenie objektu Piece na hernú plochu. Na základe pozície kocky vyráta pozície jej jednotlivých dielikov a vyplní ich príslušnou farbou, resp. jej obrázkom. PlacePiece sa postará o dátové umiestnenie kocky do hry, konkrétne výpočet jej úvodnej pozície, priradenie referencie do premennej ActivePiece a zavolanie DrawPiece). Tretia v poradí NewPiece bude volaná zo všetkých miest v programe, kde bude požadované vloženie ďalšej kocky do hry. Vyberie náhodnú kocku a pomocou PlacePiece ju umiestni na plochu (Neskôr si jej funkčnosť ešte rozšírime). Volanie funkcie NewPiece vložíme aj na koniec NewGame
Zdrojový kód:
NewGame: function ()
{
...
//Nova kocka na plochu
this.NewPiece();
},
DrawPiece: function (piece)
{
var Left = 0;
var Top = 0; for (var i = 0; i < piece.Height; i++)
{
for (var j = 0; j < piece.Width; j++)
{
var FieldType = piece.Blocks[i][j]; Top = piece.Top + i;
Left = piece.Left + j; if (FieldType === FieldStates.fs_Block)
{
this.DrawBlock(Top, Left, piece.Color);
}
}
}
},
PlacePiece: function (Piece)
{
var Left = Math.floor(this.GameArrayWidth / 2 - Piece.Width / 2);
var Top = 0;
Piece.Left = Left;
Piece.Top = Top; this.ActivePiece = Piece;
this.DrawPiece(Piece); },
NewPiece: function ()
{
var NewPiece = this.Create_Random_Piece();
this.PlacePiece(NewPiece);
}
{
...
//Nova kocka na plochu
this.NewPiece();
},
DrawPiece: function (piece)
{
var Left = 0;
var Top = 0; for (var i = 0; i < piece.Height; i++)
{
for (var j = 0; j < piece.Width; j++)
{
var FieldType = piece.Blocks[i][j]; Top = piece.Top + i;
Left = piece.Left + j; if (FieldType === FieldStates.fs_Block)
{
this.DrawBlock(Top, Left, piece.Color);
}
}
}
},
PlacePiece: function (Piece)
{
var Left = Math.floor(this.GameArrayWidth / 2 - Piece.Width / 2);
var Top = 0;
Piece.Left = Left;
Piece.Top = Top; this.ActivePiece = Piece;
this.DrawPiece(Piece); },
NewPiece: function ()
{
var NewPiece = this.Create_Random_Piece();
this.PlacePiece(NewPiece);
}
Náhodná kocka v hernom poli
Tetris v HTML5 – I. Popis riešenia a základná konštrukcia | 0 |
Tetris v HTML5 – II. Herná logika 1/4 | 0 |
Tetris v HTML5 – III. Herná logika 2/4 | 0 |
... | |
Tetris v HTML5 – V. Herná logika 4/4 | 2 |
Žiadne príspevky v diskusii.
Na prispievanie do diskusie musíte byť prihlásený.