提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助檔案
文章目錄
- 前言
- 一、掃雷的玩法,以及實作功能介紹
- 二、代碼實作
- 1.引入庫
- 2.宏定義部分
- 3.初始化游戲界面
- 4.加載圖片
- 5.繪制圖片到視窗
- 6.操作控制(滑鼠控制)及功能實作
- 7.main函式
- 總結
前言
提示:這里給大家介紹的是easyX圖形庫的應用,來制作掃雷小游戲
解釋:EasyX 是針對 C++ 的圖形庫,可以幫助 C/C++ 初學者快速上手圖形和游戲編程,
過多的在這我不多說自己去了解
提示:以下是本篇文章正文內容,下面案例可供參考
一、掃雷的玩法,以及實作功能介紹
掃雷相信很多人小時候都玩過,就是在一個矩形框框中有很多小方塊,左擊對應的小方塊,可能會出現數字,數字代表以數字為中心的九宮格中,數字周圍雷的個數,但數字是 0 的時候打開0四周的所有格子,玩的話,就要自己判斷了,
二、代碼實作
1.引入庫
代碼如下(示例):
#include<stdio.h>
#include<stdlib.h>
#include<graphics.h> //圖形庫
#include<time.h>
#include<windows.h>
2.宏定義部分
因為我們知道在掃雷里面有些已經固定了的值,比如:雷的個數,每個格子的大小,一行多少個格子,一列多少個格子,
代碼如下(示例):
#define ROW 20 //行數
#define COL 20 //列數
#define NUM 100 //雷的個數
#define SIZE 30 //圖片尺寸
3.初始化游戲界面
(1)定義一個二維陣列作為地圖
int map[ROW+2][COL+2]; //定義一個地圖
注意:為什么要在行和列上都加一個2呢,這是因為要考慮在這個四邊的資料要遍歷九宮格的時候會越界,
(2)初始化函式
這里我們要對地圖賦初值為0;
然后再在地圖上隨機產生 NUM 個雷,即《布雷》;
布完雷后,我們要遍歷每一個不為雷的格子填充資料,也就是以當前位置為中心計算周圍的雷的個數;
加密資料(這是為了后面好計算);
輸出檢查(這個在剛開始的時候可以輸出檢查檢查,之后就可以注釋掉,或刪掉);
(代碼如下):
//初始化游戲界面
void gameInit()
{
srand((unsigned int)time(NULL));
for (int i = 0; i < ROW + 2; i++)
{
for (int j = 0; j < COL + 2; j++)
{
map[i][j] = 0;
}
}
//布雷 -1 表示為 雷
int r, c, n = 0;
while (n < NUM)
{
r = rand() % ROW + 1; //隨機產生行坐標
c = rand() % COL + 1; //隨機產生列坐標
if (map[r][c] == -1) //判斷當前位置是不是“雷” 目的:為了在同一位置重復布雷
{
continue;
}
else
{
map[r][c] = -1; //不是“雷”則當前位置布置為雷
rayxy[n].x = r;
rayxy[n].y = c;
n++;
}
}
//填充資料
for (int i = 1; i <= ROW; i++)
{
for (int j = 1; j <= COL; j++)
{
if (map[i][j] != -1)
{
//遍歷九宮格 (i,j) 表示當前坐標
for (int r = i - 1; r <= i + 1; r++) // (i-1,j-1) (i-1,j) (i-1,j+1)
{ // (i,j-1) (i,j) (i,j+1)
for (int c = j - 1; c <= j + 1; c++) // (i+1,j-1) (i+1,j) (i+1,j+1)
{
if (map[r][c] == -1)
{
map[i][j]++;
}
}
}
}
}
}
//加密資料
/*
元素 圖片
0-8 數字 +20 20-28
-1 雷 +20 19
19-28 空白圖片
>30 標記
*/
for (int i = 1; i <= ROW; i++)
{
for (int j = 1; j <= COL; j++)
{
map[i][j] += 20;
}
}
//輸出檢查
/*for (int i = 1; i <= ROW; i++)
{
for (int j = 1; j <= COL; j++)
{
printf("%2d ", map[i][j]);
}
printf("\n");
}
*/
}
4.加載圖片
IMAGE img[13];//定義為全域
void loadImg()//匯入圖片
{
// 這里要使用多位元組字符集
loadimage(&img[0], "./images/0.jpg", SIZE, SIZE);//0
loadimage(&img[1], "./images/1.jpg", SIZE, SIZE);
loadimage(&img[2], "./images/2.jpg", SIZE, SIZE);
loadimage(&img[3], "./images/3.jpg", SIZE, SIZE);
loadimage(&img[4], "./images/4.jpg", SIZE, SIZE);
loadimage(&img[5], "./images/5.jpg", SIZE, SIZE);
loadimage(&img[6], "./images/6.jpg", SIZE, SIZE);
loadimage(&img[7], "./images/7.jpg", SIZE, SIZE);
loadimage(&img[8], "./images/8.jpg", SIZE, SIZE);//8
loadimage(&img[9], "./images/9.jpg", SIZE, SIZE);//標記
loadimage(&img[10], "./images/10.jpg", SIZE, SIZE);//空白
loadimage(&img[11], "./images/11.jpg", SIZE, SIZE);//雷
loadimage(&img[12], "./images/12.jpg", SIZE*ROW, SIZE*COL);
}
5.繪制圖片到視窗
(代碼如下):
void drawGraph()
{
/*
元素 圖片
0-8 數字 +20 20-28
-1 img[11] +20 19
19-28 img[10]
>30 img[9]
*/
for (int i = 1; i <= ROW; i++)
{
for (int j = 1; j <= COL; j++)
{
printf("%3d ", map[i][j]);
if (map[i][j] == -1)
{
putimage((j - 1)*SIZE, (i - 1) * SIZE, &img[11]);//雷
}
else if (map[i][j] >= 0 && map[i][j] <= 8)
{
putimage((j - 1) * SIZE, (i - 1) * SIZE, &img[map[i][j]]);//0-8的數字
}
else if (map[i][j] >= 19 && map[i][j] <= 28)
{
putimage((j - 1) * SIZE, (i - 1) * SIZE, &img[10]);//空白
}
else if (map[i][j] > 30)
{
putimage((j - 1) * SIZE, (i - 1) * SIZE, &img[9]);//標記圖片
}
}
printf("\n\n");
}
printf("\n");
}
6.操作控制(滑鼠控制)及功能實作
單擊左鍵,打開空白圖片,右擊標記,為“ 0 ”時打開四周的空白圖片 (如圖):

(代碼如下):
//為“0”時打開四周的空白圖片
void openZero(int r, int c) //實作遞回
{
map[r][c] -= 20;
count++;
for (int m = r - 1; m <= r + 1; m++)
{
for (int n = c - 1; n <= c + 1; n++) //九宮格
{
if (m >= 1 && m <= ROW && n >= 1 && n <= COL) //游戲區的內容
{
if (map[m][n] >= 19 && map[m][n] <= 28)
{
if (map[m][n] != 20)
{
map[m][n] -= 20;
count++;
}
else
{
openZero(m, n);
}
}
}
}
}
}
//玩游戲
int playGame()
{
MOUSEMSG msg = { 0 };
int r, c;
while (1)
{
msg = GetMouseMsg(); //獲取滑鼠當前資訊
switch (msg.uMsg) //判斷當前滑鼠訊息
{
case WM_LBUTTONDOWN: //左擊,打開空白圖片
c = msg.x / SIZE + 1;
r = msg.y / SIZE + 1;
if (map[r][c] >= 19 && map[r][c] <= 28)
{
if (map[r][c] == 20)
{
openZero(r, c);//遞回
}
else
{
map[r][c] -= 20;
count++;
}
}
return map[r][c];
break;
case WM_RBUTTONDOWN: //右擊 標記一個空白圖片
c = msg.x / SIZE + 1;
r = msg.y / SIZE + 1;
if (map[r][c] >= 19 && map[r][c] <= 28)
{
map[r][c] += 50; //>30 變成標記圖片
}
else if (map[r][c] >= 30)
{
map[r][c] -= 50;
}
return map[r][c];
break;
}
}
}
7.main函式
我要說的都在下面的代碼里面進行了注釋
有一個 count 的 全域變數 是用來統計判斷所有的雷是否全部找出的,
還有一個 showAllRay() 的函式是用來當點到雷的是后顯示所有的雷的
這個函式代碼希望大家盡量自己完成(不會的加我 QQ:2793179445)
int main()
{
srand((unsigned int)time(NULL));
initgraph(ROW * SIZE, COL * SIZE); //創建視窗
loadImg(); //匯入圖片
putimage(0, 0, &img[12]); //開始界面
Sleep(1000); //模擬加載延遲
settextstyle(30, 10, "楷體"); //設定提示文字大小和字體
settextcolor(RGB(rand() % 256, rand() % 256, rand() % 256)); //設定提示文字顏色
outtextxy(getwidth() / 2 - 50, COL*SIZE-50, "請稍后..."); //定位提示文字輸出位置,以及提示文字內容
Sleep(2000); //模擬加載延遲
closegraph(); //清除
loop:
HWND hwnd = initgraph(ROW * SIZE, COL * SIZE/*, SHOWCONSOLE*/); //重新創建一個視窗
gameInit(); //呼叫初始化界面函式
while (1) //游戲回圈
{
drawGraph();
if (playGame() == -1) //判斷點到的是不是雷,為雷結束
{
drawGraph();
showAllRay(); //顯示所有的雷
drawGraph();
Sleep(2000);
MessageBox(hwnd, "you are a low B", "提示", MB_OK);
int x = MessageBox(hwnd, "重開一局", "提示", MB_OKCANCEL);
if (x == 1) //判斷是否為“確定”
{ //若是重開一局
goto loop;
}
break;
}
if (ROW * COL - NUM == count)
{
drawGraph();
MessageBox(hwnd, "you are very good !!!", "提示", MB_OK);
break;
}
}
return 0;
}
效果如下:



總結
提示:這里對文章進行總結:
例如:以上就是今天要講的內容,本文介紹了EasyX的使用,以及掃雷實作方法,
希望對大家有一些幫助,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/237538.html
標籤:其他
上一篇:推箱子——功能更新
