本文章是由小主的<<推箱子游戏>>文章的升级版,加上了数据库
一.用户登录
步骤:(配合下边的代码)
首先请用户输入信息到一个结构体变量user中,输入后将user放到fetch_user_info()函数中判断(连数据库->查询记录->判断是否有该用户->接收记录),如果该用户在数据库中就开始游戏!
fetch_user_info()的判断步骤:
1.先用connect_db()函数连接数据库,
2.根据用户名和密码获取用户信息(本质就是在c++编译器中使用数据库中的语句,操作数据库,这里先定义一个字符串sql,然后用snprintf(),将用户输入的数据和查询语句一起放到qsl字符串中,因为用户信息不一样,所以用snprintf()复制,之后数据库会根据语句查询,如果成功返回真,否则返回假)
3.返回结果 将查询的所有记录传给res 在把res中的记录,一行一行用row表示出来,这里因为就一行,所以没有循环, 将一行记录中的用户id和关卡id传出来,atoi用来转换数据类型
4.关闭数据库
connect_db() 函数解释:
(1)先初始化句柄
(2)因为MYsQL的字符集和vs2019不一样,所以需要先转换一下
(3).连接数据库,这里需要数据库用户和密码,以及一些端口信息
数据库里关于用户和关卡的信息(这里用户james的密码为123456 用了md5加密 )
首先建立一个database.h和database.cpp文件,用来存储数据库的一些操作
database.h
定义一个用户的结构体用来存储信息
一个用户获取信息的函数
#pragma once
#include <string>
using namespace std;
//用户信息
typedef struct _userinfo {
int id; //用户id
string username; //用户名
string passwd; //密码
int level_id; //关卡id
}userinfo;
bool fetch_user_info(userinfo& user);
database.cpp
#include"database.h"
#include<mysql.h>
#include<stdio.h>
#define DB_NAME "box_man"
#define DB_HOST "127.0.0.1"
#define DB_POST 3306
#define DB_USER "root"
#define DB_USER_PASSWD "123456Aa"
static bool connect_db(MYSQL& mysql);
/*************************************
*功能:通过用户名和密码获取用户信息
*输入:
* user - 用户信息结构体
*
*返回值:
* 获取成功返回true,失败false
*
**************************************/
bool fetch_user_info(userinfo& user) {
MYSQL mysql;
MYSQL_RES* res;//查询结果集
MYSQL_ROW row;//记录结构体
char sql[256];
bool ret = false;
//1.连接到数据库
if (connect_db(mysql) == false) {
return false;
}
//2.根据用户名和密码获取用户信息
snprintf(sql,256,"select id,level_id from users where username ='%s' and password=md5('%s');",user.username.c_str(),user.passwd.c_str());
ret = mysql_query(&mysql, sql);
if (ret) {
printf("数据库查询出错,%s 错误原因:%s\n",sql,mysql_error(&mysql));
mysql_close(&mysql);
return false;
}
//3.返回结果
res = mysql_store_result(&mysql);
row = mysql_fetch_row(res);
if (row == NULL) {//没有查到记录
mysql_free_result(res);
mysql_close(&mysql);
return false;
}
user.id = atoi(row[0]);
user.level_id = atoi(row[1]);
printf("userid:%d level_id: %d\n",user.id,user.level_id);//打印ID
//4.关闭数据库
mysql_free_result(res);
mysql_close(&mysql);
return true;
}
bool connect_db(MYSQL &mysql) {
//1.初始化数据库句柄
mysql_init(&mysql);
//2.设置字符编码
mysql_options(&mysql,MYSQL_SET_CHARSET_NAME,"gbk");
//3.连接数据库
if (mysql_real_connect(&mysql, DB_HOST, DB_USER, DB_USER_PASSWD, DB_NAME, DB_POST, NULL, 0)==NULL) {
printf("数据库连接失败,错误原因:%s\n",mysql_error(&mysql));
return false;
}
return true;
}
二.通过关卡id获取关卡的信息
步骤:根据第一步获取的用户信息,将用户关卡id放入fetch_level_info()中获取挂关卡信息;
fetch_level_info()的判断步骤:
1.先用connect_db()函数连接数据库,
2.根据关卡id查询数据库 获取关卡地图信息
3.返回结果 将查询的所有记录传给res 在把res中的记录,一行一行用row表示出来,这里因为就一行,所以没有循环, 将一行记录中的用户id和关卡id传出来,atoi用来转换数据类型
4.关闭数据库
database.h
定义一个关卡信息的结构体用来存储信息
一个关卡获取信息的函数
typedef struct _levelinfo {
int id; //关卡的id
string name; //关卡的名字
int map_row; //地图的总行数
int map_column; //地图的总列数
string map_data; //二维地图的数据
int next_level; //下一关卡的id
}levelinfo;
bool fetch_level_info(levelinfo &level,int level_id);
database.cpp
bool fetch_level_info(levelinfo& level, int level_id)
{
MYSQL mysql;
MYSQL_RES* res; //查询结果集
MYSQL_ROW row; //记录结构体
char sql[256];
bool ret = false;
//1.连接到数据库
if (connect_db(mysql) == false) {
return false;
}
//2.根据关卡id查询数据库 获取关卡地图信息
snprintf(sql, 256, "select name, map_row, map_colum, map_data, next_level_id from levels where id=%d;", level_id);
ret = mysql_query(&mysql, sql);//成功返回0
if (ret) {
printf("数据库查询出错,%s 错误原因:%s\n", sql, mysql_error(&mysql));
mysql_close(&mysql);
return false;
}
//3.获取结果
res = mysql_store_result(&mysql);
row = mysql_fetch_row(res);
if (row == NULL) {//没有查到记录
mysql_free_result(res);
mysql_close(&mysql);
return false;
}
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]);
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 true;
}
三.根据用户所在的关卡id获取关卡的数据
步骤:就是通过transform_map_dbtoarry()函数,将获取的地图信息的坐标赋值给map数组(将地图数据一行一行一个一个的分解,复制给)
transform_map_dbtoarry()函数讲解: 它有两个参数,分别是地图信息和二维数组map。
先判断是否是越界
将数据分解成一行一行的,用 | 来区一行的结尾在哪,之后line接收一行
再对这一行分解,利用strtok_s()进行分解,分解出一个后,赋值给map,
在分解每一个的时候列+1,分解行的时候行数+1,之后不断循环,即可找出
bool transform_map_dbtoarry(levelinfo& level, int map[MAP_X][MAP_Y])
{
if (level.map_row > MAP_X || level.map_column > MAP_Y) {
printf("地图太大,请重新设置!\n");
return false;
}
if (level.map_data.length() < 1) {
printf("地图数据有误,请重新设置!\n");
return false;
}
int strat = 0, end = 0;
int row = 0, column = 0;
//一行一行的获取(通过|来分割),然后对一行中的每一个数据进行解析,把他们放到数组中
do {
end = level.map_data.find('|', strat);
if (end < 0) {
end = level.map_data.length();
//如果到达了最后一行,因为最后一行没有|,所以返回-1,
//但是因为这一行也需要解析,所以end为最后那一个数据位置
}
if (strat >= end) {
break;
}
string line = level.map_data.substr(strat, end - strat);
printf("get line:%s\n", line.c_str());
//对地图进行解析
char* next_token = NULL;
char* item = strtok_s((char*)line.c_str(), ",", &next_token);
//strtok_s()函数,将line字符串进行分割,第一次需要写入字符串,以后就可以设置为空
//截断后的首地址赋值给next_token
column = 0;
while (item && column < level.map_column) {
printf("%s ", item);
map[row][column] = atoi(item);
column++;
item = strtok_s(NULL, ",", &next_token);
}
if (column < level.map_column) {
printf("地图解析错误!\n");
return false;
}
printf("\n");
row++;
if (row >= level.map_row) {
break;
}
strat = end + 1;
} while (1);
if (row < level.map_row) {
printf("地图行数少于设定,%d(need:%d),终止!\n",row,level.map_row);
return false;
}
return true;
}
四.跳转下一关
步骤: 修改以前的代码,以前的玩了一个就结束了,而如果想跳转的话需要加循环,
如果本关闯过去了,判断是否还有下一关,如果有,那么将下一关的id赋值给用户关卡id,之后下次循环的时候,数据库通过访问
用户就可以获取新的关卡id了,再将这些信息赋值给level完成闭环
bool update_user_level(userinfo& user, int next_level_id)
{
MYSQL mysql;
MYSQL_RES* res; //查询结果集
MYSQL_ROW row; //记录结构体
char sql[256];
bool ret = false;
//1.连接到数据库
if (connect_db(mysql) == false) {
return false;
}
//2.根据用户id更新下一关的的level_id;
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;
}
return true;
}
五.数据库信息
建立了一个box_man数据库,里面有两个表,一个是用户信息,一个是关卡信息
这里一共写了七关.
六.全部代码
datebase.h
#pragma once
#include <string>
#include"boxman.h"
using namespace std;
//用户信息
typedef struct _userinfo {
int id; //用户id
string username; //用户名
string passwd; //密码
int level_id; //关卡id
}userinfo;
typedef struct _levelinfo {
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);
bool fetch_level_info(levelinfo &level,int level_id);
bool transform_map_dbtoarry(levelinfo &level,int map[MAP_X][MAP_Y]);
bool update_user_level(userinfo & user,int next_level_id);
datebase.cpp
#include"database.h"
#include<mysql.h>
#include<stdio.h>
#define DB_NAME "box_man"
#define DB_HOST "127.0.0.1"
#define DB_POST 3306
#define DB_USER "root"
#define DB_USER_PASSWD "123456Aa"
static bool connect_db(MYSQL& mysql);
/*************************************
*功能:通过用户名和密码获取用户信息
*输入:
* user - 用户信息结构体
*
*返回值:
* 获取成功返回true,失败false
*
**************************************/
bool fetch_user_info(userinfo& user) {
MYSQL mysql;
MYSQL_RES* res;//查询结果集
MYSQL_ROW row;//记录结构体
char sql[256];
bool ret = false;
//1.连接到数据库
if (connect_db(mysql) == false) {
return false;
}
//2.根据用户名和密码获取用户信息
snprintf(sql,256,"select id,level_id from users where username ='%s' and password=md5('%s');",user.username.c_str(),user.passwd.c_str());
ret = mysql_query(&mysql, sql);
if (ret) {
printf("数据库查询出错,%s 错误原因:%s\n",sql,mysql_error(&mysql));
mysql_close(&mysql);
return false;
}
//3.返回结果
res = mysql_store_result(&mysql);
row = mysql_fetch_row(res);
if (row == NULL) {//没有查到记录
mysql_free_result(res);
mysql_close(&mysql);
return false;
}
user.id = atoi(row[0]);
user.level_id = atoi(row[1]);
printf("userid:%d level_id: %d\n",user.id,user.level_id);//打印ID
//4.关闭数据库
mysql_free_result(res);
mysql_close(&mysql);
return true;
}
/*************************************
*功能:通过关卡的id获取完成的关卡信息(如:地图,下一关等)
*输入:
* level - 保存关卡信息的结构体变量
* level_id - 要获取详细关卡信息的id
*返回值:
* 获取成功返回true,失败false
*
**************************************/
bool fetch_level_info(levelinfo& level, int level_id)
{
MYSQL mysql;
MYSQL_RES* res; //查询结果集
MYSQL_ROW row; //记录结构体
char sql[256];
bool ret = false;
//1.连接到数据库
if (connect_db(mysql) == false) {
return false;
}
//2.根据关卡id查询数据库 获取关卡地图信息
snprintf(sql, 256, "select name, map_row, map_colum, map_data, next_level_id from levels where id=%d;", level_id);
ret = mysql_query(&mysql, sql);//成功返回0
if (ret) {
printf("数据库查询出错,%s 错误原因:%s\n", sql, mysql_error(&mysql));
mysql_close(&mysql);
return false;
}
//3.获取结果
res = mysql_store_result(&mysql);
row = mysql_fetch_row(res);
if (row == NULL) {//没有查到记录
mysql_free_result(res);
mysql_close(&mysql);
return false;
}
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]);
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 true;
}
bool transform_map_dbtoarry(levelinfo& level, int map[MAP_X][MAP_Y])
{
if (level.map_row > MAP_X || level.map_column > MAP_Y) {
printf("地图太大,请重新设置!\n");
return false;
}
if (level.map_data.length() < 1) {
printf("地图数据有误,请重新设置!\n");
return false;
}
int strat = 0, end = 0;
int row = 0, column = 0;
//一行一行的获取(通过|来分割),然后对一行中的每一个数据进行解析,把他们放到数组中
do {
end = level.map_data.find('|', strat);
if (end < 0) {
end = level.map_data.length();
//如果到达了最后一行,因为最后一行没有|,所以返回-1,
//但是因为这一行也需要解析,所以end为最后那一个数据位置
}
if (strat >= end) {
break;
}
string line = level.map_data.substr(strat, end - strat);
printf("get line:%s\n", line.c_str());
//对地图进行解析
char* next_token = NULL;
char* item = strtok_s((char*)line.c_str(), ",", &next_token);
//strtok_s()函数,将line字符串进行分割,第一次需要写入字符串,以后就可以设置为空
//截断后的首地址赋值给next_token
column = 0;
while (item && column < level.map_column) {
printf("%s ", item);
map[row][column] = atoi(item);
column++;
item = strtok_s(NULL, ",", &next_token);
}
if (column < level.map_column) {
printf("地图解析错误!\n");
return false;
}
printf("\n");
row++;
if (row >= level.map_row) {
break;
}
strat = end + 1;
} while (1);
if (row < level.map_row) {
printf("地图行数少于设定,%d(need:%d),终止!\n",row,level.map_row);
return false;
}
return true;
}
/*************************************
*功能:更新用户的关卡id
*输入:user - 将下一关的id赋值给user
* next_level_id - 下一关的id
**************************************/
bool update_user_level(userinfo& user, int next_level_id)
{
MYSQL mysql;
MYSQL_RES* res; //查询结果集
MYSQL_ROW row; //记录结构体
char sql[256];
bool ret = false;
//1.连接到数据库
if (connect_db(mysql) == false) {
return false;
}
//2.根据用户id更新下一关的的level_id;
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;
}
return true;
}
bool connect_db(MYSQL &mysql) {
//1.初始化数据库句柄
mysql_init(&mysql);
//2.设置字符编码
mysql_options(&mysql,MYSQL_SET_CHARSET_NAME,"gbk");
//3.连接数据库
if (mysql_real_connect(&mysql, DB_HOST, DB_USER, DB_USER_PASSWD, DB_NAME, DB_POST, NULL, 0)==NULL) {
printf("数据库连接失败,错误原因:%s\n",mysql_error(&mysql));
return false;
}
return true;
}
boxman.h
#pragma once
#define KEY_UP 'w'
#define KEY_DOWN 's'
#define KEY_LEFT 'a'
#define KEY_RIGHT 'd'
#define KEY_QUITE 'q'
#define MAP_X 48
#define MAP_Y 48
#define RATIO 61 //像素点
#define SCREEN_WIDTH 960
#define SCREEN_HEIGHT 768
#define isValid(pos) pos.x>=0 && pos.x<MAP_X&&pos.y>=0 &&pos.y<MAP_Y
#define MAX_RETRY_TIMES 3
typedef enum _PROPS PROPS;
typedef enum _DIRECTION DIRECTION;
typedef struct _POS POS;
struct _POS {
int x; //小人所在二维数组的行
int y; //小人所在二维数组的列
};
enum _PROPS {
WALL, //墙
FLOOR, //地板
BOX_DES,//箱子的目的地
MAN, //主角
BOX, //箱子
HIT, //箱子已经退到目的地
ALL //道具的个数
};
enum _DIRECTION {
UP,
DOWN,
LEFT,
RIGHT
};
boxman.cpp
#include<graphics.h>
#include<Windows.h>
#include<stdlib.h>
#include<string>
#include<iostream>
#include<conio.h>
#include"boxman.h"
#include <iostream>
#include"database.h"
using namespace std;
int hold = 0; //用来标记是否小人踩在目的地上
struct _POS man; //小人在二维数组中的位置
IMAGE images[ALL]; //加载图片的数组
int map[MAP_X][MAP_Y] = {0};
/*int map[MAP_X][MAP_Y] = {
{0,0,0,0,0,0,0,0,0,0,0,0},
{0,1,0,1,1,1,1,1,1,1,0,0},
{0,1,4,1,0,2,1,0,2,1,0,0},
{0,1,0,1,0,1,0,0,1,1,1,0},
{0,1,0,2,0,1,1,4,1,1,1,0},
{0,1,1,1,0,3,1,1,1,4,1,0},
{0,1,2,1,1,4,1,1,1,1,1,0},
{0,1,0,0,1,0,1,1,0,0,1,0},
{0,0,0,0,0,0,0,0,0,0,0,0},
};*/
void changeMap(POS* pos, PROPS prop);
void gameControl(DIRECTION direction);
bool isGameover();
void Gameover(IMAGE* bg);
void gameNextScene(IMAGE* bg);
bool login(userinfo& user);
void welcome(IMAGE& bg_img);
void init_game_graph(IMAGE& bg_img);
int main() {
//用户身份验证
userinfo user;
levelinfo level;
bool ret = false;
IMAGE bg_img; //用来承接图片
if (!login(user)) {
cout << "登录失败,请重新登录" << endl;
::system("pause");
exit(-1);
}
else {
cout << "登录成功,稍后进入游戏" << endl;
::system("pause");
}
//初始化舞台
welcome(bg_img);
::system("pause");
init_game_graph(bg_img);
bool quite = false;
do {
hold = 0;//每次到新的一关人物肯定不在目的地
//根据用户所在的关卡id获取关卡的数据
ret = fetch_level_info(level, user.level_id);
if (!ret) {
cout << "获取关卡数据失败,请重试!" << endl;
::system("pause");
exit(-1);
}
//把数据库中的地图数据转换到map中
ret = transform_map_dbtoarry(level, map);
if (!ret) {
cout << "转化地图失败,请重试!" << endl;
::system("pause");
exit(-1);
}
if (!ret) {
printf("适配失败!\n");
exit(-1);
}
//::system("pause");
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;
}
putimage(100 + j * 61, 150 + i * 61, &images[map[i][j]]);
}
}
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 == KEY_QUITE) {
quite = true;
}
else if (ch == KEY_RENWE) {
break;
}
if (isGameover()) {
if (level.next_level < 1) {
Gameover(&bg_img);
quite = true;
break;
}
gameNextScene(&bg_img);
//更新用户下一关的关卡信息
if (update_user_level(user, level.next_level)) {
user.level_id = level.next_level;
putimage(0, 0, &bg_img); //显示图片
}
break;
//quite = true;
}
}
Sleep(100);
} while (!quite);
}while(quite == false);
::system("pause");
closegraph();
return 0;
}
/************
* 作用:显示道具
* line:道具在数组的列坐标
* cloumn:道具在数组的行坐标
* prop:道具的类型
*
**************/
void changeMap(POS* pos, PROPS prop) {
map[pos->x][pos->y] = prop;
putimage(100 + pos->y * RATIO, 150 + pos->x * RATIO, &images[prop]);
}
/************
实现游戏四个方向(上,下,左,右)的控制
**************/
void gameControl(DIRECTION direction) {
POS next_pos = man;
POS next_next_pos = man;
switch (direction) {
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;
} //isValid()为宏展开
if (isValid(next_pos) && map[next_pos.x][next_pos.y] == FLOOR) { //判断是否为地板
if (hold == 0) {
changeMap(&next_pos, MAN);
changeMap(&man, FLOOR);
man = next_pos;
}
else {
changeMap(&next_pos, MAN);
changeMap(&man, BOX_DES);
man = next_pos;
hold = 0;
}
}
else if (isValid(next_pos) && map[next_pos.x][next_pos.y] == BOX_DES) {//小人前方是否为目的地
if (hold == 1) {
changeMap(&next_pos, MAN);
changeMap(&man, BOX_DES);
man = next_pos;
}
else {
changeMap(&next_pos, MAN);
changeMap(&man, FLOOR);
man = next_pos;
hold = 1;
}
}
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) { //判断箱子前面是都为地板
if (hold == 0) {
changeMap(&next_pos, MAN);
changeMap(&man, FLOOR);
man = next_pos;
changeMap(&next_next_pos, BOX);
}
else {
changeMap(&next_pos, MAN);
changeMap(&man, BOX_DES);
man = next_pos;
changeMap(&next_next_pos, BOX);
hold = 0;
}
}
else if (map[next_next_pos.x][next_next_pos.y] == BOX_DES) { //判断箱子前方是否为目的地
if (hold==1) {
changeMap(&next_pos, MAN);
changeMap(&man, BOX_DES);
man = next_pos;
changeMap(&next_next_pos, HIT);
hold = 0;
}
else {
changeMap(&next_pos, MAN);
changeMap(&man, FLOOR);
man = next_pos;
changeMap(&next_next_pos, HIT);
}
}
}
else if (isValid(next_next_pos) && map[next_pos.x][next_pos.y] == HIT) { //判断小人前方是否箱子目的地重合的地方
if (hold == 1) {
changeMap(&next_pos, MAN);
changeMap(&man, BOX_DES);
man = next_pos;
changeMap(&next_next_pos, BOX);
}else {
changeMap(&next_pos, MAN);
changeMap(&man, FLOOR);
man = next_pos;
changeMap(&next_next_pos, BOX);
hold = 1;
}
}
}
/*根据用户输入的数据,访问数据库进行登录*/
bool login(userinfo& user) {
int times = 0;
bool ret = false;
do {
cout << "请输入用户名:";
cin >> user.username;
cout << "请输入密码:";
cin >> user.passwd;
ret = fetch_user_info(user);
times++;
if (times >= MAX_RETRY_TIMES) {
break;
}
if (ret == false) {
cout << "登录失败,请重新尝试!" << endl;
}
} while (!ret);
return ret;
}
void init_game_graph(IMAGE& bg_img) {
initgraph(960, 768); //搭建戏台
loadimage(&bg_img, _T("blackground.bmp"), 960, 768, true);//加载背景图片
putimage(0, 0, &bg_img); //显示图片
loadimage(&images[WALL], _T("wall.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.bmp"), RATIO, RATIO, true);
loadimage(&images[HIT], _T("box.bmp"), RATIO, RATIO, true);
}
/************
*判断游戏是否结束
*如果数组中不存在任何一个箱子目的地,就代表游戏结束
*
*
**************/
bool isGameover() {
int i, j;
if (hold == 1) {
return false;
}
for (i = 0;i < MAP_X;i++) {
for (j = 0;j < MAP_Y;j++) {
if (map[i][j] == BOX_DES) {
return false;
}
}
}
return true;
}
/*欢迎界面*/
void welcome(IMAGE& bg_img){
initgraph(960, 768); //搭建戏台
loadimage(&bg_img, _T("welcome.bmp"), 960, 768, true);//加载背景图片
putimage(0, 0, &bg_img); //显示图片
}
/*
显示游戏结束画面
*/
void Gameover(IMAGE* bg) {
putimage(0, 0, bg);
settextcolor(WHITE);
RECT rec = { 0,0,SCREEN_WIDTH,SCREEN_HEIGHT };
settextstyle(20, 0, _T("宋体"));
drawtext(_T("恭喜你~\n!通关了!!"), &rec, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
void gameNextScene(IMAGE* bg) {
putimage(0, 0, bg);
settextcolor(WHITE);
RECT rec = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
settextstyle(20, 0, _T("宋体"));
drawtext(_T("恭喜您~ \n此关挑战成功,任意键跳转到下一关!"), &rec, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
::system("pause");
cleardevice();
}
七.演示效果
开始界面: