fqy131314

项目实战——推箱子小游戏(引入数据库)

数据库表设计

用户表

表名

Users

字段名

类型

是否为空

默认值

主、外键

备注

id

int(11)

NOT

1,自增长

PK

用户id

username

varchar(64)

NOT

用户名:英文字符、数字和特殊符号的组合

password

varchar(32)

NOT

密码:英文字符、数字和特殊符号的组合,8-16位

level_id

int

1

当前关卡,关联Levels表中的id

关卡表

表名

Levels

字段名

类型

是否为空

默认值

主、外键

备注

id

int

NOT

1

PK

游戏关卡序号,从1开始

name

varchar(64)

NOT

地图名称

map_row

int

NOT

地图二位组的总行数

map_column

int

NOT

地图二维组的总列数

map_data

varchar(4096)

NOT

地图数据,二维数组对应的行列式,多行以|分开,列以逗号分隔,最大接近支持45x45的地图

next_level_id

int

0

下一关的关卡id,0代表通关

mysql>  create database box_man;   #创建数据库box_man                                                                                                                       

mysql>                                                                                    

mysql>  create table users(          #创建用户表                                                              

             id int(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,                             

             username varchar(64) NOT NULL UNIQUE,                                                

             password varchar(32) NOT NULL ,                                                 

             level_id int  default 1                                                             

         );                                                                                  

mysql>  create table levels(         #创建关卡表                                                         

             id int NOT NULL PRIMARY KEY default 1,                                                 

             name varchar(64) NOT NULL UNIQUE,                                                   

             map_row int  NOT NULL,                                                              

             map_column   int NOT NULL,                                                           

             map_data     varchar(4096) NOT NULL,                                       

             next_level_id  int default 0                                                    

         );                                                                                  

mysql>   insert into users values(1000, 'martin', md5('123456qweQWE'), 1);                    

mysql>   insert into levels values(1, '牛刀小试', 9, 12,                                            

 '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',0);                                                                                      

                                                                                                                 

代码优化

登录认证

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_PORT  3306

#define DB_USER  "root"

#define DB_USER_PASSWD  "123456qweQWE"

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.根据用户名和密码获取用户信息(id, level_id)

    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); //成功返回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;

    }

    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_PORT, NULL, 0) == NULL) {

        printf("数据库连接出错, 错误原因: %s\n", mysql_error(&mysql));

        return false;

    }

    return true;

}

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);

boxman.cpp

bool login(userinfo& user) {

    int times = 0;

    bool ret = false;

    do{

        cout << "请输入用户名: ";

        cin >> user.username;

        cout << "请输入密码: ";

        cin >> user.passwd;

        //返回 bool ,成功返回true ,失败返回false .

        ret = fetch_user_info(user);

        times++;

        if (times >= MAX_RETRY_TIMES) {

            break;

        }

        if (ret == false) {

            cout << "登陆失败,请重新输入!" << endl;

        }

    } while (!ret);

    return ret;

}

获取关卡

//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

/***************************************************

 *功能:根据关卡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_column, 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[5]);

    if(debug) 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);

   

    //释放结果集

    mysql_free_result(res);

    //关闭数据库

    mysql_close(&mysql);

    return  true;

}

地图适配

//database.h

bool transform_map_db2array(levelinfo &level, int map[LINE][COLUMN]);

//database.cpp

bool transform_map_db2array(levelinfo& level, int map[LINE][COLUMN]) {

    if (level.map_row > LINE || level.map_column > COLUMN) {

        printf("地图超大,请重新设置!\n");

        return false;

    }

    if (level.map_data.length() < 1) {

        printf("地图数据有误,请重新设置!\n");

        return false;

    }

    int start = 0, end = 0;

    int row = 0, column = 0;

    do {

        end = level.map_data.find('|', start);

        if (end < 0) {

            end = level.map_data.length();

        }

        if (start >= end) break;

        string line = level.map_data.substr(start, end - start);

        printf("get line: %s\n", line.c_str());

        //对行地图数据进行解析

        char *next_token = NULL;

        char* item = strtok_s((char*)line.c_str(), ",", &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;

        }

        start = end + 1;

    } while (1 == 1);

    if (row < level.map_row) {

        printf("地图行数少于设定, %d(need: %d),终止!\n", row, level.map_row);

        return false;

    }

    return true;

}

//boxman.cpp

//把数据库中的地图数据转换到map 中

  ret = transform_map_db2array(level, map);

下一关跳转

//database.h

bool update_user_level(userinfo& user, int next_level_id);

//database.cpp

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;

    }

    //关闭数据库

    mysql_close(&mysql);

    return true;

}

//boxman.cpp

//...............前面省略N行代码....................

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();

}

//...............中间省略N行代码....................

if (isGameOver()) {

    if (level.next_level < 1) {

        gameOverScene(&bg_img);

        quit = true;

        break;

    }

    gameNextScene(&bg_img);

    //更新用户下一关的关卡信息

    if (update_user_level(user, level.next_level)) {

        user.level_id = level.next_level;

    }

                   

    break;

    //quit = true;

}

以下是完整代码实现:

box_man.h

#pragma once
#include <graphics.h>

#define KEY_UP 'w'
#define KEY_DOWN 's'
#define KEY_LEFT 'a'
#define KEY_RIGHT 'd'
#define KEY_QUIT 'q'

#define START_X 100		//x轴偏移
#define START_Y 150		//y轴偏移

#define WEIGHT 960		//舞台长
#define HEIGHT 768		//舞台宽

#define RATIO 61

#define isValid(pos) pos.x>=0 && pos.x<MAP_X && pos.y>=0 && pos.y<MAP_Y		//判断小人在地图行走后是否有效

#define MAX_REIRY_TIMES	4

#define MAP_X   48		
#define MAP_Y 12


enum _RES
{
	WALL,
	FLOOR,
	BOX_DES,
	MAN,
	BOX,
	HIT,
	ALL
};

enum _DIRECT
{
	UP,
	DOWN,
	LEFT,
	RIGHT
};

struct _POS		//小人坐标
{
	int x;
	int y;
};



box_man.cpp

#include <iostream>
#include <Windows.h>
#include <string>
#include <conio.h>
#include "box_man.h"
#include "database.h"

using namespace std;

int map[MAP_X][MAP_Y] = { 0 };

int hold = 0;

IMAGE pic[ALL];		//资源图片

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);




void changeMap(struct _POS* pos, enum _RES prop)
{
	map[pos->x][pos->y] = prop;
	putimage(START_X + pos->y * RATIO, START_Y + pos->x * RATIO, &pic[prop]);
}


struct _POS man;

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 gameOverScene(IMAGE* bg)
{
	putimage(0, 0, bg);
	settextcolor(WHITE);
	RECT rec = { 0,0,WEIGHT,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,WEIGHT,HEIGHT };
	settextstyle(20, 0, _T("宋体"));
	drawtext(_T("恭喜您~\n此关挑战成功,任意键跳转到下一关!"), &rec, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
	::system("pause");
	cleardevice();
}

void gameCotrol(enum _DIRECT direct)
{
	struct _POS next_pos = man;
	struct _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;
	}

	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)	//小人前是箱子目的地
	{
		changeMap(&next_pos, MAN);
		changeMap(&man, FLOOR);
		man = next_pos;
		hold = 1;
	}
	else if (isValid(next_pos) && map[next_pos.x][next_pos.y] == BOX)		//小人前是箱子
	{
		if (isValid(next_next_pos) && map[next_next_pos.x][next_next_pos.y] == BOX_DES)
		{
			changeMap(&next_next_pos, HIT);
			changeMap(&next_pos, MAN);
			changeMap(&man, FLOOR);
			man = next_pos;
		}
		else if (isValid(next_next_pos) && map[next_next_pos.x][next_next_pos.y] == FLOOR)		//箱子前面是地板
		{
			if (hold == 1)
			{
				changeMap(&next_next_pos, BOX);
				changeMap(&next_pos, MAN);
				changeMap(&man, BOX_DES);
				man = next_pos;
				hold = 0;
			}
			else
			{
				changeMap(&next_next_pos, BOX);
				changeMap(&next_pos, MAN);
				changeMap(&man, FLOOR);
				man = next_pos;
			}
		}
	}
	else if (isValid(next_next_pos) && map[next_pos.x][next_pos.y] == HIT)		//小人前方箱子和目的地重合
	{
		changeMap(&next_next_pos, BOX);
		changeMap(&next_pos, MAN);
		changeMap(&man, FLOOR);
		man = next_pos;
		hold = 1;
	}

}

bool login(userinfo& user)
{
	int times = 0; //登录次数
	int ret = false;

	do
	{
		cout << "请输入用户名:";
		cin >> user.username;

		cout << "请输入登录密码:";
		cin >> user.passwd;

		if (times > MAX_REIRY_TIMES)
		{
			cout << "输入用户名或密码错误过多!" << endl;
			return false;
		}

		ret = fetch_user_info(user);

	} while (ret == false);

	return ret;
}

void init_game_graph(IMAGE &bg_img)
{
	initgraph(WEIGHT, HEIGHT);

	loadimage(&bg_img, L"blackground.bmp", WEIGHT, HEIGHT, true);
	putimage(0, 0, &bg_img);

	loadimage(&pic[WALL], L"wall_right.bmp", RATIO, RATIO, true);
	loadimage(&pic[FLOOR], L"floor.bmp", RATIO, RATIO, true);
	loadimage(&pic[BOX_DES], L"des.bmp", RATIO, RATIO, true);
	loadimage(&pic[MAN], L"man.bmp", RATIO, RATIO, true);
	loadimage(&pic[BOX], L"box.bmp", RATIO, RATIO, true);
	loadimage(&pic[HIT], L"box.bmp", RATIO, RATIO, true);
}

int main(void)
{
	userinfo user;
	levelinfo level;
	bool ret = false;

	IMAGE bg_img;

	if (!login(user))
	{
		cout << "登录失败" << endl;
	}
	else
	{
		cout << "登录成功!请开始你的表演" << endl;
	}

	//初始化游戏舞台
	init_game_graph(bg_img);
	::system("pause");
	
	bool quit = false;

	do
	{
		hold = 0; //每次到新的一关人物肯定不在目的地

		//根据用户所在的关卡id获取关卡数据
		ret = fetch_level_info(level, user.level_id);
		if (!ret)
		{
			cout << "获取关卡数据失败,请重试!" << endl;
			::system("pause");
			exit(-1);
		}
		else
		{
			cout << "登录成功,用户id:" << user.id << ",您所在的关卡是:" << user.level_id << ",请开始您的表演!" << endl;
		}

		//把数据库中的地图数据转换到map中
		ret = transform_map_dbtoarry(level, map);
		if (!ret)
		{
			cout << "转换地图失败,请重试!" << endl;
			::system("pause");
			exit(-1);
		}

		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(START_X + j * RATIO, START_Y + i * RATIO, &pic[map[i][j]]);
			}
		}

		do
		{
			if (_kbhit())
			{
				char ch = _getch();

				if (ch == KEY_UP)
				{
					gameCotrol(UP);

				}
				else if (ch == KEY_DOWN)
				{
					gameCotrol(DOWN);

				}
				else if (ch == KEY_LEFT)
				{
					gameCotrol(LEFT);

				}
				else if (ch == KEY_RIGHT)
				{
					gameCotrol(RIGHT);

				}
				else if (ch == KEY_QUIT)
				{
					quit = false;
				}
				if (isGameOver())
				{

					if (level.next_level < 1)
					{
						gameOverScene(&bg_img);
						quit = 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;
				}
			}
			Sleep(100);
		} while (!quit);

	} while (quit == false);
	::system("pause");
	closegraph();

	return 0;
}

database.cpp

#include <mysql.h>
#include <stdio.h>
#include "database.h"

using namespace std;

#define DB_NAME "box_man"
#define DB_HOST "127.0.0.1"
#define DB_POST 3306
#define DB_USER "root"
#define DB_USER_PASSWD "rfly"

//static bool connect_db(MYSQL& mysql);


bool connect_db(MYSQL& mysql)
{
	mysql_init(&mysql);

	mysql_options(&mysql,MYSQL_SET_CHARSET_NAME,"gbk");

	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;
}


/****************************
*功能:通过用户名和密码获取用户信息
*输入:
*		user - 用户信息结构体
* 
* 返回值:
*		获取成功返回true
*		获取失败返回false
*****************************/

bool fetch_user_info(userinfo& user)
{
	MYSQL mysql;
	MYSQL_RES* res; //查询结果集
	MYSQL_ROW row;  //查询记录行
	char a[256];      //用来保存字符串查询语句
	int ret = false;

	//1.连接数据库
	if (connect_db(mysql) == false) 
	{
		cout << "数据库连接失败" << endl;
		return false;
	}

	snprintf(a, 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, a); //等于0,表示查询成功

	if (ret)
	{
		printf("数据库查询出错,%s 错误原因:%s\n", a, mysql_error(&mysql));
		mysql_close(&mysql);
		return false;
	}

	res = mysql_store_result(&mysql);
	row = mysql_fetch_row(res);

	if (row == NULL)
	{
		cout <<"查询到空数据,失败!" << endl;
		mysql_free_result(res);
		mysql_close(&mysql);
		return false;
	}

	user.id = atoi(row[0]);
	user.level_id = atoi(row[1]);
	cout << "用户名id:" << user.id << "\t" << "用户关卡:" << user.level_id;

	mysql_free_result(res);
	mysql_close(&mysql);
	return true;
}

bool fetch_level_info(levelinfo& level, int level_id)
{
	MYSQL mysql;
	MYSQL_RES* res; //查询结果集
	MYSQL_ROW row;  //查询记录行
	char sql[256];
	bool ret = false;

	if (connect_db(mysql) == false)
	{
		cout << "数据库连接失败" << endl;
		return false;
	}

	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);
	
	if (ret)
	{
		printf("数据库查询出错,%s 错误原因:%s\n", sql, mysql_error(&mysql));
		mysql_close(&mysql);
		return false;
	}

	res = mysql_store_result(&mysql);
	row = mysql_fetch_row(res);

	if (row == NULL)
	{
		cout << "查询到空数据,失败!" << endl;
		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]);

	mysql_free_result(res);
	mysql_close(&mysql);

	return true;
}

bool transform_map_dbtoarry(levelinfo& level, int map[MAP_X][MAP_Y])
{
	//1.合法性检查
	if (level.map_row > MAP_X || level.map_column > MAP_Y)
	{
		cout << "给定的地图太大!" << endl;
		return false;
	}

	if (level.map_data.length() < 1)
	{
		printf("地图数据有误,请重新设置!\n");
		return false;
	}

	int start = 0, end = 0;
	int row = 0, column = 0;

	do
	{
		end = level.map_data.find('|', start);

		//find找到最后一行,没有'|'返回-1
		if (end < 0)
		{
			end = level.map_data.length();
		}

		if (start >= end)
		{
			break;
		}

		string line = level.map_data.substr(start, end - start);
		printf("get line:%s\n", line.c_str());

		//去除逗号
		char* next_token = NULL;
		char* item = strtok_s((char*)line.c_str(), ",", &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;
		}

		start = 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;
}

database.h

#pragma once 
#include <string>
#include "box_man.h"
#include <iostream>

using namespace std;

typedef struct _userinfo
{
	int id;
	string username;
	string passwd;
	int level_id;
}userinfo;

typedef struct _levelinfo
{
	int id;	//关卡的id
	string name; //关卡的名字
	int map_row; //地图的总行数
	int map_column; //地图的总列数
	string map_data; //二维地图的数据
	int next_level; //下一关卡的id
}levelinfo;

posted on   会飞的鱼-blog  阅读(17)  评论(0编辑  收藏  举报  

相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示