美工资源:
链接:https://pan.baidu.com/s/1MZv8pDBXdNDbXxuAAPSM-A **提取码:**2syq
图形库: www.easyx.cn
#include "box_man.h"
#include
#include
#include
#include
#include
#include
#include
#include
#pragma comment(lib, "WINMM.LIB")
using namespace std;
IMAGE images[ALL];
struct _POS man; /* 小人在二维数组的位置 */
int map[LINE][COLUMN] =
{
{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, 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, 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, 1, 1, 1},
{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
};
/*****************************************************
* 判断游戏是否结束, 如果不存在任何一个箱子目的地, 就代表游戏结束
* 输入: 无
* 返回值:
* true - 游戏结束 false - 游戏继续
*****************************************************/
bool isGameOver()
{
for (int i = 0; i < LINE; i++)
{
for (int j = 0; j < COLUMN; j++)
{
if (map[i][j] == BOX_DES)
{
return false;
}
}
}
return true;
}
/***************************************************
* 功能: 游戏结束场景, 在玩家通过后显示
* 输入:
* bg - 背景图片变量的指针
* 返回值: 无
***************************************************/
void gameOverScene(IMAGE* bg)
{
putimage(0, 0, bg);
settextcolor(WHITE);
RECT rec = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
settextstyle(20, 0, _T("宋体"));
drawtext(_T("恭喜你, 通关了!!!"), &rec, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
/*************************************************
* 功能: 改变游戏地图视图中一格对应的道具并重新显示
* 输入:
* pos - 道具在地图数组的行列下标
* prop - 道具的类型
* 返回值: 无
*************************************************/
void changeMap(POS* pos, PROPS prop)
{
map[pos->x][pos->y] = prop;
putimage(START_X + pos->y * RATIO, START_Y + pos->x * RATIO, &images[prop]);
}
/**********************************************
* 功能: 实现游戏四个方向 (上, 下, 左, 右) 的控制
* 输入:
* direct - 人前进的方向
* 输出: 无
**********************************************/
void gameControl(DIRECTION direct)
{
POS next_pos = man; /* man 类型(结构体) 与 next_pos 相同 */
POS next_next_pos = man;
switch (direct)
{
case UP:
next_pos.x--;
next_next_pos.x -= 2;
break;
case DOWN:
next_pos.x++;
next_next_pos.x += 2;
break;
case LEFT:
next_pos.y--;
next_next_pos.y -= 2;
break;
case RIGHT:
next_pos.y++;
next_next_pos.y += 2;
break;
}
/* 宏展开 next_pos.x >= 0 && next_pos.x < LINE && next_pos.y >= 0 && next_pos.y < COLUMN */
if (isValid(next_pos) && map[next_pos.x][next_pos.y] == FLOOR) /* 人的前方是地板 */
{
changeMap(&next_pos, MAN);
changeMap(&man, FLOOR);
man = next_pos;
}
else if (isValid(next_next_pos) && map[next_pos.x][next_pos.y] == BOX)
{
if (map[next_next_pos.x][next_next_pos.y] == FLOOR)
{
changeMap(&next_next_pos, BOX);
changeMap(&next_pos, MAN); /* 小人前进一格 */
changeMap(&man, FLOOR);
man = next_pos;
}
else if (map[next_next_pos.x][next_next_pos.y] == BOX_DES)
{
changeMap(&next_next_pos, HIT);
changeMap(&next_pos, MAN);
changeMap(&man, FLOOR);
man = next_pos;
}
}
}
int main(void)
{
IMAGE bg_img;
/* 搭台 */
initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);
loadimage(&bg_img, _T("blackground.bmp"), SCREEN_WIDTH, SCREEN_HEIGHT);
putimage(0, 0, &bg_img);
//播放音乐
mciSendString(TEXT("open mp3.wma alias mysong"), NULL, 0, NULL); //load音乐
mciSendString(TEXT("play mysong repeat"), NULL, 0, NULL);//打开报警音
//mciSendString(TEXT("close mysong"), NULL, 0, NULL);//关闭报警音
/* 加载道具 */
loadimage(&images[WALL], _T("wall_right.bmp"), RATIO, RATIO, true);
loadimage(&images[FLOOR], _T("floor.bmp"), RATIO, RATIO, true);
loadimage(&images[BOX_DES], _T("des.bmp"), RATIO, RATIO, true);
loadimage(&images[MAN], _T("man.bmp"), RATIO, RATIO, true);
loadimage(&images[BOX], _T("box.bmp"), RATIO, RATIO, true);
loadimage(&images[HIT], _T("box.bmp"), RATIO, RATIO, true);
// 随机地图
int arrFree[LINE - 2][COLUMN - 2];
int* p = &arrFree[0][0];
for (int i = 0;i < (LINE - 2) * (COLUMN - 2);i++) {
p[i] = 1;
}
int z[19];
srand((unsigned)time(NULL));
for (int i = 0;i < 19; i++) {
SJS:z[i] = rand() % ((LINE - 2) * (COLUMN - 2));
for (int j=0;j<i;j++){
if (z[i] == z[j]) {
goto SJS;
}
}
}
p[z[0]] = 3;
p[z[1]] = 2;
p[z[2]] = 2;
p[z[3]] = 2;
p[z[4]] = 2;
p[z[5]] = 4;
p[z[6]] = 4;
p[z[7]] = 4;
p[z[8]] = 4;
for (int i = 9;i < 19;i++ ) {
*(p + z[i]) = 0;
}
for (int i = 1; i < LINE-1; i++)
{
for (int j = 1; j < COLUMN -1; j++)
{
map[i][j] = arrFree[i - 1][j - 1];
}
}
// 绘制地图
for (int i = 0; i < LINE; i++)
{
for (int j = 0; j < COLUMN; j++)
{
if (map[i][j] == MAN)
{
man.x = i;
man.y = j;
}
putimage(START_X + j * RATIO, START_Y + i * RATIO, &images[map[i][j]]);
}
}
/* 游戏环节 */
bool quit = false;
do
{
if (_kbhit())
{
char ch = _getch();
if (ch == KEY_UP)
{
gameControl(UP);
}
else if (ch == KEY_DOWN)
{
gameControl(DOWN);
}
else if (ch == KEY_LEFT)
{
gameControl(LEFT);
}
else if (ch == KEY_RIGHT)
{
gameControl(RIGHT);
}
else if (ch == KEY_QUIT)
{
quit = true;
}
if (isGameOver())
{
gameOverScene(&bg_img);
quit = true;
}
}
Sleep(100);
} while (quit == false);
::system("pause");
closegraph();
return 0;
}
#pragma once
#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 650
#define RATIO 50
/* 控制键 上 下 左 右 控制方向 */
#define KEY_UP 72
#define KEY_LEFT 75
#define KEY_RIGHT 77
#define KEY_DOWN 80
#define KEY_QUIT 'q'
#define LINE 9
#define COLUMN 12
#define START_X 100
#define START_Y 100
enum _PROPS /* 道具 */
{
WALL, /* 墙 */
FLOOR, /* 地板 */
BOX_DES, /* 箱子的目地 */
MAN, /* 小人 */
BOX, /* 箱子 */
HIT, /* 箱子命中目标 */
ALL
};
/* 游戏控制方向 */
enum _DIRECTION
{
UP,
DOWN,
LEFT,
RIGHT
};
struct _POS /* 位置 */
{
int x; /* 小人所在二维数组的行 */
int y; /* 小人所在二维数据在列 */
};
typedef enum _PROPS PROPS; /* 道具 */
typedef enum _DIRECTION DIRECTION; /* 控制方向 */
typedef struct _POS POS; /* 道具的位置 */
#define isValid(pos) pos.x>=0 && pos.x<LINE && pos.y>=0 && pos.y < COLUMN