C++加EasyX实现多关卡推箱子(包括撤回,存档功能)

C++加EasyX实现多关卡推箱子,包括撤回,存档功能。

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include <graphics.h>
#include <conio.h>
#include <fstream>
using namespace std;
const int Length = 5, width = 12, height = 16;
/*-------------------------按钮---------------------------*/
class  Button
{
	int Buttonwidth = 80;
	int  Buttonheight = 40;
	const char* str;
	int x, y;
public:
	Button(int x, int y, const char* str, int Buttonwidth = 80, int  Buttonheight = 40)
	{
		this->x = x;
		this->y = y;
		this->str = str;
		this->Buttonwidth = Buttonwidth;
		this->Buttonheight = Buttonheight;
	}
	//位置(x,y)处画按钮
	void drawButton() 
	{
		setfillcolor(WHITE);
		fillrectangle(x, y, x + Buttonwidth, y + Buttonheight);
		setbkmode(TRANSPARENT);
		RECT r1 = { x,y,x + Buttonwidth,y + Buttonheight };
		settextstyle(20, 0, _T("华文楷体"),0,0,100,false, false, false);
		settextcolor(BLACK);
		drawtext(str, &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
	}
};
//判断点(x,y)是不是在按钮(bx,by)范围内
bool judgeButton(int x, int y, int bx, int by, int Buttonwidth = 80, int  Buttonheight = 40) {
	if (x >= bx && x <= bx + Buttonwidth && y >= by && y <= by + Buttonheight)
		return true;
	return false;
}
/*---------------------------图片输出的类----------------------------*/
class PRINT
{
	int X, Y;
	int XX, YY;
	int t;
	int x, y;
	int n, m;
	const int fangcun = 40;
	char CH;
	IMAGE xiaozhi, wasi, jinglingqiuK, jinglingqiuP, qiang, pikaqiu, jinglingqiu, bai;
public:
	void sdfs(int t, int const& width, int const& height,
		char const CH, int const WIDTH, int const HEIGHT)
	{
		this->x = 0;
		this->y = 0;
		this->m = width;
		this->n = height;
		this->t = t;
		this->CH = CH;
		this->X = WIDTH;
		this->Y = HEIGHT;
		loadimage(&qiang, "qiang.jpg", fangcun, fangcun);
		loadimage(&jinglingqiuK, "jinglingqiuk.jpg", fangcun, fangcun);
		loadimage(&bai, "bai.jpg", fangcun, fangcun);
		loadimage(&xiaozhi, "xiaozhi1.jpg", fangcun, fangcun);
		loadimage(&jinglingqiuP, "jinglingqiuP.jpg", fangcun, fangcun);
		loadimage(&pikaqiu, "pikaqiu.jpg", fangcun, fangcun);
	}
	void Tihuan(char(*A)[width][height])
	{
		for (x = 0; x < n; x++)
			for (y = 0; y < m; y++)
			{
				switch (A[t][y][x])
				{
				case '#':
					putimage(x * fangcun, y * fangcun, &qiang);
					break;
				case 'S':
					putimage(x * fangcun, y * fangcun, &xiaozhi);
					break;
				case 'O':
					putimage(x * fangcun, y * fangcun, &pikaqiu);
					break;
				case '*':
					putimage(x * fangcun, y * fangcun, &jinglingqiuK);
					break;
				case '@':
					putimage(x * fangcun, y * fangcun, &jinglingqiuP);
					break;
				case '1':
					putimage(x * fangcun, y * fangcun, &bai);
					break;
				}
			}
	}
};
/*-----------------------------------------------------------------------------------------------------*/
class observers
{
public:
	void Step(int& X, int& Y, char ch)
	{
		switch (ch)
		{
		case 'd':
			Y++;
			break;
		case 'w':
			X--;
			break;
		case 'a':
			Y--;
			break;
		case 's':
			X++;
			break;
		}
	}
	void BehindStep(int& X1, int& Y1, char ch)
	{
		switch (ch)
		{
		case 'd':
			Y1--;
			break;
		case 'w':
			X1++;
			break;
		case 'a':
			Y1++;
			break;
		case 's':
			X1--;
			break;
		}
	}
	void TWOstep(int& X1, int& Y1, char ch)
	{
		switch (ch)
		{
		case 'd':
			Y1 += 2;
			break;
		case 'w':
			X1 -= 2;
			break;
		case 'a':
			Y1 -= 2;
			break;
		case 's':
			X1 += 2;
			break;
		}
	}
	void STEP(int& x, int& y, char ch)
	{
		switch (ch)
		{
		case 'd':
			y++;
			break;
		case 'w':
			x--;
			break;
		case 'a':
			y--;
			break;
		case 's':
			x++;
			break;
		}
	}
	void ALTER(int t, int& k, int x, int y, int X1, int Y1, char(*a)[width][height], int* steps_s, int step)
	{

		if (a[t][X1][Y1] == '*')
		{
			if (k != 0) //人所在的位置是否是箱子的目的地
			{          
				a[t][x][y] = '*';
				k--;
			}
			else
				a[t][x][y] = '1';
		}
		else if (a[t][X1][Y1] == '#')
		{
			if (k != 0) 
			{           
				a[t][x][y] = '*';
				k--;
			}
			else
				a[t][x][y] = '1';
		}
		else if (a[t][X1][Y1] == '1')
		{
			if (k != 0) 
			{           
				a[t][x][y] = '*';
				k--;
			}
			else
				a[t][x][y] = '1';
		}
		else if (a[t][X1][Y1] == '@')
		{
			if (steps_s[step] == 1)
			{
				if (k != 0) 
				{           
					a[t][X1][Y1] = '*';
					a[t][x][y] = '@';
					k--;
				}
				else
					a[t][X1][Y1] = '*';
				a[t][x][y] = 'O';
			}
			else
			{
				a[t][X1][Y1] = '@';
				a[t][x][y] = '1';
			}
		}
		else if (a[t][X1][Y1] == 'O')
		{
			if (steps_s[step] == 1)
			{
				if (k != 0)
				{
					a[t][X1][Y1] = '1';
					a[t][x][y] = '@';
					k--;
				}
				else
				{
					a[t][X1][Y1] = '1';
					a[t][x][y] = 'O';
				}
			}
			else
			{
				if (k != 0)
				{
					a[t][x][y] = '*';
					k--;
				}
				
				else 
				a[t][x][y] = '1';
			}
		}
		else if (k != 0) 
		{                
			a[t][x][y] = '*';
			k--;
		}
	}
};
/*----------------------------------------------关于人物行动的函数----------------------------------------*/
void FORward(int& k, char(*a)[width][height], int& t, int& x,
	int& y, char& ch, char* steps, int* steps_s, int& step)
{
	observers FORwardobserver;
	int X = x, Y = y;
	FORwardobserver.Step(X, Y, ch);
	if (a[t][X][Y] == '1')
	{
		steps[step] = ch;
		step++;
		if (k != 0) 
		{
			a[t][x][y] = '*';
			k--;
		}
		else
			a[t][x][y] = '1';
		FORwardobserver.STEP(x, y, ch);
		a[t][x][y] = 'S';
	}
	int X1 = x, Y1 = y;
	FORwardobserver.TWOstep(X1, Y1, ch);
	if (a[t][X][Y] == 'O' && a[t][X1][Y1] != '#' && a[t][X1][Y1] != 'O' && a[t][X1][Y1] != '@')
	{
		steps[step] = ch;
		steps_s[step] = 1;
		step++;
		if (k != 0) 
		{
			a[t][x][y] = '*';
			k--;
		}
		else
			a[t][x][y] = '1';
		FORwardobserver.STEP(x, y, ch);
		a[t][x][y] = 'S';
		if (a[t][X1][Y1] == '*')
			a[t][X1][Y1] = '@';
		if (a[t][X1][Y1] == '1')
			a[t][X1][Y1] = 'O';

	}
	if (a[t][X][Y] == '@' && a[t][X1][Y1] != '#' && a[t][X1][Y1] != 'O' && a[t][X1][Y1] != '@')
	{
		steps[step] = ch;
		steps_s[step] = 1;
		step++;
		if (k != 0)
		{
			a[t][x][y] = '*';
			k--;
		}
		else
			a[t][x][y] = '1';
		FORwardobserver.STEP(x, y, ch);
		a[t][x][y] = 'S';
		if (a[t][X1][Y1] == '*')
			a[t][X1][Y1] = '@';
		if (a[t][X1][Y1] == '1')
			a[t][X1][Y1] = 'O';
		k++;
	}
	if (a[t][X][Y] == '*')
	{
		steps[step] = ch;
		step++;
		if (k != 0) 
		{
			a[t][x][y] = '*';
			k--;
		}
		else
			a[t][x][y] = '1';
		FORwardobserver.STEP(x, y, ch);
		a[t][x][y] = 'S';
		if (a[t][X1][Y1] == '*')
			a[t][X1][Y1] = '@';
		k++;
	}
}
/*---------------------------------------关于撤回的函数--------------------------------------*/
void retreat(int& k, char(*a)[width][height], int& t, int& x,
	int& y, char& ch, int* steps_s, int& step)
{
	observers retreatobserver;
	int X = x, Y = y;
	retreatobserver.Step(X, Y, ch);
	int X1 = x, Y1 = y;
	retreatobserver.BehindStep(X1, Y1, ch);
	if (a[t][X][Y] == '1')
	{
		retreatobserver.ALTER(t, k, x, y, X1, Y1, a, steps_s, step);
		retreatobserver.STEP(x, y, ch);
		a[t][x][y] = 'S';
	}
	if (a[t][X][Y] == '*')
	{
		retreatobserver.ALTER(t, k, x, y, X1, Y1, a, steps_s, step);
		retreatobserver.STEP(x, y, ch);
		a[t][x][y] = 'S';
		k++;
	}
}
/*------------------------------------------------------------------------------------------*/
int main(void)
{
	/*---------------------------------画布----------------------------------*/
	initgraph(800, 600);
	cleardevice();
	//#:墙:O:皮卡丘;S:小智;1:空白;*:精灵球:@:有皮卡丘的精灵球
	char a[Length][width][height] = {
		{"    ###        ",
		 "    #*#        ",
		 "    #1#        ",
		 "    #O#        ",
		 "#####1#########",
		 "#*11O1111SO11*#",
		 "#######1#######",
		 "      #1#      ",
		 "      #O#      ",
		 "      #1#      ",
		 "      #*#      ",
		 "      ###      "},

		{"###############",
		 "#1111111111111#",
		 "#1O11111111111#",
		 "######11111111#",
		 "#1111111111111#",
		 "#11111S1111111#",
		 "#11111#########",
		 "#1111111111111#",
		 "#1111111111111#",
		 "#111111111111*#",
		 "###############"},

		{"  ####    ",
		 "  #11#####",
		 "###1*#111#",
		 "#11111111#",
		 "#S11O1111#",
		 "#1##@#####",
		 "#111O11#  ",
		 "###1*11#  ",
		 "  #11###  ",
		 "  ####    "},

		{"   #######",
		 "  ##11#1S#",
		 "  #111#O1#",
		 "  #O11O11#",
		 "  #1O##11#",
		 "###1O1#1##",
		 "#*****111#",
		 "##########"},

		{"  ##### ",
		 "###111# ",
		 "#*S1O1# ",
		 "###1O*# ",
		 "#*##O1# ",
		 "#1#1*1##",
		 "#O1@OO*#",
		 "#111*11#",
		 "########"} };
	int t = 0;//记录关卡
	/*-----------------------------------存档读取-------------------------------------*/
	ifstream readFile("PlaceOnFile.txt", ios::in);
	readFile >> t;
	//cout << t << endl;
	readFile.close();
	/*------------------------创建按钮--------------------------*/
	if (t >=0 && t < Length)
	{	
		outtextxy(300, 250, "您保存了游戏进度是否继续?");
		Button proceed(200, 300, _T("继续"),100,40);
		proceed.drawButton();
		Button Restart(460, 300, _T("重新开始"),100,40);
		Restart.drawButton();
		MOUSEMSG msg;
		/*----------------------------------是否重新游戏---------------------------------*/
		while (true) {
			while (MouseHit())// 当有鼠标消息的时候执行
			{
				msg = GetMouseMsg();
				if (msg.uMsg == WM_LBUTTONDOWN) {
					if (judgeButton(msg.x, msg.y, 200, 300, 100, 40)) //继续
					{
						ofstream outfile;
						outfile.open("PlaceOnFile.txt", ios::out);
						outfile << -1 << endl;
						outfile.close();
						cleardevice();
						goto toCheckpoint;
					}
					if (judgeButton(msg.x, msg.y, 460, 300, 100, 40)) //重新开始
					{
						t = 0;
						ofstream outfile;
						outfile.open("PlaceOnFile.txt", ios::out);
						outfile << -1 << endl;
						outfile.close();
						cleardevice();
						goto toCheckpoint;
					}
				}
			}
		}
	}
	else t = 0;
toCheckpoint:
	/*------------------------------------------开始关卡------------------------------------------------*/
	while (t < Length)
	{
		int m = sizeof(a[t][0]);  //列数
		int n = sizeof(a[t]) / m; //行数
		int x = 0, y = 0;
		int cnt = 0;
		/*-------------------------记录有多少个箱子---------------------------*/
		for (x = 0; x < n; x++)
		{
			for (y = 0; y < m; y++)
			{
				if (a[t][x][y] == '*' || a[t][x][y] == '@')
					cnt++;
			}
		}
		/*----------------------找到人的位置(x,y)-----------------------------*/
		for (x = 0; x < n; x++)
		{
			for (y = 0; y < m; y++)
			{
				if (a[t][x][y] == 'S')
					goto SPosition1;
			}
		}
	SPosition1:
		int k = 0;
		char ch = '0';
		char steps[200] = { 0 };//记录每一步方向
		int steps_s[200] = { 0 };
		int step = 0;//记录步数
		while (true)
		{
			/*---------------------------打印-------------------------*/
			PRINT InitGame2;
			InitGame2.sdfs(t, n, m, ch, x, y);
			InitGame2.Tihuan(a);
			settextcolor(YELLOW);
			settextstyle(24, 0, _T("华文楷体"),1,1,100, true, true,false);
			outtextxy(100, 550, "w:向上;a:向左;s:向下;d:向右;z:上一步;");
			ch = _getch();//获取字符
			if (ch == 'a' || ch == 'd' || ch == 's' || ch == 'w')
			{
				FORward(k, a, t, x, y, ch, steps, steps_s, step); //人物行走
				//cleardevice();
			}
			if (ch == 'z' && step > 0)
			{
				step--;
				switch (steps[step])
				{
				case 'w':
					ch = 's';
					break;
				case 'a':
					ch = 'd';
					break;
				case 's':
					ch = 'w';
					break;
				case 'd':
					ch = 'a';
					break;
				}
				retreat(k, a, t, x, y, ch, steps_s, step);
				steps[step] = '0';
			}
			/*----------------------得到人的位置(x,y)-------------------------*/
			for (x = 0; x < n; x++)
			{
				for (y = 0; y < m; y++)
					if (a[t][x][y] == 'S')
						goto SPosition2;
			}
		SPosition2:
			int X = 0, Y = 0, sum = 0;
			/*---------------------判断是否通关------------------------*/
			for (X = 0; X < n; X++)
			{
				for (Y = 0; Y < m; Y++)
					if (a[t][X][Y] == '@')
						sum++;
			}
			if (cnt == sum)
			{
				t++;
				cleardevice();
				sum = 0;
				cnt = 0;
				break;
				step = 0;
			}
			else
				sum = 0;
		}
		/*-----------------------------通关提示-------------------------------------------*/
		cleardevice();
		settextcolor(GREEN);
		settextstyle(30, 0, _T("黑体"), 0, 0, 100, false, false, false);
		outtextxy(300, 230, "YOU WIN!");
		outtextxy(140, 260, "恭喜您通过了第");
		char T[5];
		sprintf_s(T, "%d", t);
		outtextxy(350, 260, T);
		outtextxy(410, 260, "关,还有");
		char TS[5];
		sprintf_s(TS, "%d", 5 - t);
		outtextxy(530, 260, TS);
		outtextxy(590, 260, "关");
		outtextxy(140, 300, "任意键继续游戏,保存退出游戏请按:n");
		if (_getch() == 'n')
		{
			ofstream outfile;
			outfile.open("PlaceOnFile.txt",ios::out);
			outfile << t << endl;
			outfile.close();
			goto out;
		}
		cleardevice();
	}
	out:
	closegraph();
	return 0;
}

素材就不放了,百度吧
成品大概长这样…

在这里插入图片描述

实在是有点儿乱

但又懒得改emmm…

不足之处望不吝指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值