如何才能提供自己的编程水平,就要千锤百炼。今天给大家推荐的是拼图小游戏;采用 c++ 编写, 主要使用到了两个类, 分别是 GameFrame 和 Picture。GameFrame 负责游戏界面的初始化和原始信息的绘制;Picture 负责图片的切割, 图片位置的初始化,通关条件判断, 控制整个游戏正确运行。另外这次还修改了鼠标位置与图片的定位算法, 同时图片位置初始化由正确的通关位置移动而来, 所以能保证拼图游戏绝对有解. 不需要使用复杂的数学公式来判断。
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421picture.cpp // 加载头文件 #include "../Inc/picture.h" int main() { GameFrame gameframe; // 建立游戏框架 Picture picture; // 建立图片框架 gameframe.DrawBackground(); // 绘制背景 gameframe.StartMenu(); // 绘制开始信息 while (1) { picture.Run(); // 运行控制函数 Sleep(10); // 适当增加延时, 节约 CPU } getch(); return 0; } // 游戏框架类的默认构造函数 GameFrame::GameFrame() { initgraph (xLength, yLength); setbkcolor (BgColor); cleardevice (); } // 绘制背景图像 void GameFrame::DrawBackground() { float H, S, L; // 定义 HSL 颜色模型的 3 个变量 H = 70; S = -2.2555f; // 饱和度 L = 0.525617f; BeginBatchDraw(); for(int i = 0; i != yLength; ++i) // 绘制游戏背景颜色 { L += 0.000000085f; S -= 0.0013f; setlinecolor(HSLtoRGB(H, S, L)); line(0, i, xLength, i); } EndBatchDraw(); } // 开始菜单 void GameFrame::StartMenu() { setbkmode(TRANSPARENT); // 设置背景为透明 settextcolor(BLUE); // 设置文字颜色为蓝色 settextstyle(23, 0, _T("华文行楷")); // 设置字体信息 outtextxy(700, 25, _T("游戏作者: Bob")); // 绘制游戏作者的名字 settextstyle(30, 0, _T("华文行楷")); // 设置字体的大小 outtextxy(230, 85, _T("欢迎来到拼图游戏的世界")); // 绘制提示信息 settextstyle(23, 0, _T("华文行楷")); // 设置字体信息 outtextxy(300, 170, _T("选择游戏的难度:")); // 绘制提示信息 outtextxy(300, 210, _T("<A> 一般")); outtextxy(300, 270, _T("<B> 中等")); outtextxy(300, 330, _T("<C> 较难")); setlinestyle(PS_SOLID, 5, NULL); setlinecolor(BLUE); // 设置线条颜色为蓝色 rectangle(200,50,600,400); line(200, 150, 600, 150); } // 控制函数 void Picture::Run() { switch (Control) { case 0: { SetGameDifficult(); // 设置游戏难度 break; } case 1: { SetPicture(); // 设置图像 DrawRect(); // 绘制矩形 break; } case 2: { PrintPicture(); // 将图像输出到屏幕上 break; } case 3: { ProcessMouse(); // 处理鼠标消息 IsPass(); // 是否通关 break; } default: { break; } } } // 设置游戏的难度 void Picture::SetGameDifficult() { char num; // 读取键盘的键值 while (1) { if (kbhit()) { mciSendString("play Res\key.wav", NULL, 0, NULL); num = getch(); // 从键盘获取信息 switch (num) { case 'a':Diffcult = 3;break; case 'b':Diffcult = 4;break; case 'c':Diffcult = 5;break; default:Diffcult = 0; } } // 如果游戏难度已获取则退出循环 if (Diffcult != 0) { Control = 1; break; } } } // 设置图片 void Picture::SetPicture() { loadimage(&img, String.c_str(), Width, Height); // 加载图像 singleWidth = Width / Diffcult; // 单个切割图像的长度 singleHeight = Height / Diffcult; image = new Image *[Diffcult]; // 分配空间 Query = new int *[Diffcult]; // 给查询数组分配空间 SetWorkingImage(&img); // 设置绘图设备 // 切割图像, 设置其位置 for (int i = 0; i < Diffcult; ++i) { image[i] = new Image[Diffcult]; Query[i] = new int [Diffcult]; for (int j = 0; j < Diffcult; ++j) { image[i][j].x = j; image[i][j].y = i; Query[i][j] = i * Diffcult + j; if (i != Diffcult - 1 || j != Diffcult - 1) { getimage(&(image[i][j].image), j * singleWidth, i * singleHeight, singleWidth - 3, singleHeight - 3); } } } SetWorkingImage(); // 恢复默认绘图设备 // 从正确的结果出发来打散图片, 这样能保证结果绝对有解 SetLocal(); // 对最切割成小图片后的最后一张进行处理 image[Diffcult - 1][Diffcult - 1].image.Resize(singleWidth - 3, singleHeight - 3); SetWorkingImage(&(image[Diffcult - 1][Diffcult -1].image)); // 设置绘图设备 float H, S, L; // 定义 HSL 颜色模型的 3 个变量 H = 50; // 色相 S = -3.2555f; // 饱和度 L = 0.525617f; for(int i = 0; i != singleHeight; ++i) // 将线条绘制到图像中去 { L += 0.000000085f; S -= 0.0015f; setlinecolor(HSLtoRGB(H, S, L)); line(0, i, singleWidth, i); } SetWorkingImage(); Control = 2; } // 将图像输出到屏幕 void Picture::PrintPicture() { // 将切割后的图像加载到屏幕中去 for (int i = 0; i < Diffcult; ++i) { for (int j = 0; j < Diffcult; ++j) { putimage(image[i][j].x * singleWidth + 3, image[i][j].y * singleHeight + 3, &(image[i][j].image)); } } Resize(&img, 300, 225); loadimage(&img, String.c_str(), 300, 225); // 加载完整图像 setbkmode(TRANSPARENT); settextstyle(23, 0, _T("华文行楷")); // 设置字体信息 settextcolor(BLUE); outtextxy(700, 25, _T("游戏作者: Bob")); // 绘制游戏作者的名字 outtextxy(740, 70, _T("完整图像")); putimage(630, 100, &img); Control = 3; } // 绘制线条 void Picture::DrawRect() { setlinecolor(BgColor); // 设置边框颜色 setfillcolor(BgColor); // 设置填充颜色 POINT points[] = {{0, 0}, {0, 453}, {600, 453}, {600,0}}; fillpolygon(points, 4); Control = 2; } // 处理鼠标信息 void Picture::ProcessMouse() { int ImageX = image[Diffcult - 1][Diffcult - 1].x; int ImageY = image[Diffcult - 1][Diffcult - 1].y; // 如果鼠标按下 while (MouseHit()) { MouseMessage = GetMouseMsg(); // 获取鼠标消息 switch (MouseMessage.uMsg) { case WM_LBUTTONDOWN: // 鼠标左键按下 { mciSendString("play Res\key.wav", NULL, 0, NULL); // 播放声音 LocalX = MouseMessage.x / singleWidth; // 获取鼠标的所在的图像的特征 LocalY = MouseMessage.y / singleHeight; break; } default: { break; } } // 在空图像四周才会处理该鼠标信息 if (LocalX == ImageX) { if (LocalY == ImageY - 1 || LocalY == ImageY + 1) { ProcessPicture(); } } else if (LocalY == ImageY) { if (LocalX == ImageX - 1 || LocalX == ImageX + 1) { ProcessPicture(); } } } } void Picture::ProcessPicture() { int num = 0; int Diff = Diffcult -1; int x1, y1; num = Query[LocalY][LocalX]; // 定位鼠标处所在的图片 y1 = num / Diffcult; x1 = num % Diffcult; // 修改查询数组的值 Query[image[Diff][Diff].y][image[Diff][Diff].x] = num; Query[LocalY][LocalX] = Diffcult * Diffcult - 1; // 交换图片的位置 image[y1][x1].x = image[Diff][Diff].x; image[y1][x1].y = image[Diff][Diff].y; image[Diff][Diff].x = LocalX; image[Diff][Diff].y = LocalY; // 放置图片 putimage(image[y1][x1].x * singleWidth + 3, image[y1][x1].y * singleHeight + 3, &(image[y1][x1].image)); putimage(LocalX * singleWidth + 3, LocalY * singleHeight + 3,&(image[Diff][Diff].image)); } // 判断是否通关 void Picture::IsPass() { int flag = 0; char str[20]; setbkmode(OPAQUE); sprintf(str, "第 %d / %d 关", Pass + 1, PassCount); settextstyle(23, 0, _T("华文行楷")); // 设置字体信息 outtextxy(700, 350, _T("当前状态: 游戏中")); // 输出游戏状态 outtextxy(730, 400, str); // 输出当前的关数 for (int i = 0; i < Diffcult; ++i) { for (int j = 0; j < Diffcult; ++j) { if (image[i][j].x == j && image[i][j].y == i) { ++flag; } } } // 通关条件 if (flag == Diffcult * Diffcult) { Resize(&img, Width, Height); loadimage(&img, String.c_str(), Width, Height); // 加载图像 putimage(0, 0, &img); outtextxy(700, 350, _T("当前状态: 已通关")); // 输出游戏状态 ++Pass; // 关数加一 String[4] = char((Pass / 10) + 48); // 修改 String[5] = char((Pass % 10) + 48); Control = 1; mciSendString("play Res\胜利.mp3", NULL, 0, NULL); Sleep(3000); // 延时 3 秒钟 } if (Pass == PassCount) { cleardevice(); settextstyle(50, 0, _T("华文行楷")); // 设置字体信息 outtextxy(220, 250, _T("恭喜你, 已通关全部关卡")); // 输出游戏状态 Control = 4; // 改变控制值 } } // 设置图片位置 void Picture::SetLocal() { // 记录四个方向的值 int sentryX[4] = {-1, 0, 1, 0}; int sentryY[4] = {0, -1, 0, 1}; int index = -1; int num = 0; int Diff = Diffcult -1; int Len = Diff; int x1, y1; int k = 0; loop: for (int l = 0; l < 8; ++l) { ++index; index = index % 4; for (k = Len; k > 0; k--) { // 记录 LocalX 和 LocalY 的位置 LocalX = image[Diff][Diff].x + sentryX[index]; LocalY = image[Diff][Diff].y + sentryY[index]; // 定位图片位置 num = Query[LocalY][LocalX]; // 记录 y1, x1 的位置 y1 = num / Diffcult; x1 = num % Diffcult; // 修改查询数组的值 Query[LocalY][LocalX] = Diffcult * Diffcult - 1; Query[image[Diff][Diff].y][image[Diff][Diff].x] = num; // 交换图片位置 image[y1][x1].x = image[Diff][Diff].x; image[y1][x1].y = image[Diff][Diff].y; image[Diff][Diff].x = LocalX; image[Diff][Diff].y = LocalY; } } Len--; if (Len > 0) { goto loop; } // 经过上面的处理之后, 图片应该被打散了, 然后再进行随机过程处理 srand(time(NULL)); for (k = 0; k < 100; k++) { loop1: index = rand() % 4; // 记录 LocalX 和 LocalY 的位置 LocalX = image[Diff][Diff].x + sentryX[index]; LocalY = image[Diff][Diff].y + sentryY[index]; if (LocalX >= 0 && LocalX <= Diff && LocalY >= 0 && LocalY <= Diff) { // 定位图片位置 num = Query[LocalY][LocalX]; // 记录 y1, x1 的位置 y1 = num / Diffcult; x1 = num % Diffcult; // 修改查询数组的值 Query[LocalY][LocalX] = Diffcult * Diffcult - 1; Query[image[Diff][Diff].y][image[Diff][Diff].x] = num; // 交换图片位置 image[y1][x1].x = image[Diff][Diff].x; image[y1][x1].y = image[Diff][Diff].y; image[Diff][Diff].x = LocalX; image[Diff][Diff].y = LocalY; } else { goto loop1; } } }
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85picture.h #ifndef picture_h #define picture_h // 加载头文件 #include <easyx.h> #include <conio.h> #include <string> #include <ctime> using namespace std; // 定义游戏的背景颜色 #define BgColor LIGHTGREEN #pragma comment(lib,"winmm.lib") //加载库文件 // 游戏的关数 const int PassCount = 8; // 游戏边框的大小 const int xLength = 953; const int yLength = 453; const int Width = 600; const int Height = 450; // 图片, 结构体, 保存图像 struct Image { IMAGE image; // 保存图像 int x; // 保存图像的 x 坐标 int y; // 保存图像的 y 坐标 }; // 游戏的框架类 class GameFrame { public: GameFrame(); // 默认构造函数 void DrawBackground(); // 绘制背景图像 void StartMenu(); // 开始界面, 选择游戏难度 }; // 图像类 class Picture { private: IMAGE img; // 保存完整图像 Image **image; // 保存切割图像 int Control; // 控制值 int Diffcult; // 难度值 int Pass; // 记录当前的关数 int LocalX; // 记录鼠标的位置信息 int LocalY; string String; // 保存图片路径 MOUSEMSG MouseMessage; // 鼠标消息 int singleWidth; // 单幅图像的宽度 int singleHeight; // 单幅图像的高度 int **Query; // 查询数组, 快速定位图片 public: Picture() // 默认构造函数 { Control = 0; Diffcult = 0; Pass = 0; String = "Res\00.jpg"; LocalX = 0; LocalY = 0; singleWidth = 0; singleHeight = 0; } void Run(); // 控制函数 void SetGameDifficult(); // 设置游戏的难度 void SetPicture(); // 设置图片 void SetLocal(); // 设置位置 void DrawRect(); // 绘制线条 void PrintPicture(); // 将图像输出到屏幕 void ProcessMouse(); // 处理鼠标消息, 实现移动的关键算法 void ProcessPicture(); // 处理图像 void IsPass(); // 判断是否通关 }; #endif
运行结果:
下载链接:
c++编程拼图小游戏.zip-C++文档类资源-CSDN下载
或者私信我。
最后
以上就是靓丽豌豆最近收集整理的关于c++编程拼图小游戏的全部内容,更多相关c++编程拼图小游戏内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复