欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言+MySQL實現(xiàn)推箱子游戲

 更新時間:2022年02月21日 09:52:24   作者:霸道小明  
經(jīng)典的推箱子是一個來自日本的古老游戲,目的是在訓(xùn)練你的邏輯思考能力。本文將通過C語言和MySQL實現(xiàn)推箱子這一經(jīng)典游戲,感興趣的可以了解一下

圖片素材及源碼

下載鏈接

數(shù)據(jù)庫SQL語句

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 '下一關(guān)的id,0代表通關(guān)',
    primary key(id)
);
insert into users 
    values(1,'Jack',md5(123456),1);
insert into levels 
    values(1,'小試牛刀→第一關(guān)',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,'絕地強者→第二關(guān)',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,'天外強人→第三關(guān)',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,'死而復(fù)生→BOSS關(guān)',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);
 

操作數(shù)據(jù)庫C++代碼

database.h

#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;	// 關(guān)卡id
	string name;	// 關(guān)卡名字
	int map_row;	// 地圖行數(shù)
	int map_column;	//地圖列數(shù)
	string map_data;	// 二維地圖數(shù)據(jù)
	int next_level;	//下一關(guān)卡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

記得更改自己的用戶名和密碼

#include"database.h"
#include<mysql.h>
#include<stdio.h>	// 會使用C的接口
 
#define DB_NAME	"box_man"    //數(shù)據(jù)庫名
#define DB_HOST	"127.0.0.1"    //IP地址
#define DB_PORT 3306            //端口號
#define DB_USER "root"           //用戶名
#define DB_USER_PASSWORD "123456"    //密碼
 
 
 
/******************************
 *功能:數(shù)據(jù)庫鏈接
 * 輸入:
 *		mysql - 數(shù)據(jù)庫訪問句柄
 *
 * 返回值:
 *		true - 連接成功
 *		false - 連接失敗
 *****************************/
bool connect_db(MYSQL& mysql) {
	//1.初始數(shù)據(jù)庫句柄
	mysql_init(&mysql);
 
	//2.設(shè)置字符編碼(為句柄設(shè)置)
	//windows支持中文,在windows上一般是gbk字符集,gbk包含中文簡體和繁體,簡體是gbk2312
	mysql_options(&mysql, MYSQL_SET_CHARSET_NAME, "gbk");
 
	//3.連接數(shù)據(jù)庫
	//句柄,主機,用戶名,密碼,數(shù)據(jù)庫,端口號,——,——
	if (mysql_real_connect(&mysql, DB_HOST, DB_USER, DB_USER_PASSWORD, DB_NAME, DB_PORT, NULL, 0) == NULL) {
		printf("數(shù)據(jù)庫連接失敗,錯誤原因:%s\n", mysql_error(&mysql));
		return false;
	}
	return true;
}
 
/******************************
 *功能:通過用戶名和密碼獲取用戶信息
 * 輸入:
 *		user - 用戶信息結(jié)構(gòu)體
 *
 * 返回值:
 *		獲取成功返回true,失敗false
 *****************************/
bool fetch_user_info(userinfo& user) {
	MYSQL mysql;	//定義一個句柄,對mysql的訪問都是通過這個句柄(就是一個集合)
	MYSQL_RES* res;		// 查詢的結(jié)果集
	MYSQL_ROW row;		// 如果結(jié)果集有多條,可以使用row獲取
	char sql[256];
	bool ret = false;
	//1.連接數(shù)據(jù)庫
	if (connect_db(mysql) == false) {
		return false;
	}
	//2.設(shè)置SQL查詢語句
	//snprintf函數(shù),設(shè)將可變參數(shù)(...)按照 format 格式化成字符串,并將字符串復(fù)制到 str 中,size 為要寫入的字符的最大數(shù)目,超過 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("數(shù)據(jù)庫查詢出錯,%s錯誤原因:%s\n", sql, mysql_error(&mysql));
		// 關(guān)閉數(shù)據(jù)庫
		mysql_close(&mysql);
		return false;
	}
	
	//3.獲取查到的結(jié)果
	res = mysql_store_result(&mysql);
	//row獲得結(jié)果集里的一行記錄,再通過下標(biāo)訪問記錄里的數(shù)據(jù),如果結(jié)果集有多行時可以通過 while(row = mysql_fetch_row(res)){ }循環(huán)獲得
	row = mysql_fetch_row(res);
 
	if (row == NULL) {	//沒有查到記錄
		//1.釋放結(jié)果集
		mysql_free_result(res);
		//1.關(guān)閉數(shù)據(jù)庫
		mysql_close(&mysql);
		return false;
	}
	user.id = atoi(row[0]);	// 字符串轉(zhuǎn)整數(shù)
	user.level_id = atoi(row[1]);
	//4.返回結(jié)果
	mysql_free_result(res);
	mysql_close(&mysql);
	return true;
}
 
/*********************************
 *功能:根據(jù)關(guān)卡id獲取完整的關(guān)卡信息(如:地圖,下一關(guān)等)
 * 輸入:
 *		level - 保存關(guān)卡信息的結(jié)構(gòu)體
 *		level_id - 獲取關(guān)卡id
 * 返回值:
 *		-1 - 數(shù)據(jù)庫連接或查詢出錯
 *		0  - 查找結(jié)果為空
 *		1 - 查找成功
 *********************************/
int fetch_level_info(levelinfo& level, int level_id) {
	MYSQL mysql;	//定義一個句柄,對mysql的訪問都是通過這個句柄(就是一個集合)
	MYSQL_RES* res;		// 查詢的結(jié)果集
	MYSQL_ROW row;		// 如果結(jié)果集有多條,可以使用row獲取
	char sql[256];
	bool ret = false;
	//1.連接數(shù)據(jù)庫
	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("數(shù)據(jù)庫查詢出錯,%s錯誤原因:%s\n", sql, mysql_error(&mysql));
		// 關(guān)閉數(shù)據(jù)庫
		mysql_close(&mysql);
		return -1;
	}
 
	//3.獲取查到的結(jié)果
	res = mysql_store_result(&mysql);
	//row獲得結(jié)果集里的一行記錄,再通過下標(biāo)訪問記錄里的數(shù)據(jù),如果結(jié)果集有多行時可以通過 while(row = mysql_fetch_row(res)){ }循環(huán)獲得
	row = mysql_fetch_row(res);
 
	if (row == NULL) {	//沒有查到記錄
		//1.釋放結(jié)果集
		mysql_free_result(res);
		//1.關(guān)閉數(shù)據(jù)庫
		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.返回結(jié)果
	mysql_free_result(res);
	mysql_close(&mysql);
	return 1;
}
 
/******************************
 *功能:將獲得的關(guān)卡數(shù)據(jù)轉(zhuǎn)換到map地圖數(shù)組中
 * 輸入:
 *		level - 關(guān)卡數(shù)據(jù)
 *		map - 二維地圖數(shù)組
 *
 * 返回值:
 *		false - 轉(zhuǎn)換失敗
 *		true - 轉(zhuǎn)換成功
 *****************************/
bool transform_map_db2array(levelinfo& level, int map[][COLUMN]) {
	if (level.map_row > LINE || level.map_column > COLUMN) {
		printf("地圖過大,請重新設(shè)置\n");
		return false;
	}
	if (level.map_data.length() < 1) {
		printf("地圖數(shù)據(jù)有誤,請重新設(shè)置!\n");
		return false;
	}
	long long start = 0, end = 0;
	int row = 0, column = 0;
	do {
		/******************************
		 *find返回size_t類型值,size_t在64位下是8字節(jié)長度,因此這里把start和end設(shè)置成long long類型(不設(shè)置會有“數(shù)據(jù)丟失”警告)。當(dāng)然也可以簡單粗暴的修改警告設(shè)置
		******************************/
		end = level.map_data.find('|', start);
		if (end == -1) {
			end = level.map_data.length();
		}
		//合法性檢查,結(jié)束時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());
		// 對行數(shù)據(jù)進行解析:0,1,0,1,1,1,1,1,1,1,0,0
		char* next_token = NULL;
		//line轉(zhuǎn)為const char*(C語言中的字符串),strtok_s會修改line里的值,按照某個特定字符,所以需要將line.c_str()轉(zhuǎn)為char *
		// strtok_s第一個參數(shù)是要劈開的字符串(要求是一個char *類型的);第二個參數(shù)是按某個字符劈開(會把“,”逗號變成‘\0'結(jié)束符,也就是說會修改原來字符串,所以要把原來的const char*轉(zhuǎn)為char*);第三個參數(shù)是這個接口
		// 需要的,用來做定位功能,
		//printf("%p\n", &line[2]);
		char* item = strtok_s((char*)line.c_str(), ",", &next_token);
		column = 0;
	    //printf("%p", next_token);
		//::system("pause");
		//如果某行數(shù)據(jù)個數(shù)多余這個地圖列數(shù),控制只讀取level.map_column-1個
		while (item&&column<level.map_column) {
			map[row][column] = atoi(item);
			column++;
			//再使用strtok_s接口第一個參數(shù)可以寫NULL,應(yīng)該是next_token參數(shù)上一次做定位功能時已經(jīng)記錄了要劈開字符串給的某個位置
			item = strtok_s(NULL, ",", &next_token);
		}
 
		//合法性檢查
		if (column < level.map_column) {	// 某行的數(shù)據(jù)個數(shù)小于這個地圖的列數(shù)
			printf("地圖數(shù)據(jù)解析出錯,終止!\n");
			return false;
		}
		row++;
 
		//列數(shù)多余的話直接舍棄
		if (row >= level.map_row) {
			break;
		}
		start = end + 1;
	} while (1 == 1);
	//列數(shù)多余則直接報錯
	if (row < level.map_row) {
		printf("地圖行數(shù)少于設(shè)定,終止!");
		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.連接數(shù)據(jù)庫
	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("數(shù)據(jù)庫更新出錯,%s錯誤原因:%s\n", sql, mysql_error(&mysql));
		// 關(guān)閉數(shù)據(jù)庫
		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.連接數(shù)據(jù)庫
	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.判斷查詢結(jié)果
	if (ret) {
		printf("數(shù)據(jù)庫更新出錯,%s錯誤原因:%s\n", sql, mysql_error(&mysql));
		// 關(guān)閉數(shù)據(jù)庫
		mysql_close(&mysql);
		return false;
	}
	user.level_id = 1;
	//4.關(guān)閉數(shù)據(jù)庫
	mysql_close(&mysql);
	return true;
}

推箱子游戲代碼

box_man.h

#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,	//箱子命中目標(biāo)
	MAN_DES,	//人站在目標(biāo)上
	VECTOR	//通關(guān)圖片
};
 
enum  _DIRECTION {
	UP,
	DOWN,
	LEFT,
	RIGHT
};
 
struct _POS {
	int x;	//小人所在二維數(shù)組的行數(shù)
	int y;	//小人所在二維數(shù)組的列數(shù)
};

box_man.cpp

#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];
 
/*****************************
* 功能:判斷游戲是否結(jié)束
* 輸入:
*		無
* 輸出:
*		true - 未結(jié)束
*		flase - 結(jié)束
*****************************/
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;
}
 
/*****************************
* 功能:加載游戲結(jié)束圖片
* 輸入:
*		無
* 輸出:
*		無
*****************************/
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;
	//圖片的寬,高最后一個參數(shù)“是否拉伸”
	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坐標(biāo),y為Y坐標(biāo)
{
 
	// 變量初始化
	DWORD* dst = GetImageBuffer();    // GetImageBuffer()函數(shù),用于獲取繪圖設(shè)備的顯存指針,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();       //獲取繪圖區(qū)的寬度,EASYX自帶
	int graphHeight = getheight();     //獲取繪圖區(qū)的高度,EASYX自帶
	int dstX = 0;    //在顯存里像素的角標(biāo)
 
	// 實現(xiàn)透明貼圖 公式: 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; //在顯存里像素的角標(biāo)
			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; //在顯存里像素的角標(biāo)
				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
			}
		}
	}
}
 
/*****************************
* 功能:載入“恭喜通關(guān)”圖片
* 輸入:
*		無
* 輸出:
*		無
*****************************/
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 - 擋墻關(guān)卡數(shù)據(jù)
*		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()) {
				//更新用戶下一關(guān)關(guān)卡信息(用戶通關(guān)后直接跳轉(zhuǎn)下一關(guān))
				update_user_level(user, level.next_level);
				quit=true;
			}
		}
		wait(100);
	} while (quit == false);
}
 
/*****************************
* 功能:根據(jù)“由用戶ID獲取關(guān)卡數(shù)據(jù)”的返回結(jié)果進行判斷
* 輸入:
*		result - 返回結(jié)果(-1:獲取失敗  0:用戶已通關(guān)  1:獲取成功)
*		level - 關(guān)卡數(shù)據(jù)
*		user - 用戶信息
* 輸出:
*		無
*****************************/
void judge_by_result(int result, levelinfo& level, userinfo& user) {
	if (result == 1) {
		return;
	}
	else if (result == -1) {
		closegraph();
		cout << "獲取關(guān)卡數(shù)據(jù)失敗,請重試!" << 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();
	//循環(huán)(讀取關(guān)卡→用戶操作)
	do {
		//根據(jù)用戶信息加載關(guān)卡數(shù)據(jù)
		int result = fetch_level_info(level, user.level_id);
		judge_by_result(result, level, user);
		//將關(guān)卡數(shù)據(jù)數(shù)據(jù)轉(zhuǎn)換到map游戲地圖中
		transform_map_db2array(level, map);	
		//加載游戲圖片
		show_images(level);
		//小人移動
		game_operation(level, user);
		//恭喜通關(guān)
		promot_over();
	} while (1);
	std::system("pause");
	closegraph();
	return 0;
}

到此這篇關(guān)于C語言+MySQL實現(xiàn)推箱子游戲的文章就介紹到這了,更多相關(guān)C語言 MySQL推箱子內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++編譯報錯:||error: ld returned 1 exit status|的解決

    C++編譯報錯:||error: ld returned 1 exit 

    這篇文章主要介紹了C++編譯報錯:||error: ld returned 1 exit status|的解決方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • C++中stack容器的使用

    C++中stack容器的使用

    本文主要介紹了C++中stack容器的使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • C語言經(jīng)典順序表真題演練講解

    C語言經(jīng)典順序表真題演練講解

    程序中經(jīng)常需要將一組數(shù)據(jù)元素作為整體管理和使用,需要創(chuàng)建這種元素組,用變量記錄它們,傳進傳出函數(shù)等。一組數(shù)據(jù)中包含的元素個數(shù)可能發(fā)生變化,順序表則是將元素順序地存放在一塊連續(xù)的存儲區(qū)里,元素間的順序關(guān)系由它們的存儲順序自然表示
    2022-04-04
  • QT5實現(xiàn)簡單的TCP通信的實現(xiàn)

    QT5實現(xiàn)簡單的TCP通信的實現(xiàn)

    本文主要介紹了QT5實現(xiàn)簡單的TCP通信的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 詳解設(shè)計模式中的模板方法模式及在C++中的使用

    詳解設(shè)計模式中的模板方法模式及在C++中的使用

    這篇文章主要介紹了設(shè)計模式中的模板方法模式及在C++中的使用,模板方法將邏輯封裝到一個類中,并采取組合(委托)的方式解決這個問題,需要的朋友可以參考下
    2016-03-03
  • C++ 中的虛函數(shù)表及虛函數(shù)執(zhí)行原理詳解

    C++ 中的虛函數(shù)表及虛函數(shù)執(zhí)行原理詳解

    這篇文章主要介紹了C++ 中的虛函數(shù)表及虛函數(shù)執(zhí)行原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • C語言對磁盤文件進行快速排序簡單實例

    C語言對磁盤文件進行快速排序簡單實例

    這篇文章主要介紹了C語言對磁盤文件進行快速排序簡單實例的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Qt進程和線程QProcess和QThread的使用

    Qt進程和線程QProcess和QThread的使用

    本文主要介紹了Qt進程和線程QProcess和QThread的使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • C++字符串類的封裝你真的了解嗎

    C++字符串類的封裝你真的了解嗎

    這篇文章主要為大家詳細介紹了C++字符串類的封裝,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • VS2010+Opencv+MFC讀取圖像和視頻顯示在Picture控件

    VS2010+Opencv+MFC讀取圖像和視頻顯示在Picture控件

    這篇文章主要為大家詳細介紹了VS2010+Opencv+MFC讀取圖像和視頻顯示在Picture控件,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-08-08

最新評論