调节台小游戏MineSweeper
调控台小游戏MineSweeper,小游戏minesweeper
决定台扫雷游戏。
材料:EasyX图形库
1 #include<set>
2 #include<array>
3 #include<string>
4 #include<time.h>
5 #include<graphics.h>
6
7 using namespace std;
8 #define Num 20 //小方块数量Num*Num //rand()使得Num数值太小进入死循环
9 #define Size 25 //每个小方块大小
10 using UInt16 = unsigned short int;
11 using TheMap = array<array<UInt16, Num + 2>, Num + 2>; //引索地图
12 #define Trap (UInt16)0X0000 //地雷
13 #define InitMap (UInt16)0X0001 //表示无地雷,每次X2表示周围地雷数+1
14 #define Asked (UInt16)0XFFFF //标志已询问
15
16 void Init(TheMap &Map); //生成Map、地雷,绘制窗口
17 bool MainLoop(TheMap &Map); //游戏循环
18 void DisplayEmpty(TheMap &Map, int i, int j); //对提示区0的绘制
19 void DisplayNum(TheMap &Map, int i, int j); //对提示区1-8的绘制
20 int DisplayFlag(TheMap &Map, int i, int j); //对标志的绘制
21
22 int main() {
23 auto hwnd = initgraph(Num * Size, Num * Size);
24 //游戏的实现
25 TheMap Map;
26 Init(Map);
27 if (MainLoop(Map))
28 MessageBox(hwnd, L"Win", L"Mine Clerance", MB_OK);
29 else
30 MessageBox(hwnd, L"Defeated", L"Mine Clerance", MB_OK);
31 //离开游戏
32 closegraph();
33 return 0;
34 }
35 void Init(TheMap &Map) {
36 //初始化Map
37 for (auto &It : Map)
38 It.assign(InitMap);
39 //随机生成地雷
40 srand((unsigned)time(NULL));
41 for (UInt16 k = 0; k < 2 * Num;) {
42 auto i = rand() % Num + 1;
43 auto j = rand() % Num + 1;
44 if (Map[i][j] == InitMap) {
45 Map[i][j] = Trap;
46 for (int m = -1; m <= 1; ++m)
47 for (int n = -1; n <= 1; ++n)
48 Map[i + m][j + n] <<= 1;
49 ++k;
50 }
51 }
52 //赋值Asked,防止越界
53 for (size_t i = 0; i < Num + 2; ++i) {
54 Map[i][0] = Asked;
55 Map[i][Num + 1] = Asked;
56 Map[0][i] = Asked;
57 Map[Num + 1][i] = Asked;
58 }
59 //绘制可视地图
60 setlinecolor(LIGHTGREEN);
61 for (size_t i = Size; i < Size * Num; i += Size) {
62 line(i, 0, i, Size * Num);
63 line(0, i, Size * Num, i);
64 }
65 }
66 bool MainLoop(TheMap &Map) {
67 int Ret = 0;
68 MOUSEMSG Point;
69 while (Ret != 1) {
70 Point = GetMouseMsg();
71 if (Point.mkLButton) { //鼠标左键--点开小方块
72 Point = GetMouseMsg();
73 size_t i = Point.x / Size + 1;
74 size_t j = Point.y / Size + 1;
75 switch (Map[i][j]) {
76 case Trap: //按到地雷
77 for (size_t i = 1; i < Num + 1; ++i)
78 for (size_t j = 1; j < Num + 1; ++j)
79 if (Map[i][j] == Trap)
80 outtextxy(i*Size - Size / 2, j*Size - 3 * Size / 4, L"X");
81 return false;
82 case InitMap: //按到0
83 DisplayEmpty(Map, i, j);
84 break;
85 case InitMap << 1:
86 case InitMap << 2:
87 case InitMap << 3:
88 case InitMap << 4:
89 case InitMap << 5:
90 case InitMap << 6:
91 case InitMap << 7:
92 case InitMap << 8:
93 DisplayNum(Map, i, j); //按到1-8
94 break;
95 }
96 }
97 else if (Point.mkRButton) { //鼠标右键--标记
98 Point = GetMouseMsg();
99 auto i = Point.x / Size + 1;
100 auto j = Point.y / Size + 1;
101 Ret = DisplayFlag(Map, i, j);
102 if (Ret == -1) {
103 DisplayFlag(Map, i, j);
104 MessageBox(GetHWnd(), L"NO More Mark", L"MineSweeper", MB_OK);
105 }
106 }
107 }
108 return true;
109 }
110 void DisplayEmpty(TheMap &Map, int i, int j) {
111 //九宫格历遍,递归
112 for (int m = i - 1; m <= i + 1; ++m)
113 for (int n = j - 1; n <= j + 1; ++n) {
114 if (Map[m][n] == InitMap) {
115 Map[m][n] = Asked;
116 outtextxy(m*Size - Size / 2, n*Size - 3 * Size / 4, wstring(to_wstring(0)).c_str());
117 DisplayEmpty(Map, m, n);
118 }
119 else if (Map[m][n] != Asked)
120 DisplayNum(Map, m, n);
121 }
122 }
123 void DisplayNum(TheMap &Map, int i, int j) {
124 UInt16 num = 8;
125 switch (Map[i][j]) {
126 case 2:--num;
127 case 4:--num;
128 case 8:--num;
129 case 16:--num;
130 case 32:--num;
131 case 64:--num;
132 case 128:--num;
133 case 256:num;
134 Map[i][j] = Asked;
135 outtextxy(i*Size - Size / 2, j*Size - 3 * Size / 4, wstring(to_wstring(num)).c_str());
136 break;
137 }
138 }
139 int DisplayFlag(TheMap &Map, int i, int j) {
140 static UInt16 TrueFlags = 0; //定义被正确标志的地雷的数量
141 static UInt16 FlagTimes = 0; //定义被用户标志的地雷的数量
142 static set<UInt16> Record; //定义容器,用于记录标记点
143 if (Map[i][j] == Asked) //对已经访问点不做操作
144 return 0;
145 UInt16 ret = i << 8 | j; //适用:Map下标最大0XFFFF
146 auto Iter = Record.insert(ret);
147 if (Iter.second) {//标记
148 outtextxy(i*Size - Size / 2, j*Size - 3 * Size / 4, L"\?");
149 if (Map[i][j] == Trap)
150 ++TrueFlags;
151 ++FlagTimes;
152 }
153 else {//清除标记
154 Record.erase(ret);
155 setfillcolor(BLACK);
156 fillrectangle(i*Size - Size, j*Size - Size, i*Size, j*Size);
157 if (Map[i][j] == Trap)
158 --TrueFlags;
159 --FlagTimes;
160 }
161 if (TrueFlags == 2 * Num)
162 return 1;
163 if (FlagTimes > 2 * Num) //控制标记数
164 return -1;
165 return 0;
166 }
2018-02-26
调节台扫雷游戏。 材料:EasyX图形库 1 #调节台小游戏MineSweeper。include set 2 #include array 3
#include string 4 #include time.h 5 #include…
调控台扫雷游戏。
C++小游戏BrickHit,小游戏brickhit
打砖块小游戏。材质:EasyX图形库。
撞击的拍卖,木板移动方法还索要优化。
1 //定义 Circle,Brick,Broad
2 #include<cmath>
3 #include<graphics.h>
4
5 #ifndef _PROPERTY_H_
6 #define _PROPERTY_H_
7 struct Circle {
8 int x0, y0, r;
9 int mvX, mvY;
10 COLORREF color;
11 virtual ~Circle() {}
12 Circle(int x0_, int y0_, int r_, int mvX_, int mvY_, COLORREF color_)
13 :x0(x0_), y0(y0_), r(r_), mvX(mvX_), mvY(mvY_), color(color_) {}
14 //小球起始位置
15 void prtCirl() {
16 setfillcolor(color);
17 solidcircle(x0, y0, r);
18 }
19 //小球的移动
20 void CirlMove() {
21 setfillcolor(BLACK);
22 solidcircle(x0, y0, r);
23 x0 += mvX;
24 y0 += mvY;
25 setfillcolor(color);
26 solidcircle(x0, y0, r);
27 }
28 //判断小球是否离开宽口内。
29 //参数:窗口左上坐标、宽、高。
30 //离开返回真。
31 bool IsCirlQuit(int x, int y, int width, int height) {
32 if (x0 - x <= r && mvX < 0) {
33 mvX = -mvX;
34 return false;
35 }
36 else if (x + width - x0 <= r && mvX > 0) {
37 mvX = -mvX;
38 return false;
39 }
40 else if (y0 - y <= r && mvY < 0) {
41 mvY = -mvY;
42 return false;
43 }
44 else if (y + height - y0 <= r)
45 return true;
46 return false;
47 }
48 };
49 struct Brick {
50 int x0, y0;
51 COLORREF color;
52 int height, width;
53 virtual ~Brick() {}
54 Brick(int x0_, int y0_, int width_, int height_, COLORREF color_)
55 :x0(x0_), y0(y0_), width(width_), height(height_), color(color_) {}
56 //砖块的绘制
57 void prtBrick() {
58 setfillcolor(color);
59 solidrectangle(x0, y0, x0 + width, y0 + height);
60 }
61 //判断砖块是否与小球发生碰撞
62 //参数:小球
63 //发生碰撞返回真
64 bool IsCrashCirl(Circle &arg) {
65 if (arg.x0 + arg.r < x0 || x0 + width < arg.x0 - arg.r)
66 return false;
67 int disY = min(abs(y0 - arg.y0), abs(y0 + height - arg.y0));
68 if (disY <= arg.r) {
69 arg.mvY = -arg.mvY;
70 return true;
71 }
72 return false;
73 }
74 //砖块的清除
75 void BrickClr() {
76 setfillcolor(BLACK);
77 solidrectangle(x0, y0, x0 + width, y0 + height);
78 }
79 };
80 struct Broad :public Brick{
81 int mvX;
82 int floor, ceiling;
83 virtual ~Broad() {}
84 Broad(int x0_, int y0_, int width_, int height_, int mvX_,
85 int floor_, int ceiling_, COLORREF color_)
86 :Brick(x0_, y0_, width_, height_, color_), mvX(mvX_), floor(floor_), ceiling(ceiling_) {}
87 //重载,判断木板是否与小球发生碰撞
88 //参数:小球
89 //发生碰撞返回真
90 bool IsCrashCirl(Circle &arg) {
91 if (arg.x0 + arg.r < x0 || x0 + width < arg.x0 - arg.r)
92 return false;
93 if (y0 - arg.y0 <= arg.r&&arg.mvY > 0) {
94 arg.mvY = -arg.mvY;
95 return true;
96 }
97 return false;
98 }
99 //木板移动
100 void BroadMove() {
101 POINT point;
102 GetCursorPos(&point);
103 if (x0 <= point.x&&point.x <= x0)
104 return;
105 BrickClr();
106 if (point.x < x0)
107 x0 = max(x0 - mvX, floor);
108 else
109 x0 = min(x0 + mvX, ceiling - width);
110 setfillcolor(color);
111 solidrectangle(x0, y0, x0 + width, y0 + height);
112 }
113 };
114 #endif // _PROPERTY_H_
//Main.cpp
#include<list>
#include<algorithm>
#include"property.cpp"
using namespace std;
const int WndW = 400, WndH = 400; //窗口大小
list<Brick> CreatBricks();
bool theGame(list<Brick> &MyBrks, Broad &MyBrd, Circle&MyCirl);
int main() {
//brick布局
list<Brick> MyBrks = move(CreatBricks());
//broad:60*20,移速5,WHITE
Broad MyBrd(WndW/2 - 30, WndH - 20, 60, 20, 5, 0, WndW, WHITE);
//circle:半径5,移速5,DARKGRAY
Circle MyCirl(WndW/2 - 10, WndH - 20 - 10, 10, 5, 5, DARKGRAY);
HWND Hwnd = initgraph(WndW, WndH);
bool GameOver = theGame(MyBrks, MyBrd, MyCirl);
if (GameOver)
MessageBox(Hwnd, L"u Win!", L"BrickHit",MB_OK);
else
MessageBox(Hwnd, L"default!", L"BrickHit", MB_OK);
closegraph();
return 0;
}
//bricks的实现
list<Brick> CreatBricks() {
//brick信息:5行10列,40*10
int Row = 5, Col = 10;
int BrickW = WndW / Col;
int BrickH = 10;
list<Brick> MyBrks;
bool ColChoice = true;
for (int i = Row - 1; i >= 0; i--) {
ColChoice = !ColChoice;
for (int j = 0; j < Col; j++)
switch (ColChoice) {
case true:
MyBrks.push_back({ BrickW*j,BrickH*i,BrickW,BrickH,LIGHTGREEN });
ColChoice = !ColChoice;
break;
case false:
MyBrks.push_back({ BrickW*j,BrickH*i,BrickW,BrickH,LIGHTCYAN });
ColChoice = !ColChoice;
break;
}
}
return MyBrks;
}
//游戏的实现
bool theGame(list<Brick> &MyBrks, Broad &MyBrd, Circle&MyCirl) {
//游戏起始界面
for_each(MyBrks.begin(), MyBrks.end(), [](Brick it) { it.prtBrick(); });
MyBrd.prtBrick();
MyCirl.prtCirl();
//游戏循环
while (!MyBrks.empty()) {
MyCirl.CirlMove();
MyBrd.BroadMove();
if (MyCirl.IsCirlQuit(0, 0, WndW, WndH))
return false;
MyBrd.IsCrashCirl(MyCirl);
auto theBrick = find_if(MyBrks.begin(), MyBrks.end(),
[&MyCirl](Brick it) { return it.IsCrashCirl(MyCirl); });
if (theBrick != MyBrks.end()) {
theBrick->BrickClr();
MyBrks.erase(theBrick);
}
Sleep(30);
}
return true;
}
2018-02-11
打砖块小游戏。质感:EasyX图形库。 碰撞的管理,木板移动方法还亟需优化。 1
// 定义 Circle,Brick,Broad 2 #…
学习Eaxy X图形库后小编的果实:
材料:EasyX图形库
花了一周时间做出并健全了Flappy Bird,近日效用如下:
1 #include<set>
2 #include<array>
3 #include<string>
4 #include<time.h>
5 #include<graphics.h>
6
7 using namespace std;
8 #define Num 20 //小方块数量Num*Num //rand()使得Num数值太小进入死循环
9 #define Size 25 //每个小方块大小
10 using UInt16 = unsigned short int;
11 using TheMap = array<array<UInt16, Num + 2>, Num + 2>; //引索地图
12 #define Trap (UInt16)0X0000 //地雷
13 #define InitMap (UInt16)0X0001 //表示无地雷,每次X2表示周围地雷数+1
14 #define Asked (UInt16)0XFFFF //标志已询问
15
16 void Init(TheMap &Map); //生成Map、地雷,绘制窗口
17 bool MainLoop(TheMap &Map); //游戏循环
18 void DisplayEmpty(TheMap &Map, int i, int j); //对提示区0的绘制
19 void DisplayNum(TheMap &Map, int i, int j); //对提示区1-8的绘制
20 int DisplayFlag(TheMap &Map, int i, int j); //对标志的绘制
21
22 int main() {
23 auto hwnd = initgraph(Num * Size, Num * Size);
24 //游戏的实现
25 TheMap Map;
26 Init(Map);
27 if (MainLoop(Map))
28 MessageBox(hwnd, L"Win", L"Mine Clerance", MB_OK);
29 else
30 MessageBox(hwnd, L"Defeated", L"Mine Clerance", MB_OK);
31 //离开游戏
32 closegraph();
33 return 0;
34 }
35 void Init(TheMap &Map) {
36 //初始化Map
37 for (auto &It : Map)
38 It.assign(InitMap);
39 //随机生成地雷
40 srand((unsigned)time(NULL));
41 for (UInt16 k = 0; k < 2 * Num;) {
42 auto i = rand() % Num + 1;
43 auto j = rand() % Num + 1;
44 if (Map[i][j] == InitMap) {
45 Map[i][j] = Trap;
46 for (int m = -1; m <= 1; ++m)
47 for (int n = -1; n <= 1; ++n)
48 Map[i + m][j + n] <<= 1;
49 ++k;
50 }
51 }
52 //赋值Asked,防止越界
53 for (size_t i = 0; i < Num + 2; ++i) {
54 Map[i][0] = Asked;
55 Map[i][Num + 1] = Asked;
56 Map[0][i] = Asked;
57 Map[Num + 1][i] = Asked;
58 }
59 //绘制可视地图
60 setlinecolor(LIGHTGREEN);
61 for (size_t i = Size; i < Size * Num; i += Size) {
62 line(i, 0, i, Size * Num);
63 line(0, i, Size * Num, i);
64 }
65 }
66 bool MainLoop(TheMap &Map) {
67 int Ret = 0;
68 MOUSEMSG Point;
69 while (Ret != 1) {
70 Point = GetMouseMsg();
71 if (Point.mkLButton) { //鼠标左键--点开小方块
72 Point = GetMouseMsg();
73 size_t i = Point.x / Size + 1;
74 size_t j = Point.y / Size + 1;
75 switch (Map[i][j]) {
76 case Trap: //按到地雷
77 for (size_t i = 1; i < Num + 1; ++i)
78 for (size_t j = 1; j < Num + 1; ++j)
79 if (Map[i][j] == Trap)
80 outtextxy(i*Size - Size / 2, j*Size - 3 * Size / 4, L"X");
81 return false;
82 case InitMap: //按到0
83 DisplayEmpty(Map, i, j);
84 break;
85 case InitMap << 1:
86 case InitMap << 2:
87 case InitMap << 3:
88 case InitMap << 4:
89 case InitMap << 5:
90 case InitMap << 6:
91 case InitMap << 7:
92 case InitMap << 8:
93 DisplayNum(Map, i, j); //按到1-8
94 break;
95 }
96 }
97 else if (Point.mkRButton) { //鼠标右键--标记
98 Point = GetMouseMsg();
99 auto i = Point.x / Size + 1;
100 auto j = Point.y / Size + 1;
101 Ret = DisplayFlag(Map, i, j);
102 if (Ret == -1) {
103 DisplayFlag(Map, i, j);
104 MessageBox(GetHWnd(), L"NO More Mark", L"MineSweeper", MB_OK);
105 }
106 }
107 }
108 return true;
109 }
110 void DisplayEmpty(TheMap &Map, int i, int j) {
111 //九宫格历遍,递归
112 for (int m = i - 1; m <= i + 1; ++m)
113 for (int n = j - 1; n <= j + 1; ++n) {
114 if (Map[m][n] == InitMap) {
115 Map[m][n] = Asked;
116 outtextxy(m*Size - Size / 2, n*Size - 3 * Size / 4, wstring(to_wstring(0)).c_str());
117 DisplayEmpty(Map, m, n);
118 }
119 else if (Map[m][n] != Asked)
120 DisplayNum(Map, m, n);
121 }
122 }
123 void DisplayNum(TheMap &Map, int i, int j) {
124 UInt16 num = 8;
125 switch (Map[i][j]) {
126 case 2:--num;
127 case 4:--num;
128 case 8:--num;
129 case 16:--num;
130 case 32:--num;
131 case 64:--num;
132 case 128:--num;
133 case 256:num;
134 Map[i][j] = Asked;
135 outtextxy(i*Size - Size / 2, j*Size - 3 * Size / 4, wstring(to_wstring(num)).c_str());
136 break;
137 }
138 }
139 int DisplayFlag(TheMap &Map, int i, int j) {
140 static UInt16 TrueFlags = 0; //定义被正确标志的地雷的数量
141 static UInt16 FlagTimes = 0; //定义被用户标志的地雷的数量
142 static set<UInt16> Record; //定义容器,用于记录标记点
143 if (Map[i][j] == Asked) //对已经访问点不做操作
144 return 0;
145 UInt16 ret = i << 8 | j; //适用:Map下标最大0XFFFF
146 auto Iter = Record.insert(ret);
147 if (Iter.second) {//标记
148 outtextxy(i*Size - Size / 2, j*Size - 3 * Size / 4, L"\?");
149 if (Map[i][j] == Trap)
150 ++TrueFlags;
151 ++FlagTimes;
152 }
153 else {//清除标记
154 Record.erase(ret);
155 setfillcolor(BLACK);
156 fillrectangle(i*Size - Size, j*Size - Size, i*Size, j*Size);
157 if (Map[i][j] == Trap)
158 --TrueFlags;
159 --FlagTimes;
160 }
161 if (TrueFlags == 2 * Num)
162 return 1;
163 if (FlagTimes > 2 * Num) //控制标记数
164 return -1;
165 return 0;
166 }
1. 背景的显得
2018-02-26
2. 加入小鸟image
3. 鸟类自由下跌,按空格键/鼠标右键后上升
4. 加入静态的障碍物
5. 障碍物向左移动
6. 推断碰撞
7. 障碍物移动出侧边界后,在左侧重新出现
8. 记分模块
9. 加入开头界面、停止分界面
10. 步入背景音乐
11.加盟最高分总结(待完毕)
半路用到的lib、dll、头文件如下:
1.#调节台小游戏MineSweeper。include <graphics.h>
2.#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
#include <windows.h>
#include “mmsystem.h”
winmm.lib
产品 Flappy bird 截图如下:
可是也可以有瑕玷,柱子左移偏慢,利用putimage会变成刚烈的位移效果,以往有空再修改
项目相关代码放在了自个儿的 github 上,有意思味的能够 clone 到 Windows 的
D盘下运营。
通过学习Eaxy X图形库七日左右,可以做出如下程序
1.国际象棋棋盘绘制
2.弹球(七彩渐变,且遇荧屏反弹,反弹动向随机)
3.石英钟(正确到秒,策画到家程序,画上刻度)
运用EasyX图形库,利用图形素材做一些轻巧易行的游艺,给C语言学习增添部分乐趣。
下边贴干货链接:
EasyX安装包下载链接:
下载 — EasyX Library for
C++
怎样设置 EasyX? — EasyX Library for
C++
怎么样使用 EasyX?(Visual C++ 6.0) — EasyX Library for
C++
哪些利用 EasyX?(Visual C++ 二〇一〇) — EasyX Library for
C++官方网站还提供了一套蛮好的入门教程,我们能够自学:
VC绘图/游戏简易教程–前言 — EasyX Library for
C++对应的目录:
–前言
–1:创制新类型
–2:轻易绘图,学习单步推行
–3:熟识越来越多的绘图语句
–4:结合流程序调节制语句来绘图
–5:数学知识在绘图中的运用
–bf88必发唯一官网,6:达成轻易动画
–7:捕获按钮,完结动画的简便调整
–8:用函数简化一样图案的制作
–9:绘图中的位运算
–10:用鼠标调节绘图/打闹程序
–11:随机函数
–12:数组
–13:getimage/putimage/loadimag/saveimage/
IMAGE的用法–14:通过位运算完成颜色的分开与管理
–15:窗体句柄(Windows编制程序入门)
–16:设备上下文句柄(Windows编程入门2)
其余推荐关心河海大学C语言老师,童晶先生,特别严刻踏实、致力于入门教学的民间兴办教授,比笔者渣邮的本科老师在元气上投入确实是不能够比。
他的账户:
童晶 – 知乎
她在新浪有专栏:
做游戏,学编制程序(C语言) 二〇一五大学一年级上同学开垦的一对游戏效果 –
今日头条专栏
正在念书中,望共勉:-)