#include #include #include #include <string>#include using namespace std;#define LINE 9 //行数#define COLUMN 12 //列数#define RATIO 61 //图片大小#define START_X 64  //行偏移量#define START_Y 60 //列偏移量#define SCREEN_WIDTH 860 //屏幕的宽#define SCREEN_HEIGHT 668 //屏幕的高#define isValid(pos) pos.x>=0 && pos.x=0 && pos.y < COLUMN//控制键 上下左右控制方向 按‘q’退出#define KEY_UP 'W'#define KEY_DOWN 'S'#define KEY_LEFT 'A'#define KEY_RIGHT 'D'#define KEY_QUIT 'Q'/*游戏地图*///墙: 0,地板: 1,箱子目的地: 2, 小人: 3, 箱子: 4, 箱子命中目标: 5int map[LINE][COLUMN] = {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },{ 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0 },{ 0, 1, 4, 1, 0, 2, 1, 0, 2, 1, 0, 0 },{ 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0 },{ 0, 1, 0, 2, 0, 1, 1, 4, 1, 1, 1, 0 },{ 0, 1, 1, 1, 0, 3, 1, 1, 1, 4, 1, 0 },{ 0, 1, 2, 1, 1, 4, 1, 1, 1, 1, 1, 0 },{ 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0 },{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },};struct _POS {    int x;            //小人所在二维数组的行    int y;            //小人所在二维数组的列};enum _PROPS { //枚举常量 道具    WALL,//    FLOOR,//地板    BOX_DES,//箱子目的地    MAN,//    BOX,//箱子    HIT,//箱子命中目标    ALL};enum _DIRECTION { //游戏方向控制    UP,    DOWN,    LEFT,    RIGHT};IMAGE images[ALL];struct _POS man;struct _POS box_des1;//临时的箱子目的地存放点struct _POS box_des2;void changeMap(struct _POS *man, enum _PROPS prop) {    map[man->x][man->y] = prop;    putimage(START_X + man->y * RATIO, START_Y + man->x * RATIO, &images[prop]);}/***********************************************实现游戏四个方向(上、下、左、右)的控制* 输入:* direct - 人前进方向* 输出: 无**********************************************/void gameControl(enum _DIRECTION direct) {    struct _POS next_pos = man;    struct _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;    }    if (isValid(next_pos) && map[next_pos.x][next_pos.y] == FLOOR) {//人的前方是地板        if (map[man.x][man.y] == map[box_des1.x][box_des1.y] || map[man.x][man.y] == map[box_des2.x][box_des2.y]) { //如果人所在的位置是箱子目的地            changeMap(&next_pos, MAN);            changeMap(&man, BOX_DES);            man = next_pos;        }        else {            changeMap(&next_pos, MAN); //小人前进一格            changeMap(&man, FLOOR);            man = next_pos;        }    }    else if (map[next_pos.x][next_pos.y] == BOX_DES) {//如果人的前方是箱子目的地        box_des1.x = next_pos.x;        box_des1.y = next_pos.y;        changeMap(&next_pos, MAN);        changeMap(&man, FLOOR);        man = next_pos;    }    else if (map[next_pos.x][next_pos.y] == HIT) {//如果人的前方是HIT        changeMap(&next_next_pos, BOX);        changeMap(&next_pos, MAN); //小人前进一格        changeMap(&man, FLOOR);        man = next_pos;        box_des2.x = next_pos.x;        box_des2.y = next_pos.y;    }    else if (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;        }    }}/*********************************************** *游戏结束场景,在玩家通关后显示*输入:* 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("恭喜您~ \n 您终于成为了一个合格的搬箱子老司机!"),        &rec, DT_CENTER | DT_VCENTER | DT_SINGLELINE);}void isGameFailed(IMAGE* bg) {    putimage(0, 0, bg);    settextcolor(WHITE);    RECT rec = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };    settextstyle(20, 0, _T("宋体"));    drawtext(_T("GameOver!你这个小垃圾哈哈哈哈!"),        &rec, DT_CENTER | DT_VCENTER | DT_SINGLELINE);}/***********************************************判断游戏是否结束,如果不存在任何一个箱子目的地,就代表游戏结束*输入: 无*返回值:* 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;}int main() {    IMAGE bg_img; //背景图片    int num = 0;//统计步数    initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);    loadimage(&bg_img,_T("blackground.bmp"), SCREEN_WIDTH, SCREEN_HEIGHT,true);    putimage(0, 0, &bg_img);    //加载道具图标    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);    for (int i = 0; i < LINE; i++) {        for (int j = 0; j < COLUMN; j++) {            if (map[i][j] == 3) {                man.x = i;                man.y = j;            }            putimage(START_X + j * RATIO, START_Y + i * RATIO,                &images[map[i][j]]);        }    }    //游戏开始环节    bool isQuit = false;    ExMessage msg;    do {        //if (_kbhit()) {//如果玩家点击键盘 //win11用不了此操作        //    char ch = _getch();        //    switch (ch)        //    {        //    case KEY_UP:        //        gameControl(UP);        //    case KEY_DOWN:        //        gameControl(DOWN);        //    case KEY_LEFT:        //        gameControl(LEFT);        //    case KEY_RIGHT:        //        gameControl(RIGHT);        //    case KEY_QUIT:        //        isQuit = true;        //    if (isGameOver()) {        //        gameOverScene(&bg_img);        //        isQuit = true;        //    }        //    }        //    Sleep(100);        //}        //WM_LBUTTONDOWN 鼠标左键按下        //WM_KEYDOWN 键盘按键按下         if (peekmessage(&msg) && msg.message == WM_KEYDOWN)        {            char ch = msg.vkcode;            num++;            switch (ch)            {            case KEY_UP:                gameControl(UP);                break;            case KEY_DOWN:                gameControl(DOWN);                break;            case KEY_LEFT:                gameControl(LEFT);                break;            case KEY_RIGHT:                gameControl(RIGHT);                break;            case KEY_QUIT:                if (isGameOver()) {                    gameOverScene(&bg_img);                    isQuit = true;                }                break;            }            Sleep(100);            if (num > 80) {                isGameFailed(&bg_img);                isQuit = true;            }            if (isGameOver()) {                gameOverScene(&bg_img);                isQuit = true;            }        }    } while (!isQuit);    system("pause");    return 0;}