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



三,實現效果

項目目錄圖片

地圖文件圖片


實現效果


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章