MySQL - C/C++访问MySQL数据库(数据库编程实战-获取关卡信息)

43 篇文章 1 订阅

获取关卡信息

在这里插入图片描述

#include <graphics.h>
#include <iostream>
#include <stdlib.h>
#include <string>
#include <conio.h>

#include "box_man.h"
#include "database.h"



using namespace std;


IMAGE images[ALL];

struct _POS man;  //小人在二维数组中的位置

				  /*游戏地图*/
int map[LINE][COLUMN] = {
	{ 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 },
};


/**********************************************
*判断游戏是否结束,如果不存在任何一个箱子目的地,就代表游戏结束
*输入: 无
*返回值:
*     true -  游戏结束   false - 游戏继续
**********************************************/
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;
}

/**********************************************
*游戏结束场景,在玩家通关后显示
*输入:
*     bg - 背景图片变量的指针
*返回值: 无
**********************************************/
void gameOverScene(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);
}

/**********************************************
*改变游戏地图视图中一格对应道具并重新显示
*输入:
*     pos -   道具在地图数组的行列下标
*     prop   - 道具的类型
*返回值: 无
**********************************************/
void changeMap(POS* pos, PROPS prop) {
	map[pos->x][pos->y] = prop;
	putimage(START_X + pos->y * RATIO, START_Y + 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) {//人的前方是地板
		changeMap(&next_pos, MAN); //小人前进一格
		changeMap(&man, FLOOR);
		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); //小人前进一格
			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); //小人前进一格
			changeMap(&man, FLOOR);
			man = next_pos;
		}
	}
}

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

int main(void) {
	/* 用户身份验证 */
	userinfo user;
	levelinfo level;
	bool ret = false;

	if (login(user) == false)
	{
		cout << "登录失败, 请重新登录!!!" << endl;
		::system("pause");
		exit(-1);
	}
	else
	{
		cout << "登录成功 用户id: " << user.id << ", 你所在的关卡是: " << user.level_id << ", 请开始你的表演!!!" << endl;
		::system("pause");
	}

	/* 根据用户所在关卡id获取关卡数据 */
	ret = fetch_level_info(level, user.level_id);

	if (!ret)
	{
		cout << "获取关卡数据失败, 请重试" << endl;
		::system("pause");
		exit(-2);
	}

	::system("pause");

	IMAGE bg_img;

	//搭台唱戏
	initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);
	loadimage(&bg_img, _T("blackground.bmp"), SCREEN_WIDTH, SCREEN_HEIGHT, true);
	putimage(0, 0, &bg_img);

	//加载道具图标
	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.bmp"), RATIO, RATIO, true);
	loadimage(&images[HIT], _T("box.bmp"), RATIO, RATIO, true);

	for (int i = 0; i < LINE; i++) {
		for (int j = 0; j < COLUMN; j++) {
			if (map[i][j] == MAN) {
				man.x = i;
				man.y = j;
			}

			putimage(START_X + j * RATIO, START_Y + i * RATIO, &images[map[i][j]]);
		}
	}

	//游戏环节
	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 == KEY_QUIT) {
				quit = true;
			}
			if (isGameOver()) {
				gameOverScene(&bg_img);
				quit = true;
			}
		}
		Sleep(100);
	} while (quit == false); //!quit

	system("pause");

	//游戏结束,释放资源
	closegraph();
	return 0;
}

在这里插入图片描述

#pragma once

#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 650

#define RATIO 50

//控制键 上、下、左、右 控制方向,'q' 退出
#define	KEY_UP        'w'    //char  'a'   
#define	KEY_LEFT      'a'
#define	KEY_RIGHT     'd'
#define	KEY_DOWN      's'
#define KEY_QUIT      'q'

#define LINE   9
#define COLUMN 12

#define START_X  100
#define START_Y  100

#define MAX_RETRY_TIMES 4

//#define   PROPS    enum _PROPS
typedef   enum _PROPS      PROPS;
typedef   enum _DIRECTION  DIRECTION;
typedef   struct _POS      POS;

#define isValid(pos)  pos.x>=0 && pos.x<LINE && pos.y>=0 && pos.y <COLUMN

enum _PROPS {
	WALL,     //墙
	FLOOR,    //地板
	BOX_DES,  //箱子目的地
	MAN,      //小人
	BOX,      //箱子
	HIT,      //箱子命中目标
	ALL
};

//游戏控制方向
enum _DIRECTION
{
	UP,
	DOWN,
	LEFT,
	RIGHT
};

struct _POS {
	int x;  //小人所在的二维数组的行
	int y;  //小人所在的二维数组的列
};

在这里插入图片描述

#pragma once

#include <string>

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); /* 获取关卡信息 */

在这里插入图片描述

#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 "Wei02032001"

static int debug = 1;

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

/************************************
* 功能: 根据关卡 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 != 0)
	{
		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]);

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

具体操作

在这里插入图片描述

运行结果:

在这里插入图片描述

结语:

时间: 2020-07-16

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值