连接数据库:代码优化,登陆认证,获取关卡,地图适配,下一关跳转

107 篇文章 0 订阅
22 篇文章 1 订阅
代码优化
登陆认证
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;
}

  • 16
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 14
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Respect@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值