C語言代碼實現俄羅斯方塊
這裡為大傢敲寫一段怎樣用C語言實現俄羅斯方塊:
首先推薦大傢使用CodeBlocks這個軟件,方便添加不同的工程。
代碼中有很多註釋便於理解!
下面是效果圖和全部的代碼以及註釋,大傢可以觀看並自己新增內容!
1、首先是main.c文件:
#include <stdio.h> #include <stdlib.h> #include "game.h" int main() { gameInit(); return 0; }
2、然後是mywindows.h文件:
#ifndef MYWINDOWS_H_INCLUDED #define MYWINDOWS_H_INCLUDED // 封裝系統函數-系統調用模塊 #include <windows.h> // 初始化句柄 extern void initHandle(); // 設置顏色 extern void setColor(int color); // 設置光標位置 extern void setPos(int x, int y); // 設置光標是否可見 extern void setCursorVisible(int flag); // 關閉句柄 extern void closeHandle(); #endif // MYWINDOWS_H_INCLUDED
3、接下來是mywindows.c文件:
#include "mywindows.h" HANDLE handle; // 初始化句柄 void initHandle() { handle = GetStdHandle(STD_OUTPUT_HANDLE); } // 設置顏色 void setColor(int color) { SetConsoleTextAttribute(handle, color); } void setPos(int x, int y) { //, , COORD coord = {x*2, y}; SetConsoleCursorPosition(handle, coord); } // 設置光標是否可見 void setCursorVisible(int flag) { CONSOLE_CURSOR_INFO info; info.bVisible = flag; //光標是否可見 info.dwSize = 100; //光標寬度1-100 SetConsoleCursorInfo(handle, &info); } // 關閉句柄 void closeHandle() { CloseHandle(handle); }
4、下面是data.h文件,也就是數據庫的存儲地址:
#ifndef DATA_H_INCLUDED #define DATA_H_INCLUDED //函數聲明\變量聲明 // 存儲數據-數據模塊 //界面數組 extern int windowShape[25][26]; extern int block[7][4][4][4]; #endif // DATA_H_INCLUDED
5、數據庫內容:data.c
#include "data.h" //函數的定義 int windowShape[25][26] = { {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1} };// 邊框為1,遊戲池長度為14 int block[7][4][4][4] = { { //Z{} {{1,1,0,0},{0,1,1,0},{0,0,0,0},{0,0,0,0}}, {{0,1,0,0},{1,1,0,0},{1,0,0,0},{0,0,0,0}}, {{1,1,0,0},{0,1,1,0},{0,0,0,0},{0,0,0,0}}, {{0,1,0,0},{1,1,0,0},{1,0,0,0},{0,0,0,0}} }, { //S {{0,1,1,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}}, {{1,0,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}}, {{0,1,1,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}}, {{1,0,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}} }, { //L{} {{1,0,0,0},{1,0,0,0},{1,1,0,0},{0,0,0,0}}, {{1,1,1,0},{1,0,0,0},{0,0,0,0},{0,0,0,0}}, {{1,1,0,0},{0,1,0,0},{0,1,0,0},{0,0,0,0}}, {{0,0,1,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}} }, { //J {{0,1,0,0},{0,1,0,0},{1,1,0,0},{0,0,0,0}}, {{1,0,0,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}}, {{1,1,0,0},{1,0,0,0},{1,0,0,0},{0,0,0,0}}, {{1,1,1,0},{0,0,1,0},{0,0,0,0},{0,0,0,0}} }, { //I{} {{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, {{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}}, {{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}}, {{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}} }, { //T {{1,1,1,0},{0,1,0,0},{0,0,0,0},{0,0,0,0}}, {{0,1,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}}, {{0,1,0,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}}, {{1,0,0,0},{1,1,0,0},{1,0,0,0},{0,0,0,0}} }, { //田 {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}}, {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}}, {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}}, {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}} } };
6、遊戲頭部:game.h:
#ifndef GAME_H_INCLUDED #define GAME_H_INCLUDED // 遊戲邏輯模塊 #include <stdio.h> #include <time.h> typedef struct{ int x; int y; int shape; int status; int color; }BLOCK; // 定義當前正在下落的方塊,和下一個方塊 BLOCK curBlock; BLOCK nextBlock; // 繪制遊戲池邊框 extern void gamePool(int x, int y); // 打印操作說明 extern void printRule(); // 打印分數和等級 extern void printGradeLevel(int num); // 遊戲計時 extern void gameTime(clock_t startTime); // 打印一個方塊 extern void printBlock(int x, int y, int shape, int status, int color); // 刪除一個方塊 extern void delBlock(int x, int y, int shape, int status); //方塊左移 extern void leftBlock(); //方塊右移 extern void rightBlock(); //方塊下移 extern int downBlock(); //方塊變形 extern void changeBlock(); //方塊直接落底 extern void bottomBlock(); //遊戲暫停 extern void pause(); //隨機產生遊戲第一個方塊 extern void startBlock(); //隨機產生下一個方塊 extern void blockNext(); //拷貝方塊:把下一個方塊變成當前正在下落的方塊 extern void copyBlock(); //碰撞檢測 extern int crash(int x, int y, int shape, int status); //保存方塊 extern void saveBlock(); //刷新遊戲池 extern void updateGamePool(); //消行檢測 extern void lineClear(); //消行下移 extern void lineDown(int line); // 初始化遊戲 extern void gameInit(); #endif // GAME_H_INCLUDED
7、最後一部分,遊戲內容,game.c文件:
#include "game.h" #include "mywindows.h" #include "data.h" #include <conio.h> int level = 1; int grade = 100; // 打印遊戲池 void gamePool(int x, int y) { int i, j; for(i=0;i<25;i++) { for(j=0;j<26;j++) { if(windowShape[i][j] == 1) { setColor(0xc0); setPos(x+j,y+i); printf(" "); // printf("%2s", ""); } } } } // 打印操作說明 void printRule() { setColor(0x0f); setPos(31, 9); printf("操作規則:"); setPos(32, 11); printf("按a或A左移"); setPos(32, 12); printf("按d或D右移"); setPos(32, 13); printf("按s或S下移"); setPos(32, 14); printf("按w或W變形"); setPos(32, 15); printf("按空格暫停"); setPos(32, 16); printf("按回車直接下落"); } void printGradeLevel(int num) { switch(num) { case 0: break; case 1: grade += 10;break; case 2: grade += 25;break; case 3: grade += 50;break; case 4: grade += 70;break; } //等級-->作業 setColor(0x09); setPos(3,6); printf("分數:%d", grade); setColor(0x0a); setPos(3,7); printf("等級:%d", level); } void gameTime(clock_t startTime) { //clock_t endTime = clock(); //clock_t ti = (endTime-startTime)/CLOCKS_PER_SEC; setColor(0x0d); setPos(3,8); printf("本次遊戲運行時間:%ld", (clock()-startTime)/CLOCKS_PER_SEC); } // 打印一個方塊 void printBlock(int x, int y, int shape, int status, int color) { int i,j; setColor(color); for(i=0;i<4;i++) { for(j=0;j<4;j++) { if(1 == block[shape][status][i][j]) { setPos(x+j,y+i); printf("■"); } } } } // 刪除一個方塊 void delBlock(int x, int y, int shape, int status) { int i, j; for(i=0;i<4;i++) { for(j=0;j<4;j++) { if(1 == block[shape][status][i][j]) { setPos(x+j,y+i); printf(" "); //打印兩個空格 } } } } //方塊左移 void leftBlock() { //已經顯示的方塊刪除,改變坐標,重新打印 if(crash(curBlock.x-1, curBlock.y, curBlock.shape,curBlock.status) == -1) { return; } delBlock(curBlock.x,curBlock.y,curBlock.shape, curBlock.status); curBlock.x -= 1; printBlock(curBlock.x,curBlock.y,curBlock.shape, curBlock.status,curBlock.color); } //方塊右移 void rightBlock() { if(crash(curBlock.x+1, curBlock.y, curBlock.shape,curBlock.status) == -1) { return; } delBlock(curBlock.x,curBlock.y,curBlock.shape, curBlock.status); curBlock.x += 1; printBlock(curBlock.x,curBlock.y,curBlock.shape, curBlock.status,curBlock.color); } //方塊下移 int downBlock() { if(crash(curBlock.x, curBlock.y+1,curBlock.shape,curBlock.status) == -1) { //落到遊戲池底部,產生新方塊 saveBlock(); lineClear(); updateGamePool(); copyBlock(); return -1; }else if(crash(curBlock.x, curBlock.y+1,curBlock.shape,curBlock.status) == -2) { //遊戲結束 return -2; }else{ delBlock(curBlock.x,curBlock.y,curBlock.shape, curBlock.status); curBlock.y += 1; printBlock(curBlock.x,curBlock.y,curBlock.shape, curBlock.status,curBlock.color); return 0; } } //方塊變形 void changeBlock() { if(crash(curBlock.x, curBlock.y, curBlock.shape, (curBlock.status+1)%4) == -1){ return; } delBlock(curBlock.x,curBlock.y,curBlock.shape, curBlock.status); curBlock.status = (curBlock.status+1)%4; printBlock(curBlock.x,curBlock.y,curBlock.shape, curBlock.status,curBlock.color); } //方塊直接落底 void bottomBlock() { while(1){ //流程參考方塊下落 if(downBlock() !=0){ return; } } } //遊戲暫停 void pause() { // } //隨機產生遊戲第一個方塊 void startBlock() { //設置時間為隨機數種子 srand((unsigned)time(NULL)); //初始化curBlock curBlock.x = 22; curBlock.y = 1; //rand取一個隨機整數 curBlock.shape = rand()%7; //0-6 curBlock.status = rand()%4; //0-3 curBlock.color = rand()%0x10; if(0x00 == curBlock.color) { curBlock.color = 0x0f; } printBlock(curBlock.x, curBlock.y, curBlock.shape, curBlock.status, curBlock.color); } //隨機產生下一個方塊 void blockNext() { //初始化nextBlock delBlock(nextBlock.x,nextBlock.y, nextBlock.shape,nextBlock.status); nextBlock.x = 34; nextBlock.y = 2; nextBlock.shape = rand()%7; nextBlock.status = rand()%4; nextBlock.color = rand()%0x10; if(0x00 == nextBlock.color) { nextBlock.color = 0x0f; } printBlock(nextBlock.x,nextBlock.y, nextBlock.shape,nextBlock.status,nextBlock.color); } //拷貝方塊:把下一個方塊變成當前正在下落的方塊 void copyBlock() { //當前方塊=下一個方塊 curBlock = nextBlock; curBlock.x = 22; curBlock.y = 1; printBlock(curBlock.x, curBlock.y, curBlock.shape, curBlock.status, curBlock.color); blockNext(); } //碰撞檢測 //x,y為方塊的下一個位置, status下一種形態 //碰撞返回-1,未碰撞返回0, 遊戲結束返回-2 int crash(int x, int y, int shape, int status) { int i,j; for(i=0;i<4;i++) { for(j=0;j<4;j++) { if(block[shape][status][i][j] == 1) { if(windowShape[i+y][j+x-15] == 1) { //方塊一產生就發生碰撞 if(curBlock.x == 22 && curBlock.y == 1) { return -2; } return -1; } } } } return 0; } //保存方塊 void saveBlock() { int i,j; for(i=0;i<4;i++) { for(j=0;j<4;j++) { if(block[curBlock.shape][curBlock.status][i][j] == 1) { windowShape[i+curBlock.y][j+curBlock.x-15] = 1; } } } } //刷新遊戲池 void updateGamePool() { int i,j; //從下到上刷新遊戲池 for(i=23;i>0;i--) { for(j=1;j<15;j++) { if(windowShape[i][j] == 1) { setColor(0x0e); setPos(j+15,i); printf("■"); }else{ setColor(0x00); setPos(j+15,i); printf(" "); } } } } //消行檢測 //檢測滿行->這一行所有值都為1 void lineClear() { int i,j; int num = 0; //統計一次消行數目 for(i=23;i>0;i--) { int total = 0; for(j=1;j<15;j++) { total += windowShape[i][j]; } if(total == 14) { //滿行 lineDown(i); i += 1; num += 1; } } printGradeLevel(num); } //消行下移 //從滿行的這行開始,上面所有行順序下移 void lineDown(int line) { int i,j; for(i=line;i>1;i--) { for(j=1;j<15;j++) { windowShape[i][j] = windowShape[i-1][j]; } } } // 初始化遊戲 void gameInit() { //第一步,必須初始化句柄 //clock_t startTime = clock(); initHandle(); setCursorVisible(FALSE); gamePool(15,0); printRule(); printGradeLevel(0); startBlock(); blockNext(); //定時開始時間,結束時間,通過控制時間差實現定時 clock_t start,stop; start = clock(); while(1) //for(;;) { //檢測是否有按鍵按下 if(kbhit()) { switch(getch()) { case 'a': case 'A': case 75: leftBlock();break; case 'd': case 'D': case 77: rightBlock();break; case 's': case 'S': case 80: downBlock();break; case 'w': case 'W': case 72: changeBlock();break; case 32: pause();break; case 13: bottomBlock();break; } } //獲取時間 stop = clock(); if(stop-start>0.5*CLOCKS_PER_SEC) { downBlock(); //重新計時 start = stop; } } }
好,到現在這個遊戲也就結束瞭!
以上就是本文的全部內容,希望對大傢的學習有所幫助,也希望大傢多多支持WalkonNet。