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…
不足之处望不吝指正