SoFunction
Updated on 2025-04-06

C language + MySQL implement box-pushing game

Image material and source code

Download link

Database SQL statements

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 'The id of the next level, 0 means pass the level',
    primary key(id)
);
insert into users 
    values(1,'Jack',md5(123456),1);
insert into levels 
    values(1,'Test → First level',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,'The Jedi Strong → The Second Level',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,'The Strong Man from Heaven → The Third Level',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,'Resurrection from the Death → BOSS Pass',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);
 

Operate database C++ code

#pragma once
#include<string>
using namespace std;
 
#define LINE 48
#define COLUMN 48
 
typedef struct _userinfo {
	//The string is initially empty here	_userinfo() :id(0), username(""), password(""), level_id(0) {};
	int id;	// User ID	string username;
	string password;	// 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;	// Level id	string name;	// Level name	int map_row;	// Number of rows of map	int map_column;	//Number of map columns	string map_data;	// 2D map data	int next_level;	//Next level 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);

Remember to change your username and password

#include""
#include<>
#include<> // Will use C's interface 
#define DB_NAME "box_man" //Database name#define DB_HOST "127.0.0.1" //IP address#define DB_PORT 3306 //Port number#define DB_USER "root" //User name#define DB_USER_PASSWORD "123456" //Password 
 
 
/*********************************************
  *Function: Database link
  * Input:
  * mysql - database access handle
  *
  * Return value:
  * true - Connection is successful
  * false - Connection failed
  ***************************************/
bool connect_db(MYSQL&amp; mysql) {
	//1. Initial database handle	mysql_init(&amp;mysql);
 
	//2. Set character encoding (set for handle)	//Windows supports Chinese, generally the gbk character set on Windows, gbk contains Chinese simplified and traditional Chinese, and simplified Chinese is gbk2312	mysql_options(&amp;mysql, MYSQL_SET_CHARSET_NAME, "gbk");
 
	//3.Connect the database	// Handle, host, username, password, database, port number, ———	if (mysql_real_connect(&amp;mysql, DB_HOST, DB_USER, DB_USER_PASSWORD, DB_NAME, DB_PORT, NULL, 0) == NULL) {
		printf("Database connection failed, error reason: %s\n", mysql_error(&amp;mysql));
		return false;
	}
	return true;
}
 
/*********************************************
  *Function: Obtain user information through username and password
  * Input:
  * user - user information structure
  *
  * Return value:
  * Get success and return true, fail false
  ***************************************/
bool fetch_user_info(userinfo&amp; user) {
	MYSQL mysql;	//Define a handle, and access to mysql is through this handle (that is, a collection)	MYSQL_RES* res;		// Query result set	MYSQL_ROW row;		// If there are multiple resultsets, you can use row to get it	char sql[256];
	bool ret = false;
	//1.Connect the database	if (connect_db(mysql) == false) {
		return false;
	}
	//2. Set SQL query statement	//snprintf function, let's format the mutable parameters (...) into a string according to format and copy the string into str. Size is the maximum number of characters to be written. If size exceeds size, it will be truncated.	snprintf(sql, 256, "select id,level_id from users where username='%s' and password = md5('%s');", .c_str(), .c_str());
	ret = mysql_query(&amp;mysql, sql);	//mysql query, successfully returned 0	if (ret) {
		printf("The database query error occurred, %s error reason: %s\n", sql, mysql_error(&amp;mysql));
		// Close the database		mysql_close(&amp;mysql);
		return false;
	}
	
	//3. Obtain the found results	res = mysql_store_result(&amp;mysql);
	//row gets a row of records in the result set, and then accesses the data in the record through the subscript. If there are multiple rows in the result set, you can get it through the while(row = mysql_fetch_row(res)){ } loop	row = mysql_fetch_row(res);
 
	if (row == NULL) {	//No record was found		//1. Release the result set		mysql_free_result(res);
		//1. Close the database		mysql_close(&amp;mysql);
		return false;
	}
	 = atoi(row[0]);	// String to integer	user.level_id = atoi(row[1]);
	//4. Return the result	mysql_free_result(res);
	mysql_close(&amp;mysql);
	return true;
}
 
/************************************************
  *Function: Obtain complete level information based on level id (such as: map, next level, etc.)
  * Input:
  * level - The structure that saves level information
  * level_id - get level id
  * Return value:
  * -1 - An error occurred in database connection or query
  * 0 - The search result is empty
  * 1 - Search successfully
  ******************************************/
int fetch_level_info(levelinfo&amp; level, int level_id) {
	MYSQL mysql;	//Define a handle, and access to mysql is through this handle (that is, a collection)	MYSQL_RES* res;		// Query result set	MYSQL_ROW row;		// If there are multiple resultsets, you can use row to get it	char sql[256];
	bool ret = false;
	//1.Connect the database	if (connect_db(mysql) == false) {
		return -1;
	}
	//2. Write SQL statement	snprintf(sql, 256, "select name,map_row,  map_column,map_data,next_level_id from levels where id=%d;", level_id);
	ret = mysql_query(&amp;mysql, sql);	//mysql query, successfully returned 0	if (ret) {
		printf("The database query error occurred, %s error reason: %s\n", sql, mysql_error(&amp;mysql));
		// Close the database		mysql_close(&amp;mysql);
		return -1;
	}
 
	//3. Obtain the found results	res = mysql_store_result(&amp;mysql);
	//row gets a row of records in the result set, and then accesses the data in the record through the subscript. If there are multiple rows in the result set, you can get it through the while(row = mysql_fetch_row(res)){ } loop	row = mysql_fetch_row(res);
 
	if (row == NULL) {	//No record was found		//1. Release the result set		mysql_free_result(res);
		//1. Close the database		mysql_close(&amp;mysql);
		return 0;
	}
	 = level_id;
	 = 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 uses printf output, and using .c_str() can return a pointer to const char*	//printf("level id: %d  name: %s map row: %d  map column: %d map data: %s next level: %d\n", , .c_str(), level.map_row, level.map_column, level.map_data.c_str(), level.next_level);
	
	//4. Return the result	mysql_free_result(res);
	mysql_close(&amp;mysql);
	return 1;
}
 
/*********************************************
  *Function: Convert the obtained level data to map array
  * Input:
  * level - level data
  * map - 2D map array
  *
  * Return value:
  * false - Conversion failed
  * true - Conversion was successful
  ***************************************/
bool transform_map_db2array(levelinfo&amp; level, int map[][COLUMN]) {
	if (level.map_row &gt; LINE || level.map_column &gt; COLUMN) {
		printf("The map is too large, please reset\n");
		return false;
	}
	if (level.map_data.length() &lt; 1) {
		printf("The map data is incorrect, please reset it!\n");
		return false;
	}
	long long start = 0, end = 0;
	int row = 0, column = 0;
	do {
		/*********************************************
		  *find returns the value of size_t type, and size_t is 8 bytes in 64 bits, so here is set to start and end to long long type (there will be a "data loss" warning if it is not set).  Of course, you can also simply and roughly modify the warning settings
		 ***************************************/
		end = level.map_data.find('|', start);
		if (end == -1) {
			end = level.map_data.length();
		}
		//Legality check, end=level.map_data.length at the end, start=end+1		if (start &gt;= end)
			break;
		string line = level.map_data.substr(start, end - start);
		//printf("get-line:%s\n", line.c_str());
		// Analyze the row data: 0,1,0,1,1,1,1,1,1,1,1,0,0		char* next_token = NULL;
		//Convert line to const char* (a string in C language), strtok_s will modify the value in line to follow a specific character, so you need to convert line.c_str() to char *		// The first parameter of strtok_s is the string to be split (required to be a char* type); the second parameter is split by a certain character (the comma will be changed to the ending character of "," which means that the original string will be modified, so the original const char* needs to be converted to char*); the third parameter is this interface		// If necessary, it is used for positioning function.		//printf("%p\n", &amp;line[2]);
		char* item = strtok_s((char*)line.c_str(), ",", &amp;next_token);
		column = 0;
	    //printf("%p", next_token);
		//::system("pause");
		//If the number of data in a certain row is unnecessary, the number of map columns is controlled to only read level.map_column-1		while (item&amp;&amp;column&lt;level.map_column) {
			map[row][column] = atoi(item);
			column++;
			//You can write NULL when using the strtok_s interface first parameter. It should be that the next_token parameter was recorded when it was last used for positioning function. The position given by the string was recorded.			item = strtok_s(NULL, ",", &amp;next_token);
		}
 
		//Legality check		if (column &lt; level.map_column) {	// The number of data in a row is smaller than the number of columns in this map			printf("The map data parsing error, terminated!\n");
			return false;
		}
		row++;
 
		// If the number of columns is unnecessary, just discard it		if (row &gt;= level.map_row) {
			break;
		}
		start = end + 1;
	} while (1 == 1);
	//If the number of columns is redundant, the error will be reported directly	if (row &lt; level.map_row) {
		printf("The map row count is less than the setting, terminate!");
		return false;
	}
	return true;
}
 
/*********************************************
  *Function: Update user game progress information
  * Input:
  * user - User information
  * next_level_id - game progress
  *
  * Return value:
  * Get success and return true, fail false
  ***************************************/
bool update_user_level(userinfo&amp; user, int next_level_id) {
	MYSQL mysql;	//Define a handle, and access to mysql is through this handle (that is, a collection)	char sql[256];
	bool ret = false;
	//1.Connect the database	if (connect_db(mysql) == false) {
		return false;
	}
	//2. Write SQL statement	snprintf(sql, 256, "update users set level_id=%d where id=%d", next_level_id, );
	ret = mysql_query(&amp;mysql, sql);
 
	if (ret) {
		printf("The database update error occurred, %s error reason: %s\n", sql, mysql_error(&amp;mysql));
		// Close the database		mysql_close(&amp;mysql);
		return false;
	}
	user.level_id = next_level_id;
	mysql_close(&amp;mysql);
	return true;
}
 
/*********************************************
  *Function: Reset user game progress information
  * Input:
  * user - User information
  *
  * Return value:
  * false - Reset failed
  * true - Reset successfully
  ***************************************/
bool resiting_data(userinfo&amp; user) {
	MYSQL mysql;	//Define a handle, and access to mysql is through this handle (that is, a collection)	char sql[256];
	bool ret = false;
	//1.Connect the database	if (connect_db(mysql) == false) {
		return false;
	}
	//2. Write SQL statement	snprintf(sql, 256, "update users set level_id=1 where id=%d", );
	ret = mysql_query(&amp;mysql, sql);
	//3.Judge query results	if (ret) {
		printf("The database update error occurred, %s error reason: %s\n", sql, mysql_error(&amp;mysql));
		// Close the database		mysql_close(&amp;mysql);
		return false;
	}
	user.level_id = 1;
	//4. Close the database	mysql_close(&amp;mysql);
	return true;
}

Push box game code

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 &gt; 0 &amp;&amp; next_pos.x &lt; LINE &amp;&amp; next_pos.y&gt;0 &amp;&amp; next_pos.y &lt; COLUMN
 
typedef enum _PROPS		PROPS;
typedef enum _DIRECTION DIRECTION;
typedef struct _POS		POS;
 
enum  _PROPS  {
	WALL,	//wall	FLOOR,	//floor	BOX_DES,//Box destination	MAN,	//The little man	BOX,	//box	HIT,	//The box hits the target	MAN_DES,	//People stand on the target	VECTOR	//Performance pictures};
 
enum  _DIRECTION {
	UP,
	DOWN,
	LEFT,
	RIGHT
};
 
struct _POS {
	int x;	//The number of rows in the two-dimensional array where the villain is located	int y;	//The number of columns in the two-dimensional array where the villain is located};

box_man.cpp

#include&lt;&gt;
#include&lt;iostream&gt;
#include&lt;&gt;
#include&lt;string&gt;
#include&lt;&gt;	//???
#include"box_man.h"
#include""
using namespace std;
 
 
int map[LINE][COLUMN] = { 0 };
 
POS man;
IMAGE images[9];
 
/******************************************
 * Function: Determine whether the game ends
 * Input:
 *		none
 * Output:
 * true - Not ended
 * flase - end
 ***************************************/
bool isGameOver() {
	for (int i = 0; i &lt; LINE; ++i) {
		for (int j = 0; j &lt; COLUMN; ++j) {
			if (map[i][j] == BOX_DES)
				return false;
		}
	}
	return true;
}
 
/******************************************
 * Function: Load the end game picture
 * Input:
 *		none
 * Output:
 *		none
 ***************************************/
void show_over() {
	cleardevice();
	IMAGE game_over;
	loadimage(&amp;game_over, _T(""), SCREEN_WIDTH, SCREEN_HEIGHT, true);
	putimage(0, 0, &amp;game_over);
}
 
/******************************************
 * Function: Change map information at the specified location Display the specified picture
 * Input:
 * next_pos - specify location
 * prop - specify the picture
 * Output:
 *		none
 ***************************************/
void changeMap(POS* next_pos, PROPS prop) {
	map[next_pos-&gt;x][next_pos-&gt;y] = prop;
	putimage(START_X + next_pos-&gt;y * RATIO, START_Y + next_pos-&gt;x * RATIO, &amp;images[prop]);
}
 
/******************************************
 * Function: Display the specified picture at the specified location
 * Input:
 * next_pos - specify location
 * prop - specify the picture
 * Output:
 *		none
 ***************************************/
void changeMap2(POS* next_pos, PROPS prop) {
	putimage(START_X + next_pos-&gt;y * RATIO, START_Y + next_pos-&gt;x * RATIO, &amp;images[prop]);
}
 
/******************************************
 * Function: Control the movement of the villain in the specified direction
 * Input:
 * direct - specify direction
 * Output:
 *		none
 ***************************************/
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;
	}	
	// Macro expand next_pos.x > 0 && next_pos.x < LINE && next_pos.y>0 && next_pos.y < COLUMN	// The floor is ahead of people	if (isValid(next_pos) &amp;&amp; map[next_pos.x][next_pos.y] == FLOOR) {
		//The destination is under the feet of a person		if (map[][] == BOX_DES) {
			changeMap(&amp;next_pos, MAN);
			changeMap2(&amp;man, BOX_DES);
		}
		else {
			changeMap(&amp;man, FLOOR);
			changeMap(&amp;next_pos, MAN);
		}	
		man = next_pos;
	}
	// In front of the person is a box	else if (isValid(next_next_pos) &amp;&amp; map[next_pos.x][next_pos.y] == BOX) {	
		if (map[next_next_pos.x][next_next_pos.y] == FLOOR) {	// The front of the box is the floor			changeMap(&amp;next_next_pos, BOX);
			changeMap(&amp;next_pos, MAN);
			if (map[][] == BOX_DES) {
				changeMap(&amp;man, BOX_DES);
			}
			else {
				changeMap(&amp;man, FLOOR);
			}
			man = next_pos;
		}
		else if (map[next_next_pos.x][next_next_pos.y] == BOX_DES) {	// The destination is in front of the box			changeMap(&amp;next_next_pos, HIT);
			changeMap(&amp;next_pos, MAN);
			if (map[][] == BOX_DES) {
				changeMap(&amp;man, BOX_DES);
			}
			else {
				changeMap(&amp;man, FLOOR);
			}
			man = next_pos;
		}	
	}
	//The destination is ahead	else if (isValid(next_pos) &amp;&amp; map[next_pos.x][next_pos.y] == BOX_DES) {
		//The little man is also the destination		if (map[][] == BOX_DES) {
			changeMap2(&amp;next_pos, MAN_DES);
			changeMap(&amp;man, BOX_DES);
		}
		else {
			changeMap(&amp;man, FLOOR);
			changeMap2(&amp;next_pos, MAN_DES);
			
		}
		man = next_pos;
	}
	//The box hit point ahead is	else if (isValid(next_pos) &amp;&amp; map[next_pos.x][next_pos.y] == HIT) {
		if (map[next_next_pos.x][next_next_pos.y] == FLOOR) {	// The front of the box is the floor			changeMap(&amp;next_next_pos, BOX);
			changeMap(&amp;next_pos, BOX_DES);
			changeMap2(&amp;next_pos, MAN_DES);
			//The destination is under the feet of a person			if (map[][] == BOX_DES) {
				changeMap(&amp;man, BOX_DES);
			}
			else {
				changeMap(&amp;man, FLOOR);
			}
			man = next_pos;
		}
		else if (map[next_next_pos.x][next_next_pos.y] == BOX_DES) {	// The destination is in front of the box			changeMap(&amp;next_next_pos, HIT);
			changeMap(&amp;next_pos, BOX_DES);
			changeMap2(&amp;next_pos, MAN_DES);
			//The destination is under the feet of a person			if (map[][] == BOX_DES) {
				changeMap(&amp;man, BOX_DES);
			}
			else {
				changeMap(&amp;man, FLOOR);
			}
			man = next_pos;
		}
	}
}
 
/******************************************
 * Function: User login
 * Input:
 * user - User information
 * Output:
 * false - Login failed
 * true - Login successfully
 ***************************************/
bool login(userinfo&amp; user) {
	int times = 0;
	bool ret = false;
	do {
		cout &lt;&lt; "Please enter the username:";
		cin &gt;&gt; ;
		cout &lt;&lt; "Please enter your password:";
		cin &gt;&gt; ;
		ret = fetch_user_info(user);
		times++;
		if (times &gt;= MAX_RETRY_TIMES)
			break;
		if (ret == false) {
			cout &lt;&lt; "Login failed, please re-enter!" &lt;&lt; endl;
		}
	} while (!ret);
	return ret;
}
 
/******************************************
 * Function: Load game material
 * Input:
 *		none
 * Output:
 *		none
 ***************************************/
void init_graph() {
	initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);
	loadimage(&amp;images[WALL], _T("wall_right.bmp"), RATIO, RATIO, true);
	loadimage(&amp;images[FLOOR], _T(""), RATIO, RATIO, true);
	loadimage(&amp;images[BOX_DES], _T(""), RATIO, RATIO, true);
	loadimage(&amp;images[MAN], _T(""), RATIO, RATIO, true);
	loadimage(&amp;images[BOX], _T(""), RATIO, RATIO, true);
	loadimage(&amp;images[HIT], _T("box_des.jpg"), RATIO, RATIO, true);
	loadimage(&amp;images[MAN_DES], _T("man_des.bmp"), RATIO, RATIO, true);
	loadimage(&amp;images[VECTOR], _T(""), 6*RATIO, 6*RATIO, true);
}
 
/******************************************
 * Function: Display the specified map
 * Input:
 * level - specify map
 * Output:
 *		none
 ***************************************/
void show_images(levelinfo&amp; level) {
	cleardevice();	// Clear the screen every time the picture is posted	IMAGE bg_img;
	//The last parameter of the width and height of the picture is "whether to stretch"	loadimage(&amp;bg_img, _T(""), SCREEN_WIDTH, SCREEN_HEIGHT, true);
	putimage(0, 0, &amp;bg_img);
	for (int i = 0; i &lt; level.map_row; ++i) {
		for (int j = 0; j &lt; level.map_column; ++j) {
			if (map[i][j] == MAN) {
				 = i;
				 = j;
			}
			if (map[i][j] == BG_IMAGE)
				continue;
			putimage(START_X + j * RATIO, START_Y + i * RATIO, &amp;images[map[i][j]]);
		}
	}
	const char* str = .c_str();
	setbkmode(TRANSPARENT);
	setfont(RATIO, 0, _T("Chinese Kaiyi"));
	setcolor(WHITE);
	outtextxy(200, 25, str);
}
 
/******************************************
 * Function: Load the PNG image and remove the transparent part
 * Input:
 *		none
 * Output:
 *		none
 ***************************************/
void drawAlpha(IMAGE* picture, int  picture_x, int picture_y) //x is the X coordinate of the loading picture, and y is the Y coordinate{
 
	// Variable initialization	DWORD* dst = GetImageBuffer();    // GetImageBuffer() function is used to obtain the video memory pointer of the drawing device. EASYX comes with its own	DWORD* draw = GetImageBuffer();
	DWORD* src = GetImageBuffer(picture); //Get picture memory pointer	int picture_width = picture-&gt;getwidth(); //Get the width of the picture, EASYX comes with its own	int picture_height = picture-&gt;getheight(); //Get the height of the picture, EASYX comes with its own	int graphWidth = getwidth();       //Get the width of the drawing area, EASYX comes with its own	int graphHeight = getheight();     //Get the height of the drawing area, EASYX comes with its own	int dstX = 0;    //The angle mark of pixels in the video memory 
	// Implement transparent maps Formula: Cp=αp*FP+(1-αp)*BP, Bayes theorem to calculate the probability of point color	for (int iy = 0; iy &lt; picture_height; iy++)
	{
		for (int ix = 0; ix &lt; picture_width; ix++)
		{
			int srcX = ix + iy * picture_width; //The angle mark of pixels in the video memory			int sa = ((src[srcX] &amp; 0xff000000) &gt;&gt; 24); //0xAArrggbb;AA is transparency			int sr = ((src[srcX] &amp; 0xff0000) &gt;&gt; 16); //Get R in RGB			int sg = ((src[srcX] &amp; 0xff00) &gt;&gt; 8);   //G
			int sb = src[srcX] &amp; 0xff;              //B
			if (ix &gt;= 0 &amp;&amp; ix &lt;= graphWidth &amp;&amp; iy &gt;= 0 &amp;&amp; iy &lt;= graphHeight &amp;&amp; dstX &lt;= graphWidth * graphHeight)
			{
				dstX = (ix + picture_x) + (iy + picture_y) * graphWidth; //The angle mark of pixels in the video memory				int dr = ((dst[dstX] &amp; 0xff0000) &gt;&gt; 16);
				int dg = ((dst[dstX] &amp; 0xff00) &gt;&gt; 8);
				int db = dst[dstX] &amp; 0xff;
				draw[dstX] = ((sr * sa / 255 + dr * (255 - sa) / 255) &lt;&lt; 16)  //Formula: Cp=αp*FP+(1-αp)*BP; αp=sa/255, FP=sr, BP=dr					| ((sg * sa / 255 + dg * (255 - sa) / 255) &lt;&lt; 8)         //αp=sa/255 , FP=sg , BP=dg
					| (sb * sa / 255 + db * (255 - sa) / 255);              //αp=sa/255 , FP=sb , BP=db
			}
		}
	}
}
 
/******************************************
 * Function: Load the "Congratulations" picture
 * Input:
 *		none
 * Output:
 *		none
 ***************************************/
void promot_over() {
	setbkmode(TRANSPARENT);
	drawAlpha(&amp;images[VECTOR], 250, 130);     // Load the PNG image and remove the transparent part	Sleep(1100);
}
 
/******************************************
 * Function: Sleep
 * Input:
 * interval - sleep time
 * Output:
 *		none
 ***************************************/
void wait(int interval) {
	int count = interval / 10;
	for (int i = 0; i &lt; count; ++i) {
		Sleep(10);
		if (_kbhit())
			return;
	}
}
 
/******************************************
 * Function: Game control
 * Input:
 * level - retaining wall level data
 * user - User information
 * Output:
 *		none
 ***************************************/
void game_operation(levelinfo&amp; level, userinfo&amp; user) {
	bool quit = false;
	do {
		//Judge whether there are buttons		if (_kbhit()) {
			//Unbuffered read			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()) {
				//Update the user's next level level information (the user directly jumps to the next level after passing the level)				update_user_level(user, level.next_level);
				quit=true;
			}
		}
		wait(100);
	} while (quit == false);
}
 
/******************************************
 * Function: Make judgment based on the return result of "Get level data from user ID"
 * Input:
 * result - Return result (-1: Failed to obtain 0: The user has passed the level 1: Successful to obtain)
 * level - level data
 * user - User information
 * Output:
 *		none
 ***************************************/
void judge_by_result(int result, levelinfo&amp; level, userinfo&amp; user) {
	if (result == 1) {
		return;
	}
	else if (result == -1) {
		closegraph();
		cout &lt;&lt; "Failed to get level data, please try again!" &lt;&lt; endl;
		std::system("pause");
		exit(-1);
	}
	else if (result == 0) {
		show_over();
		do {
			//Judge whether there are buttons			if (_kbhit()) {
				//Unbuffered read				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() {
	//User authentication	userinfo user;
	levelinfo level;
	if (!login(user)) {
		cout &lt;&lt; "Login failed, please log in again!" &lt;&lt; endl;
		::system("pause");
		exit(-1);
	}
	init_graph();
	//Loop (read the level → user operation)	do {
		//Load level data based on user information		int result = fetch_level_info(level, user.level_id);
		judge_by_result(result, level, user);
		//Convert level data to map game map		transform_map_db2array(level, map);	
		//Load game pictures		show_images(level);
		//The little man moves		game_operation(level, user);
		//Congratulations on passing the		promot_over();
	} while (1);
	std::system("pause");
	closegraph();
	return 0;
}

This is the article about C language + MySQL box push game that introduces this. For more related C languages, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!