引用
有人說(shuō):“C生萬(wàn)物,編程之本”,這一點(diǎn)都沒(méi)有錯(cuò)!
C語(yǔ)言是最接近計(jì)算機(jī)的語(yǔ)言,很多時(shí)間,我們都會(huì)發(fā)現(xiàn),C語(yǔ)言是非常有必要學(xué)習(xí)的。
作為一門(mén)古老的編程語(yǔ)言,大家熟知它不僅是因?yàn)閾碛?8年的發(fā)展歷程,更主要還是因?yàn)楫?dāng)下大部分程序員走入編程世界第一個(gè)學(xué)習(xí)的語(yǔ)言就是C語(yǔ)言。
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)俄羅斯方塊小游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
本文的代碼下載地址在文章末尾,有需要的同學(xué)自取。
效果展示:

編譯環(huán)境:
Windows 10.xxx.xxx+Visual Studio 2017
游戲規(guī)則,游戲主要實(shí)現(xiàn)的功能:
- 游戲主界面是10*20的格子。
- 每輪隨機(jī)創(chuàng)建一個(gè)形狀的方塊,總共有6種形狀。
- 方塊每秒下降1格,遇到障礙無(wú)法下降時(shí)進(jìn)入下一輪。
- 方塊可以旋轉(zhuǎn)、移動(dòng)、加速下落
- 格子界面有一行放滿時(shí)可消除。
開(kāi)發(fā)思路:
1.要先下載一個(gè) graphics.h 的頭文件來(lái)繪圖。
2.初始化窗口:initgraph(x, y);這是先創(chuàng)建一個(gè)窗口的函數(shù),以左上角為(0,0),向右為x軸,向下為y軸,其中x表示長(zhǎng)x個(gè)單位,y表示寬y個(gè)單位。
3.關(guān)閉圖像窗口:closegraph();結(jié)束時(shí)用來(lái)關(guān)閉用的。
4.按任意鍵繼續(xù):getch();這個(gè)就和getchar();差不多,為了防止以運(yùn)行完就關(guān)了,這樣能停頓一下,他的頭文件是:conio.h 。
5.畫(huà)線:line(x1, y1, x2, y2);在你創(chuàng)建的那么窗口里以(x1,y1)和(x2,y2)為兩個(gè)端點(diǎn)畫(huà)線。
6.畫(huà)矩形:rectangle(x1,y1,x2,y2);以(x1,y1)和(x2,y2)為對(duì)角畫(huà)一個(gè)矩形。
7.畫(huà)圓:circle(x,y,r);以(x,y)為圓點(diǎn),r為半徑畫(huà)圓。
8.顏色:setcolor(x);用來(lái)設(shè)置顏色的,其中x是你要設(shè)置的顏色,可以填這16種:黑 BLACK、藍(lán) BLUE、綠 GREEN、青 CYAN、紅 RED、紫 MAGENTA、棕 BROWN、淺灰 LIGHTGRAY、深灰 DARKGRAY、亮藍(lán) LIGHTBLUE、亮綠 LIGHTGREEN、亮青 LIGHTCYAN、亮紅 LIGHTRED、亮紫 LIGHTMAGENTA、黃 YELLOW、白 WHITE;當(dāng)然,你也可以根據(jù)光的三原色來(lái)調(diào)自己喜歡的顏色,方法是:setcolor(RGB(x,y,z));其中RGB分別代表紅綠藍(lán),對(duì)應(yīng)的x,y,z是你選的該顏色的多少,范圍是[0,255]。
【源碼獲取】:
源碼在C語(yǔ)言/C++交流④群:836880131!資料共享在群文件里面,有需要的可以自行添加獲取~
如果對(duì)代碼有任何建議,都可以添加小編的學(xué)習(xí)交流群,歡迎大家來(lái)討論~
源碼展示:
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <time.h>
//游戲窗口
#define FrameX 4 //游戲窗口左上角的X軸坐標(biāo)
#define FrameY 4 //游戲窗口左上角的Y軸坐標(biāo)
#define Frame_height 20 //游戲窗口的高度
#define Frame_width 18 //游戲窗口的寬度
//定義全局變量
int i,j,temp,temp1,temp2; //temp,temp1,temp2用于記住和轉(zhuǎn)換方塊變量的值
int a[80][80]={0}; //標(biāo)記游戲屏幕的圖案:2,1,0分別表示該位置為游戲邊框、方塊、無(wú)圖案;初始化為無(wú)圖案
int b[4]; //標(biāo)記4個(gè)"口"方塊:1表示有方塊,0表示無(wú)方塊
//聲明俄羅斯方塊的結(jié)構(gòu)體
struct Tetris
{
int x; //中心方塊的x軸坐標(biāo)
int y; //中心方塊的y軸坐標(biāo)
int flag; //標(biāo)記方塊類型的序號(hào)
int next; //下一個(gè)俄羅斯方塊類型的序號(hào)
int speed; //俄羅斯方塊移動(dòng)的速度
int count; //產(chǎn)生俄羅斯方塊的個(gè)數(shù)
int score; //游戲的分?jǐn)?shù)
int level; //游戲的等級(jí)
};
//函數(shù)原型聲明
//光標(biāo)移到指定位置
void gotoxy(HANDLE hOut, int x, int y);
//制作游戲窗口
void make_frame();
//隨機(jī)產(chǎn)生方塊類型的序號(hào)
void get_flag(struct Tetris *);
//制作俄羅斯方塊
void make_tetris(struct Tetris *);
//打印俄羅斯方塊
void print_tetris(HANDLE hOut,struct Tetris *);
//清除俄羅斯方塊的痕跡
void clear_tetris(HANDLE hOut,struct Tetris *);
//判斷是否能移動(dòng),返回值為1,能移動(dòng),否則,不動(dòng)
int if_moveable(struct Tetris *);
//判斷是否滿行,并刪除滿行的俄羅斯方塊
void del_full(HANDLE hOut,struct Tetris *);
//開(kāi)始游戲
void start_game();
void main()
{
//制作游戲窗口
make_frame();
//開(kāi)始游戲
start_game();
}
/******光標(biāo)移到指定位置**************************************************************/
void gotoxy(HANDLE hOut, int x, int y)
{
COORD pos;
pos.X = x; //橫坐標(biāo)
pos.Y = y; //縱坐標(biāo)
SetConsoleCursorPosition(hOut, pos);
}
/******制作游戲窗口******************************************************************/
void make_frame()
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //定義顯示器句柄變量
gotoxy(hOut,FrameX+Frame_width-5,FrameY-2); //打印游戲名稱
printf("俄羅斯方塊");
gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+7); //打印選擇菜單
printf("**********下一個(gè)方塊:");
gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+13);
printf("**********");
gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+17);
printf("↑鍵:變體");
gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+19);
printf("空格:暫停游戲");
gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+15);
printf("Esc :退出游戲");
gotoxy(hOut,FrameX,FrameY); //打印框角并記住該處已有圖案
printf("╔");
gotoxy(hOut,FrameX+2*Frame_width-2,FrameY);
printf("╗");
gotoxy(hOut,FrameX,FrameY+Frame_height);
printf("╚");
gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+Frame_height);
printf("╝");
a[FrameX][FrameY+Frame_height]=2;
a[FrameX+2*Frame_width-2][FrameY+Frame_height]=2;
for(i=2;i<2*Frame_width-2;i+=2)
{
gotoxy(hOut,FrameX+i,FrameY);
printf("═"); //打印上橫框
}
for(i=2;i<2*Frame_width-2;i+=2)
{
gotoxy(hOut,FrameX+i,FrameY+Frame_height);
printf("═"); //打印下橫框
a[FrameX+i][FrameY+Frame_height]=2; //記住下橫框有圖案
}
for(i=1;i<Frame_height;i++)
{
gotoxy(hOut,FrameX,FrameY+i);
printf("║"); //打印左豎框
a[FrameX][FrameY+i]=2; //記住左豎框有圖案
}
for(i=1;i<Frame_height;i++)
{
gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+i);
printf("║"); //打印右豎框
a[FrameX+2*Frame_width-2][FrameY+i]=2; //記住右豎框有圖案
}
}
/******制作俄羅斯方塊********************************************************************/
void make_tetris(struct Tetris *tetris)
{
a[tetris->x][tetris->y]=b[0]; //中心方塊位置的圖形狀態(tài):1-有,0-無(wú)
switch(tetris->flag) //共6大類,19種類型
{
case 1: //田字方塊
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x+2][tetris->y-1]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 2: //直線方塊:----
{
a[tetris->x-2][tetris->y]=b[1];
a[tetris->x+2][tetris->y]=b[2];
a[tetris->x+4][tetris->y]=b[3];
break;
}
case 3: //直線方塊: |
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x][tetris->y-2]=b[2];
a[tetris->x][tetris->y+1]=b[3];
break;
}
case 4: //T字方塊
{
a[tetris->x-2][tetris->y]=b[1];
a[tetris->x+2][tetris->y]=b[2];
a[tetris->x][tetris->y+1]=b[3];
break;
}
case 5: //T字順時(shí)針轉(zhuǎn)90度方塊
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x][tetris->y+1]=b[2];
a[tetris->x-2][tetris->y]=b[3];
break;
}
case 6: //T字順時(shí)針轉(zhuǎn)180度方塊
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x-2][tetris->y]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 7: //T字順時(shí)針轉(zhuǎn)270度方塊
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x][tetris->y+1]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 8: //Z字方塊
{
a[tetris->x][tetris->y+1]=b[1];
a[tetris->x-2][tetris->y]=b[2];
a[tetris->x+2][tetris->y+1]=b[3];
break;
}
case 9: //Z字順時(shí)針轉(zhuǎn)90度方塊
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x-2][tetris->y]=b[2];
a[tetris->x-2][tetris->y+1]=b[3];
break;
}
case 10: //Z字順時(shí)針轉(zhuǎn)180度方塊
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x-2][tetris->y-1]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 11: //Z字順時(shí)針轉(zhuǎn)270度方塊
{
a[tetris->x][tetris->y+1]=b[1];
a[tetris->x+2][tetris->y-1]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 12: //7字方塊
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x][tetris->y+1]=b[2];
a[tetris->x-2][tetris->y-1]=b[3];
break;
}
case 13: //7字順時(shí)針轉(zhuǎn)90度方塊
{
a[tetris->x-2][tetris->y]=b[1];
a[tetris->x-2][tetris->y+1]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 14: //7字順時(shí)針轉(zhuǎn)180度方塊
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x][tetris->y+1]=b[2];
a[tetris->x+2][tetris->y+1]=b[3];
break;
}
case 15: //7字順時(shí)針轉(zhuǎn)270度方塊
{
a[tetris->x-2][tetris->y]=b[1];
a[tetris->x+2][tetris->y-1]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 16: //倒7字方塊
{
a[tetris->x][tetris->y+1]=b[1];
a[tetris->x][tetris->y-1]=b[2];
a[tetris->x+2][tetris->y-1]=b[3];
break;
}
case 17: //倒7字順指針轉(zhuǎn)90度方塊
{
a[tetris->x-2][tetris->y]=b[1];
a[tetris->x-2][tetris->y-1]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 18: //倒7字順時(shí)針轉(zhuǎn)180度方塊
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x][tetris->y+1]=b[2];
a[tetris->x-2][tetris->y+1]=b[3];
break;
}
case 19: //倒7字順時(shí)針轉(zhuǎn)270度方塊
{
a[tetris->x-2][tetris->y]=b[1];
a[tetris->x+2][tetris->y+1]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
}
}
//******判斷是否可動(dòng)*************************************************************************/
int if_moveable(struct Tetris *tetris)
{
if(a[tetris->x][tetris->y]!=0)//當(dāng)中心方塊位置上有圖案時(shí),返回值為0,即不可移動(dòng)
{
return 0;
}
else
{
if( //當(dāng)為田字方塊且除中心方塊位置外,其他"口"字方塊位置上無(wú)圖案時(shí),返回值為1,即可移動(dòng)
( tetris->flag==1 && ( a[tetris->x][tetris->y-1]==0 &&
a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
//或?yàn)橹本€方塊且除中心方塊位置外,其他"口"字方塊位置上無(wú)圖案時(shí),返回值為1,即可移動(dòng)
( tetris->flag==2 && ( a[tetris->x-2][tetris->y]==0 &&
a[tetris->x+2][tetris->y]==0 && a[tetris->x+4][tetris->y]==0 ) ) ||
( tetris->flag==3 && ( a[tetris->x][tetris->y-1]==0 &&
a[tetris->x][tetris->y-2]==0 && a[tetris->x][tetris->y+1]==0 ) ) ||
( tetris->flag==4 && ( a[tetris->x-2][tetris->y]==0 &&
a[tetris->x+2][tetris->y]==0 && a[tetris->x][tetris->y+1]==0 ) ) ||
( tetris->flag==5 && ( a[tetris->x][tetris->y-1]==0 &&
a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y]==0 ) ) ||
( tetris->flag==6 && ( a[tetris->x][tetris->y-1]==0 &&
a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
( tetris->flag==7 && ( a[tetris->x][tetris->y-1]==0 &&
a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
( tetris->flag==8 && ( a[tetris->x][tetris->y+1]==0 &&
a[tetris->x-2][tetris->y]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) ||
( tetris->flag==9 && ( a[tetris->x][tetris->y-1]==0 &&
a[tetris->x-2][tetris->y]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) ||
( tetris->flag==10 && ( a[tetris->x][tetris->y-1]==0 &&
a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
( tetris->flag==11 && ( a[tetris->x][tetris->y+1]==0 &&
a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
( tetris->flag==12 && ( a[tetris->x][tetris->y-1]==0 &&
a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y-1]==0 ) ) ||
( tetris->flag==13 && ( a[tetris->x-2][tetris->y]==0 &&
a[tetris->x-2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
( tetris->flag==14 && ( a[tetris->x][tetris->y-1]==0 &&
a[tetris->x][tetris->y+1]==0 && a[tetris->x+2][tetris->y+1]==0 ) ) ||
( tetris->flag==15 && ( a[tetris->x-2][tetris->y]==0 &&
a[tetris->x+2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
( tetris->flag==16 && ( a[tetris->x][tetris->y+1]==0 &&
a[tetris->x][tetris->y-1]==0 && a[tetris->x+2][tetris->y-1]==0 ) ) ||
( tetris->flag==17 && ( a[tetris->x-2][tetris->y]==0 &&
a[tetris->x-2][tetris->y-1]==0 && a[tetris->x+2][tetris->y]==0 ) ) ||
( tetris->flag==18 && ( a[tetris->x][tetris->y-1]==0 &&
a[tetris->x][tetris->y+1]==0 && a[tetris->x-2][tetris->y+1]==0 ) ) ||
( tetris->flag==19 && ( a[tetris->x-2][tetris->y]==0 &&
a[tetris->x+2][tetris->y+1]==0 && a[tetris->x+2][tetris->y]==0 ) ) )
{
return 1;
}
}
return 0;
}
/******隨機(jī)產(chǎn)生俄羅斯方塊類型的序號(hào)**********************************************************/
void get_flag(struct Tetris *tetris)
{
tetris->count++; //記住產(chǎn)生方塊的個(gè)數(shù)
srand((unsigned)time(NULL)); //初始化隨機(jī)數(shù)
if(tetris->count==1)
{
tetris->flag = rand()%19+1; //記住第一個(gè)方塊的序號(hào)
}
tetris->next = rand()%19+1; //記住下一個(gè)方塊的序號(hào)
}
/******打印俄羅斯方塊**********************************************************************/
void print_tetris(HANDLE hOut,struct Tetris *tetris)
{
for(i=0;i<4;i++)
{
b[i]=1; //數(shù)組b[4]的每個(gè)元素的值都為1
}
make_tetris(tetris); //制作俄羅斯方塊
for( i=tetris->x-2; i<=tetris->x+4; i+=2 )
{
for(j=tetris->y-2;j<=tetris->y+1;j++)
{
if( a[i][j]==1 && j>FrameY )
{
gotoxy(hOut,i,j);
printf("□"); //打印邊框內(nèi)的方塊
}
}
}
//打印菜單信息
gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+1);
printf("level : %d",tetris->level);
gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+3);
printf("score : %d",tetris->score);
gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+5);
printf("speed : %dms",tetris->speed);
}
附上視頻教學(xué):
https://www.bilibili.com/video/BV1zt4y1977U/
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持小編。
另外本程序還需要一部分頭文件,想要領(lǐng)取可以添加小編的C語(yǔ)言/C++交流④群:836880131,源碼在群文件里
福利來(lái)襲~
學(xué)習(xí)過(guò)程很“痛苦”,但是結(jié)果大家一定會(huì)對(duì)自己很滿意!
如果覺(jué)得學(xué)習(xí)資料難找的話,可以添加小編的C語(yǔ)言/C++交流群:836880131! 學(xué)習(xí)資料已經(jīng)共享在群里了,期待你的加入~