?
十字消除,休閑小游戲,在規定時間內,只要是十字線能連接到的相同顏色的方塊,就能獲得相應的得分,如果點擊后沒有能夠消除的方塊會扣除時間,是一款益智小游戲。
我們將編寫十字消除游戲,用戶點擊空白方塊,沿其上下左右方向尋找第一個彩色方塊,如果有兩個或兩個以上顏色一致,就將其消除。在進度條時間結束前消除足夠的方塊,可以進入下一關。
?
繪制過程
首先實現隨機顏色方塊的表示與繪制,鼠標點擊與十字消除算法;然后繪制了提示框,繪制倒計時進度條;接著進行了得分計算、勝負判斷、多關卡功能的開發;學習了地址與指針的概念,并利用地址傳遞使得程序更加模塊化;最后學習了指針和數組的知識,應用動態數組實現了游戲尺寸的動態大小調整
在規定時間內,只要是十字線能連接到的相同顏色的方塊,就能獲得相應的得分,如果點擊后沒有能夠消除的方塊會扣除時間。
操作方法
鼠標點擊兩個或多個顏色相同方塊的十字線的中心,便能成功消除方塊。
注意是點擊空白格子而不是彩色方塊哦,點錯會扣時間,點左下角的[顯示圖標提示]可切換到圖標模式
?
代碼示例:
?
#include#include #include #include #include # define BlockSize 40 // 小方塊的長寬大小 # define ColorTypeNum 9 // 除了空白方塊外,其他方塊的顏色的個數 struct Block // 小方塊結構體 { int x,y; // x y坐標 int colorId; // 對應顏色的下標 int i,j; // 小方塊在二維數組中的i j下標 }; // 全局變量 int RowNum; // 游戲畫面一共RowNum行小方塊 int ColNum; // 游戲畫面一共ColNum列小方塊 Block **blocks = NULL; // 動態二維數組指針,存儲所有方塊數據 COLORREF colors[ColorTypeNum+1]; // 顏色數組,小方塊可能的幾種顏色 int score; // 得分數,也就是消去的方塊的個數 float maxTime; // 這一關游戲的總時長 float totalTime; // 減去扣分項后的游戲總時長 float remainTime; // 剩余時間 clock_t start, finish; // 用于計時的變量 int level = 1; // 當前關卡序號 int noZeroBlockNum; // 非空白區域的磚塊的個數 void drawBlockHint(int i,int j,COLORREF color,int isfill) // 繪制出一個提示線框出來 { setlinecolor(color); setfillcolor(color); if (isfill==1) // 鼠標點擊中的方塊,畫填充方塊提示 fillrectangle(blocks[i][j].x,blocks[i][j].y,blocks[i][j].x+BlockSize,blocks[i][j].y+BlockSize); if (isfill==0) // 上下左右四個方向找到的4個方塊,畫線框提示 rectangle(blocks[i][j].x,blocks[i][j].y,blocks[i][j].x+BlockSize,blocks[i][j].y+BlockSize); } void writeRecordFile(int recordScore) //保存最高分數據文件 { FILE *fp; fp = fopen(".\gameRecord.dat","w"); fprintf(fp,"%d",recordScore); fclose(fp); } int readRecordFile() //讀取最高分數據文件 { int recordScore; FILE *fp; fp = fopen(".\gameRecord.dat","r"); // 如果打不開的話,就新建一個文件,其得分記錄為0分 if (fp==NULL) { writeRecordFile(0); return 0; } else // 能打開這個文件,就讀取下最高分記錄 { fscanf(fp,"%d",&recordScore); fclose(fp); return recordScore; } } void startup() // 初始化函數 { int i,j; start = clock(); // 記錄當前運行時刻 if (level>1) // 如果不是第1關,則先清除二維數組內存,再重新開辟內存空間 { for (i=0;i readRecordFile()) { // 更新下得分記錄 writeRecordFile(score); // 顯示恭喜超過記錄 show(); settextcolor(RGB(255,0,0)); settextstyle(100, 0, _T("黑體")); outtextxy(BlockSize*(ColNum/30.0), BlockSize*(RowNum/3.0), _T("恭喜打破得分記錄")); FlushBatchDraw(); // 批量繪制 Sleep(2000); } if (score>=int(noZeroBlockNum*0.9)) { level ++; // 如果得分達到要求,消除掉非空白方塊數目的90%,關卡加1 } startup(); // 調用初始化函數,重新開始游戲 return; } } void updateWithInput() // 和輸入有關的更新 { if (remainTime<=0) // 時間到了,不要操作 return; int i,j; MOUSEMSG m; if (MouseHit()) { m = GetMouseMsg(); if(m.uMsg == WM_LBUTTONDOWN) // 當按下鼠標左鍵時 { // 獲得點擊的小方塊的下標 int clicked_i = int(m.y)/BlockSize; int clicked_j = int(m.x)/BlockSize; // 點擊到下面提示部分了,不用處理,函數返回 if (clicked_i>=RowNum) return; // 如果當前點擊的不是空白方塊,不需要處理,返回 if (blocks[clicked_i][clicked_j].colorId!=0) return; show(); // 先顯示其他方塊,再繪制提示框,后繪制的在最前面 // 被點擊到的空白方塊,繪制下填充灰色方塊提示框 drawBlockHint(clicked_i,clicked_j,RGB(100,100,100),1); // 定義數組,存儲上、下、左、右四個方向找到第一個不是空白的方塊 Block fourBlocks[4] = {blocks[clicked_i][clicked_j]}; // 初始化為這個空白的點擊的方塊 int search; // 尋找下標 // 向上找 for (search=0;clicked_i-search>=0;search++) { if (blocks[clicked_i-search][clicked_j].colorId!=0) // 找到第一個顏色不是空白的方塊 { fourBlocks[0] = blocks[clicked_i-search][clicked_j]; // 賦給這個存儲的數組 break; } } // 向下找 for (search=0;clicked_i+search =0;search++) { if (blocks[clicked_i][clicked_j-search].colorId!=0) // 找到第一個顏色不是空白的方塊 { fourBlocks[2] = blocks[clicked_i][clicked_j-search]; // 賦給這個存儲的數組 break; } } // 向右找 for (search=0;clicked_j+search =2) // 如果這種顏色方塊個數大于等于2 { isBadClick = 0; // 能消除了,這次點擊是好的操作 // 把對應十字區域要消除的方塊顏色改成空白顏色 for (j=0;j<4;j++) // 遍歷fourBlocks { if (fourBlocks[j].colorId==i) { // 要消除的方塊區域繪制提示框 drawBlockHint(fourBlocks[j].i,fourBlocks[j].j,RGB(0,0,0),0); // 顏色序號設為0,也就是空白的灰白色 blocks[fourBlocks[j].i][fourBlocks[j].j].colorId = 0; } } score += colorStatistics[i]; // 得分加上消除的方塊數 } } // 點擊的方塊,十字區域沒有能消除的方塊,為錯誤點擊,減去10秒鐘時間 if (isBadClick==1) totalTime -= 10; FlushBatchDraw(); // 批量繪制 Sleep(300); // 繪制好提示框后暫停300毫秒 } // while 當按下鼠標左鍵時 } } int main() // 主函數運行 { startup(); while (1) { show(); updateWithoutInput(); updateWithInput(); } closegraph(); return 0; }
?
這一節主要講解了指針的相關語法知識,學習了倒計時的方法,實現了十字消除游戲。讀者可以嘗試在本章代碼基礎上繼續改進:
1、實現隨著游戲的進行,通過關卡要求消除方塊的比例越來越高;
2、利用文件讀寫,實現關卡數據與最高分的記錄與讀取。
讀者也可以參考本章的開發思路,嘗試設計并分步驟實現消消樂、消滅星星、寶石迷陣等各種消除類游戲。
審核編輯:湯梓紅
評論
查看更多