C語言制作掃雷游戲(圖形庫)
本文實(shí)例為大家分享了C語言制作掃雷游戲的具體代碼,供大家參考,具體內(nèi)容如下
游戲預(yù)覽:


學(xué)習(xí)內(nèi)容:
1.圖形庫文件的使用
2.C++的使用,如類函數(shù)
3.了解掃雷的規(guī)則,嚴(yán)謹(jǐn)?shù)乃季S邏輯
掃雷的規(guī)則:
玩家點(diǎn)擊一個(gè)地方,如果該地方是雷,則游戲結(jié)束;如果是空格,則會(huì)顯示周圍空格和周圍8個(gè)格子的雷的數(shù)量,玩家依照提示逐步挖掘全部的雷,從而結(jié)束游戲。
制作步驟:
基本的庫函數(shù)和常量
#include<stdio.h> #include<stdlib.h> #include<time.h> #include <graphics.h> #include <conio.h> #include <windows.h> #define WIDTH 10//游戲?qū)挾? #define NUM 12//雷的數(shù)量 #define SIZE 70///單張位置圖片的大小
1.生成游戲地圖
如果想生成一個(gè)M x N的掃雷地圖,是不是要定義一個(gè)map[M][N]的二維數(shù)組呢?
答案是否定的。
點(diǎn)擊一個(gè)位置,如果它是空格需要遍歷周圍8個(gè)位置,如果周圍8個(gè)位置有空格的話,那么那個(gè)空格也需遍歷周圍8個(gè)位置,如此反復(fù)。但問題來了,如果當(dāng)遍歷到了邊緣一層,邊緣周圍沒有8個(gè)位置,造成數(shù)組越界怎么辦?
所以,這里我們就要在地圖設(shè)2個(gè)區(qū),即保護(hù)區(qū)和游戲區(qū)。

假設(shè)我們像創(chuàng)作一個(gè)M x N大小的掃雷地圖,**那么就定義一個(gè)map[M+2][N+2]大小的數(shù)組。**即設(shè)計(jì)一層保護(hù)區(qū),其目的就是當(dāng)遍歷到邊緣一格時(shí),防止數(shù)組越界報(bào)錯(cuò)。
int map[WIDTH + 2][WIDTH + 2];
2.初始化游戲地圖
第一步:先假設(shè)每個(gè)位置都是空格,即0
for (int i = 1; i <= WIDTH; i++)
?? ?{
?? ??? ?for (int j = 1; j <= WIDTH; j++)
?? ??? ?{
?? ??? ??? ?map[i][j] = 0;
?? ??? ??? ?putimage(i*SIZE, j*SIZE, &img[0]);
?? ??? ?}
?? ?}第二步:初始化雷的分布
int n = 0;
?? ?while (n < NUM)
?? ?{
?? ??? ?int r = rand() % WIDTH + 1;
?? ??? ?int c = rand() % WIDTH + 1;
?? ??? ?if (map[r][c] == 0)//當(dāng)該位置是空格時(shí)才產(chǎn)生雷
?? ??? ?{
?? ??? ??? ?map[r][c] = -1;//-1代表雷
?? ??? ??? ?n++;
?? ??? ?}
?? ?}第三步:遍歷一個(gè)空格周圍8個(gè)位置的雷的數(shù)量,每有一個(gè)雷,該位置所對(duì)應(yīng)的數(shù)組值加1
for (int i = 1; i <= WIDTH; i++)//從游戲區(qū)的第1個(gè)坐標(biāo)開始
?? ?{
?? ??? ?for (int j = 1; j <= WIDTH; j++)
?? ??? ?{
?? ??? ??? ?if (map[i][j] == -1)//如果這個(gè)位置是雷
?? ??? ??? ?{
?? ??? ??? ??? ?for (int m = i - 1; m <= i + 1; m++)//遍歷周圍8八個(gè)
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?for (int n = j - 1; n <= j + 1; n++)
?? ??? ??? ??? ??? ?{
?? ??? ??? ??? ??? ??? ?if (map[m][n] != -1 && m != 0 && n != 0)
?? ??? ??? ??? ??? ??? ?{
?? ??? ??? ??? ??? ??? ??? ?map[m][n]++;
?? ??? ??? ??? ??? ??? ?}
?? ??? ??? ??? ??? ?}
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ?}第四步:給每個(gè)位置都加密,讓這些位置的在一個(gè)范圍內(nèi)顯示“■”
for (int i = 1; i <= WIDTH; i++)
?? ?{
?? ??? ?for (int j = 1; j <= WIDTH; j++)
?? ??? ?{
?? ??? ??? ?map[i][j] += 20;
?? ??? ??? ?if (map[i][j] > 11)
?? ??? ??? ?{
?? ??? ??? ??? ?printf_s("■ ");
?? ??? ??? ??? ?putimage((i-1)*SIZE, (j-1)*SIZE, &img[12]);
?? ??? ??? ?}
?? ??? ?}
?? ??? ?printf_s("\n");
?? ?}3.鼠標(biāo)點(diǎn)擊功能
定義鼠標(biāo)函數(shù),讓它可以點(diǎn)擊相應(yīng)的位置觸發(fā)函數(shù)
fflush(stdin);//清空緩沖區(qū)的字符
?? ?flushmessage(EM_MOUSE | EM_KEY);//清空緩沖區(qū)的鼠標(biāo)事件
?? ?int heng, zong;
?? ?ExMessage m;
?? ?m = getmessage(EM_MOUSE | EM_KEY);//獲取鼠標(biāo)或鍵盤事件
?? ?heng = m.x / SIZE+1;//獲取鼠標(biāo)點(diǎn)擊在控制臺(tái)上的橫坐標(biāo)
?? ?zong = m.y / SIZE+1;//獲取鼠標(biāo)點(diǎn)擊在控制臺(tái)上的縱坐標(biāo)
?? ?switch (m.message)
?? ?{
?? ?case WM_LBUTTONDOWN://按鼠標(biāo)左鍵掃雷
?? ??? ?s = DiTu.ReturnT(heng, zong);//點(diǎn)擊的位置是否能觸發(fā)函數(shù)
?? ??? ?if ((heng >= 1 && heng <= WIDTH&&zong >= 1 && zong <= WIDTH)&&s)//沒被標(biāo)記的才能被點(diǎn)擊
?? ??? ?{
?? ??? ??? ?updateNum(heng, zong);
?? ??? ??? ?DiTu.drawMap();//每點(diǎn)一下就畫一次圖
?? ??? ?}
?? ??? ?break;
?? ?case WM_RBUTTONDOWN://按鼠標(biāo)右鍵做標(biāo)記
?? ??? ?DiTu.BiaoJi(heng,zong);
?? ??? ?break;
?? ?case WM_MBUTTONDOWN://按鼠標(biāo)滑輪退出
?? ??? ?exit(0);
?? ??? ?break;
?? ?}判斷函數(shù):判斷點(diǎn)擊的位置是否合理
bool ReturnT(int heng, int zong)
{
?? ?if (map[heng][zong]<50)
?? ?{
?? ??? ?return true;
?? ?}
? ? else
? ? {
?? ??? ?return false;
? ? }
}標(biāo)記函數(shù):點(diǎn)擊鼠標(biāo)右邊標(biāo)記該點(diǎn),使該點(diǎn)不能被點(diǎn)擊
void BiaoJi(int heng, int zong)
{
?? ?if (map[heng][zong]>10 && map[heng][zong] < 50)
?? ?{
?? ??? ?map[heng][zong] += 50;
?? ?}
?? ?else{
?? ??? ?map[heng][zong] -= 50;
?? ?}
}4.掃出周圍數(shù)字的函數(shù),如果有周圍有空格則遍歷執(zhí)行
void UpdateNum(int heng, int zong)
{
?? ?if (map[heng][zong] - 20 == 0)//0才需要遍歷
?? ?{
?? ??? ?for (int i = heng - 1; i <= heng + 1; i++)
?? ??? ?{
?? ??? ??? ?for (int j = zong - 1; j <= zong + 1; j++)
?? ??? ??? ?{
?? ??? ??? ??? ?UpdateNum(i, j);//遞歸
?? ??? ??? ??? ?if (map[heng][zong] > 10 && map[heng][zong]<50)//除去保護(hù)密碼
?? ??? ??? ??? ?{
?? ??? ??? ??? ??? ?map[heng][zong] -= 20;
?? ??? ??? ??? ??? ?putimage(heng*SIZE, zong*SIZE, &img[map[heng][zong]]);
?? ??? ??? ??? ?}
?? ??? ??? ?}
?? ??? ?}
?? ?}
?? ?if (map[heng][zong] > 10 && map[heng][zong] < 50)//除去保護(hù)密碼
?? ?{
?? ??? ?map[heng][zong] -= 20;
?? ??? ?putimage(heng*SIZE, zong*SIZE, &img[map[heng][zong]]);
?? ?}
}游戲效果瀏覽

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
FFmpeg實(shí)現(xiàn)音頻漸響效果參數(shù)值詳解
這篇文章主要為大家介紹了FFmpeg實(shí)現(xiàn)音頻漸響效果參數(shù)值詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
虛函數(shù)被類的構(gòu)造析構(gòu)函數(shù)和成員函數(shù)調(diào)用虛函數(shù)的執(zhí)行過程
虛函數(shù)被類的構(gòu)造析構(gòu)函數(shù)和成員函數(shù)調(diào)用虛函數(shù)的執(zhí)行過程,需要的朋友可以參考下2013-02-02
C語言中使用快速排序算法對(duì)元素排序的實(shí)例詳解
這篇文章主要介紹了C語言中使用快速排序算法對(duì)元素排序的實(shí)例詳解,文中細(xì)分了幾個(gè)情況來舉例,在注釋里有說明,需要的朋友可以參考下2016-04-04

