Professional Documents
Culture Documents
How To Make Tetris Game
How To Make Tetris Game
n Gin
Vi Ngn Ng C/C++ Trn DOS
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.
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
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:
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)
Khi trn s c biu din bng ma trn trng thi nh sau: vi Row=2 v Col=3
-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
S tng
ca chui ny l 51.
Khi:
S tng ng
chui ny l 57.
Khi:
S tng
chui ny l 58.
Khi:
1
S quy nh l
biu din v lc
Khi:
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.
Ci hm ny s v ln mn hnh nh th ny:
+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
-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
..
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));
}
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
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;
}
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 :
pkhoigach->jBoard-=1; //Dich vi tri cua bang trang thai sang trai 1 so voi Board[22][10].
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;
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;
}
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;
}
}
}
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())
i.
}
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);
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.