首頁 > 軟體

C語言製作掃雷遊戲(圖形庫)

2022-06-07 14:00:28

本文範例為大家分享了C語言製作掃雷遊戲的具體程式碼,供大家參考,具體內容如下

遊戲預覽:

學習內容:

1.圖形庫檔案的使用
2.C++的使用,如類函數
3.瞭解掃雷的規則,嚴謹的思維邏輯

掃雷的規則:

玩家點選一個地方,如果該地方是雷,則遊戲結束;如果是空格,則會顯示周圍空格和周圍8個格子的雷的數量,玩家依照提示逐步挖掘全部的雷,從而結束遊戲。

製作步驟:

基本的庫函數和常數

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include <graphics.h>
#include <conio.h>
#include <windows.h>

#define WIDTH 10//遊戲寬度
#define NUM 12//雷的數量
#define SIZE 70///單張位置圖片的大小

1.生成遊戲地圖

如果想生成一個M x N的掃雷地圖,是不是要定義一個map[M][N]的二維陣列呢?
答案是否定的。
點選一個位置,如果它是空格需要遍歷周圍8個位置,如果周圍8個位置有空格的話,那麼那個空格也需遍歷周圍8個位置,如此反覆。但問題來了,如果當遍歷到了邊緣一層,邊緣周圍沒有8個位置,造成陣列越界怎麼辦?
所以,這裡我們就要在地圖設2個區,即保護區遊戲區

假設我們像創作一個M x N大小的掃雷地圖,**那麼就定義一個map[M+2][N+2]大小的陣列。**即設計一層保護區,其目的就是當遍歷到邊緣一格時,防止陣列越界報錯。

int map[WIDTH + 2][WIDTH + 2];

2.初始化遊戲地圖

第一步:先假設每個位置都是空格,即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)//當該位置是空格時才產生雷
        {
            map[r][c] = -1;//-1代表雷
            n++;
        }
    }

第三步:遍歷一個空格周圍8個位置的雷的數量,每有一個雷,該位置所對應的陣列值加1

for (int i = 1; i <= WIDTH; i++)//從遊戲區的第1個座標開始
    {
        for (int j = 1; j <= WIDTH; j++)
        {
            if (map[i][j] == -1)//如果這個位置是雷
            {
                for (int m = i - 1; m <= i + 1; m++)//遍歷周圍8八個
                {
                    for (int n = j - 1; n <= j + 1; n++)
                    {
                        if (map[m][n] != -1 && m != 0 && n != 0)
                        {
                            map[m][n]++;
                        }
                    }
                }
            }
        }
    }

第四步:給每個位置都加密,讓這些位置的在一個範圍內顯示“■”

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.滑鼠點選功能

定義滑鼠函數,讓它可以點選相應的位置觸發函數

fflush(stdin);//清空緩衝區的字元
    flushmessage(EM_MOUSE | EM_KEY);//清空緩衝區的滑鼠事件
    int heng, zong;
    ExMessage m;
    m = getmessage(EM_MOUSE | EM_KEY);//獲取滑鼠或鍵盤事件
    heng = m.x / SIZE+1;//獲取滑鼠點選在控制檯上的橫座標
    zong = m.y / SIZE+1;//獲取滑鼠點選在控制檯上的縱座標
    switch (m.message)
    {
    case WM_LBUTTONDOWN://按滑鼠左鍵掃雷
        s = DiTu.ReturnT(heng, zong);//點選的位置是否能觸發函數
        if ((heng >= 1 && heng <= WIDTH&&zong >= 1 && zong <= WIDTH)&&s)//沒被標記的才能被點選
        {
            updateNum(heng, zong);
            DiTu.drawMap();//每點一下就畫一次圖
        }
        break;
    case WM_RBUTTONDOWN://按滑鼠右鍵做標記
        DiTu.BiaoJi(heng,zong);
        break;
    case WM_MBUTTONDOWN://按滑鼠滑輪退出
        exit(0);
        break;
    }

判斷函數:判斷點選的位置是否合理

bool ReturnT(int heng, int zong)
{
    if (map[heng][zong]<50)
    {
        return true;
    }
    else
    {
        return false;
    }
}

標記函數:點選滑鼠右邊標記該點,使該點不能被點選

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.掃出周圍數位的函數,如果有周圍有空格則遍歷執行

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)//除去保護密碼
                {
                    map[heng][zong] -= 20;
                    putimage(heng*SIZE, zong*SIZE, &img[map[heng][zong]]);
                }
            }
        }
    }
    if (map[heng][zong] > 10 && map[heng][zong] < 50)//除去保護密碼
    {
        map[heng][zong] -= 20;
        putimage(heng*SIZE, zong*SIZE, &img[map[heng][zong]]);
    }
}

遊戲效果瀏覽

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。


IT145.com E-mail:sddin#qq.com