栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C+++实现推箱子(附加回撤功能)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C+++实现推箱子(附加回撤功能)

跟着B站老师 做的,链接[C/C++]180行代码,推箱子就是这么简单~抄详细,学不会我还不信了,关卡切换和回退都实现了哦_哔哩哔哩_bilibili

编码环境:VS2019 

利用 链栈实现的回撤功能。

linkStack.h

#pragma once

#ifdef _cplusplus
extern "C"
{
#endif


#include 
#include 
#include
using namespace std;

#define OK 1
#define ERROR 0
#define OVERFLOW -2
//typedef int Data;

struct Point
{
    int r;
    int c;
    int data;
};

typedef struct _State
{
    Point pos[3];
}Data,State;

typedef struct StackNode
{
    Data data;
    struct StackNode* next;
} StackNode, * linkStack;

//算法1 链栈的初始化(无头节点)
void InitStack(linkStack& S)
{ // 构造一个空栈 S,栈顶指针置空
    S = NULL;
   // return OK;
}

//算法2 链栈的入栈
void Push(linkStack& S, Data e)
{ //在栈顶插入元素e
    linkStack p;
    p = new StackNode; //生成新结点
    p->data = e;       //将新结点数据域置为e
    p->next = S;       //将新结点插入栈顶(类似与前插法,只不过没有头节点)
    S = p;             //修改栈顶指针为p
    printf("okn");
    //return OK;
}

//算法3链栈的出栈
void Pop(linkStack& S)
{ //删除S的栈顶元素,用e返回其值
    linkStack p;
    if (S == NULL)
        return ; //栈空
   // e = S->data;      //将栈顶元素赋给e
    p = S;            //用p临时保存栈顶元素空间,以备释放
    S = S->next;      //修改栈顶指针
    delete p;         //释放原栈顶元素的空间
   // return OK;
}
//算法4 取链栈的栈顶元素
Data GetTop(linkStack S)
{                       //返回S的栈顶元素,不修改栈顶指针
    if (S != NULL)      //栈非空
        return S->data; //返回栈顶元素的值,栈顶指针不变
}

bool empty(linkStack& S) {
    if (S == NULL)
        return true;

    else return false;
}
//
//void empty(linkStack& S) {
//
//}

#ifdef _cplusplus
}
#endif

cpp文件

#include
#include
#include
#include
#include
#include
#include 
#include  //包含IMAGE数组
#include"linkStack.h"

using namespace std;

#define SIZE 10
#define TOTAL_LEVEL 3

linkStack ls; //??

enum MINE {
    SPACE,
    WALL,
    DEST,
    BOX,
    PLAYER,

};

//linkStack* ls;

int x;
int y;
int level;
IMAGE all_image[6];
//空地0 墙1 目的地2 箱子3 玩家4 
//PLAYER+DEST 5   BOX+DEST:6
//a75  d77 72w 80s

int map[TOTAL_LEVEL][SIZE][SIZE] = {
    {
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,1,1,1,0,0,0,0},
        {0,0,0,1,2,1,0,0,0,0},
        {0,0,0,1,3,1,1,1,1,0},
        {0,1,1,1,0,0,3,2,1,0},
        {0,1,2,3,4,0,1,1,1,0},
        {0,1,1,1,1,3,1,0,0,0},
        {0,0,0,0,1,2,1,0,0,0},
        {0,0,0,0,1,1,1,0,0,0},
        {0,0,0,0,0,0,0,0,0,0}
    },
    {
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,1,1,1,1,1,1,0,0},
        {0,0,1,0,2,0,0,1,0,0},
        {0,0,1,0,0,3,0,1,0,0},
        {0,0,1,0,0,0,0,1,0,0},
        {0,0,1,0,0,4,0,1,0,0},
        {0,0,1,1,1,1,1,1,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0}
    },
    {
        {0,0,0,0,0,0,0,0,0,0},
        {0,1,1,1,0,0,0,0,0,0},
        {0,1,2,1,0,0,0,0,0,0},
        {0,1,3,1,0,0,0,0,0,0},
        {0,1,4,1,0,0,0,0,0,0},
        {0,1,1,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0}
    }

};

void loadIMG()
{

    for (int i = 0; i < 6; i++)
    {
        char file[20] = "";
        sprintf(file, "./image/%d.bmp", i);
        loadimage(all_image + i, file, 64, 64);//IMAGE *pDstImg(// 保存图像的 IMAGE 对象指针), 
        //e.g.loadimage(all_image + i,"0.bmp",64,64); //LPCTSTR pImgFile,图片文件名
                                             //int nWidth = 0, int nHeight = 0, bool bResize = false);					
        //putimage(i*64,0,all_image + i); //坐标原点为左上角。注意x,y坐标

    }

}

void upMove() {
    if (map[level][x - 1][y] == SPACE || map[level][x - 1][y] == DEST) {
        map[level][x - 1][y] += PLAYER;
        map[level][x][y] -= PLAYER;
    }
    else if (map[level][x - 1][y] == BOX || map[level][x - 1][y] == BOX + DEST) {
        if (map[level][x - 2][y] == SPACE || map[level][x - 2][y] == DEST) {
            map[level][x - 2][y] += BOX;
            map[level][x - 1][y] = map[level][x - 1][y] + PLAYER - BOX;
            map[level][x][y] -= PLAYER;
        }

    }

}

void downMove() {
    if (map[level][x + 1][y] == SPACE || map[level][x + 1][y] == DEST) {
        map[level][x + 1][y] += PLAYER;
        map[level][x][y] -= PLAYER;
    }
    else if (map[level][x + 1][y] == BOX || map[level][x + 1][y] == BOX + DEST) {
        if (map[level][x + 2][y] == SPACE || map[level][x + 2][y] == DEST) {
            map[level][x + 2][y] += BOX;
            map[level][x + 1][y] = map[level][x + 1][y] + PLAYER - BOX;
            map[level][x][y] -= PLAYER;
        }

    }

}

void leftMove() {
    if (map[level][x][y - 1] == SPACE || map[level][x][y - 1] == DEST) {
        map[level][x][y - 1] += PLAYER;
        map[level][x][y] -= PLAYER;
    }
    else if (map[level][x][y - 1] == BOX || map[level][x][y - 1] == BOX + DEST) {
        if (map[level][x][y - 2] == SPACE || map[level][x][y - 2] == DEST) {
            map[level][x][y - 2] += BOX;
            map[level][x][y - 1] = map[level][x][y - 1] + PLAYER - BOX;
            map[level][x][y] -= PLAYER;
        }

    }

}

void rightMove() {
    if (map[level][x][y + 1] == SPACE || map[level][x][y + 1] == DEST) {
        map[level][x][y + 1] += PLAYER;
        map[level][x][y] -= PLAYER;
    }
    else if (map[level][x][y + 1] == BOX || map[level][x][y + 1] == BOX + DEST) {
        if (map[level][x][y + 2] == SPACE || map[level][x][y + 2] == DEST) {
            map[level][x][y + 2] += BOX;
            map[level][x][y + 1] = map[level][x][y + 1] + PLAYER - BOX;
            map[level][x][y] -= PLAYER;
        }

    }

}

void gameDraw() {
    for (int i = 0; i < SIZE; i++)
    {
        for (int j = 0; j < SIZE; j++)
        {
            switch (map[level][i][j])
            {
            case SPACE:
                putimage(j * 64, i * 64, all_image);
                break;
            case WALL:
                putimage(j * 64, i * 64, all_image + 1);
                break;
            case DEST:
                putimage(j * 64, i * 64, all_image + 2);
                break;
            case BOX:
                putimage(j * 64, i * 64, all_image + 3);
                break;
            case PLAYER:
                x = i;
                y = j;
                putimage(j * 64, i * 64, all_image + 4);
                break;
            case PLAYER + DEST:
                putimage(j * 64, i * 64, all_image + 4);
                x = i;
                y = j;
                break;
            case BOX + DEST:
                putimage(j * 64, i * 64, all_image + 5);
                break;
            default:
                break;
            }

        }
        cout << endl;

    }

}

//对应的ASC码值
//W w:119,87  Dd:100,68 Ww:119,87 Ss:115,83 空格:32
void saveState(int x, int y, int dir) {//player的坐标,以及keyevent
    //State t;
    State t;
    memset(&t, 0, sizeof(State));
    switch (dir)
    {
    case 119://w
    case 87:
        for (int i = 0; i < 3; i++)
        {
            t.pos[i].r = x - i;  //依次记录 player 、player的下一格、以及player的下下一格 的行列坐标以及data
            t.pos[i].c = y;
            t.pos[i].data = map[level][t.pos[i].r][t.pos[i].c];

        }
        Push(ls, t);
        break;
    case 115://s
    case 83:
        for (int i = 0; i < 3; i++)
        {
            t.pos[i].r = x + i;  //依次记录 player 、player的下一格、以及player的下下一格 的行列坐标以及data
            t.pos[i].c = y;
            t.pos[i].data = map[level][t.pos[i].r][t.pos[i].c];

        }
        Push(ls, t);
        Data p = GetTop(ls);
        break;

    case 97://a
    case 65:
        for (int i = 0; i < 3; i++)
        {
            t.pos[i].r = x;  //依次记录 player 、player的下一格、以及player的下下一格 的行列坐标以及data
            t.pos[i].c = y - i;
            t.pos[i].data = map[level][t.pos[i].r][t.pos[i].c];
        }
        Push(ls, t);
        break;

    case 100://d
    case 68:
        for (int i = 0; i < 3; i++)
        {
            t.pos[i].r = x;  //依次记录 player 、player的下一格、以及player的下下一格 的行列坐标以及data
            t.pos[i].c = y + i;
            t.pos[i].data = map[level][t.pos[i].r][t.pos[i].c];

        }
        Push(ls, t);
        break;
    default:
        break;
    }
    
}

void rollBack() {
    if (empty(ls))
    {
        return;
    }
    State t = GetTop(ls);
    for (int i = 0; i < 3; i++)
    {
        map[level][t.pos[i].r][t.pos[i].c] = t.pos[i].data;
    }
    Pop(ls);
}

void keyEvent() {
    char event = _getch();
    if (event != 32  && event != -32) {
        saveState(x, y, event);
    }
    switch (event)
    {
    case 'W':
    case 'w':
        upMove();
        break;

    case 's':
    case 'S':
        downMove();
        break;

    case 'A':
    case 'a':
        leftMove();
        break;
    case 'd':
    case 'D':
        rightMove();
        break;
    case 32:
        rollBack();
        break;
    default:
        break;
    }


}

bool judge_pass() {
    for (int i = 0; i < SIZE; i++)
    {
        for (int j = 0; j < SIZE; j++)
        {
            if (map[level][i][j] == BOX)
            {
                return false;
            }

        }

    }

    return true;
}

int main() {
    InitStack(ls);
    initgraph(SIZE * 64, SIZE * 64, TRUE);
    loadIMG();
    //system("mode con lines=20 cols=25");
    level = 0;
    while (level < TOTAL_LEVEL)
    {
        //system("cls");
        gameDraw();
        keyEvent();

        if (judge_pass())
        {
            if (level == TOTAL_LEVEL - 1) {
                //system("cls");
                gameDraw();
            }
            level++;
            while (!empty(ls))
            {
                Pop(ls);
            }

        }

    }

    MessageBox(NULL, TEXT("CONGRATULATIONS!"), TEXT("GAME OVER"), MB_OK);

    // getchar();


    return 0;
}

附文件结构 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/352486.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号