用c++和easyx圖形庫做一個低配版掃雷遊戲

用c++和easyx圖形庫做一個低配版掃雷遊戲

  1. 遊戲界面
    由於這個遊戲是我抱着玩一玩的心態做出來的,所以沒有過多的去設計界面,也沒有去找遊戲的資源(圖片、遊戲音效等)。僅使用了不同顏色的方塊來表示遊戲中方塊的狀態和種類。(綠色爲初始狀態(未翻轉的狀態),黃色爲翻轉後的背景顏色,藍色表示已插旗的方塊,紅色代表地雷)

圖1 遊戲主菜單界面

圖1遊戲的主菜單

圖二 模式一的遊戲界面(20*20 40個雷)

圖2 模式1的遊戲界面

圖三 模式二的遊戲界面(10*10 20個雷)

圖3 模式2的遊戲界面

圖四 遊戲成功界面

圖四 遊戲成功界面

圖五 遊戲失敗界面

遊戲失敗界面

2.全部代碼

#include<graphics.h>
#include<iostream>
#include<conio.h>
#include<time.h>
using namespace std;

#define POINTWIDTH 30

//雷的數量
int mineCnt;
int mapSize;
//已翻轉的個數
int _count;
//是否有雷
bool mine[20][20] = { false };

//是否已翻轉
bool overturned[20][20] = { false };

bool flaged[20][20] = { false };
//遊戲模式
int mode;
//遊戲重新開始的標誌
int cmd = 1;
//遊戲結束標誌
bool gameOver;
//玩家獲勝標誌
bool _win;

//小方格(座標)
typedef struct point {
	int x;
	int y;
	point(int _x, int _y) {
		x = _x; y = _y;
	}
}point;

//計算周圍的地雷數量
int getAroundMineCnt(point p) {
	int cnt=0;
	for (int i = p.x - 1; i <= p.x + 1; i++) {
		for (int j = p.y - 1; j <= p.y + 1; j++) {
			if (i >= 0 && i < 20 && j >= 0 && j < 20 && mine[i][j])
				cnt++;
		}
	}
	return cnt;
}
//畫點(小方格)
void drawPoint(point p,int color) {
	setfillcolor(color);
	fillrectangle(p.x*POINTWIDTH +140,p.y*POINTWIDTH +140, p.x * POINTWIDTH + 140+ POINTWIDTH, p.y * POINTWIDTH + 140+ POINTWIDTH);
}

//畫地雷(紅色方塊代替)
void drawMine(point p) {
	setfillcolor(RED);
	fillrectangle(p.x * POINTWIDTH + 140, p.y * POINTWIDTH + 140, p.x * POINTWIDTH + 140+POINTWIDTH, p.y * POINTWIDTH + 140+POINTWIDTH);
}

//畫旗(藍色方塊代替)
void drawflag(point p) {
			flaged[p.x][p.y] = true;

	drawPoint(p, BLUE);
}


//遊戲結束對話框與"重玩"、"退出"
void gameover(int &cmd) {
	gameOver = 1;
	for (int i = 0; i < mapSize; i++) {
		for (int j = 0; j < mapSize; j++) {
			if (mine[i][j]) { 
				point p(i, j);
				drawMine(p); }
		}
	}
	Sleep(500);
	setfillcolor(LIGHTGRAY);
	fillrectangle(200,300,700,550);
	rectangle(200, 500, 350, 550);
	rectangle(550, 500, 700, 550);
	setbkmode(1);
	settextstyle(60, 0, 0);
	outtextxy(300, 400, _T("Game over"));
	settextstyle(38, 0, 0);
	outtextxy(220, 510, _T("Restart"));
	outtextxy(560, 510, _T( "    Quit"));
	MOUSEMSG m;
	while (1) {
		m = GetMouseMsg();
		if (m.mkLButton&&m.y > 500 && m.y < 550 && m.x>200 && m.x < 350)
			break;
		else if (m.mkLButton&&m.y > 500 && m.y < 550 && m.x>550 && m.x < 700) {
			cmd = 0;
			break;
		}

	}
}

//遊戲勝利對話框與"重玩"、"退出"
void win(int &cmd) {
	_win = 1;
	setfillcolor(LIGHTGRAY);
	fillrectangle(200, 300, 700, 550);
	rectangle(200, 500, 350, 550);
	rectangle(550, 500, 700, 550);
	setbkmode(1);
	settextstyle(60, 0, 0);
	outtextxy(300, 400, _T("You Win!"));
	settextstyle(38, 0, 0);
	outtextxy(220, 510, _T("Restart"));
	outtextxy(560, 510, _T("    Quit"));
	MOUSEMSG m;
	while (1) {
		m = GetMouseMsg();
		if (m.mkLButton&&m.y > 500 && m.y < 550 && m.x>200 && m.x < 350)
			break;
		else if (m.mkLButton&&m.y > 500 && m.y < 550 && m.x>550 && m.x < 700) {
			cmd = 0;
			break;
		}

	}

}

//翻轉
void overturn(point p,int t) {
	settextstyle(POINTWIDTH*0.8 , POINTWIDTH*0.8 , 0);
	settextcolor(BLACK);
	if (t == 1) {
		if (!mine[p.x][p.y]) {
			_count++;
			drawPoint(p, YELLOW);
			overturned[p.x][p.y] =true ;
			//判斷周圍的雷的數量是否爲0,爲0則翻轉該方塊周邊的8個方塊
			if (getAroundMineCnt(p) != 0) {
				int cnt = getAroundMineCnt(p);
				_TCHAR a[3];
				_stprintf_s(a, L"%d", cnt);
				outtextxy(p.x*POINTWIDTH+POINTWIDTH*0.1+ 140, p.y*POINTWIDTH+POINTWIDTH*0.1 + 140, a);
				if (_count == mapSize * mapSize - mineCnt) { win(cmd); return; }
			}
			else {
				for (int i = p.x - 1; i <= p.x + 1; i++) {
					for(int j=p.y-1;j<=p.y+1;j++)
						if (i >= 0 && i < mapSize && j >= 0 && j < mapSize&&!overturned[i][j]) {
							point temp(i, j);
							overturn(temp, 1);
						}
				}
			}
		}
		else { gameover(cmd); return; }
	}
	else {
		if (!flaged[p.x][p.y]) {
			drawflag(p);
		}
		else {
			flaged[p.x][p.y] = false;
			drawPoint(p, GREEN);
		}
	}
}

//右鍵插旗

void play() {
	
	while (true) {
		MOUSEMSG m;
		m = GetMouseMsg();
		if (m.mkLButton&&m.x > 140 && m.x < 140+mapSize*POINTWIDTH && m.y > 140 && m.y < 140+mapSize*POINTWIDTH)
		{
			point p((m.x - 140) / POINTWIDTH, (m.y - 140) / POINTWIDTH);//將鼠標點擊的座標轉換成對應位置的方塊
			if(!overturned[p.x][p.y])
			overturn(p,1);
		}
		if (m.mkRButton&&m.x > 140 && m.x < 740 && m.y > 140 && m.y < 740)
		{
			point p((m.x - 140) / POINTWIDTH, (m.y - 140) / POINTWIDTH);
			if(!overturned[p.x][p.y])
			overturn(p, 2);
		}
		if (gameOver) return;
		else if (_win) return;
	}


}



//初始化遊戲界面
void  initGameface() {
	if(mode==1)
	rectangle(140, 140, 740, 740);
	else rectangle(140, 140, 440, 440);
	setbkcolor(LIGHTGRAY);
	cleardevice();
	setbkcolor(YELLOW);
	point p(0, 0);
	for (int i = 0; i < mapSize; i++) {
		for (int j = 0; j < mapSize; j++) {
			p.x = i;
			p.y = j;
			drawPoint(p, GREEN);
		}
	}
	
}

//地雷的隨機生成器
void  generator() {
	int cnt = 0;

	while (cnt < mineCnt) {
		int i = rand() % mapSize;
		int j = rand() % mapSize;
		if (!mine[i][j]) {
			mine[i][j] = true;
			cnt++;
		}
	}

}
//遊戲的開始界面(圖1)
void startInterface(int &mode) {
	mode = 1;
	initgraph(880, 880);
	setbkcolor(LIGHTGRAY);
	cleardevice();
	setlinecolor(RED);
	rectangle(100, 100, 780, 300);
	rectangle(300, 400, 580, 500);
	rectangle(300, 530, 580, 630);
	rectangle(300,660, 580, 760);
	settextcolor(RED);
	settextstyle(100,0,0);
	outtextxy(300,140,L"掃  雷");
	settextstyle(60, 0, 0);
	outtextxy(320, 420, L"新 遊 戲");
	outtextxy(320, 550, L"簡        單");
	outtextxy(320, 680, L"遊戲幫助");
	MOUSEMSG m;
	while (1) {
		m = GetMouseMsg();
		if (m.mkLButton&&m.x > 300 && m.x < 580 && m.y>400 && m.y < 500)
			break;
		else if (m.mkLButton&&m.x > 300 && m.x < 580 && m.y>530 && m.y < 630)
			if (mode == 1) {
				mode = 2;
				rectangle(300, 530, 580, 630);
				outtextxy(320, 550, L"困        難");
			}
			else {
				mode = 1;
				rectangle(300, 530, 580, 630);
				outtextxy(320, 550, L"簡        單");
			}
		else if (m.mkLButton&&m.x > 300 && m.x < 580 && m.y>660 && m.y < 760) {
			cleardevice();
			MOUSEMSG mm;
			while (1) {
				mm = GetMouseMsg();
				if (mm.mkLButton) break;
			}
			startInterface(mode);
		}
	}
}


//初始化遊戲
void initgame(int mode) {
	_win = 0;
	_count = 0;
	gameOver = 0;
	if (mode == 1) {
		mineCnt= 40;
		mapSize = 20;
	}
	else {
		mineCnt = 20;
		mapSize = 10;
	}
	for (int i = 0; i < mapSize; i++) {
		for (int j = 0; j < mapSize; j++) {
			mine[i][j] = 0;
			flaged[i][j] = 0;
			overturned[i][j] = 0;
		}
	}
}

//整個遊戲過程
void game() {
	srand(unsigned(time));
	startInterface(mode);
	while (cmd) {
		initgame(mode);
		initGameface();
		generator();
		play();
	}

}


int main() {
	game();

}

3. 符加說明:本程序使用了簡單好用的easyx圖形庫:可以Easyx官網中下載安裝,且Easyx官網提供的文檔詳細的介紹了各種函數的用法,很容易上手。

發佈了17 篇原創文章 · 獲贊 27 · 訪問量 2624
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章