俄罗斯方块(C语言源代码)
#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <time.h>
//游戲窗口
#define FrameX 4 //游戲窗口左上角的X軸坐標
#define FrameY 4 //游戲窗口左上角的Y軸坐標
#define Frame_height 20 //游戲窗口的高度
#define Frame_width 18 //游戲窗口的寬度
//定義全局變量
int i, j, temp, temp1, temp2; //temp,temp1,temp2用于記住和轉換方塊變量的值
int a[80][80] = { 0 }; //標記游戲屏幕的圖案:2,1,0分別表示該位置為游戲邊框、方塊、無圖案;初始化為無圖案
int b[4]; //標記4個"口"方塊:1表示有方塊,0表示無方塊
//聲明俄羅斯方塊的結構體
struct Tetris
{
int x; //中心方塊的x軸坐標int y; //中心方塊的y軸坐標int flag; //標記方塊類型的序號int next; //下一個俄羅斯方塊類型的序號int speed; //俄羅斯方塊移動的速度int count; //產生俄羅斯方塊的個數int score; //游戲的分數int level; //游戲的等級};
//函數原型聲明
//光標移到指定位置
void gotoxy(HANDLE hOut, int x, int y);
//制作游戲窗口
void make_frame();
//隨機產生方塊類型的序號
void get_flag(struct Tetris*);
//制作俄羅斯方塊
void make_tetris(struct Tetris*);
//打印俄羅斯方塊
void print_tetris(HANDLE hOut, struct Tetris*);
//清除俄羅斯方塊的痕跡
void clear_tetris(HANDLE hOut, struct Tetris*);
//判斷是否能移動,返回值為1,能移動,否則,不動
int if_moveable(struct Tetris*);
//判斷是否滿行,并刪除滿行的俄羅斯方塊
void del_full(HANDLE hOut, struct Tetris*);
//開始游戲
void start_game();
void main()
{
//制作游戲窗口make_frame();//開始游戲start_game();}
/光標移到指定位置********************************************************/
void gotoxy(HANDLE hOut, int x, int y)
{
COORD pos;pos.X = x; //橫坐標pos.Y = y; //縱坐標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("**********下一個方塊:");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]; //中心方塊位置的圖形狀態:1-有,0-無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字順時針轉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字順時針轉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字順時針轉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字順時針轉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字順時針轉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字順時針轉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字順時針轉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字順時針轉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字順時針轉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字順指針轉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字順時針轉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字順時針轉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;}}}
//判斷是否可動*******************************************************************/
int if_moveable(struct Tetris* tetris)
{
if (a[tetris->x][tetris->y] != 0)//當中心方塊位置上有圖案時,返回值為0,即不可移動{return 0;}else{if ( //當為田字方塊且除中心方塊位置外,其他"口"字方塊位置上無圖案時,返回值為1,即可移動(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)) ||//或為直線方塊且除中心方塊位置外,其他"口"字方塊位置上無圖案時,返回值為1,即可移動(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;}
/隨機產生俄羅斯方塊類型的序號****************************************************/
void get_flag(struct Tetris* tetris)
{
tetris->count++; //記住產生方塊的個數srand((unsigned)time(NULL)); //初始化隨機數if (tetris->count == 1){tetris->flag = rand() % 19 + 1; //記住第一個方塊的序號}tetris->next = rand() % 19 + 1; //記住下一個方塊的序號}
/打印俄羅斯方塊****************************************************************/
void print_tetris(HANDLE hOut, struct Tetris* tetris)
{
for (i = 0; i < 4; i++){b[i] = 1; //數組b[4]的每個元素的值都為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("□"); //打印邊框內的方塊}}}//打印菜單信息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);}
/清除俄羅斯方塊的痕跡**********************************************************/
void clear_tetris(HANDLE hOut, struct Tetris* tetris)
{
for (i = 0; i < 4; i++){b[i] = 0; //數組b[4]的每個元素的值都為0}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] == 0 && j > FrameY){gotoxy(hOut, i, j);printf(" "); //清除方塊}}}}
/判斷是否滿行并刪除滿行的俄羅斯方塊**********************************************/
void del_full(HANDLE hOut, struct Tetris* tetris)
{ //當某行有Frame_width-2個方塊時,則滿行
int k, del_count = 0; //分別用于記錄某行方塊的個數和刪除方塊的行數的變量for (j = FrameY + Frame_height - 1; j >= FrameY + 1; j--){k = 0;for (i = FrameX + 2; i < FrameX + 2 * Frame_width - 2; i += 2){if (a[i][j] == 1) //豎坐標依次從下往上,橫坐標依次由左至右判斷是否滿行{k++; //記錄此行方塊的個數if (k == Frame_width - 2){for (k = FrameX + 2; k < FrameX + 2 * Frame_width - 2; k += 2){ //刪除滿行的方塊a[k][j] = 0;gotoxy(hOut, k, j);printf(" ");Sleep(1);}for (k = j - 1; k > FrameY; k--){ //如果刪除行以上的位置有方塊,則先清除,再將方塊下移一個位置for (i = FrameX + 2; i < FrameX + 2 * Frame_width - 2; i += 2){if (a[i][k] == 1){a[i][k] = 0;gotoxy(hOut, i, k);printf(" ");a[i][k + 1] = 1;gotoxy(hOut, i, k + 1);printf("□");}}}j++; //方塊下移后,重新判斷刪除行是否滿行del_count++; //記錄刪除方塊的行數}}}}tetris->score += 100 * del_count; //每刪除一行,得100分if (del_count > 0 && (tetris->score % 1000 == 0 || tetris->score / 1000 > tetris->level - 1)){ //如果得1000分即累計刪除10行,速度加快20ms并升一級tetris->speed -= 20;tetris->level++;}}
/開始游戲************************************************************************/
void start_game()
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //定義顯示器句柄變量struct Tetris t, * tetris = &t; //定義結構體的指針并指向結構體變量unsigned char ch; //定義接收鍵盤輸入的變量tetris->count = 0; //初始化俄羅斯方塊數為0個tetris->speed = 300; //初始移動速度為300mstetris->score = 0; //初始游戲的分數為0分tetris->level = 1; //初始游戲為第1關while (1){//循環產生方塊,直至游戲結束get_flag(tetris); //得到產生俄羅斯方塊類型的序號temp = tetris->flag; //記住當前俄羅斯方塊序號//打印下一個俄羅斯方塊的圖形(右邊窗口)tetris->x = FrameX + 2 * Frame_width + 6;tetris->y = FrameY + 10;tetris->flag = tetris->next;print_tetris(hOut, tetris);tetris->x = FrameX + Frame_width; //初始中心方塊x坐標tetris->y = FrameY - 1; //初始中心方塊y坐標tetris->flag = temp; //取出當前的俄羅斯方塊序號while (1){//控制方塊方向,直至方塊不再下移label:print_tetris(hOut, tetris);//打印俄羅斯方塊Sleep(tetris->speed); //延緩時間clear_tetris(hOut, tetris); //清除痕跡temp1 = tetris->x; //記住中心方塊橫坐標的值temp2 = tetris->flag; //記住當前俄羅斯方塊序號if (kbhit()){ //判斷是否有鍵盤輸入,有則用ch↓接收ch = getch();if (ch == 75) //按←鍵則向左動,中心橫坐標減2{tetris->x -= 2;}if (ch == 77) //按→鍵則向右動,中心橫坐標加2{tetris->x += 2;}if (ch == 72) //按↑鍵則變體即當前方塊順時針轉90度{if (tetris->flag >= 2 && tetris->flag <= 3){tetris->flag++;tetris->flag %= 2;tetris->flag += 2;}if (tetris->flag >= 4 && tetris->flag <= 7){tetris->flag++;tetris->flag %= 4;tetris->flag += 4;}if (tetris->flag >= 8 && tetris->flag <= 11){tetris->flag++;tetris->flag %= 4;tetris->flag += 8;}if (tetris->flag >= 12 && tetris->flag <= 15){tetris->flag++;tetris->flag %= 4;tetris->flag += 12;}if (tetris->flag >= 16 && tetris->flag <= 19){tetris->flag++;tetris->flag %= 4;tetris->flag += 16;}}if (ch == 32) //按空格鍵,暫停{print_tetris(hOut, tetris);while (1){if (kbhit()) //再按空格鍵,繼續游戲{ch = getch();if (ch == 32){goto label;}}}}if (if_moveable(tetris) == 0) //如果不可動,上面操作無效{tetris->x = temp1;tetris->flag = temp2;}else //如果可動,執行操作{goto label;}}tetris->y++; //如果沒有操作指令,方塊向下移動if (if_moveable(tetris) == 0) //如果向下移動且不可動,方塊放在此處{tetris->y--;print_tetris(hOut, tetris);del_full(hOut, tetris);break;}}for (i = tetris->y - 2; i < tetris->y + 2; i++){//游戲結束條件:方塊觸到框頂位置if (i == FrameY){j = 0; //如果游戲結束,j=0}}if (j == 0){system("cls");getch();break;}//清除下一個俄羅斯方塊的圖形(右邊窗口)tetris->flag = tetris->next;tetris->x = FrameX + 2 * Frame_width + 6;tetris->y = FrameY + 10;clear_tetris(hOut, tetris);}}
//QAQ翻箱倒柜從自己的有道云筆記找出來了,好久沒有發筆記了,得發一點證明自己還在學。
總結
以上是生活随笔為你收集整理的俄罗斯方块(C语言源代码)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Arcengine 基本操作(待更新)
- 下一篇: C语言排序(桶排序,冒泡排序,选择排序,