C++实现推箱子游戏

一,项目简介

用两天闲余时间回顾了推箱子这款经典的小游戏,目前设置了5关,只能实现基本的人物移动。判断胜利条件,其他功能还未实现(例:撤回到上一步,自由选择关卡等),也顺便复习了C++的相关知识。

二, 代码区

Class Map(地图类)

Map.h:
#pragma once
#define N 10
#define M 10
//地图类
class Map
{
public:
	Map();
	~Map();
	void Init();

	void ReadMapFile(int map[M][N], int size,const char* filename );
	void WriteMapFile(int map[M][N], int size, const char* filename);
private:
	
};

Map.cpp:
#include "Map.h"
#include<iostream>
#include<fstream>
using namespace std;


Map::Map()
{
	
}
//地图初始化方法
void Map::Init()
{
	int Map[10][10] =
	{
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
		{ 1, 0, 0, 4, 3, 0, 1, 1, 1, 1 },
		{ 1, 0, 4, 3, 4, 3, 0, 0, 1, 1 },
		{ 1, 7, 3, 4, 3, 4, 2, 0, 1, 1 },
		{ 1, 0, 4, 3, 4, 3, 0, 1, 1, 1 },
		{ 1, 0, 0, 4, 3, 0, 0, 1, 1, 1 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
	};
	WriteMapFile(Map, 10, "map/map_05.txt");

}
//读取地图文件
void Map::ReadMapFile(int map[M][N], int size, const char* filename)
{
	FILE* pfile = nullptr;
	fopen_s(&pfile, filename, "rb");
	fread(map, 10 * size * 4, 1, pfile);
	fclose(pfile);
}
//写入地图文件
void Map::WriteMapFile(int map[M][N], int size, const char* filename)
{
	FILE* pfile = nullptr;
	fopen_s(&pfile, filename, "wb");
	fwrite(map, 10 * size * 4, 1, pfile);
	fclose(pfile);
}
Map::~Map()
{

}
Class Game (游戏类)

Game.h:
#define _GAEM_H__
#ifdef _GAEM_H__

#include <iostream>
using namespace std;
#include <string.h>
#include <conio.h>
#pragma warning (disable:4996)
#define N 10
#define M 10

/***************************建立一个推箱子相关操作的类***********************/
/*--------------------------Game类编写-----------------------------------*/
/****************************************************************************/
class Game
{
public:
	int Move(int map[M][N], char ch);
	void Drop(int map[M][N],int c);
	int juide(int map[M][N]);
private:
	int push(int map[M][N], int offsetX,int offsetY);
	void Postion(int map[M][N]);
	int posX;
	int posY;
};
#endif /*_GAME_H__*/


Game.cpp:
#include "Game.h"

//按键控制人物移动
int Game::Move(int map[M][N], char ch)
{
	static int step = 0;
	int offsetx = 0;
	int offsety = 0;
	switch (ch)
	{
		//向上移动
	case 'w':case 'W':
		offsetx = -1;
		offsety = 0;
		if (push(map, offsetx, offsety) == 1)
			step++;
		break;
		//向下移动
	case 's':case 'S':
		offsetx = 1;
		offsety = 0;
		if (push(map, offsetx, offsety) == 1)
			step++;
		break;
		//向左移动
	case 'a':case 'A':
		offsetx = 0;
		offsety = -1;
		if (push(map, offsetx, offsety) == 1)
			step++;
		break;
		//向右移动
	case 'd':case 'D':
		offsetx = 0;
		offsety = 1;
		if (push(map, offsetx, offsety) == 1)
			step++;
		break;
	default:
		break;
	}
	return step;
}
//界面打印
void Game::Drop(int map[M][N], int c)
{
	cout <<"\t\t"<<"**********************第 "<<c<<" 关**************************" << endl;
	cout <<"\t\t"<<"***************W-w:向上       S-s:向下*****************"  << endl;
	cout <<"\t\t"<<"***************A-a:向左       D-d:向右*****************"  << endl;
	cout << endl;
	for (int i = 0; i < M; i++)
	{
		cout << "                          ";
		for (int j = 0; j < N; j++)
		{
			switch (map[i][j])
			{
				//打印空地
			case 0:
				cout << "  ";
				break;
				//打印墙壁
			case 1:
				cout << "■";
				break;
				//打印玩家
			case 2:
				cout << "♀";
				posX = i;
				posY = j;
				break;
				//打印箱子
			case 3:
				cout << "□";
				break;
				//打印终点
			case 4:
				cout << "○";
				break;
				//人 + 终点
			case 6:
				cout << "★";
				posX = i;
				posY = j;
				break;
				//箱子 + 终点
			case 7:
				cout << "●";
				break;
			default:
				break;
			}
		}
		cout << endl;           //换行
	}
}
//判断游戏胜利条件
int Game::juide(int map[M][N])
{
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < N; j++)
		{
			if (4 == map[i][j] || 6 == map[i][j])      //地图中还存在终点/终点+人
				return 1;
		}
	}
	return 0;
}
//更新游戏
int Game::push(int map[M][N], int offsetX, int offsetY)
{
	Postion(map);                                        //确定人物坐标
	if (map[posX + offsetX][posY + offsetY] == 0)        //下一格是空地
	{
		map[posX][posY] -= 2;                            //上一格变为空地或终点
		map[posX + offsetX][posY + offsetY] += 2;        //下一格变为人或人+终点
		//改变人的坐标
		posX += offsetX;
		posY += offsetY;
	}
	else if (map[posX + offsetX][posY + offsetY] == 3)            //下一格是箱子
	{
		if (map[posX + offsetX * 2][posY + offsetY * 2] == 0
			|| map[posX + offsetX * 2][posY + offsetY * 2] == 4)  //下两格是空地/终点
		{
			map[posX][posY] -= 2;                                 //上一格变为空地/终点
			map[posX + offsetX][posY + offsetY] = 2;              //下一格变为人
			map[posX + offsetX * 2][posY + offsetY * 2] += 3;     //下两格变为箱子/箱子+终点
			posX += offsetX;
			posY += offsetY;
		}
	}
	else if (map[posX + offsetX][posY + offsetY] == 4)           //下一格是终点
	{
		map[posX][posY] -= 2;                                    //上一格变为空地/终点
		map[posX + offsetX][posY + offsetY] = 6;                 //下一格变为人+终点
		posX += offsetX;
		posY += offsetY;
	}
	else if (map[posX + offsetX][posY + offsetY] == 7)            //下一格是箱子+终点
	{
		if (map[posX + offsetX * 2][posY + offsetY * 2] == 0
			|| map[posX + offsetX * 2][posY + offsetY * 2] == 4)  //下两格是空地/终点
		{
			map[posX][posY] -= 2;                                 //上一格变为空地/终点
			map[posX + offsetX][posY + offsetY] = 6;              //下一格变为人+终点
			map[posX + offsetX * 2][posY + offsetY * 2] += 3;     //下两格变为箱子/箱子+终点
			posX += offsetX;
			posY += offsetY;
		}
	}
	else                                                          //人物不能移动
		return 0;
	return 1;

}
//找到人物坐标
void Game::Postion(int map[M][N])
{
	for (int i = 0; i < M; i++)
	{
		for (int j = 0; j < N; j++)
		{
			if (2 == map[i][j] || 6 == map[i][j])     //地图中存在终点/终点+人
			{
				//给人物坐标赋值
				posX = i;
				posY = j;
			}
		}
	}
}
Main:
#include<iostream>
#include<string.h>
using namespace std;
#pragma warning (disable:4996)
#define M 10
#define N 10

//定义一个10*10地图,1表示墙,0表示空地,2表示人
//3表示箱子,4表示成功点
//1.人物可以站到成功点中,显示人
//2.箱子推入成功点后,可以推出来
//3.记录步数,显示在控制台上
//4.界面:提示(■代表墙....)/游戏开始界面
//5.最终提示全部推入,提示成功
//周围都是墙,中间都是空地
#include"Map.h"
#include"Game.h"
int main()
{
	Map _map;
	//_map.Init();
	int map[M][N];
	char filename[] = "map/map_0";
	int custom = 2;
	while (custom <= 5)
	{
		char buffer[80];
		sprintf(buffer, "%s%d", filename, custom);         //连接filename和custom,以字符串保存到buffer中
		strcat(buffer, ".txt");                            //字符串连接
		_map.ReadMapFile(map, N, buffer);
		Game game;
		int step = 0;
		while (game.juide(map))                           //游戏胜利,跳出循环
		{
			system("cls");
			game.Drop(map, custom);
			char ch = _getch();                           //按键输入
			step = game.Move(map, ch);
			system("cls");
		}
		custom++;                            //关卡+1
		cout << "你赢了!" << endl;
		cout << "共走:" << step << "步" << endl;;
		system("pause");
		
	}
	
	
	return 0;
}



三,实现效果

项目目录图片

地图文件图片


实现效果


  • 32
    点赞
  • 128
    收藏
    觉得还不错? 一键收藏
  • 16
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值