You are on page 1of 28

Hng Dn Vit Game TETRIS

n Gin
Vi Ngn Ng C/C++ Trn DOS

Xin cho cc bn!


Chc hn chng ta cng s c ngi am m lm game v cng mun mnh c th vit c
1 hoc nhiugame ,nhng khi u nh th no? ,cch lm ra sao?,cn nhng kin thc j khi
lm game? . lm c nhng game ln,hay,p v giao din th cc bn c th bt u lm
vi nhng game nh, n gin .Mnh chc rng lm nh vy th k nng vit code ca bn s
tng rt nhanh v bn s t tin hn khi lm 1 game hay 1 chng trnh tng i ln.
Ci ny th theo kinh nghim ca mnh th rt ng.Ngi ta thng ni nng nht ,cht b
sing nng tch cp nhng kin thc nh s c ngy bn nhn ra gi tr ca nhng g bn
thn hc c.Mnh cng khng gii giang j c cng ch l 1 thng IT bnh thng,nhng bt
chc chu nn mun chia s t kinh nghim vit game n gin cho cc bn newbie(ch cc
pro th em khng dm ma my u )

Writer: tauit_dnmd
Email:tauit.dnmd@gmail.com.
Uitstudent.com & congdongcviet.com

Li ni u
Trong Tut ny mnh s hng dn cho cc bn chi tit cch lm game Xp Gch trn Dos
nh th no: t m t game chn cu trc d liucode hon chnh.
Ti sao mnh li bt u vi game trn DOS (mn hnh console) ? Ti v: mnh mun ai cng
c th c hiu c ci TUT ny ,v lm trn DOS ri th chuyn qua lm c giao din th rt
n gin.Mnh cng code game ny trn Dos v Winform(vi C#).Code demo trn C/C++
ca game ny mnh ly li ca mnh code hi mi hc C/C++ nn c th n khng c hay v
chun cho lm(v mi hc th ai m ch g.hihihi).
. tin v thun li khi theo di Tut ny cc bn cn phi bit cch hot ng v cch
chi game Xp Gch (Tetris) Loi n gin y(V tetris c rt nhiu bin th v lut chi
khc nhau).
hiu r lut ca game cc bn ti ci ny v chi l hiu :
+DOS version:
+Winform version(C#+GDI+):
-Mnh vit trn Complier l Microsoft Visual Studio 2008 nn 1 s hm ch c BC,TC s
khng xi c nn mnh s dng 1 th vin ngoi (ngi ta vit li 1 s hm m t cn
dng) .Cc hm c cha trong file support.cpp.

I/ Tm hiu cu trc game.


-Lut l ca game m mnh s trnh by:
+ Game m phng game Xp Gch (Tetris),nhim v ca ngi chi l di chuyn cc
khi gch ang ri t t xung trong kch thc hnh ch nht 18 hng x 10 ct(trn mn
hnh).Ch no c gch ri th khng di chuyn c ti v tr .
+Ngi chi c gng xp c nhng hng y nhng vin gch .Nu xp c 1
hng s c cng im v hng s b xa .
+Nu khi gch khng th rt xung c na th nu m vn cha hin ht ra mn
hnh th ngi chi s thua
-Chng ta s i xem ci game Tetris c nhng j no? Cch qun l ra sao?.Cc bn coi s ci
ny

Ci giao din chi game ,cc bn c th thy n c chia ra thnh tng vung nh ,v c tt
c l 18x10 nh th, v cc bn c th thy rng cc c th c vung hoc khng c
vung. Thc ra kch thc mn hnh chi game ny khng phi c nh,ngi vit game c
th chn 1 kch thc khc cng c.Nhng y t chn dng 18 x 10.
Nh vy lu trng thi ca tr chi ta tm thi c th dng 1 mng 2 chiu kch

thc 18x10 (18 hng x 10 ct).Khi xt n im hay cht(gameover) ta ch cn xt


trn ma trn Board ny thi.
VD: int Board[18][10];
-

Mi Board[i][j] s i din cho 1 vung nh v cha gi tr 0 hoc 1 :


+0 : cha c vung nh no .
+1: c vung nh .

V d vi ci hnh demo di y :

Nhng bn cng thy rng ,c lc khi gch ca chng ta hin c 1 phn ln ma trn kch
thc 18x10 (18 hng x 10 ct) thi ng khng no?
VD: Ta c khi hnh vung mi ch hin ra 1 na trn ma trn thi:

Vy 1 na trn u? Ta bit mng khng c ch s m ng khng no.Thc cht , d


qun l th mnh s chn thm 4 hng v na ngha l thay v dng ma trn Board[18][10] th
dng ma trn Board[22][10].Khi 4 hng u tin (0->3) c dng lm v tr tm cho cc
khi gch-cc phn ca khi gch m nm trong khu vc 4 hng u tin s khng c v ln
mn hnh game.

-Vy th ngha ma trn sau khi iu chnh l.

Kt lun:
+Vy qun l t s dng 1 ma trn 2 chiu kch thc 22x10 (22 hng x10 ct) Vi
ngha t gii thch trn.
+V gi tr ca ma trn Board ch c thit lp khi 1 khi gch khng th ri xung
c na.Cn trong qu trnh khi gch ri th gi tr ca ma trn ti khng thay i (vn
l 0)

*Qun l khi gch:


-Chng ta bit game Xp Gch c 7 loi hnh : vung,ch Z,hnh ch L,thng
ng(ging cy gy)Ta thy mi khi gch c cu to t 4 hnh vung nh xp li vi
nhau.Ta c th coi cc khi gch nh l nhng hnh ch nht c kch thc khc nhau.
Da vo kch thc khi m mnh s chia thnh 3 loi khi c bn:

-Cc hnh khc c to ra khi xoay cc khi c bn ny cc gc tng ng 90o, 180o ,


270o.Khi xoay th c ngha ta s xoay ma trn trng thi 1 gc 90o .
V vy d qun l cc khi cng nh xy dng cc phng thc xoay khi chng ta s
dng mt ma trn c kch thc Row x Col (Row hng x Col ct) xc nh hnh dng hin
ti ca mt khi - gi l Ma Trn Trng Thi . tit kim th mnh s dng b nh ng :
VD: int **arr;
chng hn,khi cn kch thc bao nhiu th ta cp pht by nhiu.V nh gii phng b nh
khi khng cn xi na.
- Mt khi gch,gi tr ca ma trn trng thi c xc nh l v tr no l gch s c nh
s 1, khng c gch nh s 0.
VD:

Khi trn s c biu din bng ma trn trng thi nh sau: vi Row=2 v Col=3

Nguyn l khi to khi gch:

-S dng nguyn l x l bit xy dng. Ma trn trng thi s c trng cho khi gch.
to ma trn trng thi cho tng khi gch ta s dng php x l bit, s dng (Row x Col) bit
c nh s t bt cao nht t tri qua phi v t trn xung di xc nh khi.
V d:
5

Khi 2x3 th ta x l trn 2x3=6 bit.


0

S tng ng vi chui nh phn 011110 v gi tr ca chui ny l 30.


Khi:

S tng
ca chui ny l 51.

ng vi chui nh phn 110011 v gi tr

Khi:

S tng ng
chui ny l 57.

vi chui nh phn 111001 v gi tr ca

Khi:

S tng
chui ny l 58.

ng vi chui nh phn 111010 v gi tr ca

Khi:
1

S tng ng vi chui nh phn 111100 v gi tr ca chui ny l 60.


Khi:

S quy nh l
biu din v lc

1111 cho phn bit ch khng mang gi tr


x l s x l ring cho khi ny.

Khi:

S quy nh l 11111 cho phn bit ch khng mang gi tr biu din v


lc x l s x l ring cho khi ny.
-Do ,mi khi gch (mi hnh dng khi gch) c bn ta c 7 loi khi c bn s c 7
con s i din cho n.

II/ T chc chng trnh,chn cu trc ci t.


- Phn I chng ta c ni s s qua tng,cu trc ca game Tetris ny ri.Phn II t s
hng dn cch vit code v t chc game.
1/ Cc hm b tr
- V trong game mnh c s dng cc hm nh gotoxy(), textcolor() ,delay()
m trong VS 2k8 khng c nn phi vit li cc hm ny.Cc hm ny ch l ph thi
nn chng ta chp code v l c ,khng cn phi hiu cc hm ny hot ng ra sao
c.
Sau y l code mu ca cc hm ny.
enum
{
BLACK,
BLUE,
GREEN,
CYAN,
RED,
PURPLE,
GRAY,
WHITE,
LIGHTGRAY,
LIGHTBLUE,
LIGHTGREEN,
LIGHTCYAN,

LIGHTRED,
LIGHTPURPLE,
LIGHTYELLOW,
LIGHTWHITE
};
void gotoxy(int x, int y)
{
COORD c;
c.X = x - 1;
c.Y = y - 1;
SetConsoleCursorPosition (GetStdHandle(STD_OUTPUT_HANDLE), c);
}
void clrscr()
{
COORD coord;
DWORD written;
CONSOLE_SCREEN_BUFFER_INFO info;
coord.X = 0;
coord.Y = 0;
GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
FillConsoleOutputCharacter (GetStdHandle(STD_OUTPUT_HANDLE), ' ',
info.dwSize.X * info.dwSize.Y, coord, &written);
gotoxy (1, 1);
}
void textcolor(WORD color)
{
HANDLE hConsoleOutput;
hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
GetConsoleScreenBufferInfo(hConsoleOutput, &screen_buffer_info);
WORD wAttributes = screen_buffer_info.wAttributes;
color &= 0x000f;
wAttributes &= 0xfff0;
wAttributes |= color;
SetConsoleTextAttribute(hConsoleOutput, wAttributes);
}
void SetBGColor(WORD color)
{
HANDLE hConsoleOutput;
hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info;
GetConsoleScreenBufferInfo(hConsoleOutput, &screen_buffer_info);
WORD wAttributes = screen_buffer_info.wAttributes;
color &= 0x000f;
color <<= 4;
wAttributes &= 0xff0f;
wAttributes |= color;
SetConsoleTextAttribute(hConsoleOutput, wAttributes);
}
void delay(int x){ Sleep(x);}

void Nocursortype()
{
CONSOLE_CURSOR_INFO Info;
Info.bVisible = FALSE;
Info.dwSize=20;
SetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &Info);
}

2/ Cu trc game
Mnh s chn cch vit code game ny dng Structure.Mc d theo mnh thy dng class s
d qun l v nhn trc quan hn.Nhng nhiu bn cha hc hng i tng (OOP) nn
dng Structure l hp l cho cc bn.Dng structure nn 1 s ch mnh t chc qun l cha
tt nn cc ban thng cm nha.ng chm em m ti nghip.

Nh mnh ni phn I th game s c qun l chung bng 1 ma trn Board[22][10]. Do


mnh s khai bo ma trn ny l kiu int ,v l bin ton cc.
#define MaxI 22
#define MaxJ 10
int Board[MaxI][MaxJ];

- xc nh v tr v khung mn hnh chi game ( tng ng vi ma trn map) ln mn hnh


console.Lu rng nh mnh ni th Board c kch thc [22][10] nhng tht s ch v
ln mn hnh kch thc 18x10 ta b i 4 hng u trong ma trn Board i(c index t i =0
3).
Ta khai bo :
#define LEFT 4
#define TOP 4

d hnh dung th bn bit .Mn hnh console c kch thc l 25 hng x 80 ct .

Sau y l hm v ci khung hin th ln mn hnh .


void DrawBoard()
{
int i,j;
for(i=LEFT;i<=LEFT+10+1;i++)
for(j=TOP;j<=TOP+18+1;j++)
{
if((j==TOP||j==TOP+18+1)&&i>LEFT&&i<LEFT+10+1)
{
gotoxy(i,j);textcolor(7);cprintf("%c",205);
}
if((i==LEFT||i==LEFT+10+1)&&j>TOP&&j<TOP+18+1)
{
gotoxy(i,j);textcolor(7);cprintf("%c",186);
}
}
gotoxy(LEFT,TOP);textcolor(LIGHTRED);cprintf("%c",219);
gotoxy(LEFT+10+1,TOP);textcolor(LIGHTRED);cprintf("%c",219);
gotoxy(LEFT,TOP+18+1);textcolor(LIGHTRED);cprintf("%c",219);
gotoxy(LEFT+10+1,TOP+18+1);textcolor(LIGHTRED);cprintf("%c",219);
}

Ci hm ny s v ln mn hnh nh th ny:

Hm v trng thi ma trn ca game.Nu Board[i][j] =1 (ngha l c gch y ) v i phi


>=4 th v k t c m ASCII = 2 (hnh mt ci) ln mn hnh .ngc li th khng v ln
mn hnh.
void DisplayBoard()
{
int i,j;
for(i=0;i<MaxI;i++)
for(j=0;j<MaxJ;j++)
{
if(Board[i][j]==1&&i>=4)
{
gotoxy(j+LEFT+1,i+TOP+1-4);textcolor(15);cprintf("%c",2);
}
if(Board[i][j]==0&&i>=4)
{
textcolor(BLACK);gotoxy(j+LEFT+1,i+TOP+1-4);cprintf(" ");
}
}
}

i khi l n s hot ng tng t nh v d m t bn di.

-Khi xp c 1 hng y th ta phi xa hng v cp nht li gi tr cho ma trn Board li


cho ng.
void CapNhatLaiToaDo(int hang)
{
int i,j;
for(i=hang;i>0;i--)
for(j=0;j<MaxJ;j++)
{
Board[i][j]=Board[i-1][j];
}
}

Structure qun l khi gch:


-Nh ni tng trn,mnh s code ha cu trc nh sau:
typedef struct
{
int **arr;
int Row,Col;
int iBoard,jBoard;
}KhoiGach;

+arr l 1 con tr m t Ma Trn Trng Thi cho tng loi khi gch: 4x1 ,2x2,2x3 .
Cn 2 bin Row,Col th hin kch thc ca ma trn trng thi ( arr,Row,Col s cho bit
hnh dng ca khi gch l hnh j).Ma trn ny dng kim tra va chm khi di chuyn khi
gch,xoay khi gch

+iBoard,jBoard : cho bit v tr hin ti ca Khi Gch ang nm u trn ma trn


Board[22][10] chnh l v tr ca arr[0][0] so vi ma trn Board[22][10].Khi mi khi to
khi gch th iBoard,jBoard s nm khu vc khng c hin th.

-Mnh phn tch phn I rng mnh s dng 1 con s tng trng cho tng khi
gch.Khi bit s i din ca n th ta ch cn dng php ton dch bt suy ra ma trn trng
thi ca chng.
+15: Thng ng
+31: Hnh vung
..

-Hm khi to thng s 1 khi gch tng ng vi s ID ca n:


KhoiGach *TaoKhoiGach(int ID)
{
KhoiGach *pkhoigach=(KhoiGach*)malloc(sizeof(KhoiGach));
switch(ID)
{
case 15:
pkhoigach->Row=4;
pkhoigach->Col=1;
pkhoigach->iBoard=0;
pkhoigach->jBoard=5;
break;
case 31:
pkhoigach->Row=pkhoigach->Col=2;
pkhoigach->iBoard=2;
pkhoigach->jBoard=5;
break;
default:
pkhoigach->Row=2;
pkhoigach->Col=3;
pkhoigach->iBoard=2;
pkhoigach->jBoard=5;
break;
}
pkhoigach->arr=(int**)malloc(pkhoigach->Row*sizeof(int*));
for(int i=0;i<pkhoigach->Row;i++)
{
pkhoigach->arr[i]=(int*)malloc(pkhoigach->Col*sizeof(int));
}
for(int k=0;k<pkhoigach->Col*pkhoigach->Row;k++)
{
pkhoigach->arr[k/pkhoigach->Col][k%pkhoigach->Col]=(ID>>(pkhoigach>Col*pkhoigach->Row-1-k))&1;
}
return pkhoigach;
}

on :
pkhoigach->arr=(int**)malloc(pkhoigach->Row*sizeof(int*));
for(int i=0;i<pkhoigach->Row;i++)
{
pkhoigach->arr[i]=(int*)malloc(pkhoigach->Col*sizeof(int));
}

Ch l cp pht b nh cho ma trn trng thi thi .Chc hn cc bn s thc mc rng nu c


ID=58 th sao c th to ra ma trn trng thi l:
1
1
1
0

Rt n gin thi:
V d : vi ID=58 th khi gch s c ma trn trng thi l 2x3 .Row=2,Col=3.
Ban u ma trn trng thi arr:
0

V Row xCol=2x3=6 (bit) .Nn ta i 58 sang s nh phn 6 di bit l: 111010


on code:
for(int k=0;k<pkhoigach->Col*pkhoigach->Row;k++)
{
pkhoigach->arr[k/pkhoigach->Col][k%pkhoigach->Col]=(ID>>(pkhoigach>Col*pkhoigach->Row-1-k))&1;
}

+Ton t >> l ton t dch bt sang phi.


+arr[k/Col][k%Col]=(ID dch sang phi (RowxCol-1-k) bit ) & 1 // (php AND trong tin
hc chc ai cng bit)
Vi k=0: [arr[k/Col][k%Col]=arr[0][0].
58 dch sang phi (6-1-0) bt= 111010 dch sang phi 5 bit l 000001 .Sau kt
hp vi 000001&1 th kt qu s l 1. ->Vy arr[0][0]=1;
1

Vi k=1: [arr[k/Col][k%Col]=arr[0][1].
58 dch sang phi (6-1-1) bt= 111010 dch sang phi 4 bit l 000011 .Sau kt
hp vi 000011&1 th kt qu s l 1. ->Vy arr[0][1]=1;

Vi k=2: [arr[k/Col][k%Col]=arr[0][2].
58 dch sang phi (6-1-2) bt= 111010 dch sang phi 3 bit l 000111 .Sau kt
hp vi 000111&1 th kt qu s l 1. ->Vy arr[0][2]=1;
1

Vi k=3: [arr[k/Col][k%Col]=arr[1][0].
58 dch sang phi (6-1-3) bt= 111010 dch sang phi 2 bit l 001110 .Sau kt
hp vi (001110 )&1 th kt qu s l 0. ->Vy arr[1][0]=0;
1

Vi k=4: [arr[k/Col][k%Col]=arr[1][1].
58 dch sang phi (6-1-4) bt= 111010 dch sang phi 1 bit l 011101 .Sau kt
hp vi (011101 )&1 th kt qu s l 1. ->Vy arr[1][1]=1;
1

Vi k=5: [arr[k/Col][k%Col]=arr[1][2].
58 dch sang phi (6-1-5) bt= 111010 dch sang phi 0 bit l 111010 .Sau kt
hp vi (111010 )&1 th kt qu s l 0. ->Vy arr[1][2]=0;
1

Vy cui cng: ta c ma trn trng thi dng vi con s ID=58. Vi cc khi gch mang
ID khc th cch lm cng tng t thi

Hm kim tra va chm khi di chuyn khi gch sang tri ,sang phi,ri xung:
tng:
+ xc nh xem 1 v tr i,j trn ma trn Board c di chuyn sang tri c hay
khng th ta xem lin k bn tri(chnh l v tr i , j-1) ca n c gch hay cha,nu c
gch th khng di chuyn c( a[i][j]=1 th c gch v ngc li a[i][j]=0 l khng c gch)
.Di chuyn sang phi hay xt ri xung cng tng t nh th thi( cng xt lin k bn
phi i,j+1 hoc lin k bn di i+1,j)
+Nh vy xt nguyn khi gch (gm 4 gch nh ) c th di chuyn c th tt
c cc gch nh fai di chuyn c ,nu c 1 khng di chuyn c th khi gch
khng th di chuyn c.

int Inside(int i,int j) //Xem i,j c thuc mng Board[22][10] hay khng?
{
return (i>=0&&i<MaxI&&j>=0&&j<MaxJ);
}
int Left(int i,int j)
{
if(j>0&&Inside(i,j)&&Board[i][j-1]==0) return 1;
return 0;
}
int Right(int i,int j)
{
if(j<MaxJ-1&&Inside(i,j)&&Board[i][j+1]==0) return 1;
return 0;
}
int Down(int i,int j)
{
if(i<MaxI-1&&Inside(i,j)&&Board[i+1][j]==0) return 1;
return 0;
}

+Hm trn mi ch xt 1 di chuyn cho 1 ( i,j) thi. Sau y s l hm xt di chuyn


cho tt c khi gch.

Note:
+1 khi gch ch di chuyn sang tri v phi khi khng nm trong khu vc khng c hin
th (ngha l iBoard>3) .
+ i,j trn ma trn trng thi c v tr tng ng trn ma trn Board l :
pkhoigach->iBoard+i,pkhoigach->jBoard+j :

void SangTrai(KhoiGach *pkhoigach)


{
for(int i=0;i<pkhoigach->Row;i++)
for(int j=0;j<pkhoigach->Col;j++)
if(pkhoigach->arr[i][j]==1)
{
if(Left(pkhoigach->iBoard+i,pkhoigach->jBoard+j)==0||pkhoigach>iBoard<=3) return;
}
}

pkhoigach->jBoard-=1; //Dich vi tri cua bang trang thai sang trai 1 so voi Board[22][10].

void SangPhai(KhoiGach *pkhoigach)


{
for(int i=0;i<pkhoigach->Row;i++)
for(int j=0;j<pkhoigach->Col;j++)
if(pkhoigach->arr[i][j]==1)
{
if(Right(pkhoigach->iBoard+i,pkhoigach->jBoard+j)==0||pkhoigach>iBoard<=3) return;
}
pkhoigach->jBoard+=1; //Dich vi tri cua bang trang thai sang phai 1 so voi
Board[22][10].
}
int RoiXuong(KhoiGach *pkhoigach) //0 : khng th ri xung,1 : c th ri xung.
{

for(int i=0;i<pkhoigach->Row;i++)
for(int j=0;j<pkhoigach->Col;j++)
if(pkhoigach->arr[i][j]==1)
{
if(Down(pkhoigach->iBoard+i,pkhoigach->jBoard+j)==0) return 0;
}
pkhoigach->iBoard+=1; //Roi xuong 1 so voi Board[22][10]
return 1;

Hm gn gi tr cho ma trn Board khi khi gch khng ri xung c na:Khi vi


nhng arr[i][j] ==1 ca ma trn trng thi th ta gn gi tr bng 1 cho Board[i][j] .Vi (i,j)
l ta tng ng ca (i,j) trn ma trn Board ,m cch i mnh ni trn ri.
void GanGiaTri(KhoiGach* pkhoigach)
{
for(int i=0;i<pkhoigach->Row;i++)
for(int j=0;j<pkhoigach->Col;j++)
if(pkhoigach->arr[i][j]==1)
{
Board[pkhoigach->iBoard+i][pkhoigach->jBoard+j]=1;
}
}

-Haizz,ti y th ta cng gn xong nhng ci c bn ca game Xp Gch ri. Chng ta s ti


hm xoay khi gch na l coi nh xong .Ci xoay khi gch ny rt d ,bn no lm bi
xoay ma trn 2 chiu 1 gc 90o theo chiu kim ng h ri th ci ny rt d hiu.
Hm xoay: Xoay khi gch thc cht cc bn ch cn xoay ma trn trng thi ca khi gch
1 gc 90o theo chiu kim ng h thi ,v ma trn y khng phi l ma trn vung nn
khi xoay th kch thc ca ma trn s b thay i Row=Col,Col=Row.Ta ch cn vit 1 hm
xoay duy nht th c th xoay c tt c cc loi khi gch (7 loi c bn v cc khi khi
c xoay khc) .Chng ta s xoay th ma trn trng thi v sau xt xem v tr ca ma trn
sau khi xoay tng ng trn ma trn Board c hp l hay khng (khng c ln Board[i]
[j] ==1 no v khng vt ra khi gii hn ca Board).Nu hp l th mi chp nhn ,cn
ngc li th vn gi nguyn ma trn trng thi nh ban u.
+V trc v sau khi xoay th iBoard,jBoard khng thay i gi tr (vn gi nguyn)
ci ny l cch mnh chn cho d( v x l ,rc ri thm) thi.Ch cc bn c th chn

cch khc xoay cho p hn.V cc bn coi ci hnh m t di y.

void XoayKhoiGach(KhoiGach* pkhoigach)


{
int i,j;
int ** tmpArr;
int tmpRow=pkhoigach->Col;
int tmpCol=pkhoigach->Row;
//Cp pht b nh cho ma trn ph tmpArr.
tmpArr=(int**)malloc(tmpRow*sizeof(int*));
for( i=0;i<tmpRow;i++)
{
tmpArr[i]=(int*)malloc(tmpCol*sizeof(int));
}
///////////////////////////////////////////////
for(i=pkhoigach->Row-1;i>=0;i--)
for(j=pkhoigach->Col-1;j>=0;j--)
{
tmpArr[j][pkhoigach->Row-i-1]=pkhoigach->arr[i][j];
}
//Kim tra hp l.
for (i=0;i<tmpRow;i++)
{
for(j=0;j<tmpCol;j++)
if(!Inside(pkhoigach->iBoard+i,pkhoigach->jBoard+j)||
Board[pkhoigach->iBoard+i][pkhoigach->jBoard+j]==1)
return;
}
for(i=0;i<pkhoigach->Row;i++) free(pkhoigach->arr[i]);
free(pkhoigach->arr);
//Cp nht thay i sau khi xoay.
pkhoigach->Col=tmpCol;
pkhoigach->Row=tmpRow;
pkhoigach->arr=tmpArr;
}

Khi lm vic vi b nh ng th cc bn nn cn thn xin cp pht xong v khi khng xi


na th phi gii phng b nh trnh tnh trng memory leak.
Hm v ,xa khi gch ln mn hnh console: Mnh ni trn th mnh dng bin
LEFT,TOP xc nh v tr v ma trn Board ln mn hnh console.
void VeKhoiGach(KhoiGach* pkhoigach)
{
int i;
int j;
for(i=0;i<pkhoigach->Row;i++)
for(j=0;j<pkhoigach->Col;j++)
if(pkhoigach->arr[i][j]==1&&(pkhoigach->iBoard+i)>3)
{
textcolor(LIGHTRED);
gotoxy(LEFT+pkhoigach->jBoard+j+1,TOP+pkhoigach->iBoard+i-3);
cprintf("%c",2);
}
}
void XoaKhoiGach(KhoiGach *pkhoigach)
{
int i;
int j;
for(i=0;i<pkhoigach->Row;i++)
for(j=0;j<pkhoigach->Col;j++)
if(pkhoigach->arr[i][j]==1&&(pkhoigach->iBoard+i)>3)
{
textcolor(BLACK);
gotoxy(LEFT+pkhoigach->jBoard+j+1,TOP+pkhoigach->iBoard+i-3);
cprintf(" ");
}
}

3/ Thng tin v im,cp ,tc .


-Game th khng th thiu phn tnh im v thng tin level . tng tnh hp dn cho
game.Di y mnh demo 1 cch tnh im v kh 1 cch rt n gin cho game.Ci
phn ny cc bn c th ty chnh theo mnh.Mnh khai bo 1 structure lu thng tin.
typedef struct
{
int score;
int level;
float speed;
}INFO;

+Mnh s chia game ra lm 2 cp : Cp 1 : 0->200 Cp 2 :200->300


+Mi hng n c s c +10 .
+Khi tng Level th speed cng nhanh hn 1 cht .
+Nu c 300 tr ln th Win game.
Cc hm b tr:
void InitGame(INFO *info)
{
info->level=1;
info->score=0;
info->speed=0.4;
}

int CapNhat(INFO *info, int score)


{
info->score+=score;
if(info->score>=200&&info->level<2)
{
info->level++;
info->speed-=0.1;
}
return 0; //Chua win game.
}
void VeBangDiem(INFO info)
{
textcolor(LIGHTYELLOW);
gotoxy(LEFT+MaxJ+2,10);cprintf("SCORE:%3d",info.score);
gotoxy(LEFT+MaxJ+2,11);cprintf("LEVEL:%3d",info.level);
gotoxy(LEFT+MaxJ+2,12);cprintf("SPEED:%3f",info.speed);
}

Kim tra gameover hay khng v tnh ton s hng n im:Khi khi gch khng th ri
xung c na th ta kim tra:
+ Game kt thc khi khi gch khng ri xung c na m iBoard vn <=3. th
Gameover.
+Nu cha gameover,ta xt xem c n c hng no khng? Ta khng cn phi xt
ht tt c cc hng ca ma trn Board[22][10] ( v nh vy tn chi ph ) m ch cn kim tra
ln lt cc hng iBoard+0 ,iBoard+ 1 , ,,iBoard+Row-1 l OK.Nu hng no c MaxJ
c gi tr bng 1 th hng n im c.
+n nhiu nht ch c 4 hng/1 ln.
int KiemTra(KhoiGach *pkhoigach,INFO *infogame) //-1 : gameover 0: win
{
int i,j,count;
i=pkhoigach->Row-1;
if(pkhoigach->iBoard<=3) return -1;//Gameover
if(infogame->score>=300) return 0;//Win
do
{
count=0;
for(j=0;j<MaxJ;j++)
{
if(Board[pkhoigach->iBoard+i][j]==1) count++;
}
if(count==MaxJ)
{
CapNhat(infogame,20);
CapNhatLaiToaDo(pkhoigach->iBoard+i);
DisplayBoard();
}
else
{
i=i-1;
}
}while(i>=0);
return 1;
}

Hm tr v -1 nu game over,tr v 0 nu ngi chi win(score>=300).V trong structure


KhoiGach c s dng con tr(arr-ma trn trng thi) cp pht ng nn mnh s phi vit 1
hm gii phng b nh trnh vic memory leak.
void HuyKhoiGach(KhoiGach* pkhoigach)
{
int i;
//Huy bo nho cua ma tran trang thai arr.

for(i=0;i<pkhoigach->Row;i++) free(pkhoigach->arr[i]);
free(pkhoigach->arr);
/////////////////////////////////////////////////////////
//Sau do moi free(pkhoigach)
free(pkhoigach);
pkhoigach=NULL;
}

4/ Chn ngu nhin khi gch v khi gch tip theo s xut hin.
Hm ny s random 1 khi gch chi. Tr v s i din cho khi gch .
int Loai()
{
int x=rand()%7;
switch(x)
{
case 0:
return
break;
case 1:
return
break;
case 2:
return
break;
case 3:
return
break;
case 4:
return
break;
case 5:
return
break;
case 6:
return
break;
}
}

15;
31;
51;
30;
58;
57;
60;

Hm v,xa khi gch tip theo s xut hin:


void Ve_Next(int ID)
{
KhoiGach *pnext=TaoKhoiGach(ID);
int iRoot=LEFT+MaxJ+5;
int jRoot=TOP;
for(int i=0;i<pnext->Row;i++)
{
for (int j=0;j<pnext->Col;j++)
{
if(pnext->arr[i][j]==1)
{
textcolor(LIGHTGREEN);
gotoxy(iRoot+j,jRoot+i);cprintf("%c",2);
}
}
}
HuyKhoiGach(pnext);
}
void Xoa_Next()
{
int iRoot=LEFT+MaxJ+5;
int jRoot=TOP;
for(int i=0;i<4;i++)
{
for (int j=0;j<4;j++)
{
textcolor(BLACK);
gotoxy(iRoot+j,jRoot+i);cprintf(" ");

}
}
}

Kt lun:
+Coi nh game hon thnh nhng phn c bn.By gi ta ghp cc thnh phn li
vi nhau v vit bt u vit hm main cho game chy thi.
5/Cng vic cui cng: Vit hm main v vng lp ca game.
-Vic to hiu ng chuyn ng l do vic xa c ,v mi kt hp vi hm delay() c
t trong 1 vng lp to nn cm gic chuyn ng.
- bit c khi no bn phm c nhn v phm no c nhn ta dng lnh _kbhit() v
getch() bt.Trong game ny mnh quy nh l:
+Phm di chuyn sang tri l : A (ASCII=65)
+Phm di chuyn sang phi l : D
+Phm xoay khi l : W
+Phm tng tc ri l : S
-on code x l nhn bn phm:
if(_kbhit())

//Nu bn phm c nhn


{
c=toupper(getch()); //Ly m phm va c bm
XoaKhoiGach(currKhoi); //Xa khi gch
switch(c)
{
case 'W':
XoayKhoiGach(currKhoi);
break;
case 'A':
SangTrai(currKhoi);
break;
case 'D':
SangPhai(currKhoi);
break;
case 'S':
RoiXuong();
break;
}
VeKhoiGach(currKhoi);//V li khi gch sau khi cp nht thay

i.
}

*Vng lp cho game:


-Khi to gi tr ban u cho game.V khung giao din.Khi to cc tham s
level,score,speed.
Do
{
- V li khi gch v ma trn Board ln mn hinh.
-Trong khi cha ht INFO.speed th lp li qu trnh:
Nu c s kin nhn bn phm xy ra( if(_kbhit()) ) th

+Xa Khi gch.


+X l nhn bn phm
+V li khi gch sau khi thay i.
- Cho khi gch ri xung:
-Nu ri xung khng c:
+Gn gi tr cho ma trn Board.S dng hm : void

GanGiaTri(KhoiGach*

pkhoigach)

+Kim tra thng thua v cp nht li im.Nu gameover hoc win th kt thc
tr chi.
+Hy b nh ca khi gch hin ti v sau khi to khi gch mi.
}While(!gameover hoc !win);
Code demo vng lp ca game l:
do
{
VeBangDiem(info);
VeKhoiGach(currKhoi);
Xoa_Next();
Ve_Next(IDKhoiTiepTheo);
Start=clock();
do
{
if(_kbhit())
{
c=toupper(getch());
XoaKhoiGach(currKhoi);
switch(c)
{
case 'W':
XoayKhoiGach(currKhoi);
break;
case 'A':
SangTrai(currKhoi);
break;
case 'D':
SangPhai(currKhoi);
break;
case 'S':
RoiXuong(currKhoi);
break;
}
VeKhoiGach(currKhoi);
}
End=clock();
}while(float(End-Start)/CLK_TCK<info.speed);
XoaKhoiGach(currKhoi);
if(RoiXuong(currKhoi)==0) //ko di chuyen xuong dc
{
GanGiaTri(currKhoi);
int ketqua=KiemTra(currKhoi,&info);
if((ketqua==-1||ketqua==0)) break;
HuyKhoiGach(currKhoi); //Giai phong bo nho.
currKhoi=TaoKhoiGach(IDKhoiTiepTheo);
IDKhoiTiepTheo=Loai();
DisplayBoard();
}
}while(1);

OK! Cc bn to project v chy th game no.V y l hnh nh ca game khi chy.Mnh


ch hng dn cch qun l ,xy dng cu trc chng trnh game thi,mnh demo rt t chc
nng .Nu mun cc bn c th vit thm phn save,load game,pause game

III/ Kt Thc
+Vy l xong Tut hng dn vit game Tetris vi C/C++ .Cm n cc bn theo di tut
ny.Mnh hi vng c s ng h v kin ca cc bn ln sau c th vit 1 Tut khc hay
v hp cc bn hn.
+Hn cc bn bi vit tip theo.C th l hng dn cch lm game Line( tt c ch l nu
c th ).V nu c copy bi vit ny i ni khc th xin hay ghi r ngun v tc gi.Cm n
nhu nhu.
+,mnh c nh km theo nguyn project ca game ny vit trn VS2K8.Cc bn c th ti
v coi +tut ny s d hnh dung hn.

Chng trnh ti y l ht ri.Cm n qu v quan tm theo di .Xin hn gp li


vo chng trnh ln sau! Cm n v cho tm bit

You might also like