C++实现推箱子小游戏(源码公开)

***效果如图所示

一、资源的获取

        首先的获取墙壁,地板,人,箱子目的的的图片

注意:需要VS安装easyX插件,安装过程参照之前文章

二、项目分析

        1、地图初始化

        2、热键控制

        3、逻辑判断

        4、游戏结束

三、具体实现

        1、地图初始化

IMAGE image[ALL];
//初始化地图
int map[LINE][COLMON]{
	{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},
};
//图片的句柄
		IMAGE bg_img;

		//创建窗口
		initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);

		//加载图片
		loadimage(&bg_img, L"blackground.bmp", SCREEN_WIDTH, SCREEN_HEIGHT, true);
		putimage(0, 0, &bg_img);

		//加载道具
		loadimage(&image[Wall], L"wall_right.bmp", RATIO, RATIO, true);
		loadimage(&image[FLOOR], L"floor.bmp", RATIO, RATIO, true);
		loadimage(&image[BOX_DEX], L"des.bmp", RATIO, RATIO, true);
		loadimage(&image[MAN], L"man.bmp", RATIO, RATIO, true);
		loadimage(&image[BOX], L"box.bmp", RATIO, RATIO, true);
		loadimage(&image[HIT], L"box.bmp", RATIO, RATIO, true);

		//地图的加载
		for (int i = 0; i < LINE; i++)
		{
			for (int j = 0; j < COLMON; j++)
			{
				putimage(START_X + j * RATIO, START_Y + i * RATIO, &image[map[i][j]]);
				//确定小人的位置
				if (map[i][j] == MAN)
				{
					man.x = i;
					man.y = j;
				}
			}
		}

        2、定义游戏热键

//定义游戏热键
		bool quit = false;
		do {
			if (_kbhit())
			{
				char ch = _getch();
				if (ch == KEY_LEFT)
				{
					getControl(LEFT);
				}
				else if (ch == KEY_RIGHT)
				{
					getControl(RIGHT);
				}
				else if (ch == KEY_UP)
				{
					getControl(UP);
				}
				else if (ch == KEY_down)
				{
					getControl(DOWN);
				}
				else if (ch == KEY_QUIT)
				{
					quit = true;
				}
				if (isGameOver())
				{
					gameoverScreen(&bg_img);
					quit = true;
				}
			}

			Sleep(100);

		} while (quit == false);

        3、逻辑判断

*
改变游戏中视图中一格道具并重新显示
输入: line-地图数组的行下标   column-地图数组的列下标   prop道具的类型
输出:无
*/
void change_Map(POS* next_POS , PROPOS prop)
{
	map[next_POS->x][next_POS->y] = prop;
	putimage(START_X + next_POS->y * RATIO, START_Y + next_POS->x * RATIO, &image[map[next_POS->x][next_POS->y]]);
}

/*====================================
实现小人的控制
 输入:deriect
 输出: 无
 ====================================*/
void getControl(Decoration dricit)
{

	POS next_POS = man;
	POS next_next_POS = man;
	switch (dricit)
	{
	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)
	{
		change_Map(&next_POS, MAN); //小人前进一格

		change_Map(&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)
		{
			change_Map(&next_next_POS, BOX);
			change_Map(&next_POS, MAN);
			change_Map(&man, FLOOR);
			man = next_POS;
		}
		else if (map[next_next_POS.x][next_next_POS.y] == BOX_DEX)
		{
			change_Map(&next_next_POS, HIT);
			change_Map(&next_POS, MAN);
			change_Map(&man, FLOOR);
			man = next_POS;
		}
	}
}

        4、游戏结束

//判断游戏是否结束
bool isGameOver()
{
	for (int i = 0; i < LINE; i++)
	{
		for (int j = 0; j < COLMON; j++)
		{
			if (map[i][j] == BOX_DEX) return false;
		}
	}
	return true;

}

//游戏结束
void gameoverScreen(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);
}

四、完整的代码

        1、为了方便,编写头文件,将定义好的变量放入

***** man_box.h  的编写

#pragma once
#define RATIO 61 //图片的尺寸
#define SCREEN_WIDTH 960 //背景宽度
#define SCREEN_HEIGHT 768	//背景高度

#define LINE 9
#define COLMON 12

#define START_X 100
#define START_Y 150

#define KEY_LEFT 'a'
#define KEY_RIGHT 'd'
#define KEY_UP    'w'
#define KEY_down  's'
constexpr auto KEY_QUIT = 'q';

typedef enum _PROPOS PROPOS;
typedef enum _Decoration Decoration;

typedef struct _POS POS;

2、源文件的实现

#include<iostream>
#include<stdio.h>
#include<string>
#include<graphics.h>
#include<conio.h>
#include"box_man.h"


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


using namespace std;
//定义小人的结构体
struct _POS{
	int x;
	int y;
};
//道具表示
// 0--墙  1--地板  2--箱子目的地  3--小人  4--箱子  5--箱子命中目标
//定义一个枚举类型,为了初始化地图
enum _PROPOS {
	Wall,	//墙
	FLOOR,	//地板
	BOX_DEX,//箱子目的地
	MAN,	//小人	
	BOX,	//箱子
	HIT,	//箱子目的地
	ALL,
};

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


//创建一个小人的结构体
POS man;

IMAGE image[ALL];
//初始化地图
int map[LINE][COLMON]{
	{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},
};

//判断游戏是否结束
bool isGameOver()
{
	for (int i = 0; i < LINE; i++)
	{
		for (int j = 0; j < COLMON; j++)
		{
			if (map[i][j] == BOX_DEX) return false;
		}
	}
	return true;

}

//游戏结束
void gameoverScreen(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);
}
/*
改变游戏中视图中一格道具并重新显示
输入: line-地图数组的行下标   column-地图数组的列下标   prop道具的类型
输出:无
*/
void change_Map(POS* next_POS , PROPOS prop)
{
	map[next_POS->x][next_POS->y] = prop;
	putimage(START_X + next_POS->y * RATIO, START_Y + next_POS->x * RATIO, &image[map[next_POS->x][next_POS->y]]);
}

/*====================================
实现小人的控制
 输入:deriect
 输出: 无
 ====================================*/
void getControl(Decoration dricit)
{

	POS next_POS = man;
	POS next_next_POS = man;
	switch (dricit)
	{
	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)
	{
		change_Map(&next_POS, MAN); //小人前进一格

		change_Map(&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)
		{
			change_Map(&next_next_POS, BOX);
			change_Map(&next_POS, MAN);
			change_Map(&man, FLOOR);
			man = next_POS;
		}
		else if (map[next_next_POS.x][next_next_POS.y] == BOX_DEX)
		{
			change_Map(&next_next_POS, HIT);
			change_Map(&next_POS, MAN);
			change_Map(&man, FLOOR);
			man = next_POS;
		}
	}
}
int main()
	{
		//图片的句柄
		IMAGE bg_img;

		//创建窗口
		initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);

		//加载图片
		loadimage(&bg_img, L"blackground.bmp", SCREEN_WIDTH, SCREEN_HEIGHT, true);
		putimage(0, 0, &bg_img);

		//加载道具
		loadimage(&image[Wall], L"wall_right.bmp", RATIO, RATIO, true);
		loadimage(&image[FLOOR], L"floor.bmp", RATIO, RATIO, true);
		loadimage(&image[BOX_DEX], L"des.bmp", RATIO, RATIO, true);
		loadimage(&image[MAN], L"man.bmp", RATIO, RATIO, true);
		loadimage(&image[BOX], L"box.bmp", RATIO, RATIO, true);
		loadimage(&image[HIT], L"box.bmp", RATIO, RATIO, true);

		//地图的加载
		for (int i = 0; i < LINE; i++)
		{
			for (int j = 0; j < COLMON; j++)
			{
				putimage(START_X + j * RATIO, START_Y + i * RATIO, &image[map[i][j]]);
				//确定小人的位置
				if (map[i][j] == MAN)
				{
					man.x = i;
					man.y = j;
				}
			}
		}

		//定义游戏热键
		bool quit = false;
		do {
			if (_kbhit())
			{
				char ch = _getch();
				if (ch == KEY_LEFT)
				{
					getControl(LEFT);
				}
				else if (ch == KEY_RIGHT)
				{
					getControl(RIGHT);
				}
				else if (ch == KEY_UP)
				{
					getControl(UP);
				}
				else if (ch == KEY_down)
				{
					getControl(DOWN);
				}
				else if (ch == KEY_QUIT)
				{
					quit = true;
				}
				if (isGameOver())
				{
					gameoverScreen(&bg_img);
					quit = true;
				}
			}

			Sleep(100);

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

		closegraph();
		return 0;
	}

3、当然,只有一关啦,但在此基础上可以拓展别的关卡呀。。。。。。

----------------------------------------------------

创作不易,望各位多多点赞哈!!!

以上仅代表个人观点!!

  • 10
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
好的,推箱子小游戏可以使用C语言编写。下面是一个基本的游戏框架: ``` #include <stdio.h> #include <conio.h> #define MAX_MAP_SIZE 10 //地图最大尺寸 char map[MAX_MAP_SIZE][MAX_MAP_SIZE]; //地图数组 int playerX, playerY; //玩家的位置 int boxCount, boxX[MAX_MAP_SIZE], boxY[MAX_MAP_SIZE]; //箱子的数量和位置 void initMap(); //初始化地图 void drawMap(); //绘制地图 int moveBox(int x, int y, int dx, int dy); //移动箱子 int main() { char ch; initMap(); while (1) { drawMap(); ch = getch(); switch (ch) { case 'w': //向上移动 if (map[playerY-1][playerX] == '.') playerY--; else if (map[playerY-1][playerX] == 'B' && map[playerY-2][playerX] == '.') { if (moveBox(playerX, playerY-1, 0, -1)) playerY--; } break; case 'a': //向左移动 if (map[playerY][playerX-1] == '.') playerX--; else if (map[playerY][playerX-1] == 'B' && map[playerY][playerX-2] == '.') { if (moveBox(playerX-1, playerY, -1, 0)) playerX--; } break; case 's': //向下移动 if (map[playerY+1][playerX] == '.') playerY++; else if (map[playerY+1][playerX] == 'B' && map[playerY+2][playerX] == '.') { if (moveBox(playerX, playerY+1, 0, 1)) playerY++; } break; case 'd': //向右移动 if (map[playerY][playerX+1] == '.') playerX++; else if (map[playerY][playerX+1] == 'B' && map[playerY][playerX+2] == '.') { if (moveBox(playerX+1, playerY, 1, 0)) playerX++; } break; case 'q': //退出游戏 return 0; } } } void initMap() { //初始化地图数组 //其中 '#' 表示墙壁,'.' 表示空地,'P' 表示玩家,'B' 表示箱子 //例如: //##### //#...# //#.BP# //#...# //##### //表示一个大小为5x5的地图,其中有4个墙壁,1个玩家和1个箱子。 } void drawMap() { //绘制地图 //例如: //##### //#...# //#.BP# //#...# //##### //玩家当前位置用 'P' 表示,箱子当前位置用 'B' 表示。 } int moveBox(int x, int y, int dx, int dy) { //移动箱子 //x, y 表示箱子当前位置,dx, dy 表示箱子的

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值