图片素材及源码
下载链接
数据库SQL语句
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
|
create database box_man if not exists; use box_man; create table users ( id int not null auto_increment, username varchar (64) not null , password varchar (32) not null , level_id int default 1, primary key (id), unique key username(username) ); create table levels( id int not null auto_increment, name varchar (64) not null , map_row int not null , map_column int not null , map_data varchar (4096) not null , next_level_id int default 0 comment '下一关的id,0代表通关' , primary key (id) ); insert into users values (1, 'Jack' ,md5(123456),1); insert into levels values (1, '小试牛刀→第一关' ,8,10, '-1,0,0,0,0,0,0,0,-1,-1|-1,0,2,2,2,2,1,0,-1,-1|0,0,0,2,2,2,4,0,0,0|0,1,1,4,0,4,1,4,1,0|0,1,4,4,1,1,0,4,1,0|0,1,1,1,3,0,1,1,1,0|0,0,0,0,1,1,1,0,0,0,|-1,-1,-1,0,0,0,0,0,-1,-1' ,2), (2, '绝地强者→第二关' ,6,6, '0,0,0,0,0,0|0,2,2,1,1,0|0,4,4,1,3,0|0,2,1,4,0,0|0,1,1,1,0,-1|0,0,0,0,0,-1' ,3), (3, '天外强人→第三关' ,8,10, '-1,-1,0,0,0,0,0,0,-1,-1|0,0,0,1,1,1,0,0,0,0|0,1,1,1,4,1,4,1,1,0|0,1,4,1,1,1,4,1,3,0|0,0,0,4,4,0,0,0,0,0,|-1,-1,0,1,1,2,2,0,-1,-1|-1,-1,0,2,2,2,2,0,-1,-1|-1,-1,0,0,0,0,0,0,-1,-1' ,4), (4, '死而复生→BOSS关' ,8,8, '-1,0,0,0,0,0,0,-1|-1,0,2,1,2,2,0,-1|-1,0,2,1,4,2,0,-1|0,0,0,1,1,4,0,0|0,1,4,1,1,4,1,0|0,1,0,4,0,0,1,0|0,1,1,1,3,1,1,0|0,0,0,0,0,0,0,0' ,0); |
操作数据库C++代码
database.h
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
|
#pragma once #include<string> using namespace std; #define LINE 48 #define COLUMN 48 typedef struct _userinfo { //这里将字符串初始为空 _userinfo() :id(0), username( "" ), password( "" ), level_id(0) {}; int id; // 用户id string username; string password; // 密码 int level_id; }userinfo; typedef struct _levelinfo { _levelinfo() :id(0), name( "" ), map_row(0), map_column(0), map_data( "" ), next_level(0) {}; int id; // 关卡id string name; // 关卡名字 int map_row; // 地图行数 int map_column; //地图列数 string map_data; // 二维地图数据 int next_level; //下一关卡id }levelinfo; bool fetch_user_info(userinfo& user); int fetch_level_info(levelinfo& level, int level_id); bool transform_map_db2array(levelinfo& level, int map[][COLUMN]); bool update_user_level(userinfo& user, int next_level_id); bool resiting_data(userinfo& user); |
database.cpp
记得更改自己的用户名和密码
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
|
#include"database.h" #include<mysql.h> #include<stdio.h> // 会使用C的接口 #define DB_NAME "box_man" //数据库名 #define DB_HOST "127.0.0.1" //IP地址 #define DB_PORT 3306 //端口号 #define DB_USER "root" //用户名 #define DB_USER_PASSWORD "123456" //密码 /****************************** *功能:数据库链接 * 输入: * mysql - 数据库访问句柄 * * 返回值: * true - 连接成功 * false - 连接失败 *****************************/ bool connect_db(MYSQL& mysql) { //1.初始数据库句柄 mysql_init(&mysql); //2.设置字符编码(为句柄设置) //windows支持中文,在windows上一般是gbk字符集,gbk包含中文简体和繁体,简体是gbk2312 mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk" ); //3.连接数据库 //句柄,主机,用户名,密码,数据库,端口号,——,—— if (mysql_real_connect(&mysql, DB_HOST, DB_USER, DB_USER_PASSWORD, DB_NAME, DB_PORT, NULL, 0) == NULL) { printf ( "数据库连接失败,错误原因:%s\n" , mysql_error(&mysql)); return false ; } return true ; } /****************************** *功能:通过用户名和密码获取用户信息 * 输入: * user - 用户信息结构体 * * 返回值: * 获取成功返回true,失败false *****************************/ bool fetch_user_info(userinfo& user) { MYSQL mysql; //定义一个句柄,对mysql的访问都是通过这个句柄(就是一个集合) MYSQL_RES* res; // 查询的结果集 MYSQL_ROW row; // 如果结果集有多条,可以使用row获取 char sql[256]; bool ret = false ; //1.连接数据库 if (connect_db(mysql) == false ) { return false ; } //2.设置SQL查询语句 //snprintf函数,设将可变参数(...)按照 format 格式化成字符串,并将字符串复制到 str 中,size 为要写入的字符的最大数目,超过 size 会被截断。 snprintf(sql, 256, "select id,level_id from users where username='%s' and password = md5('%s');" , user.username.c_str(), user.password.c_str()); ret = mysql_query(&mysql, sql); //mysql查询,成功返回0 if (ret) { printf ( "数据库查询出错,%s错误原因:%s\n" , sql, mysql_error(&mysql)); // 关闭数据库 mysql_close(&mysql); return false ; } //3.获取查到的结果 res = mysql_store_result(&mysql); //row获得结果集里的一行记录,再通过下标访问记录里的数据,如果结果集有多行时可以通过 while(row = mysql_fetch_row(res)){ }循环获得 row = mysql_fetch_row(res); if (row == NULL) { //没有查到记录 //1.释放结果集 mysql_free_result(res); //1.关闭数据库 mysql_close(&mysql); return false ; } user.id = atoi (row[0]); // 字符串转整数 user.level_id = atoi (row[1]); //4.返回结果 mysql_free_result(res); mysql_close(&mysql); return true ; } /********************************* *功能:根据关卡id获取完整的关卡信息(如:地图,下一关等) * 输入: * level - 保存关卡信息的结构体 * level_id - 获取关卡id * 返回值: * -1 - 数据库连接或查询出错 * 0 - 查找结果为空 * 1 - 查找成功 *********************************/ int fetch_level_info(levelinfo& level, int level_id) { MYSQL mysql; //定义一个句柄,对mysql的访问都是通过这个句柄(就是一个集合) MYSQL_RES* res; // 查询的结果集 MYSQL_ROW row; // 如果结果集有多条,可以使用row获取 char sql[256]; bool ret = false ; //1.连接数据库 if (connect_db(mysql) == false ) { return -1; } //2.编写SQL语句 snprintf(sql, 256, "select name,map_row, map_column,map_data,next_level_id from levels where id=%d;" , level_id); ret = mysql_query(&mysql, sql); //mysql查询,成功返回0 if (ret) { printf ( "数据库查询出错,%s错误原因:%s\n" , sql, mysql_error(&mysql)); // 关闭数据库 mysql_close(&mysql); return -1; } //3.获取查到的结果 res = mysql_store_result(&mysql); //row获得结果集里的一行记录,再通过下标访问记录里的数据,如果结果集有多行时可以通过 while(row = mysql_fetch_row(res)){ }循环获得 row = mysql_fetch_row(res); if (row == NULL) { //没有查到记录 //1.释放结果集 mysql_free_result(res); //1.关闭数据库 mysql_close(&mysql); return 0; } level.id = level_id; level.name = row[0]; level.map_row = atoi (row[1]); level.map_column = atoi (row[2]); level.map_data = row[3]; level.next_level = atoi (row[4]); //string用printf输出,使用.c_str()可以返回一个const char* 的指针 //printf("level id: %d name: %s map row: %d map column: %d map data: %s next level: %d\n", level.id, level.name.c_str(), level.map_row, level.map_column, level.map_data.c_str(), level.next_level); //4.返回结果 mysql_free_result(res); mysql_close(&mysql); return 1; } /****************************** *功能:将获得的关卡数据转换到map地图数组中 * 输入: * level - 关卡数据 * map - 二维地图数组 * * 返回值: * false - 转换失败 * true - 转换成功 *****************************/ bool transform_map_db2array(levelinfo& level, int map[][COLUMN]) { if (level.map_row > LINE || level.map_column > COLUMN) { printf ( "地图过大,请重新设置\n" ); return false ; } if (level.map_data.length() < 1) { printf ( "地图数据有误,请重新设置!\n" ); return false ; } long long start = 0, end = 0; int row = 0, column = 0; do { /****************************** *find返回size_t类型值,size_t在64位下是8字节长度,因此这里把start和end设置成long long类型(不设置会有“数据丢失”警告)。当然也可以简单粗暴的修改警告设置 ******************************/ end = level.map_data.find( '|' , start); if (end == -1) { end = level.map_data.length(); } //合法性检查,结束时end=level.map_data.length,start=end+1 if (start >= end) break ; string line = level.map_data.substr(start, end - start); //printf("get-line:%s\n", line.c_str()); // 对行数据进行解析:0,1,0,1,1,1,1,1,1,1,0,0 char * next_token = NULL; //line转为const char*(C语言中的字符串),strtok_s会修改line里的值,按照某个特定字符,所以需要将line.c_str()转为char * // strtok_s第一个参数是要劈开的字符串(要求是一个char *类型的);第二个参数是按某个字符劈开(会把“,”逗号变成‘\0'结束符,也就是说会修改原来字符串,所以要把原来的const char*转为char*);第三个参数是这个接口 // 需要的,用来做定位功能, //printf("%p\n", &line[2]); char * item = strtok_s(( char *)line.c_str(), "," , &next_token); column = 0; //printf("%p", next_token); //::system("pause"); //如果某行数据个数多余这个地图列数,控制只读取level.map_column-1个 while (item&&column<level.map_column) { map[row][column] = atoi (item); column++; //再使用strtok_s接口第一个参数可以写NULL,应该是next_token参数上一次做定位功能时已经记录了要劈开字符串给的某个位置 item = strtok_s(NULL, "," , &next_token); } //合法性检查 if (column < level.map_column) { // 某行的数据个数小于这个地图的列数 printf ( "地图数据解析出错,终止!\n" ); return false ; } row++; //列数多余的话直接舍弃 if (row >= level.map_row) { break ; } start = end + 1; } while (1 == 1); //列数多余则直接报错 if (row < level.map_row) { printf ( "地图行数少于设定,终止!" ); return false ; } return true ; } /****************************** *功能:更新用户游戏进度信息 * 输入: * user - 用户信息 * next_level_id - 游戏进度 * * 返回值: * 获取成功返回true,失败false *****************************/ bool update_user_level(userinfo& user, int next_level_id) { MYSQL mysql; //定义一个句柄,对mysql的访问都是通过这个句柄(就是一个集合) char sql[256]; bool ret = false ; //1.连接数据库 if (connect_db(mysql) == false ) { return false ; } //2.编写SQL语句 snprintf(sql, 256, "update users set level_id=%d where id=%d" , next_level_id, user.id); ret = mysql_query(&mysql, sql); if (ret) { printf ( "数据库更新出错,%s错误原因:%s\n" , sql, mysql_error(&mysql)); // 关闭数据库 mysql_close(&mysql); return false ; } user.level_id = next_level_id; mysql_close(&mysql); return true ; } /****************************** *功能:重置用户游戏进度信息 * 输入: * user - 用户信息 * * 返回值: * false - 重置失败 * true - 重置成功 *****************************/ bool resiting_data(userinfo& user) { MYSQL mysql; //定义一个句柄,对mysql的访问都是通过这个句柄(就是一个集合) char sql[256]; bool ret = false ; //1.连接数据库 if (connect_db(mysql) == false ) { return false ; } //2.编写SQL语句 snprintf(sql, 256, "update users set level_id=1 where id=%d" , user.id); ret = mysql_query(&mysql, sql); //3.判断查询结果 if (ret) { printf ( "数据库更新出错,%s错误原因:%s\n" , sql, mysql_error(&mysql)); // 关闭数据库 mysql_close(&mysql); return false ; } user.level_id = 1; //4.关闭数据库 mysql_close(&mysql); return true ; } |
推箱子游戏代码
box_man.h
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
|
#pragma once #define RATIO 40 #define SCREEN_WIDTH 740 #define SCREEN_HEIGHT 500 #define START_X 50 #define START_Y 75 #define KEY_UP 'W' #define KEY_LEFT 'A' #define KEY_RIGHT 'D' #define KEY_DOWN 'S' #define KEY_OUT 'Q' #define GAME_AGAIN 'R' #define MAX_RETRY_TIMES 4 #define BG_IMAGE -1 #define isValid(next_pos) next_pos.x > 0 && next_pos.x < LINE && next_pos.y>0 && next_pos.y < COLUMN typedef enum _PROPS PROPS; typedef enum _DIRECTION DIRECTION; typedef struct _POS POS; enum _PROPS { WALL, //墙 FLOOR, //地板 BOX_DES, //箱子目的地 MAN, //小人 BOX, //箱子 HIT, //箱子命中目标 MAN_DES, //人站在目标上 VECTOR //通关图片 }; enum _DIRECTION { UP, DOWN, LEFT, RIGHT }; struct _POS { int x; //小人所在二维数组的行数 int y; //小人所在二维数组的列数 }; |
box_man.cpp
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
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
|
#include<graphics.h> #include<iostream> #include<stdlib.h> #include<string> #include<conio.h> //??? #include"box_man.h" #include"database.h" using namespace std; int map[LINE][COLUMN] = { 0 }; POS man; IMAGE images[9]; /***************************** * 功能:判断游戏是否结束 * 输入: * 无 * 输出: * true - 未结束 * flase - 结束 *****************************/ bool isGameOver() { for ( int i = 0; i < LINE; ++i) { for ( int j = 0; j < COLUMN; ++j) { if (map[i][j] == BOX_DES) return false ; } } return true ; } /***************************** * 功能:加载游戏结束图片 * 输入: * 无 * 输出: * 无 *****************************/ void show_over() { cleardevice(); IMAGE game_over; loadimage(&game_over, _T( "gameover.png" ), SCREEN_WIDTH, SCREEN_HEIGHT, true ); putimage(0, 0, &game_over); } /***************************** * 功能:在指定位置更改地图信息 显示指定图片 * 输入: * next_pos - 指定位置 * prop - 指定图片 * 输出: * 无 *****************************/ void changeMap(POS* next_pos, PROPS prop) { map[next_pos->x][next_pos->y] = prop; putimage(START_X + next_pos->y * RATIO, START_Y + next_pos->x * RATIO, &images[prop]); } /***************************** * 功能:在指定位置显示指定图片 * 输入: * next_pos - 指定位置 * prop - 指定图片 * 输出: * 无 *****************************/ void changeMap2(POS* next_pos, PROPS prop) { putimage(START_X + next_pos->y * RATIO, START_Y + next_pos->x * RATIO, &images[prop]); } /***************************** * 功能:控制小人向指定方向移动 * 输入: * direct - 指定方向 * 输出: * 无 *****************************/ void gameControl(DIRECTION direct) { POS next_pos = man; POS next_next_pos = man; switch (direct) { case UP: next_pos.x--; next_next_pos.x -= 2; break ; case DOWN: next_pos.x++; next_next_pos.x += 2; break ; case LEFT : next_pos.y--; next_next_pos.y -= 2; break ; case RIGHT: next_pos.y++; next_next_pos.y += 2; break ; } //宏展开next_pos.x > 0 && next_pos.x < LINE && next_pos.y>0 && next_pos.y < COLUMN // 人的前方是地板 if (isValid(next_pos) && map[next_pos.x][next_pos.y] == FLOOR) { //人的脚下是目的地 if (map[man.x][man.y] == BOX_DES) { changeMap(&next_pos, MAN); changeMap2(&man, BOX_DES); } else { changeMap(&man, FLOOR); changeMap(&next_pos, MAN); } man = next_pos; } // 人的前方是箱子 else if (isValid(next_next_pos) && map[next_pos.x][next_pos.y] == BOX) { if (map[next_next_pos.x][next_next_pos.y] == FLOOR) { // 箱子的前方是地板 changeMap(&next_next_pos, BOX); changeMap(&next_pos, MAN); if (map[man.x][man.y] == BOX_DES) { changeMap(&man, BOX_DES); } else { changeMap(&man, FLOOR); } man = next_pos; } else if (map[next_next_pos.x][next_next_pos.y] == BOX_DES) { // 箱子前面是目的地 changeMap(&next_next_pos, HIT); changeMap(&next_pos, MAN); if (map[man.x][man.y] == BOX_DES) { changeMap(&man, BOX_DES); } else { changeMap(&man, FLOOR); } man = next_pos; } } //前方是目的地 else if (isValid(next_pos) && map[next_pos.x][next_pos.y] == BOX_DES) { //小人脚下也是目的地 if (map[man.x][man.y] == BOX_DES) { changeMap2(&next_pos, MAN_DES); changeMap(&man, BOX_DES); } else { changeMap(&man, FLOOR); changeMap2(&next_pos, MAN_DES); } man = next_pos; } //前方是箱子命中点 else if (isValid(next_pos) && map[next_pos.x][next_pos.y] == HIT) { if (map[next_next_pos.x][next_next_pos.y] == FLOOR) { // 箱子的前方是地板 changeMap(&next_next_pos, BOX); changeMap(&next_pos, BOX_DES); changeMap2(&next_pos, MAN_DES); //人的脚下是目的地 if (map[man.x][man.y] == BOX_DES) { changeMap(&man, BOX_DES); } else { changeMap(&man, FLOOR); } man = next_pos; } else if (map[next_next_pos.x][next_next_pos.y] == BOX_DES) { // 箱子前面是目的地 changeMap(&next_next_pos, HIT); changeMap(&next_pos, BOX_DES); changeMap2(&next_pos, MAN_DES); //人的脚下是目的地 if (map[man.x][man.y] == BOX_DES) { changeMap(&man, BOX_DES); } else { changeMap(&man, FLOOR); } man = next_pos; } } } /***************************** * 功能:用户登录 * 输入: * user - 用户信息 * 输出: * false - 登录失败 * true - 登录成功 *****************************/ bool login(userinfo& user) { int times = 0; bool ret = false ; do { cout << "请输入用户名:" ; cin >> user.username; cout << "请输入密码:" ; cin >> user.password; ret = fetch_user_info(user); times++; if (times >= MAX_RETRY_TIMES) break ; if (ret == false ) { cout << "登录失败,请重新输入!" << endl; } } while (!ret); return ret; } /***************************** * 功能:加载游戏素材 * 输入: * 无 * 输出: * 无 *****************************/ void init_graph() { initgraph(SCREEN_WIDTH, SCREEN_HEIGHT); loadimage(&images[WALL], _T( "wall_right.bmp" ), RATIO, RATIO, true ); loadimage(&images[FLOOR], _T( "floor.bmp" ), RATIO, RATIO, true ); loadimage(&images[BOX_DES], _T( "des.bmp" ), RATIO, RATIO, true ); loadimage(&images[MAN], _T( "man.bmp" ), RATIO, RATIO, true ); loadimage(&images[BOX], _T( "box.jpg" ), RATIO, RATIO, true ); loadimage(&images[HIT], _T( "box_des.jpg" ), RATIO, RATIO, true ); loadimage(&images[MAN_DES], _T( "man_des.bmp" ), RATIO, RATIO, true ); loadimage(&images[VECTOR], _T( "vector.png" ), 6*RATIO, 6*RATIO, true ); } /***************************** * 功能:显示指定地图 * 输入: * level - 指定地图 * 输出: * 无 *****************************/ void show_images(levelinfo& level) { cleardevice(); // 每次贴图清屏一下 IMAGE bg_img; //图片的宽,高最后一个参数“是否拉伸” loadimage(&bg_img, _T( "bgimage.png" ), SCREEN_WIDTH, SCREEN_HEIGHT, true ); putimage(0, 0, &bg_img); for ( int i = 0; i < level.map_row; ++i) { for ( int j = 0; j < level.map_column; ++j) { if (map[i][j] == MAN) { man.x = i; man.y = j; } if (map[i][j] == BG_IMAGE) continue ; putimage(START_X + j * RATIO, START_Y + i * RATIO, &images[map[i][j]]); } } const char * str = level.name.c_str(); setbkmode(TRANSPARENT); setfont(RATIO, 0, _T( "华文楷体" )); setcolor(WHITE); outtextxy(200, 25, str); } /***************************** * 功能:载入PNG图并去透明部分 * 输入: * 无 * 输出: * 无 *****************************/ void drawAlpha(IMAGE* picture, int picture_x, int picture_y) //x为载入图片的X坐标,y为Y坐标 { // 变量初始化 DWORD * dst = GetImageBuffer(); // GetImageBuffer()函数,用于获取绘图设备的显存指针,EASYX自带 DWORD * draw = GetImageBuffer(); DWORD * src = GetImageBuffer(picture); //获取picture的显存指针 int picture_width = picture->getwidth(); //获取picture的宽度,EASYX自带 int picture_height = picture->getheight(); //获取picture的高度,EASYX自带 int graphWidth = getwidth(); //获取绘图区的宽度,EASYX自带 int graphHeight = getheight(); //获取绘图区的高度,EASYX自带 int dstX = 0; //在显存里像素的角标 // 实现透明贴图 公式: Cp=αp*FP+(1-αp)*BP , 贝叶斯定理来进行点颜色的概率计算 for ( int iy = 0; iy < picture_height; iy++) { for ( int ix = 0; ix < picture_width; ix++) { int srcX = ix + iy * picture_width; //在显存里像素的角标 int sa = ((src[srcX] & 0xff000000) >> 24); //0xAArrggbb;AA是透明度 int sr = ((src[srcX] & 0xff0000) >> 16); //获取RGB里的R int sg = ((src[srcX] & 0xff00) >> 8); //G int sb = src[srcX] & 0xff; //B if (ix >= 0 && ix <= graphWidth && iy >= 0 && iy <= graphHeight && dstX <= graphWidth * graphHeight) { dstX = (ix + picture_x) + (iy + picture_y) * graphWidth; //在显存里像素的角标 int dr = ((dst[dstX] & 0xff0000) >> 16); int dg = ((dst[dstX] & 0xff00) >> 8); int db = dst[dstX] & 0xff; draw[dstX] = ((sr * sa / 255 + dr * (255 - sa) / 255) << 16) //公式: Cp=αp*FP+(1-αp)*BP ; αp=sa/255 , FP=sr , BP=dr | ((sg * sa / 255 + dg * (255 - sa) / 255) << 8) //αp=sa/255 , FP=sg , BP=dg | (sb * sa / 255 + db * (255 - sa) / 255); //αp=sa/255 , FP=sb , BP=db } } } } /***************************** * 功能:载入“恭喜通关”图片 * 输入: * 无 * 输出: * 无 *****************************/ void promot_over() { setbkmode(TRANSPARENT); drawAlpha(&images[VECTOR], 250, 130); // 载入PNG图并去透明部分 Sleep(1100); } /***************************** * 功能:休眠 * 输入: * interval - 休眠时间 * 输出: * 无 *****************************/ void wait( int interval) { int count = interval / 10; for ( int i = 0; i < count; ++i) { Sleep(10); if (_kbhit()) return ; } } /***************************** * 功能:游戏控制 * 输入: * level - 挡墙关卡数据 * user - 用户信息 * 输出: * 无 *****************************/ void game_operation(levelinfo& level, userinfo& user) { bool quit = false ; do { //判断是否有按键按下 if (_kbhit()) { //无缓冲读取 char ch = _getch(); if (ch == KEY_UP) { gameControl(UP); } else if (ch == KEY_DOWN) { gameControl(DOWN); } else if (ch == KEY_LEFT) { gameControl(LEFT); } else if (ch == KEY_RIGHT) { gameControl(RIGHT); } else if (ch == GAME_AGAIN) { fetch_level_info(level, user.level_id); transform_map_db2array(level, map); show_images(level); } else if (ch == KEY_OUT) { closegraph(); exit (0); } if (isGameOver()) { //更新用户下一关关卡信息(用户通关后直接跳转下一关) update_user_level(user, level.next_level); quit= true ; } } wait(100); } while (quit == false ); } /***************************** * 功能:根据“由用户ID获取关卡数据”的返回结果进行判断 * 输入: * result - 返回结果(-1:获取失败 0:用户已通关 1:获取成功) * level - 关卡数据 * user - 用户信息 * 输出: * 无 *****************************/ void judge_by_result( int result, levelinfo& level, userinfo& user) { if (result == 1) { return ; } else if (result == -1) { closegraph(); cout << "获取关卡数据失败,请重试!" << endl; std:: system ( "pause" ); exit (-1); } else if (result == 0) { show_over(); do { //判断是否有按键按下 if (_kbhit()) { //无缓冲读取 char ch = _getch(); if (ch == KEY_OUT) { closegraph(); exit (0); } else if (ch == GAME_AGAIN) { if (!resiting_data(user)) { std:: system ( "pause" ); closegraph(); exit (0); } break ; } } Sleep(50); } while (1); fetch_level_info(level, user.level_id); } } int main() { //用户身份验证 userinfo user; levelinfo level; if (!login(user)) { cout << "登录失败,请重新登录!" << endl; :: system ( "pause" ); exit (-1); } init_graph(); //循环(读取关卡→用户操作) do { //根据用户信息加载关卡数据 int result = fetch_level_info(level, user.level_id); judge_by_result(result, level, user); //将关卡数据数据转换到map游戏地图中 transform_map_db2array(level, map); //加载游戏图片 show_images(level); //小人移动 game_operation(level, user); //恭喜通关 promot_over(); } while (1); std:: system ( "pause" ); closegraph(); return 0; } |
到此这篇关于C语言+MySQL实现推箱子游戏的文章就介绍到这了,更多相关C语言 MySQL推箱子内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!
原文链接:https://blog.csdn.net/qq_54169998/article/details/122990017