利用c++和easyx图形库做一个低配版扫雷游戏
时间:2021-05-01 09:34:48|栏目:C代码|点击: 次
游戏界面
由于这个游戏是我抱着玩一玩的心态做出来的,所以没有过多的去设计界面,也没有去找游戏的资源(图片、游戏音效等)。仅使用了不同颜色的方块来表示游戏中方块的状态和种类。(绿色为初始状态(未翻转的状态),黄色为翻转后的背景颜色,蓝色表示已插旗的方块,红色代表地雷)
图1 游戏主菜单界面
图二 模式一的游戏界面(20*20 40个雷)
图三 模式二的游戏界面(10*10 20个雷)
图四 游戏成功界面
图五 游戏失败界面
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官网提供的文档详细的介绍了各种函数的用法,很容易上手。
总结
栏 目:C代码
本文地址:http://www.codeinn.net/misctech/112686.html