|
|
|
@ -0,0 +1,935 @@
|
|
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
#include <conio.h>
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
#include <graphics.h>
|
|
|
|
|
#include <mmsystem.h>
|
|
|
|
|
#include <string>
|
|
|
|
|
#include <ctime>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
#pragma comment(lib,"winmm.lib") //静态库资源
|
|
|
|
|
|
|
|
|
|
#define ROW 12
|
|
|
|
|
#define COL 12
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const int WALL = 1;
|
|
|
|
|
const int BOX = 4;
|
|
|
|
|
const int TARGET = 3;
|
|
|
|
|
const int PLAYER = 5;
|
|
|
|
|
const int EMPTY = 0;
|
|
|
|
|
|
|
|
|
|
const int _SIZE = 12;
|
|
|
|
|
int DUISHU = 3;
|
|
|
|
|
const std::vector<std::pair<int, int>> dir = { {0, 1}, {1, 0}, {0, -1}, {-1, 0} };
|
|
|
|
|
|
|
|
|
|
class MyMap {
|
|
|
|
|
public:
|
|
|
|
|
int Map[_SIZE][_SIZE]{ WALL };
|
|
|
|
|
private:
|
|
|
|
|
int X1{}, X2{}, Y1{}, Y2{};//分别为1、2步之前的坐标
|
|
|
|
|
int X{}, Y{}, Direction{};//当前坐标、方向
|
|
|
|
|
int PX{}, PY{};//玩家坐标
|
|
|
|
|
int StartX{}, StartY{};//记录起点,用于生成箱子
|
|
|
|
|
|
|
|
|
|
bool test() {//一定程度避免随机数整烂活;
|
|
|
|
|
int test{};
|
|
|
|
|
for (int i = 0; i < _SIZE; i++) {
|
|
|
|
|
for (int j = 0; j < _SIZE; j++) {
|
|
|
|
|
if (Map[i][j] == 3)test += 1;
|
|
|
|
|
if (Map[i][j] == 4)test += 10;
|
|
|
|
|
if (Map[i][j] == 5)test += 100;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return (test == 100 + 11 * DUISHU);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool _near(int StartX, int StartY, int X, int Y) {
|
|
|
|
|
return (StartX == X + 1 && StartY == Y ||
|
|
|
|
|
StartX == X - 1 && StartY == Y ||
|
|
|
|
|
StartY == Y + 1 && StartX == X ||
|
|
|
|
|
StartY == Y - 1 && StartX == X);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void update() {
|
|
|
|
|
X2 = X1;
|
|
|
|
|
Y2 = Y1;
|
|
|
|
|
X1 = X;
|
|
|
|
|
Y1 = Y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void change(int x, int y) {
|
|
|
|
|
if (Map[x][y] == WALL) {
|
|
|
|
|
Map[x][y] = EMPTY;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void through() {//打通箱子周边,使得每个箱子都可推动
|
|
|
|
|
int dx = StartX - PX, dy = StartY - PY;
|
|
|
|
|
if (dx == 0) {
|
|
|
|
|
change(StartX + 2 * (StartX > _SIZE / 2) - 1, StartY);
|
|
|
|
|
change(StartX + 2 * (StartX > _SIZE / 2) - 1, StartY + 1);
|
|
|
|
|
change(StartX + 2 * (StartX > _SIZE / 2) - 1, StartY - 1);
|
|
|
|
|
}
|
|
|
|
|
if (dy == 0) {
|
|
|
|
|
change(StartX, StartY + 2 * (StartX > _SIZE / 2) - 1);
|
|
|
|
|
change(StartX - 1, StartY + 2 * (StartX > _SIZE / 2) - 1);
|
|
|
|
|
change(StartX + 1, StartY + 2 * (StartX > _SIZE / 2) - 1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
MyMap() {
|
|
|
|
|
for (int i = 0; i < _SIZE; i++) {
|
|
|
|
|
for (int j = 0; j < _SIZE; j++) {
|
|
|
|
|
Map[i][j] = WALL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}//初始化
|
|
|
|
|
|
|
|
|
|
bool generatemap(int Complexity) {
|
|
|
|
|
int time{};
|
|
|
|
|
do {//主体
|
|
|
|
|
for (int i = 0; i < _SIZE; i++) {
|
|
|
|
|
for (int j = 0; j < _SIZE; j++) {
|
|
|
|
|
Map[i][j] = WALL;
|
|
|
|
|
}
|
|
|
|
|
}//初始化
|
|
|
|
|
for (int a = 0; a < DUISHU; a++)//箱子与目标的对数
|
|
|
|
|
{
|
|
|
|
|
do {
|
|
|
|
|
X = rand() % (_SIZE - 4) + 2;
|
|
|
|
|
Y = rand() % (_SIZE - 4) + 2;
|
|
|
|
|
time++;
|
|
|
|
|
if (time > 100) {
|
|
|
|
|
std::cout << "error" << std::endl;
|
|
|
|
|
return 0;
|
|
|
|
|
}//防死循环
|
|
|
|
|
} while (Map[X][Y] != WALL);//在墙上生成起点
|
|
|
|
|
time = 0;
|
|
|
|
|
StartX = X; StartY = Y;//记录起点,用于生成箱子
|
|
|
|
|
do {
|
|
|
|
|
int _time{};//实际运动次数
|
|
|
|
|
for (int i = 0; i < Complexity; i++) {
|
|
|
|
|
int temp = rand() % 6;
|
|
|
|
|
switch (temp) {
|
|
|
|
|
case 0:
|
|
|
|
|
Direction++;
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
Direction--;
|
|
|
|
|
}//控制直走和转弯的概率,不要频繁转弯且不会掉头
|
|
|
|
|
Direction = (4 + Direction) % 4;//防止负数
|
|
|
|
|
if (//各种不宜移动的情况
|
|
|
|
|
X + dir[Direction].first <= 2 ||
|
|
|
|
|
X + dir[Direction].first >= _SIZE - 3 ||
|
|
|
|
|
Y + dir[Direction].second <= 2 ||
|
|
|
|
|
Y + dir[Direction].second >= _SIZE - 3 ||
|
|
|
|
|
Map[X + dir[Direction].first][Y + dir[Direction].second] == BOX
|
|
|
|
|
) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
update();
|
|
|
|
|
X += dir[Direction].first;
|
|
|
|
|
Y += dir[Direction].second;
|
|
|
|
|
change(X, Y);
|
|
|
|
|
change(X - 2 * dir[Direction].first, Y - 2 * dir[Direction].second);
|
|
|
|
|
if (_time > 0) {
|
|
|
|
|
change(
|
|
|
|
|
dir[Direction].first == 0 ? X2 : X - 2 * dir[Direction].first,
|
|
|
|
|
dir[Direction].second == 0 ? Y2 : Y - 2 * dir[Direction].second
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (_time == 0) {
|
|
|
|
|
PX = X - 2 * dir[Direction].first;
|
|
|
|
|
PY = Y - 2 * dir[Direction].second;
|
|
|
|
|
|
|
|
|
|
}//生成玩家
|
|
|
|
|
_time++;
|
|
|
|
|
}
|
|
|
|
|
Map[StartX][StartY] = BOX;
|
|
|
|
|
Map[X][Y] = TARGET;
|
|
|
|
|
} while (_near(StartX, StartY, X, Y));
|
|
|
|
|
through();
|
|
|
|
|
}
|
|
|
|
|
Map[PX][PY] = PLAYER;
|
|
|
|
|
} while (test() == 0);
|
|
|
|
|
for (int i = 0; i < _SIZE; i++)//修复墙壁
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < _SIZE; j++) {
|
|
|
|
|
if (i == 0 || j == 0 || i == _SIZE - 1 || j == _SIZE - 1) {
|
|
|
|
|
Map[i][j] = WALL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void printmap() {
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
for (int i = 0; i < _SIZE; i++) {
|
|
|
|
|
for (int j = 0; j < _SIZE; j++) {
|
|
|
|
|
std::cout << Map[i][j] << ' ';
|
|
|
|
|
}
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//用三维数组特定的数字描绘出这个地图
|
|
|
|
|
int cas = 0;//地图编号
|
|
|
|
|
int _count = 0;//已走步数
|
|
|
|
|
wchar_t result[10] = { L"0" };//用来显示步数
|
|
|
|
|
int temp_map[ROW][COL] = { 0 };//用来暂存地图,以备重置
|
|
|
|
|
char c[10] = { 0 };
|
|
|
|
|
int map[4][ROW][COL] = { 0 };
|
|
|
|
|
|
|
|
|
|
IMAGE img[6]; //6张图片,6个名字
|
|
|
|
|
IMAGE* bacground=new IMAGE;
|
|
|
|
|
void loadResource()
|
|
|
|
|
{
|
|
|
|
|
loadimage(img + 0, L"0.bmp", 50, 50);
|
|
|
|
|
loadimage(img + 1, L"1.bmp", 50, 50);
|
|
|
|
|
loadimage(img + 2, L"3.bmp", 50, 50);
|
|
|
|
|
loadimage(img + 3, L"4.bmp", 50, 50);
|
|
|
|
|
loadimage(img + 4, L"5.bmp", 50, 50);
|
|
|
|
|
loadimage(img + 5, L"7.bmp", 50, 50);
|
|
|
|
|
loadimage(bacground, L"背景.png", 50, 50);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//绘制地图
|
|
|
|
|
void drawGraph()
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < ROW; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < COL; j++)
|
|
|
|
|
{
|
|
|
|
|
//算贴图的坐标
|
|
|
|
|
int x = 50 * j;
|
|
|
|
|
int y = 50 * i;
|
|
|
|
|
switch (map[cas][i][j])
|
|
|
|
|
{
|
|
|
|
|
case 0:
|
|
|
|
|
//一个汉字符号占用两个位置
|
|
|
|
|
//printf(" ");
|
|
|
|
|
putimage(x, y, img + 0);
|
|
|
|
|
break;
|
|
|
|
|
case 1:
|
|
|
|
|
putimage(x, y, img + 1);
|
|
|
|
|
//printf("■");
|
|
|
|
|
break;
|
|
|
|
|
case 3:
|
|
|
|
|
putimage(x, y, img + 2);
|
|
|
|
|
//printf("☆");
|
|
|
|
|
break;
|
|
|
|
|
case 4:
|
|
|
|
|
putimage(x, y, img + 3);
|
|
|
|
|
//printf("★");
|
|
|
|
|
break;
|
|
|
|
|
case 5:
|
|
|
|
|
case 8:
|
|
|
|
|
putimage(x, y, img + 4);
|
|
|
|
|
//printf("人");
|
|
|
|
|
break;
|
|
|
|
|
case 7:
|
|
|
|
|
putimage(x, y, img + 5);
|
|
|
|
|
//printf("●");
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//printf("\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void drawGraph1()//绘制背景图
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < ROW; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < COL; j++)
|
|
|
|
|
{
|
|
|
|
|
int x = 50 * j;
|
|
|
|
|
int y = 50 * i;
|
|
|
|
|
putimage(x, y, bacground);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//玩游戏
|
|
|
|
|
void keyDown()
|
|
|
|
|
{
|
|
|
|
|
int userKey = _getch(); //不可见输入
|
|
|
|
|
//定位:找到人的位置
|
|
|
|
|
int i = 0;
|
|
|
|
|
int j = 0;
|
|
|
|
|
for (i = 1; i < ROW; i++)
|
|
|
|
|
{
|
|
|
|
|
for (j = 1; j < COL; j++)
|
|
|
|
|
{
|
|
|
|
|
if (map[cas][i][j] == 5 || map[cas][i][j] == 8)
|
|
|
|
|
{
|
|
|
|
|
goto NEXT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
NEXT:
|
|
|
|
|
|
|
|
|
|
//我们这个游戏用什么按键去玩
|
|
|
|
|
switch (userKey)
|
|
|
|
|
{
|
|
|
|
|
case 'W':
|
|
|
|
|
case 'w':
|
|
|
|
|
case 72:
|
|
|
|
|
if (map[cas][i - 1][j] == 0 || map[cas][i - 1][j] == 3)
|
|
|
|
|
{
|
|
|
|
|
map[cas][i][j] -= 5;
|
|
|
|
|
map[cas][i - 1][j] += 5;
|
|
|
|
|
_count++;
|
|
|
|
|
}
|
|
|
|
|
if (map[cas][i - 1][j] == 4 || map[cas][i - 1][j] == 7)
|
|
|
|
|
{
|
|
|
|
|
if (map[cas][i - 2][j] == 0 || map[cas][i - 2][j] == 3)
|
|
|
|
|
{
|
|
|
|
|
map[cas][i][j] -= 5;
|
|
|
|
|
map[cas][i - 1][j] += 1;
|
|
|
|
|
map[cas][i - 2][j] += 4;
|
|
|
|
|
_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 's':
|
|
|
|
|
case 'S':
|
|
|
|
|
case 80:
|
|
|
|
|
if (map[cas][i + 1][j] == 0 || map[cas][i + 1][j] == 3)
|
|
|
|
|
{
|
|
|
|
|
map[cas][i][j] -= 5;
|
|
|
|
|
map[cas][i + 1][j] += 5;
|
|
|
|
|
_count++;
|
|
|
|
|
}
|
|
|
|
|
if (map[cas][i + 1][j] == 4 || map[cas][i + 1][j] == 7)
|
|
|
|
|
{
|
|
|
|
|
if (map[cas][i + 2][j] == 0 || map[cas][i + 2][j] == 3)
|
|
|
|
|
{
|
|
|
|
|
map[cas][i][j] -= 5;
|
|
|
|
|
map[cas][i + 1][j] += 1;
|
|
|
|
|
map[cas][i + 2][j] += 4;
|
|
|
|
|
_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'a':
|
|
|
|
|
case 'A':
|
|
|
|
|
case 75:
|
|
|
|
|
if (map[cas][i][j - 1] == 0 || map[cas][i][j - 1] == 3)
|
|
|
|
|
{
|
|
|
|
|
//a+=1 a=a+1 复合赋值运算符
|
|
|
|
|
map[cas][i][j] -= 5;
|
|
|
|
|
map[cas][i][j - 1] += 5;
|
|
|
|
|
_count++;
|
|
|
|
|
}
|
|
|
|
|
if (map[cas][i][j - 1] == 4 || map[cas][i][j - 1] == 7)
|
|
|
|
|
{
|
|
|
|
|
if (map[cas][i][j - 2] == 0 || map[cas][i][j - 2] == 3)
|
|
|
|
|
{
|
|
|
|
|
map[cas][i][j] -= 5;
|
|
|
|
|
map[cas][i][j - 1] += 1;
|
|
|
|
|
map[cas][i][j - 2] += 4;
|
|
|
|
|
_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'd':
|
|
|
|
|
case 'D':
|
|
|
|
|
case 77:
|
|
|
|
|
if (map[cas][i][j + 1] == 0 || map[cas][i][j + 1] == 3)
|
|
|
|
|
{
|
|
|
|
|
map[cas][i][j] -= 5;
|
|
|
|
|
map[cas][i][j + 1] += 5;
|
|
|
|
|
_count++;
|
|
|
|
|
}
|
|
|
|
|
if (map[cas][i][j + 1] == 4 || map[cas][i][j + 1] == 7)
|
|
|
|
|
{
|
|
|
|
|
if (map[cas][i][j + 2] == 0 || map[cas][i][j + 2] == 3)
|
|
|
|
|
{
|
|
|
|
|
map[cas][i][j] -= 5;
|
|
|
|
|
map[cas][i][j + 1] += 1;
|
|
|
|
|
map[cas][i][j + 2] += 4;
|
|
|
|
|
_count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
case 'z'://按下z重置
|
|
|
|
|
case 'Z':
|
|
|
|
|
for (int i = 0; i < ROW; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < COL; j++)
|
|
|
|
|
{
|
|
|
|
|
map[cas][i][j] = temp_map[i][j];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
_count = 0;
|
|
|
|
|
for (int k = 0; k < 10; k++)
|
|
|
|
|
{
|
|
|
|
|
result[k] = 0;
|
|
|
|
|
}
|
|
|
|
|
result[0] = L'0';
|
|
|
|
|
drawGraph();
|
|
|
|
|
setbkmode(TRANSPARENT);
|
|
|
|
|
settextcolor(BLACK);
|
|
|
|
|
settextstyle(20, 0, _T("微软雅黑"));
|
|
|
|
|
outtextxy(145, 55, L"已走步数:");
|
|
|
|
|
outtextxy(230, 55, result);
|
|
|
|
|
break;
|
|
|
|
|
case 'x':
|
|
|
|
|
case 'X':
|
|
|
|
|
|
|
|
|
|
cas = 3;
|
|
|
|
|
for (int i = 0; i < ROW; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < COL; j++)
|
|
|
|
|
{
|
|
|
|
|
map[cas][i][j] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//胜负的判断:
|
|
|
|
|
int gameOver()
|
|
|
|
|
{
|
|
|
|
|
//地图上没有箱子就可以结束
|
|
|
|
|
for (int i = 0; i < ROW; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < COL; j++)
|
|
|
|
|
{
|
|
|
|
|
if (map[cas][i][j] == 4)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
class Button
|
|
|
|
|
{
|
|
|
|
|
private:
|
|
|
|
|
int x; // 按钮左上角x坐标
|
|
|
|
|
int y; // 按钮左上角y坐标
|
|
|
|
|
int width; // 按钮宽度
|
|
|
|
|
int height; // 按钮高度
|
|
|
|
|
float scale; // 缩放比例,用于实现鼠标悬停效果
|
|
|
|
|
bool isMouseOver; // 表示鼠标是否在按钮上方
|
|
|
|
|
bool has_been_clicked;//表示此按钮是否被点击过(主要用于难度选择)
|
|
|
|
|
wstring text; // 按钮文本
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
|
|
|
|
|
Button(int x, int y, int width, int height, const wstring& text)
|
|
|
|
|
: x(x), y(y), width(width), height(height), text(text), scale(1.0f), isMouseOver(false),has_been_clicked(false)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查鼠标是否在按钮上方
|
|
|
|
|
void checkMouseOver(int mouseX, int mouseY)
|
|
|
|
|
{
|
|
|
|
|
isMouseOver = (mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height);
|
|
|
|
|
|
|
|
|
|
if (isMouseOver) {
|
|
|
|
|
scale = 1.0f; // 鼠标悬停时缩放按钮
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
scale = 1.0f; // 恢复按钮原始大小
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 检查鼠标点击是否在按钮内,并执行函数
|
|
|
|
|
bool checkClick(int mouseX, int mouseY)
|
|
|
|
|
{
|
|
|
|
|
if (mouseX >= x && mouseX <= x + width && mouseY >= y && mouseY <= y + height)
|
|
|
|
|
{
|
|
|
|
|
has_been_clicked_convert();
|
|
|
|
|
isMouseOver = false;
|
|
|
|
|
scale = 1.0f;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void has_been_clicked_convert()
|
|
|
|
|
{
|
|
|
|
|
if (has_been_clicked == false)
|
|
|
|
|
has_been_clicked = true;
|
|
|
|
|
else
|
|
|
|
|
has_been_clicked = false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool get_has_been_clicked()
|
|
|
|
|
{
|
|
|
|
|
return has_been_clicked;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 绘制按钮
|
|
|
|
|
void draw()
|
|
|
|
|
{
|
|
|
|
|
int scaledWidth = width * scale; // 缩放后的按钮宽度
|
|
|
|
|
int scaledHeight = height * scale; // 缩放后的按钮高度
|
|
|
|
|
int scaledX = x + (width - scaledWidth) / 2; // 缩放后的按钮x坐标
|
|
|
|
|
int scaledY = y + (height - scaledHeight) / 2; // 缩放后的按钮y坐标
|
|
|
|
|
|
|
|
|
|
if (isMouseOver || has_been_clicked)
|
|
|
|
|
{
|
|
|
|
|
setlinecolor(RGB(0, 120, 215)); // 鼠标悬停时按钮边框颜色
|
|
|
|
|
setfillcolor(RGB(229, 241, 251)); // 鼠标悬停时按钮填充颜色
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
setlinecolor(RGB(173, 173, 173)); // 按钮边框颜色
|
|
|
|
|
setfillcolor(RGB(225, 225, 225)); // 按钮填充颜色
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fillrectangle(scaledX, scaledY, scaledX + scaledWidth, scaledY + scaledHeight); // 绘制按钮
|
|
|
|
|
settextcolor(BLACK); // 设置文本颜色为黑色
|
|
|
|
|
setbkmode(TRANSPARENT); // 设置文本背景透明
|
|
|
|
|
settextstyle(20 * scale, 0, _T("微软雅黑")); // 设置文本大小和字体
|
|
|
|
|
//居中显示按钮文本
|
|
|
|
|
int textX = scaledX + (scaledWidth - textwidth(text.c_str())) / 2; // 计算文本在按钮中央的x坐标
|
|
|
|
|
int textY = scaledY + (scaledHeight - textheight(_T("微软雅黑"))) / 2; // 计算文本在按钮中央的y坐标
|
|
|
|
|
outtextxy(textX, textY, text.c_str()); // 在按钮上绘制文本
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
void play_easy()
|
|
|
|
|
{
|
|
|
|
|
const wchar_t* mapping = L"0123456789";
|
|
|
|
|
_count = 0;
|
|
|
|
|
std::srand(static_cast<unsigned int>(std::time(0)));
|
|
|
|
|
MyMap _map{};
|
|
|
|
|
DUISHU = 2;
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
while (!_map.generatemap(50))
|
|
|
|
|
{
|
|
|
|
|
if (_map.generatemap(50))
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (int j = 0; j < ROW; j++)
|
|
|
|
|
{
|
|
|
|
|
for (int k = 0; k < COL; k++)
|
|
|
|
|
{
|
|
|
|
|
map[i][j][k] = _map.Map[j][k];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < ROW; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < COL; j++)
|
|
|
|
|
{
|
|
|
|
|
temp_map[i][j] = map[cas][i][j];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/*Button* restart = new Button{ 100, 300, 100, 25, L"重置" };*/
|
|
|
|
|
/*ExMessage msg;*/
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
drawGraph();
|
|
|
|
|
setbkmode(TRANSPARENT);
|
|
|
|
|
settextcolor(BLACK);
|
|
|
|
|
settextstyle(20, 0, _T("微软雅黑"));
|
|
|
|
|
outtextxy(500, 570, L"已走步数:");
|
|
|
|
|
outtextxy(100, 570, L"重置:Z");
|
|
|
|
|
outtextxy(200, 570, L"主菜单:X");
|
|
|
|
|
int q = 0;
|
|
|
|
|
int temp = _count;
|
|
|
|
|
while (temp != 0)
|
|
|
|
|
{
|
|
|
|
|
c[q] = mapping[temp % 10];
|
|
|
|
|
temp /= 10;
|
|
|
|
|
q++;
|
|
|
|
|
}
|
|
|
|
|
if (q != 0)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < q; j++)
|
|
|
|
|
{
|
|
|
|
|
result[j] = c[q - j - 1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
outtextxy(570, 570, result);
|
|
|
|
|
if (gameOver())//如果游戏结束
|
|
|
|
|
{
|
|
|
|
|
cas++; //变换关卡
|
|
|
|
|
_count = 0;
|
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
|
|
|
result[i] = 0;
|
|
|
|
|
result[0] = { L'0' };
|
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
|
|
|
c[i] = 0;
|
|
|
|
|
if (cas != 4)
|
|
|
|
|
{
|
|
|
|
|
Sleep(500);
|
|
|
|
|
drawGraph();
|
|
|
|
|
setbkmode(TRANSPARENT);
|
|
|
|
|
settextcolor(BLACK);
|
|
|
|
|
settextstyle(20, 0, _T("微软雅黑"));
|
|
|
|
|
outtextxy(500, 570, L"已走步数:");
|
|
|
|
|
outtextxy(570, 570, result);
|
|
|
|
|
outtextxy(100, 570, L"重置:Z");
|
|
|
|
|
outtextxy(200, 570, L"主菜单:X");
|
|
|
|
|
for (int i = 0; i < ROW; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < COL; j++)
|
|
|
|
|
{
|
|
|
|
|
temp_map[i][j] = map[cas][i][j];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (cas == 4)
|
|
|
|
|
{
|
|
|
|
|
cas = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
FlushBatchDraw(); // 将缓冲区内容显示在屏幕上
|
|
|
|
|
Sleep(10);
|
|
|
|
|
keyDown();//循环按下按键
|
|
|
|
|
//system("cls");
|
|
|
|
|
}
|
|
|
|
|
/*delete restart;*/
|
|
|
|
|
}
|
|
|
|
|
void play_normal()
|
|
|
|
|
{
|
|
|
|
|
const wchar_t* mapping = L"0123456789";
|
|
|
|
|
_count = 0;
|
|
|
|
|
std::srand(static_cast<unsigned int>(std::time(0)));
|
|
|
|
|
MyMap _map{};
|
|
|
|
|
DUISHU = 4;
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
while (!_map.generatemap(30))
|
|
|
|
|
{
|
|
|
|
|
if (_map.generatemap(30))
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (int j = 0; j < ROW; j++)
|
|
|
|
|
{
|
|
|
|
|
for (int k = 0; k < COL; k++)
|
|
|
|
|
{
|
|
|
|
|
map[i][j][k] = _map.Map[j][k];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0; i < ROW; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < COL; j++)
|
|
|
|
|
{
|
|
|
|
|
temp_map[i][j] = map[cas][i][j];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
drawGraph();
|
|
|
|
|
setbkmode(TRANSPARENT);
|
|
|
|
|
settextcolor(BLACK);
|
|
|
|
|
settextstyle(20, 0, _T("微软雅黑"));
|
|
|
|
|
outtextxy(500, 570, L"已走步数:");
|
|
|
|
|
outtextxy(100, 570, L"重置:Z");
|
|
|
|
|
outtextxy(200, 570, L"主菜单:X");
|
|
|
|
|
int q = 0;
|
|
|
|
|
int temp = _count;
|
|
|
|
|
while (temp != 0)
|
|
|
|
|
{
|
|
|
|
|
c[q] = mapping[temp % 10];
|
|
|
|
|
temp /= 10;
|
|
|
|
|
q++;
|
|
|
|
|
}
|
|
|
|
|
if (q != 0)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < q; j++)
|
|
|
|
|
{
|
|
|
|
|
result[j] = c[q - j - 1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
outtextxy(570, 570, result);
|
|
|
|
|
if (gameOver())//如果游戏结束
|
|
|
|
|
{
|
|
|
|
|
cas++; //变换关卡
|
|
|
|
|
_count = 0;
|
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
|
|
|
result[i] = 0;
|
|
|
|
|
result[0] = { L'0' };
|
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
|
|
|
c[i] = 0;
|
|
|
|
|
if (cas != 4)
|
|
|
|
|
{
|
|
|
|
|
Sleep(500);
|
|
|
|
|
drawGraph();
|
|
|
|
|
setbkmode(TRANSPARENT);
|
|
|
|
|
settextcolor(BLACK);
|
|
|
|
|
settextstyle(20, 0, _T("微软雅黑"));
|
|
|
|
|
outtextxy(500, 570, L"已走步数:");
|
|
|
|
|
outtextxy(570, 570, result);
|
|
|
|
|
outtextxy(100, 570, L"重置:Z");
|
|
|
|
|
outtextxy(200, 570, L"主菜单:X");
|
|
|
|
|
for (int i = 0; i < ROW; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < COL; j++)
|
|
|
|
|
{
|
|
|
|
|
temp_map[i][j] = map[cas][i][j];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (cas == 4)
|
|
|
|
|
{
|
|
|
|
|
cas = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
FlushBatchDraw(); // 将缓冲区内容显示在屏幕上
|
|
|
|
|
Sleep(10);
|
|
|
|
|
keyDown();//循环按下按键
|
|
|
|
|
//system("cls");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
void play_hard()
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
const wchar_t* mapping = L"0123456789";
|
|
|
|
|
_count = 0;
|
|
|
|
|
std::srand(static_cast<unsigned int>(std::time(0)));
|
|
|
|
|
MyMap _map{};
|
|
|
|
|
DUISHU = 6;
|
|
|
|
|
for (int i = 0; i < 4; i++)
|
|
|
|
|
{
|
|
|
|
|
while (!_map.generatemap(8))
|
|
|
|
|
{
|
|
|
|
|
if (_map.generatemap(8))
|
|
|
|
|
{
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (int j = 0; j < ROW; j++)
|
|
|
|
|
{
|
|
|
|
|
for (int k = 0; k < COL; k++)
|
|
|
|
|
{
|
|
|
|
|
map[i][j][k] = _map.Map[j][k];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (int i = 0; i < ROW; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < COL; j++)
|
|
|
|
|
{
|
|
|
|
|
temp_map[i][j] = map[cas][i][j];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
drawGraph();
|
|
|
|
|
setbkmode(TRANSPARENT);
|
|
|
|
|
settextcolor(BLACK);
|
|
|
|
|
settextstyle(20, 0, _T("微软雅黑"));
|
|
|
|
|
outtextxy(500, 570, L"已走步数:");
|
|
|
|
|
outtextxy(100, 570, L"重置:Z");
|
|
|
|
|
outtextxy(200, 570, L"主菜单:X");
|
|
|
|
|
int q = 0;
|
|
|
|
|
int temp = _count;
|
|
|
|
|
while (temp != 0)
|
|
|
|
|
{
|
|
|
|
|
c[q] = mapping[temp % 10];
|
|
|
|
|
temp /= 10;
|
|
|
|
|
q++;
|
|
|
|
|
}
|
|
|
|
|
if (q != 0)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < q; j++)
|
|
|
|
|
{
|
|
|
|
|
result[j] = c[q - j - 1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
outtextxy(570, 570, result);
|
|
|
|
|
if (gameOver())//如果游戏结束
|
|
|
|
|
{
|
|
|
|
|
cas++; //变换关卡
|
|
|
|
|
_count = 0;
|
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
|
|
|
result[i] = 0;
|
|
|
|
|
result[0] = { L'0' };
|
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
|
|
|
c[i] = 0;
|
|
|
|
|
if (cas != 4)
|
|
|
|
|
{
|
|
|
|
|
Sleep(500);
|
|
|
|
|
drawGraph();
|
|
|
|
|
setbkmode(TRANSPARENT);
|
|
|
|
|
settextcolor(BLACK);
|
|
|
|
|
settextstyle(20, 0, _T("微软雅黑"));
|
|
|
|
|
outtextxy(500, 570, L"已走步数:");
|
|
|
|
|
outtextxy(570, 570, result);
|
|
|
|
|
outtextxy(100, 570, L"重置:Z");
|
|
|
|
|
outtextxy(200, 570, L"主菜单:X");
|
|
|
|
|
for (int i = 0; i < ROW; i++)
|
|
|
|
|
{
|
|
|
|
|
for (int j = 0; j < COL; j++)
|
|
|
|
|
{
|
|
|
|
|
temp_map[i][j] = map[cas][i][j];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (cas == 4)
|
|
|
|
|
{
|
|
|
|
|
cas = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
FlushBatchDraw(); // 将缓冲区内容显示在屏幕上
|
|
|
|
|
Sleep(10);
|
|
|
|
|
keyDown();//循环按下按键
|
|
|
|
|
//system("cls");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int main()
|
|
|
|
|
{
|
|
|
|
|
loadResource();//定义加载资源函数
|
|
|
|
|
//mciSendString(L"open 1.mp3", 0, 0, 0);//加载音乐
|
|
|
|
|
//mciSendString(L"play 1.mp3 repeat", 0, 0, 0);//循环播放音乐资源
|
|
|
|
|
initgraph(50 * ROW, 50 * COL);
|
|
|
|
|
Button* start = new Button{ 150, 400, 100, 25, L"开始" };
|
|
|
|
|
Button* easy = new Button{ 100, 300, 100, 25, L"简单" };
|
|
|
|
|
Button* normal = new Button{ 250, 300, 100, 25, L"中等" };
|
|
|
|
|
Button* hard = new Button{ 400, 300, 100, 25, L"困难" };
|
|
|
|
|
Button* exit = new Button{ 350, 400, 100, 25, L"退出" };
|
|
|
|
|
while (1)
|
|
|
|
|
{
|
|
|
|
|
if (start->get_has_been_clicked())
|
|
|
|
|
start->has_been_clicked_convert();
|
|
|
|
|
if (easy->get_has_been_clicked())
|
|
|
|
|
easy->has_been_clicked_convert();
|
|
|
|
|
if (normal->get_has_been_clicked())
|
|
|
|
|
normal->has_been_clicked_convert();
|
|
|
|
|
if (hard->get_has_been_clicked())
|
|
|
|
|
hard->has_been_clicked_convert();
|
|
|
|
|
if (exit->get_has_been_clicked())
|
|
|
|
|
exit->has_been_clicked_convert();
|
|
|
|
|
drawGraph1();
|
|
|
|
|
setbkmode(TRANSPARENT);
|
|
|
|
|
settextcolor(BLACK);
|
|
|
|
|
settextstyle(50, 0, _T("微软雅黑"));
|
|
|
|
|
outtextxy(250, 150, L"推箱子");
|
|
|
|
|
ExMessage msg;
|
|
|
|
|
while (true)
|
|
|
|
|
{
|
|
|
|
|
if (peekmessage(&msg)) // 检查是否有消息
|
|
|
|
|
{
|
|
|
|
|
int mouseX = msg.x; // 获取鼠标x坐标
|
|
|
|
|
int mouseY = msg.y; // 获取鼠标y坐标
|
|
|
|
|
if (msg.message == WM_LBUTTONDOWN)
|
|
|
|
|
{
|
|
|
|
|
if (start->checkClick(mouseX, mouseY))
|
|
|
|
|
{
|
|
|
|
|
if (easy->get_has_been_clicked())
|
|
|
|
|
{
|
|
|
|
|
play_easy();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if (normal->get_has_been_clicked())
|
|
|
|
|
{
|
|
|
|
|
play_normal();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else if(hard->get_has_been_clicked())
|
|
|
|
|
{
|
|
|
|
|
play_hard();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (easy->checkClick(mouseX, mouseY))
|
|
|
|
|
{
|
|
|
|
|
if (normal->get_has_been_clicked())
|
|
|
|
|
normal->has_been_clicked_convert();
|
|
|
|
|
if (hard->get_has_been_clicked())
|
|
|
|
|
hard->has_been_clicked_convert();
|
|
|
|
|
}
|
|
|
|
|
else if (normal->checkClick(mouseX, mouseY))
|
|
|
|
|
{
|
|
|
|
|
if (easy->get_has_been_clicked())
|
|
|
|
|
easy->has_been_clicked_convert();
|
|
|
|
|
if (hard->get_has_been_clicked())
|
|
|
|
|
hard->has_been_clicked_convert();
|
|
|
|
|
}
|
|
|
|
|
else if (hard->checkClick(mouseX, mouseY))
|
|
|
|
|
{
|
|
|
|
|
if (normal->get_has_been_clicked())
|
|
|
|
|
normal->has_been_clicked_convert();
|
|
|
|
|
if (easy->get_has_been_clicked())
|
|
|
|
|
easy->has_been_clicked_convert();
|
|
|
|
|
}
|
|
|
|
|
else if (exit->checkClick(mouseX, mouseY))
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else if (msg.message == WM_MOUSEMOVE)
|
|
|
|
|
{
|
|
|
|
|
start->checkMouseOver(mouseX, mouseY);
|
|
|
|
|
easy->checkMouseOver(mouseX, mouseY);
|
|
|
|
|
normal->checkMouseOver(mouseX, mouseY);
|
|
|
|
|
hard->checkMouseOver(mouseX, mouseY);
|
|
|
|
|
exit->checkMouseOver(mouseX, mouseY);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
start->draw(); // 绘制当前页面内容
|
|
|
|
|
easy->draw();
|
|
|
|
|
normal->draw();
|
|
|
|
|
hard->draw();
|
|
|
|
|
exit->draw();
|
|
|
|
|
FlushBatchDraw(); // 将缓冲区内容显示在屏幕上
|
|
|
|
|
Sleep(10);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
delete start;
|
|
|
|
|
delete easy;
|
|
|
|
|
delete normal;
|
|
|
|
|
delete hard;
|
|
|
|
|
delete exit;
|
|
|
|
|
delete bacground;
|
|
|
|
|
closegraph();//关闭窗口
|
|
|
|
|
return 0;
|
|
|
|
|
}
|