c++实现简单制作推箱子

知识点

结构体,循环,函数,枚举,数组

玩法

1.通过控制w,s,a,d来实现人物的移动,或者上下左右。

2.将三个箱子推到洞中游戏胜利。

3.将箱子推到四周墙边会自动判定失败

创作历程

1.头文件及调用命名空间

#include<iostream>
#include<Windows.h>
using namespace std;

2.宏定义

#define KEY_DOWN(vk_code) GetAsyncKeyState(vk_code) & 0x8000
#define VK_ESCAPE         0x1B
#define VK_RETURN         0x0D

3.枚举

//枚举
enum
{
    E_GAME_MENU,
    E_GAME_MAP,
    E_GAME_WIN,
    E_GAME_OVER
};

enum
{
    E_MENU_START,
    E_MENU_SET,
    E_MENU_EXIT
};

enum
{
    E_OVER_AGAIN,
    E_OVER_EXIT
};

4.结构体创建玩家,箱子和洞

struct SPlayer
{
    int nRow;
    int nCol;
    int nRowBk; //玩家的备份坐标
    int nColBk;
};

struct SBox
{
    int nRow;
    int nCol;
    int nRowBk; //箱子的备份坐标
    int nColBk;
};

struct SHole
{
    int nRow;
    int nCol;
};

5.清屏函数(只管用就好了)

void gotoxy(int x, int y) //清屏函数
{
    COORD coord;
    coord.X = x;
    coord.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}

6.主函数中实现游戏逻辑

int main()
{
    int arrMap[20][20] = {
        {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
        {1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1},
        {1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,1},
        {1,4,0,1,0,0,0,1,0,1,0,0,0,0,0,1,2,1,4,1},
        {1,4,0,1,0,0,0,1,0,1,0,0,0,0,0,0,1,0,4,1},
        {1,4,0,0,1,0,0,1,0,1,1,1,1,0,0,0,0,0,4,1},
        {1,4,0,0,0,0,0,1,2,0,0,0,0,0,0,0,0,0,4,1},
        {1,4,0,0,0,0,0,1,1,1,1,1,1,0,0,0,0,0,4,1},
        {1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,1},
        {1,4,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,1},
        {1,4,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,4,1},
        {1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,1},
        {1,4,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,4,1},
        {1,4,0,0,1,0,0,0,0,0,0,0,0,0,1,1,2,0,4,1},
        {1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,4,1},
        {1,4,0,1,0,1,0,0,0,0,0,0,0,0,1,0,0,1,4,1},
        {1,4,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,4,1},
        {1,4,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,4,1},
        {1,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,1},
        {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
    };
    int nMenuState = 0;
    int nOverState = 0;
    int nGameScene = 0;
    int nPushIndex = 0; //定义一个指数来记录当前推的箱子
    bool bClear = false;
    bool bPutBox = false;
    SPlayer player;
    player.nRow = 14;
    player.nCol = 9;
    SBox arrBox[3];
    arrBox[0].nRow = 12;
    arrBox[0].nCol = 8;
    arrBox[1].nRow = 12;
    arrBox[1].nCol = 9;
    arrBox[2].nRow = 12;
    arrBox[2].nCol = 10;
    SHole arrHole[3];
    arrHole[0].nRow = 3;
    arrHole[0].nCol = 16;
    arrHole[1].nRow = 6;
    arrHole[1].nCol = 8;
    arrHole[2].nRow = 13;
    arrHole[2].nCol = 16;

    while (1)
    {
        gotoxy(0, 0); //每一帧都进行清屏,防止出现死循环
        if (nGameScene == E_GAME_MENU)
        {
            if (KEY_DOWN(VK_RETURN))
            {
                if (nMenuState == E_MENU_START)
                {
                    nGameScene = E_GAME_MAP;
                }
                else if (nMenuState == E_MENU_EXIT)
                {
                    system("cls");
                    exit(0);
                }
            }
            if (KEY_DOWN(VK_UP))
            {
                nMenuState--;
                if (nMenuState < E_MENU_START)
                {
                    nMenuState = E_MENU_EXIT;
                }
            }
            else if (KEY_DOWN(VK_DOWN))
            {
                nMenuState++;
                if (nMenuState > E_MENU_EXIT)
                {
                    nMenuState = E_MENU_START;
                }
            }
            if (nMenuState == E_MENU_START)
            {
                cout << "■■■■■■■■■■■■■" << endl;
                cout << "■                      ■" << endl;
                cout << "■       游戏菜单       ■" << endl;
                cout << "■                      ■" << endl;
                cout << "■     ->开始游戏       ■" << endl;
                cout << "■       游戏设置       ■" << endl;
                cout << "■       退出游戏       ■" << endl;
                cout << "■                      ■" << endl;
                cout << "■■■■■■■■■■■■■" << endl;
            }
            else if (nMenuState == E_MENU_SET)
            {
                cout << "■■■■■■■■■■■■■" << endl;
                cout << "■                      ■" << endl;
                cout << "■       游戏菜单       ■" << endl;
                cout << "■                      ■" << endl;
                cout << "■       开始游戏       ■" << endl;
                cout << "■     ->游戏设置       ■" << endl;
                cout << "■       退出游戏       ■" << endl;
                cout << "■                      ■" << endl;
                cout << "■■■■■■■■■■■■■" << endl;
            }
            else if (nMenuState == E_MENU_EXIT)
            {
                cout << "■■■■■■■■■■■■■" << endl;
                cout << "■                      ■" << endl;
                cout << "■       游戏菜单       ■" << endl;
                cout << "■                      ■" << endl;
                cout << "■       开始游戏       ■" << endl;
                cout << "■       游戏设置       ■" << endl;
                cout << "■     ->退出游戏       ■" << endl;
                cout << "■                      ■" << endl;
                cout << "■■■■■■■■■■■■■" << endl;
            }
        }
        else if (nGameScene == E_GAME_MAP)
        {
            if (KEY_DOWN(VK_ESCAPE)) //退出
            {
                nGameScene = E_GAME_MENU;
                bClear = true;
            }
            //将玩家的坐标保存起来
            player.nRowBk = player.nRow;
            player.nColBk = player.nCol;
            if (KEY_DOWN(VK_UP))
            {
                player.nRow--;
            }
            else if (KEY_DOWN(VK_DOWN))
            {
                player.nRow++;
            }
            else if (KEY_DOWN(VK_LEFT))
            {
                player.nCol--;
            }
            else if (KEY_DOWN(VK_RIGHT))
            {
                player.nCol++;
            }
            //如果撞墙就将玩家的坐标改为备份坐标
            if (arrMap[player.nRow][player.nCol] == 1)
            {
                player.nRow = player.nRowBk; 
                player.nCol = player.nColBk;
            }
            for (int i = 0; i < 3; i++)
            {
                arrBox[i].nRowBk = arrBox[i].nRow;
                arrBox[i].nColBk = arrBox[i].nCol;
            }
            for (int i = 0; i < 3; i++)
            {
                if (player.nRow == arrBox[i].nRow && player.nCol == arrBox[i].nCol)
                {
                    arrBox[i].nRow += player.nRow - player.nRowBk;
                    arrBox[i].nCol += player.nCol - player.nColBk;
                    nPushIndex = i;
                }
            }
            //当两个箱子相撞时,推的箱子和玩家返回备份坐标
            for (int i = 0; i < 3; i++)
            {
                if (arrBox[nPushIndex].nRow == arrBox[i].nRow && arrBox[nPushIndex].nCol == arrBox[i].nCol && i != nPushIndex)
                {
                    arrBox[nPushIndex].nRow = arrBox[nPushIndex].nRowBk;
                    arrBox[nPushIndex].nCol = arrBox[nPushIndex].nColBk;
                    player.nRow = player.nRowBk;
                    player.nCol = player.nColBk;
                }
            }
            //防止将箱子推进墙中
            if (arrMap[arrBox[nPushIndex].nRow][arrBox[nPushIndex].nCol] == 1)
            {
                arrBox[nPushIndex].nRow = arrBox[nPushIndex].nRowBk;
                arrBox[nPushIndex].nCol = arrBox[nPushIndex].nColBk;
                player.nRow = player.nRowBk;
                player.nCol = player.nColBk;
            }
            //计算推进箱子的数量
            int nCount = 0;
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (arrBox[i].nRow == arrHole[j].nRow && arrBox[i].nCol == arrHole[j].nCol)
                    {
                        nCount++;
                    }
                }
            }
            //绘制地图
            for (int i = 0; i < 20; i++)
            {
                for (int j = 0; j < 20; j++)
                {
                    bool bDrawBox = false;
                    for (int n = 0; n < 3; n++)
                    {
                        if (arrBox[n].nRow == i && arrBox[n].nCol == j)
                        {
                            bDrawBox = true;
                        }
                    }
                    if (arrMap[i][j] == 1)
                    {
                        cout << "■";
                    }
                    else if (bDrawBox)
                    {
                        cout << "●";
                    }
                    else if (arrMap[i][j] == 2)
                    {
                        cout << "坑";
                    }
                    else if (player.nRow == i && player.nCol == j)
                    {
                        cout << "玩";
                    }
                    else if (arrMap[i][j] == 4)
                    {
                        cout << "  ";
                    }
                    else if (arrMap[i][j] == 0)
                    {
                        cout << "  ";
                    }
                }
                cout << endl;
            }
            //判断胜利
            if (nCount == 3)
            {
                nGameScene = E_GAME_WIN;
                bClear = true;
            }
            //判断失败
            for (int i = 0; i < 3; i++)
            {
                if (arrMap[arrBox[i].nRow][arrBox[i].nCol] == 4)
                {
                    nGameScene = E_GAME_OVER;
                    bClear = true;
                }
            }
            if (bClear)
            {
                system("cls");
                bClear = false;
            }
        }
        else if (nGameScene == E_GAME_WIN)
        {
            if (KEY_DOWN(VK_RETURN))
            {
                //重置游戏
                if (nOverState == E_OVER_AGAIN)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        arrMap[arrHole[i].nRow][arrHole[i].nCol] = 2;
                    }
                    player.nRow = 14;
                    player.nCol = 9;
                    arrBox[0].nRow = 12;
                    arrBox[0].nCol = 8;
                    arrBox[1].nRow = 12;
                    arrBox[1].nCol = 9;
                    arrBox[2].nRow = 12;
                    arrBox[2].nCol = 10;
                    nGameScene = E_GAME_MAP;
                }
                else if (nOverState == E_OVER_EXIT)
                {
                    system("cls");
                    exit(0);
                }
            }
            if (KEY_DOWN(VK_UP))
            {
                nOverState--;
                if (nOverState < 0)
                {
                    nOverState = 1;
                }
            }
            else if (KEY_DOWN(VK_DOWN))
            {
                nOverState++;
                if (nOverState > 1)
                {
                    nOverState = 0;
                }
            }
            if (nOverState == E_OVER_AGAIN)
            {
                cout << "■■■■■■■■■■■■■" << endl;
                cout << "■                      ■" << endl;
                cout << "■       游戏胜利       ■" << endl;
                cout << "■                      ■" << endl;
                cout << "■     ->再玩一次       ■" << endl;
                cout << "■       退出游戏       ■" << endl;
                cout << "■                      ■" << endl;
                cout << "■■■■■■■■■■■■■" << endl;
            }
            else if (nOverState == E_OVER_EXIT)
            {
                cout << "■■■■■■■■■■■■■" << endl;
                cout << "■                      ■" << endl;
                cout << "■       游戏胜利       ■" << endl;
                cout << "■                      ■" << endl;
                cout << "■       再玩一次       ■" << endl;
                cout << "■     ->退出游戏       ■" << endl;
                cout << "■                      ■" << endl;
                cout << "■■■■■■■■■■■■■" << endl;
            }
        }
        else if (nGameScene == E_GAME_OVER)
        {
            if (KEY_DOWN(VK_RETURN))
            {
                //重置游戏
                if (nOverState == E_OVER_AGAIN)
                {
                    for (int i = 0; i < 3; i++)
                    {
                        arrMap[arrHole[i].nRow][arrHole[i].nCol] = 2;
                    }
                    player.nRow = 14;
                    player.nCol = 9;
                    arrBox[0].nRow = 12;
                    arrBox[0].nCol = 8;
                    arrBox[1].nRow = 12;
                    arrBox[1].nCol = 9;
                    arrBox[2].nRow = 12;
                    arrBox[2].nCol = 10;
                    nGameScene = E_GAME_MAP;
                }
                else if (nOverState == E_OVER_EXIT)
                {
                    system("cls");
                    exit(0);
                }
            }
            if (KEY_DOWN(VK_UP))
            {
                nOverState--;
                if (nOverState < 0)
                {
                    nOverState = 1;
                }
            }
            else if (KEY_DOWN(VK_DOWN))
            {
                nOverState++;
                if (nOverState > 1)
                {
                    nOverState = 0;
                }
            }
            if (nOverState == E_OVER_AGAIN)
            {
                cout << "■■■■■■■■■■■■■" << endl;
                cout << "■                      ■" << endl;
                cout << "■       游戏失败       ■" << endl;
                cout << "■                      ■" << endl;
                cout << "■     ->再玩一次       ■" << endl;
                cout << "■       退出游戏       ■" << endl;
                cout << "■                      ■" << endl;
                cout << "■■■■■■■■■■■■■" << endl;
            }
            else if (nOverState == E_OVER_EXIT)
            {
                cout << "■■■■■■■■■■■■■" << endl;
                cout << "■                      ■" << endl;
                cout << "■       游戏失败       ■" << endl;
                cout << "■                      ■" << endl;
                cout << "■       再玩一次       ■" << endl;
                cout << "■     ->退出游戏       ■" << endl;
                cout << "■                      ■" << endl;
                cout << "■■■■■■■■■■■■■" << endl;
            }
        }
        Sleep(80); //暂停程序80ms
    }
    system("pause");
    return 0;
}

 注意事项

1.要在终端设置中将下图设置为Windows控制台主机

作用:防止乱码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值