日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【C语言】俄罗斯方块的源代码

發布時間:2023/12/10 编程问答 50 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C语言】俄罗斯方块的源代码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

GitHub:【C語言】實現俄羅斯方塊源代碼

Head.h

#ifndef _HEAD_H_ #define _HEAD_H_#include<graphics.h> #include<stdio.h> #include<conio.h> #include<stdlib.h> #include<time.h> #include<string.h> #define _CRT_SECURE_NO_WARNINGS 1//界面的相關的參數 #define WALL_SQUARE_WIDTH 10 //圍墻方塊的寬度 #define xWALL_SQUARE_NUM 30 //x軸方向的方塊的數目 #define yWALL_SQUARE_WIDTH 46 //y軸方向的方塊的數目 #define GAME_WALL_WIDTH (WALL_SQUARE_WIDTH*xWALL_SQUARE_NUM) //游戲區域的寬度 300 #define GAME_WALL_HTGH (WALL_SQUARE_WIDTH*yWALL_SQUARE_WIDTH) //游戲區域的高度 460#define WINDOW_WIDTH 480 // 游戲總窗口寬度 480 #define WINDOW_HIGH 460 // 游戲總窗口高度 460//定義俄羅斯方塊的相關參數 #define ROCK_SQUARE_WIDTH (2*WALL_SQUARE_WIDTH) //俄羅斯方塊的大小是圍墻的兩倍 20 #define xROCK_SQUARE_NUM ((GAME_WALL_WIDTH -20)/ROCK_SQUARE_WIDTH) // 游戲區x軸放的方塊數目:14 #define yROCK_SQUARE_NUM ((GAME_WALL_HTGH -20)/ROCK_SQUARE_WIDTH) // 游戲區y軸放的方塊數目:22//定義移動方塊的相關操作 #define DIRECT_UP 3 #define DIRECT_DOWN 2 #define DIRECT_LEFT -1 #define DIRECT_RIGHT 1 /*數據結構-線性表(結構體數組)*/ typedef struct ROCK {//用來表示方塊的形狀(每一個字節是8位,用每4位表示方塊中的一行) unsigned short rockShapeBits;int nextRockIndex; //下一個方塊,在數組中的下標 } RockType;//方塊在圖形窗口中的位置(即定位4*4大塊的左上角坐標) typedef struct LOCATE {int left;int top; } RockLocation_t;//全局變量-游戲板的狀態描述(即表示當前界面哪些位置有方塊) //0表示沒有,1表示有(多加了兩行和兩列,形成一個圍墻,便于判斷方塊是否能夠移動) int game_board[yROCK_SQUARE_NUM + 2][xROCK_SQUARE_NUM + 2] = { 0 }; int game_socres = 0; //全局分數// 把俄羅斯方塊的19種類放到數組中 int rockTypeNum = 19; RockType RockArray[19] = { (0, 0) };//預覽區的方塊的位置 RockLocation_t preRockLocation = {GAME_WALL_WIDTH+70,70}; //每次生成初始化方塊的位置 RockLocation_t initRockLocation = { (WALL_SQUARE_WIDTH + 100), WALL_SQUARE_WIDTH }; //分數顯示的位置//各個文件中的函數 // 畫出界面以及畫出方塊Draw.h中 void DrawGameWindow(); void DisplayRock(int rockIdx, RockLocation_t* LocatePtr, bool displayed); //初始化Init源文件 void InitGame();//game.h void PlayGame(); bool IsGameOver();#endif

Draw.h

#include"Head.h"//畫出游戲界面 void DrawGameWindow() {//先畫出圍墻setcolor(BLUE);setlinestyle(PS_SOLID,NULL,0);setfillcolor(BLUE);//畫出上下圍墻for (int x = WALL_SQUARE_WIDTH; x <= GAME_WALL_WIDTH; x += WALL_SQUARE_WIDTH){fillrectangle(x - WALL_SQUARE_WIDTH, 0, x, WALL_SQUARE_WIDTH); //上fillrectangle(x - WALL_SQUARE_WIDTH, GAME_WALL_HTGH - WALL_SQUARE_WIDTH, x, GAME_WALL_HTGH);//下}//畫出左右圍墻for (int y = WALL_SQUARE_WIDTH; y <= GAME_WALL_HTGH; y += WALL_SQUARE_WIDTH){fillrectangle(0, y, WALL_SQUARE_WIDTH, y + WALL_SQUARE_WIDTH);//左fillrectangle(GAME_WALL_WIDTH - WALL_SQUARE_WIDTH, y, GAME_WALL_WIDTH, y + WALL_SQUARE_WIDTH);//右}//畫出右邊統計分數及相關東西//畫出分割線setcolor(WHITE);setlinestyle(PS_DASH,2);line(GAME_WALL_WIDTH + 20, 0, GAME_WALL_WIDTH + 20, GAME_WALL_HTGH);//設置字體LOGFONT font;gettextstyle(&font);settextstyle(18, 0, _T("宋體"));font.lfQuality = ANTIALIASED_QUALITY;//設置輸出效果為抗鋸齒 //1顯示預覽形狀outtextxy(GAME_WALL_WIDTH + 80, 30, _T("預覽"));outtextxy(GAME_WALL_WIDTH + 80, 170, _T("分數"));outtextxy(GAME_WALL_WIDTH + 65, 250, _T("操作說明"));outtextxy(GAME_WALL_WIDTH + 40, 290, _T("w a s d控制方向"));outtextxy(GAME_WALL_WIDTH + 40, 335, _T("空格 暫停"));//顯示分數setcolor(RED);outtextxy(GAME_WALL_WIDTH + 90, 200, '0'); }//在游戲區顯示編號為rockIdx的方塊 void DisplayRock(int rockIdx, RockLocation_t* LocatePtr, bool displayed) {int color;//方塊的填充顏色int lineColor = WHITE;//線的顏色int boardFalg = 0;int xRock = 0;int yRock = 0;unsigned short rockCode = RockArray[rockIdx].rockShapeBits;//如果displayed為true的話,將方塊塊顏色設置為white,game_board對應的位置設置為1;//如果displayed為false的話,將方塊塊顏色設置為black,game_board對應的位置設置為0;displayed ? (color = RED, boardFalg = 1) : (color = BLACK,lineColor = BLACK, boardFalg = 0);setcolor(lineColor);setfillcolor(color);setlinestyle(PS_SOLID);//設置為實線,xRock = LocatePtr->left;yRock = LocatePtr->top;int count = 0;//每4個換行,記錄坐標偏移量unsigned short mask = 1;for (int i = 1; i <= 16; ++i){mask = 1 << (16 - i);if ((rockCode & mask) != 0) //如果不為0的話,就畫出小方塊{ fillrectangle(xRock , yRock, xRock + ROCK_SQUARE_WIDTH, yRock + ROCK_SQUARE_WIDTH);}if (i % 4 == 0) //換行{yRock = yRock + ROCK_SQUARE_WIDTH; xRock = xRock = LocatePtr->left;}else{xRock += ROCK_SQUARE_WIDTH;}} }

Init.h

#include"Head.h"static void ShapeStrToBit(unsigned char *rockShapeStr, unsigned short& rockShapeBit); static void ReadRcok();void InitGame() {//把全局游戲游戲版初始化,邊界初始化為1for (int i = 0; i < xROCK_SQUARE_NUM + 2; i++){game_board[0][i] = 1; //上邊界game_board[yROCK_SQUARE_NUM + 1][i] = 1; //下邊界}for (int i = 0; i < yROCK_SQUARE_NUM + 2; i++){game_board[i][0] = 1 ; //左邊界game_board[i][xROCK_SQUARE_NUM + 1] = 1; //右邊界}//讀取俄羅斯方塊 ReadRcok();}//從文件中讀取方塊的形狀存儲到rockArray中 void ReadRcok() {FILE* fp = fopen("RockShape.ini","r");if (NULL == fp){printf("打開文件失敗\n");return;}unsigned char readBuf[1024]; //fp讀取到字符串readbuf中unsigned short rockShapeBit = 0;//存放方塊形狀,占16比特位unsigned char rockShapeStr[16];//存放方塊字符串int ShapeStrIdx = 0;int rockNum = 0;//統計方塊的個數以及存放方塊數組RockArray的下標int rocknext = 0;//方塊數組中下一個形狀int rockShapeStart = 0;//同一類型的形狀while (true){size_t readSize = fread(readBuf, 1, 1024, fp);if (readSize == 0)break;//處理readbuffor (size_t idx = 0; idx < readSize; ++idx){//將字符存放到rockShapeStr中while (ShapeStrIdx < 16 && idx < readSize){if (readBuf[idx] == '@' || readBuf[idx] == '#'){rockShapeStr[ShapeStrIdx] = (unsigned char)readBuf[idx];++ShapeStrIdx;}++idx; //可能idx == readSize了 if (readBuf[idx] == '*')//修改上一次方塊的next值{idx += 5;RockArray[--rockNum].nextRockIndex = rockShapeStart;rockNum++;rockShapeStart = rockNum;rocknext = rockShapeStart ;}}//可能沒有填滿if (ShapeStrIdx < 16){break;}else //填滿shapestr{ShapeStrIdx = 0;//置0//將rockShapeStr 轉為rockShapeBitShapeStrToBit(rockShapeStr, rockShapeBit);rocknext++;RockArray[rockNum].rockShapeBits = rockShapeBit;RockArray[rockNum].nextRockIndex = rocknext;rockNum++;}}}fclose(fp); } //將從文件中讀取的字符串(長度默認為16)轉換成 unsigned short void ShapeStrToBit(unsigned char *rockShapeStr, unsigned short& rockShapeBit) {rockShapeBit = 0;for (size_t idx = 0; idx < 16; ++idx){if (rockShapeStr[idx] == '@') //1{rockShapeBit |= (1 << (16 - idx - 1));}// #為0 不需要處理} }

game.h

#include"Head.h" #define _CRT_SECURE_NO_WARNINGS 1bool MoveAble(int rockIndex, RockLocation_t* currentLocatePtr, int f_direction); void SetGameBoardFlag(int rockIdx, RockLocation_t* curRockLocation); void UserHitKeyBoard(char userHit, int* RockIndex, RockLocation_t* curRockLocation); void FullLine(); void UpdateSocres(int scores); void DelCurLine(int rowIdx); bool IsGameOver();void PlayGame() {char userHit = 0;//用戶敲擊鍵盤int curRockIndex = 0;//當前方塊的rockArray下標int nextRockIndex = 0;//下次RockLocation_t curRockLocation;curRockLocation.left = initRockLocation.left;curRockLocation.top = initRockLocation.top;DWORD oldtime = 0;srand((unsigned int)time(NULL));curRockIndex = rand() % rockTypeNum;nextRockIndex = rand() % rockTypeNum;//畫出預覽區初始化方塊//在初始位置和預覽區顯示方塊形狀DisplayRock(curRockIndex, &initRockLocation, 1);DisplayRock(nextRockIndex, &preRockLocation, 1);bool moveAbled = false;while (true){//判斷當前方塊是否落地(判斷能否再下移):如果落地,判斷是否滿行,再判斷是否結束游戲, 改變game_board ,畫出下次初始化的方塊,以及生成新的預覽方塊//moveAbled = MoveAble(curRockIndex, &curRockLocation, DIRECT_DOWN);if (!moveAbled) //判斷是否落地,不能下移表示落地{//修改game_board的值SetGameBoardFlag(curRockIndex, &curRockLocation);FullLine(); if (IsGameOver()){MessageBox(NULL, _T("游戲結束"), _T("GAME OVER"), MB_OK);exit(0);} //為下次生成模塊開始準備DisplayRock(nextRockIndex, &preRockLocation, false);//擦除舊的方塊curRockIndex = nextRockIndex;nextRockIndex = rand() % rockTypeNum; //生成新的預覽方塊DisplayRock(curRockIndex, &initRockLocation, 1);DisplayRock(nextRockIndex, &preRockLocation, 1);FlushBatchDraw();//修改curRockLocation的值curRockLocation.left = initRockLocation.left;curRockLocation.top = initRockLocation.top; }if (kbhit()) //如果敲擊鍵盤了 就處理按鍵{userHit = getch();UserHitKeyBoard(userHit, &curRockIndex, &curRockLocation);}//沒有 就自動下移一個單位 :不能用else,因為可能按鍵不是上下左右DWORD newtime = GetTickCount();if (newtime - oldtime >= (unsigned int)(300) && moveAbled == TRUE){oldtime = newtime;DisplayRock(curRockIndex, &curRockLocation, false);curRockLocation.top += ROCK_SQUARE_WIDTH; //下落一格 }//AutomaticDownMove(curRockIndex, &curRockLocation);//畫出新方塊DisplayRock(curRockIndex, &curRockLocation, 1);FlushBatchDraw();Sleep(20);} }//響應鍵盤命令時間 void UserHitKeyBoard(char userHit, int* RockIndex, RockLocation_t* curRockLocation) {switch (userHit){case 'W':case 'w'://↑if (MoveAble(RockArray[*RockIndex].nextRockIndex, curRockLocation, DIRECT_UP)){DisplayRock(*RockIndex, curRockLocation, false);*RockIndex = RockArray[*RockIndex].nextRockIndex;}break;case 'S':case 's'://↓if (MoveAble(*RockIndex, curRockLocation, DIRECT_DOWN)){DisplayRock(*RockIndex, curRockLocation, false);curRockLocation->top += 2 * (ROCK_SQUARE_WIDTH);if (!MoveAble(*RockIndex, curRockLocation, DIRECT_DOWN)){curRockLocation->top -= ROCK_SQUARE_WIDTH;}}break;case 'A':case 'a': //←if (MoveAble(*RockIndex, curRockLocation, DIRECT_LEFT)){DisplayRock(*RockIndex, curRockLocation, false);curRockLocation->left -= ROCK_SQUARE_WIDTH;}break;case 'D':case 'd': //→if (MoveAble(*RockIndex, curRockLocation, DIRECT_RIGHT)){DisplayRock(*RockIndex, curRockLocation, FALSE);curRockLocation->left += ROCK_SQUARE_WIDTH;}break;case ' ': //暫停while (1){userHit = getch();if (userHit == ' ')break;}break;default:break;} }//判斷是否滿行,滿行消除,然后計算得分 void FullLine() {bool linefull = true;int idx = yROCK_SQUARE_NUM;//從最后一行往上查找 22int count = 0;while (count != xROCK_SQUARE_NUM ) //遇到空行 14{linefull = true;count = 0;for (int i = 1; i <= xROCK_SQUARE_NUM; ++i){if (game_board[idx][i] == 0){linefull = false;count++;}}if (linefull) //滿行,消除當前行,更新分數{DelCurLine(idx);game_socres += 3;UpdateSocres(game_socres);idx++;//因為下面要減1}idx--;}} void UpdateSocres(int scores) {setcolor(RED);TCHAR s[10];_stprintf(s, _T("%d"), scores);outtextxy(GAME_WALL_WIDTH + 90, 200, s); } //消除當前行 void DelCurLine(int rowIdx) {//擦除當前行setcolor(BLACK);setfillcolor(BLACK);for (int i = 1; i < xROCK_SQUARE_NUM; ++i){fillrectangle(WALL_SQUARE_WIDTH + (i - 1)*ROCK_SQUARE_WIDTH, (rowIdx - 1)*ROCK_SQUARE_WIDTH + WALL_SQUARE_WIDTH,WALL_SQUARE_WIDTH + i*ROCK_SQUARE_WIDTH, rowIdx*ROCK_SQUARE_WIDTH + WALL_SQUARE_WIDTH);}//把上面的向下移int cnt = 0;while (cnt != xROCK_SQUARE_NUM) //直到遇到是空行的為止 {cnt = 0;for (int i = 1; i <= xROCK_SQUARE_NUM; i++){game_board[rowIdx][i] = game_board[rowIdx - 1][i];//擦除上面的一行 setcolor(BLACK);setfillcolor(BLACK);fillrectangle(WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*i - ROCK_SQUARE_WIDTH ,WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*(rowIdx - 1) - ROCK_SQUARE_WIDTH ,WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*i,WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*(rowIdx - 1));//顯示下面的一行 if (game_board[rowIdx][i] == 1){setcolor(WHITE);setfillcolor(RED);fillrectangle(WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*i - ROCK_SQUARE_WIDTH ,WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*rowIdx - ROCK_SQUARE_WIDTH ,WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*i,WALL_SQUARE_WIDTH + ROCK_SQUARE_WIDTH*rowIdx);}if (game_board[rowIdx][i] == 0)cnt++; //統計一行是不是 都是空格 }//for rowIdx--;} }//是否可以移動方塊 bool MoveAble(int rockIndex, RockLocation_t* currentLocatePtr, int f_direction) {int mask;int rockX;int rockY;rockX = currentLocatePtr->left;rockY = currentLocatePtr->top;mask = (unsigned short)1 << 15;for (int i = 1; i <= 16; i++){//與掩碼相與為1的 即為方塊上的點 if ((RockArray[rockIndex].rockShapeBits & mask) != 0){//判斷能否移動(即掃描即將移動的位置 是否與設置的圍墻有重疊) //若是向上(即翻滾變形) if (f_direction == DIRECT_UP){//因為此情況下傳入的是下一個方塊的形狀,故我們直接判斷此方塊的位置是否已經被占 //判斷下一個方塊if (game_board[(rockY - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1][(rockX - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1] == 1)return false;}//如果是向下方向移動 else if (f_direction == DIRECT_DOWN){if (game_board[(rockY - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 2][(rockX - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1] == 1)return false;}else //如果是左右方向移動 { //f_direction的DIRECT_LEFT為-1,DIRECT_RIGHT為1,故直接加f_direction即可判斷。 if (game_board[(rockY - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1][(rockX - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1 + f_direction] == 1)return false;}}//每4次 換行 轉到下一行繼續 i % 4 == 0 ? (rockY += ROCK_SQUARE_WIDTH, rockX = currentLocatePtr->left): rockX += ROCK_SQUARE_WIDTH;mask >>= 1;}return true;} //給游戲game_board設置標記表示已經占了 void SetGameBoardFlag(int rockIdx, RockLocation_t* curRockLocation) {int mask;int rockX;int rockY;rockX = curRockLocation->left;rockY = curRockLocation->top;mask = (unsigned int)1 << 15;for (int i = 1; i <= 16; i++){//與掩碼相與為1的 即為方塊上的點 if ((RockArray[rockIdx].rockShapeBits & mask) != 0){game_board[(rockY - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1][(rockX - WALL_SQUARE_WIDTH) / ROCK_SQUARE_WIDTH + 1] = 1;}//每4次 換行 轉到下一行繼續畫 i % 4 == 0 ? (rockY += ROCK_SQUARE_WIDTH, rockX = curRockLocation->left): rockX += ROCK_SQUARE_WIDTH;mask >>= 1;} } //判斷游戲是否結束 bool IsGameOver() {bool topLineHaveRock = false;//頂行是否有方塊bool bottomLineHaveRock = false;for (int i = 1; i < xROCK_SQUARE_NUM; ++i){if (game_board[1][i] == 1)topLineHaveRock = true;if (game_board[yROCK_SQUARE_NUM][i] == 1)bottomLineHaveRock = true;}if (bottomLineHaveRock && topLineHaveRock)return true;else return false; }

main.cpp

#include"Head.h" #include"Draw.h" #include"Init.h" #include"game.h"int main() {initgraph(WINDOW_WIDTH,WINDOW_HIGH);DrawGameWindow();//使用 API 函數修改窗口名稱 HWND hWnd = GetHWnd();SetWindowText(hWnd, _T("俄羅斯方塊"));InitGame();PlayGame();getchar();closegraph();system("pause");return 0; }

配置文件:RockShape.ini

@### @### @@## ####@@@# @### #### ####@@## #@## #@## ######@# @@@# #### ####**** #@## #@## @@## ####@### @@@# #### ####@@## @### @### ####@@@# ##@# #### ####**** #@## @@@# #### ####@### @@## @### ####@@@# #@## #### #####@## @@## #@## ####**** #@## @@## @### ####@@## #@@# #### ####**** @### @@## #@## #####@@# @@## #### ####**** @### @### @### @###@@@@ #### #### ####**** @@## @@## #### ####****

總結

以上是生活随笔為你收集整理的【C语言】俄罗斯方块的源代码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。