精华内容
下载资源
问答
  • C语言课程设计,推箱子题目。绝对能用。包括60关的地图 精心调试无错误。 附带课程设计报告
  • 推箱子游戏(C语言课程设计+代码),基于开源的代码和程序设计! 本源码是来自:aiku嵌入式视频教程和项目开发实战
  • 推箱子游戏报告+修改建议+源代码+课程设计报告C语言程序课程设计)
  • 基于C语言推箱子游戏设计毕业论文.pdf
  • C语言 推箱子游戏 图形界面版EGE

    千次阅读 多人点赞 2020-02-10 11:08:31
    使用C语言和EGE图形库实现简单精美的推箱子小游戏 如果您喜欢我的文章可以点赞支持一下。 如果您对我的程序有什么意见和建议欢迎在评论区发表评论。 这是我目前为止写的,无论从时间上还是从工程量上来说都是最长的...

    使用C语言和EGE图形库实现简单好看的推箱子小游戏

    如果您喜欢我的文章可以点赞支持一下。
    如果您对我的程序有什么意见和建议欢迎在评论区发表评论。

    这是我目前为止写的,无论从时间上还是从工程量上来说都是最长的一个小程序。
    从初学EGE到攻克所有的技术难点,总共历时五天。
    全代码一千一百多行。

    在此向帮助过我解决问题的陌生人和老师表示由衷的感谢。

    首先展示几张程序的运行效果:

    主菜单界面
    效果1
    游戏进行中界面:
    效果2
    效果3
    效果4
    关卡选择界面
    效果5
    游戏商城界面
    效果6
    地图编辑器界面
    效果7
    程序中除操控人物移动外所有操作均使用鼠标操作

    下面进入技术环节:

    C语言 EGE实现图形界面版推箱子

    编译环境: Windows VS2019
    其他编译器,可通过查看下文的“注意事项”将代码更正为其他平台可正常版本

    需求:
    界面之间互相跳转、选择关卡、控制人物移动推箱子、游戏商城、地图编辑器

    思路:
    使用EGE库函数在图形界面上画出图片。使用三维数组存储所有关卡。
    使用wasd键控制地图数组中的值,根据值的改变实现界面的改变。
    地图编辑器根据鼠标移动到的像素坐标判断他属于哪一个格子,鼠标点击则再改格子的位置画出相应图片。

    做法:
    游戏部分:双重循环找出二维数组中人物的位置,并根据按键和条件改变数组中的值,然后根据数组中的值画出这个数组所对应的地图。
    编辑器部分:以格子宽度,通过将循环初始值0加格子边框距离边界的像素值,小于这个像素值加总的格子的宽度,最后内外层循环各循环16次,再根据这个像素值区分鼠标当前坐标所在的格子区域的xy坐标,当鼠标点击左键时在对应xy处画出对应图片。

    具体详细做法清查看代码。

    使用到知识点:
    三维二维数组,写入文件,函数之间相互调用,EGE相关操作

    难点:
    EGE各种函数的使用
    函数之间相互调用
    根据按键改变数组中的值
    编辑器循环确定鼠标对应网格坐标(不在左上角的情况)

    说明:
    在写程序的过程中,因为比较赶进度,所以在ege函数的用法和代码规范上可能存在较多缺陷,还请大家多多包涵。

    如需要程序需要的图片素材请对我留言。

    注意:

    因为该程序需要用到ege库函数,所以在编译使用该代码之前需要配置ege图形库
    并使用c++编译器进行性编译。

    如果要在VS之外的编译环境编译,需要将
    文件打开函数fopen_s(&fp, buff, “w”);更改为fp = fopen(buff, “w”);
    fprintf_s更改为fprintf fprintf_s()更改为fprintf

    代码实现:
    #include <graphics.h>       //ege
    #include <ege/sys_edit.h>   //输入
    #include <stdio.h>  //文件操作
    
    #define LEUPINX 0      //地图最左上角X坐标
    #define LEUPINY 0      //地图最左上角Y坐标
    #define N 16           //地图的宽高
    
    //设置图像对象图像大小函数:setimage();
    //参数:图片对象名称,需要修改的图片对象中图片的宽高
    void setimage(PIMAGE img, int pwidth, int pheight);
    //自定义图片大小指定位置输出函数:toddback();
    //参数:图片路径,图片宽高, 图片位置xy
    void toddback(const char charr[100], int bawidth, int baheight, int backx, int backy);
    //创建图片对象,锁定图片大小为全屏
    PIMAGE tdoimage(const char charr[100]);     //背景图片数组
    
    mouse_msg msg;  //主菜单选择鼠标信息
    mouse_msg msg2; //选择游戏模式鼠标信息
    mouse_msg msg3; //游戏中返回主菜单鼠标信息
    mouse_msg msg4; //游戏中下一关鼠标信息
    mouse_msg msg5; //商城界面鼠标信息
    
    int clonum;     //初始从第几关开始游戏
    
    //关卡选择界面
    void chcheck()              //关卡选择界面
    {
        setbkmode(TRANSPARENT);
        setcolor(WHITE);
        toddback("C:\\Users\\ASUS\\Desktop\\推箱子素材\\开始游戏选择背景图.jpg", getwidth(), getheight(), 0, 0);
        //背景图与模式选择界面相同
    
        setfont(36, 0, "黑体");   //设置字体和字号
        PIMAGE backstep = newimage();         //为文本背景图片创建新的对象
        getimage(backstep, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\用于关卡选择界面.png");//步数信息文本背景图片
        setimage(backstep, 200, 55);       //设置背景图片大小
        putimage(50, 70, backstep);        //在指定位置画出图片
        //一行四个按钮                     //一个按钮宽度200,高度55,上边距70,左边距50,标准
        outtextxy(95, 80, "第一关");
    
        putimage(100 + 200, 70, backstep); outtextxy(95 + 250, 80, "第二关");    //第二关
        putimage(150 + 400, 70, backstep); outtextxy(95 + 500, 80, "第三关");
        putimage(200 + 600, 70, backstep); outtextxy(95 + 750, 80, "第四关");   
        putimage(50, 210, backstep); outtextxy(95, 80 + 140, "第五关");
        putimage(100 + 200, 210, backstep); outtextxy(95 + 250, 80 + 140, "第六关");
        putimage(150 + 400, 210, backstep); outtextxy(95 + 500, 80 + 140, "第七关");
        putimage(200 + 600, 210, backstep); outtextxy(95 + 750, 80 + 140, "第八关");
        putimage(50, 350, backstep); outtextxy(95, 80 + 280, "第九关");
        putimage(100 + 200, 350, backstep); outtextxy(95 + 250, 80 + 280, "第十关");
        putimage(150 + 400, 350, backstep); outtextxy(95 + 482, 80 + 280, "第十一关");
    
        delimage(backstep);               //用完图片对象需要释放
    
        while (true)
        {
            msg2 = getmouse();
    
            if (msg2.is_move())          //第二条鼠标点击并移动后break,继续
                break;
            delay_fps(59);
        }
    
        while (true)                    //鼠标点击开始游戏按钮时进入下一步
        {
            msg2 = getmouse();
    
            if (msg2.x >= 50 && msg2.y >= 70 && msg2.x <= 250 && msg2.y <= 125)
                if (msg2.is_left()) { clonum = 1; break; }  //第一关开始
    
            if (msg2.x >= 300 && msg2.y >= 70 && msg2.x <= 500 && msg2.y <= 125)
                if (msg2.is_left()) { clonum = 2; break; }
    
            if (msg2.x >= 550 && msg2.y >= 70 && msg2.x <= 750 && msg2.y <= 125)
                if (msg2.is_left()) { clonum = 3; break; }
    
            if (msg2.x >= 800 && msg2.y >= 70 && msg2.x <= 1000 && msg2.y <= 125)
                if (msg2.is_left()) { clonum = 4; break; }
    
            if (msg2.x >= 50 && msg2.y >= 210 && msg2.x <= 250 && msg2.y <= 265)
                if (msg2.is_left()) { clonum = 5; break; }
    
            if (msg2.x >= 300 && msg2.y >= 210 && msg2.x <= 500 && msg2.y <= 265)
                if (msg2.is_left()) { clonum = 6; break; }
    
            if (msg2.x >= 550 && msg2.y >= 210 && msg2.x <= 750 && msg2.y <= 265)
                if (msg2.is_left()) { clonum = 7; break; }
    
            if (msg2.x >= 800 && msg2.y >= 210 && msg2.x <= 1000 && msg2.y <= 265)
                if (msg2.is_left()) { clonum = 8; break; }
    
            if (msg2.x >= 50 && msg2.y >= 350 && msg2.x <= 250 && msg2.y <= 405)
                if (msg2.is_left()) { clonum = 9; break; }
    
            if (msg2.x >= 300 && msg2.y >= 350 && msg2.x <= 500 && msg2.y <= 405)
                if (msg2.is_left()) { clonum = 10; break; }
    
            if (msg2.x >= 550 && msg2.y >= 350 && msg2.x <= 750 && msg2.y <= 405)
                if (msg2.is_left()) { clonum = 11; break; }
            //循环?
            delay_fps(100);
        }
    }
    //关卡选择界面
    
    //选择模式界面
    void selsch()
    {
        setbkmode(TRANSPARENT);
        setcolor(WHITE);
        toddback("C:\\Users\\ASUS\\Desktop\\推箱子素材\\开始游戏选择背景图.jpg", getwidth(), getheight(), 0, 0);
    
        //新游戏文字
        PIMAGE degnewbuttback = newimage();//为背景图片创建新的对象
        getimage(degnewbuttback, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\选择界面标准.png");            //步数信息文本背景图片
        setimage(degnewbuttback, 250, 70); //设置背景图片大小
        putimage_withalpha(NULL, degnewbuttback, 404, 90);//输出位置
        delimage(degnewbuttback);                //用完图片对象需要释放
    
    
        setcolor(WHITE);                //文字颜色白色
        setfont(36, 0, "黑体");         //文字自号和字体,第二个参数默认0
        outtextxy(454, 106, "新 游 戏");//输出“开始游戏”文字
        //新游戏文字
    
        //选择关卡文字
        PIMAGE degifbuttback = newimage();//为背景图片创建新的对象
        getimage(degifbuttback, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\选择界面标准.png");
        setimage(degifbuttback, 250, 70); //设置背景图片大小
        putimage_withalpha(NULL, degifbuttback, 404, 270);//输出位置
        delimage(degifbuttback);        //用完图片对象需要释放
    
        setcolor(WHITE);                //文字颜色白色
        setfont(36, 0, "黑体");         //文字自号和字体,第二个参数默认
        outtextxy(454, 286, "选择关卡");//输出“开始游戏”文字
        //选择关卡文字
    
        while (true)
        {
            msg = getmouse();
    
            if (msg.is_move())          //鼠标移动时move为1,所以必须在鼠标移动后再次点击按钮才能代表第二条鼠标消息
                break;
            delay_fps(60);
        }
    
        while (true)                    //鼠标点击开始游戏按钮时进入下一步
        {
            msg2 = getmouse();
    
            if (msg2.x >= 404 && msg2.y >= 90 && msg2.x <= 404 + 250 && msg2.y <= 90 + 70)//鼠标移动到指定范围时
                                        //这个范围是背景图片xy到背景图片xy+背景图片的宽高                      
                if (msg2.is_left())     //鼠标左键点击时
                {
                    clonum = 1;         //选择新游戏从第一关开始
                    break;
                }
    
            if (msg2.x >= 404 && msg2.y >= 270 && msg2.x <= 404 + 250 && msg2.y <= 270 + 70)
                if (msg2.is_left())
                {
                    chcheck();          //关卡选择
    
                    break;
                }
    
            delay_fps(60);     //平均延迟1000/fps毫秒,用于稳定帧率控制
        }
    
    }
    //选择模式界面结束
    
    //游戏商城界面
    int figure;         //人物形象变量
    double money = 5.0; //游戏资金变量
    
    void gamall()       //游戏商城界面
    {
        toddback("C:\\Users\\ASUS\\Desktop\\推箱子素材\\商城背景4.jpg", 1543, getheight(), 0, 0);
    
        toddback("C:\\Users\\ASUS\\Desktop\\推箱子素材\\派大星2.png", 283, 280, 50, 105);
        toddback("C:\\Users\\ASUS\\Desktop\\推箱子素材\\喜洋洋1.jpg", 250, 280, 420, 105);
        toddback("C:\\Users\\ASUS\\Desktop\\推箱子素材\\源氏商城图.jpg", 220, 280, 740, 105);
    
        setfont(32, 0, "微软雅黑");
        setfontbkcolor(BLACK);
        setbkmode(OPAQUE);      //文字背景不透明
        setcolor(YELLOW);
        outtextxy(120, 410, "价格:免费");
        outtextxy(470, 410, "价格:免费");
        outtextxy(770, 410, "价格:200元");
    
        outtextxy(120, 480, "正在使用");
        outtextxy(470, 480, "使用          ");
        outtextxy(770, 480, "购买          ");
    
    
        xyprintf(0, 60, "剩余资产:%.2lf 元", money);
    
        toddback("C:\\Users\\ASUS\\Desktop\\推箱子素材\\返回按钮.png", 50, 50, 0, 0);
    
        toddback("C:\\Users\\ASUS\\Desktop\\推箱子素材\\用于关卡选择界面.png", 200, 50, 850, 0);
        setbkmode(1);      //文字背景透明
        setcolor(WHITE);
        outtextxy(900, 10, "开始游戏");
    
        int op = 0;         //没有1购买过高级形象op为0
    
        setbkmode(OPAQUE);      //文字背景不透明
        setcolor(YELLOW);
        while (true)                    //鼠标点击开始游戏按钮时进入下一步
        {
            msg5 = getmouse();
    
            if (msg5.x >= 0 && msg5.y >= 0 && msg5.x <= 50 && msg5.y <= 50) 
                if (msg5.is_left())     //鼠标左键点击时
                {
                    void gamegoint();
                    gamegoint();        //主菜单界面
                    break;
                }
            
            if (msg5.x >= 470 && msg5.y >= 0 && msg5.x <= 1050 && msg5.y <= 50)
                if (msg5.is_left())     //鼠标左键点击时
                {
                    selsch();           //选择模式界面
                    break;
                }
    
            if (msg5.x >= 120 && msg5.y >= 480 && msg5.x <= 120 + 130 && msg5.y <= 480 + 32)
                if (msg5.is_left())     //鼠标左键点击时
                {
                    op = 0;
                    figure = 0;
                    outtextxy(120, 480, "              "); outtextxy(120, 480, "正在使用");
                    outtextxy(470, 480, "使用          "); outtextxy(770, 480, "使用          ");
                }
            if (msg5.x >= 470 && msg5.y >= 480 && msg5.x <= 470 + 130 && msg5.y <= 480 + 32)
                if (msg5.is_left())     //鼠标左键点击时
                {
                    op = 0;     //op控制是否可以点击源氏形象下方使用按钮
                    figure = 1;
                    outtextxy(470, 480, "              "); outtextxy(120, 480, "使用          ");
                    outtextxy(470, 480, "正在使用"); outtextxy(770, 480, "使用          ");
                }
            if (msg5.x >= 770 && msg5.y >= 480 && msg5.x <= 770 + 130 && msg5.y <= 480 + 32)
                if (msg5.is_left())     //鼠标左键点击时
                {
                    if (money < 200)
                    {
                        outtextxy(770, 550, "资金不足");
                        continue;               //点击购买按钮,如果游戏资金小于200则重新循环
                    }
                    
                    if (op) continue;           //如果已经购买过一次则直接进入下一次循环
                    outtextxy(770, 550, "已购买    ");
                    money -= 200;               //购买形象后,资金-200
                    xyprintf(0, 60, "剩余资产:%.2lf 元", money);
    
                    figure = 2;
                    outtextxy(770, 480, "              "); outtextxy(120, 480, "使用          ");
                    outtextxy(470, 480, "使用          "); outtextxy(770, 480, "正在使用");
                    op = 1;                     //购买过op为1
                }
    
            delay_fps(90);
        }
        
    }
    
    #define MAXP 11      //最大关数
    int mapbox[MAXP][N][N] =                       //三维数组
    {
        {       //第一关
          {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, 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},
          {0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0},
          {0, 0, 0, 0, 0, 0, 1, 9, 1, 1, 1, 1, 0, 0, 0, 0},
          {0, 0, 0, 0, 1, 1, 1, 3, 9, 3, 2, 1, 0, 0, 0, 0},
          {0, 0, 0, 0, 1, 2, 9, 3, 4, 1, 1, 1, 0, 0, 0, 0},
          {0, 0, 0, 0, 1, 1, 1, 1, 3, 1, 0, 0, 0, 0, 0, 0},
          {0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0},
          {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, 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, 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, 0, 0, 0, 0, 0, 0, 1, 2, 1, 0, 0, 0, 0, 0, 0},
          {0, 0, 0, 0, 1, 1, 1, 1, 3, 1, 1, 0, 0, 0, 0, 0},
          {0, 0, 0, 1, 9, 9, 9, 9, 9, 9, 9, 1, 0, 0, 0, 0},
          {0, 0, 1, 9, 9, 1, 1, 1, 9, 9, 9, 9, 1, 0, 0, 0},
          {0, 0, 1, 9, 2, 9, 9, 9, 2, 9, 9, 9, 1, 0, 0, 0},
          {0, 0, 1, 9, 9, 9, 9, 9, 9, 9, 1, 9, 1, 0, 0, 0},
          {0, 0, 1, 9, 1, 3, 1, 9, 9, 3, 9, 9, 1, 0, 0, 0},
          {0, 0, 1, 9, 1, 9, 1, 9, 1, 1, 1, 9, 1, 0, 0, 0},
          {0, 0, 1, 4, 1, 9, 9, 9, 9, 9, 9, 9, 1 ,0, 0 ,0},
          {0, 0, 1, 1, 1, 1, 1, 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, 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, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 1, 9, 9, 9, 1, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 1, 2, 9, 9, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 1, 9, 4, 1, 1, 9, 3, 2, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 9, 9, 9, 1, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 1, 1, 9, 9, 1, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 1, 9, 3, 2, 1, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 1, 9, 9, 9, 3, 9, 1, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 1, 9, 9, 1, 9, 1, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 0, 1, 9, 9, 9, 1, 0, 0, 0, 0},
            {0, 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, 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, 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, 1, 1, 9, 9, 9, 1, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 2, 3, 9, 1, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 2, 1, 3, 3, 9, 9, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 9, 1, 9, 2, 1, 9, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 9, 4, 3, 9, 1, 2, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 1, 9, 9, 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, 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, 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, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 9, 9, 1, 1, 1, 9, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 2, 3, 2, 1, 9, 9, 9, 1, 0, 0, 0},
            {0, 0, 1, 9, 9, 3, 1, 1, 9, 3, 9, 1, 0, 0, 0, 0},
            {0, 1, 1, 9, 3, 9, 9, 9, 9, 4, 9, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 2, 1, 1, 2, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 1, 0, 0, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0},
            {0, 0, 1, 9, 3, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0},
            {0, 0, 1, 9, 3, 9, 1, 9, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 1, 9, 3, 9, 9, 9, 0, 0, 1, 1, 0, 0, 0, 0},
            {0, 1, 2, 3, 2, 1, 4, 2, 2, 2, 9, 1, 0, 0, 0, 0},
            {0, 0, 1, 9, 3, 9, 1, 9, 0, 0, 1, 1, 0, 0, 0, 0},
            {0, 0, 1, 9, 3, 9, 1, 9, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 1, 9, 3, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 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, 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},
        },
        //第7关
        {
            {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, 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, 0, 0},
            {0, 0, 0, 0, 1, 2, 3, 9, 2, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 1, 9, 9, 9, 1, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 1, 1, 9, 9, 9, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 1, 3, 1, 4, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 1, 9, 9, 9, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 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, 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},
        },
        //8
        {
            {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, 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, 1, 1, 1, 1, 0, 0, 0},
            {0, 0, 0, 1, 9, 9, 9, 1, 9, 9, 9, 2, 1, 0, 0, 0},
            {0, 0, 0, 1, 9, 9, 3, 2, 1, 9, 9, 9, 1, 0, 0, 0},
            {0, 0, 0, 1, 9, 1, 9, 1, 9, 9, 9, 9, 1, 0, 0, 0},
            {0, 0, 0, 1, 4, 9, 9, 1, 3, 9, 9, 9, 1, 0, 0, 0},
            {0, 0, 0, 1, 1, 9, 9, 1, 9, 9, 1, 1, 1, 0, 0, 0},
            {0, 0, 0, 0, 1, 9, 9, 9, 9, 9, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 1, 9, 9, 9, 9, 1, 0, 0, 0, 0, 0},
            {0, 0, 0, 0, 0, 0, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
        },
        //9
        {
            {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, 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, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 9, 9, 9, 9, 9, 2, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 9, 9, 9, 9, 9, 9, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 9, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 9, 9, 9, 9, 9, 9, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 9, 9, 9, 9, 9, 9, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 1, 1, 1, 9, 9, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 3, 9, 9, 9, 9, 9, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 4, 9, 9, 9, 9, 9, 9, 1, 0, 0, 0, 0},
            {0, 0, 0, 1, 1, 1, 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},
        },
        //10
    
        {
            {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, 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, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 2, 1, 2, 9, 9, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 3, 1, 3, 1, 9, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 1, 9, 1, 9, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 9, 1, 9, 1, 3, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 4, 9, 9, 1, 2, 1, 0, 0, 0, 0, 0, 0},
            {0, 0, 0, 1, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
            {0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0},
            {0, 0, 1, 9, 9, 2, 1, 2, 1, 9, 9, 9, 2, 1, 0, 0},
            {0, 0, 1, 1, 1, 9, 9, 3, 1, 1, 9, 1, 9, 1, 0, 0},
            {0, 0, 1, 9, 9, 9, 1, 9, 9, 9, 3, 9, 9, 1, 0, 0},
            {0, 0, 1, 9, 3, 9, 1, 1, 9, 1, 1, 1, 9, 1, 0, 0},
            {0, 0, 1, 2, 1, 3, 9, 3, 2, 9, 9, 9, 9, 1, 0, 0},
            {0, 0, 1, 1, 1, 9, 1, 9, 1, 1, 9, 9, 1, 1, 0, 0},
            {0, 0, 1, 9, 9, 9, 1, 3, 9, 9, 1, 9, 9, 1, 0, 0},
            {0, 0, 1, 9, 1, 1, 9, 2, 1, 9, 1, 9, 9, 1, 0, 0},
            {0, 0, 1, 9, 9, 1, 9, 1, 1, 9, 9, 1, 9, 1, 0, 0},
            {0, 0, 1, 4, 9, 3, 9, 9, 3, 2, 9, 9, 2, 1, 0, 0},
            {0, 0, 1, 1, 1, 1, 1, 1, 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},
        },
    };
    
    int maptemp[N][N];          //一个临时的地图数组,最后将这个数组中的值保存进文件中
    //编辑器界面
    void editmap()              //地图编辑器函数
    {
        toddback("C:\\Users\\ASUS\\Desktop\\推箱子素材\\OW背景2.jpg", getwidth()+70, getheight(), 0, 0);//背景
        //获取地图需要用到的图片
        PIMAGE floimg2 = newimage(); PIMAGE walimg2 = newimage(); PIMAGE perimg2 = newimage(); PIMAGE boximg2 = newimage(); PIMAGE tarimg2 = newimage();
        getimage(floimg2, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\石质地板.png");
        getimage(walimg2, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\手绘树木_3.png");
        switch (figure) { case 0: getimage(perimg2, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\派大星实心.png"); break;
        case 1: getimage(perimg2, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\喜洋洋2.png");    break;
        case 2: getimage(perimg2, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\源氏皮肤.png");   break; } 
        getimage(boximg2, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\单个箱子.png"); 
        getimage(tarimg2, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\五角星实心.png"); 
        setimage(walimg2, 34, 34);
        setimage(floimg2, 34, 34); setimage(perimg2, 34, 34); setimage(boximg2, 34, 34); setimage(tarimg2, 34, 34);
        PIMAGE bkzkd2 = newimage();
        getimage(bkzkd2, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\不可走空地代替.png"); setimage(bkzkd2, 34, 34);
    
        //rectangle(0, 590, 34, 624);       //空白矩形
        //用于输出屏幕下方工具图片
        putimage(0, 590, bkzkd2);
        putimage(50, 590,walimg2); putimage(100, 590, tarimg2); putimage(150, 590, boximg2);
        putimage(200, 590, perimg2); putimage(250, 590, floimg2);
    
        //文字说明
        setfont(20, 0, "楷体");
        xyprintf(5,480,"第一个工具代表不可走空地,");
        xyprintf(5, 500, "在游戏中的显示效果为不显示,");
        xyprintf(5, 520, "编辑器中可省略不写,");
        xyprintf(5, 540, "但可走空地工具:第六个工具");
        xyprintf(5, 560, "在设计地图时不可以遗忘!");
    
        //返回按钮
        toddback("C:\\Users\\ASUS\\Desktop\\推箱子素材\\返回按钮.png", 50, 50, 0, 60);
    
    
        int cinst = 0;                  //控制使用工具变量,用于控制allimg等于不同的图片对象
    
        PIMAGE allimg = perimg2;        //图片对象变量
    
        //用于输出网格
        for (int i = 1; i < 18; i++)
            for (int j = 10; j < 26; j++)
                rectangle(9 * 34, 3 * 34, j * 34, i * 34);
    
    
        mouse_msg msg6;
        setfillcolor(WHITE);
        setbkmode(1);
    
        setfont(40, 0, "楷体");
        setcolor(WHITE);
        int x = 0, y = 0;
    
        setfillcolor(BLACK);
    
        while (true)                //在主界面点击结束鼠标又移动后,编辑器界面鼠标点击世界才会生效
        {
            msg5 = getmouse();
            if (msg5.is_move())
                break;
            delay_fps(60);
        }
    
        sys_edit editBox;           //创建输入框 类
    
        editBox.create(true);       //设置输入框是否为多行,true表示是多行
    
        editBox.move(325, 195);     //输入框位置
        editBox.size(400, 250);     //输入框大小
        editBox.setfont(24, 0, "宋体");//输入框内文本属性
        editBox.visable(true);      //设置输入框可见,默认不可见
        editBox.setfocus();         //设置输入框获取焦点
        const int buffSize = 100;   //文本输入框需要的格式
        char buff[100] = {0};       //从文本框输入的内容会被保存到这个字符数组里
        editBox.settext("请清空该段文字后,输入正确的需要将地图保存到的文件路径,否则将导致程序出错并无法保存创建的地图!");
    
        bool flag_press = false;      //标记是否按下
        int bufflen = 0;                //记录字符数组的长度
    
        for (; is_run(); delay_fps(60)) {       //获取字符数组中的数
            if (keystate(key_enter)) {
                if (!flag_press) {
                    //获取输入框内容字符串
                    editBox.gettext(buffSize, buff);
    
                    bufflen = strlen(buff);
    
                    editBox.settext("");
                    break;
                }
                flag_press = true;
            }
            else {
                flag_press = false;
            }
        }
        editBox.visable(false);     //设置输入框不可见
    
        buff[bufflen - 2] = '\0';   //三条\0缺一不可,因为字符数组长度的最后使错误的转义字符,
        buff[bufflen - 1] = '\0';   //会导致寻找文件路径错误!!
        buff[bufflen] = '\0';
    
        while (true)
        {
            msg6 = getmouse();      //获取编辑器界面内的鼠标信息
    
            if (msg6.x >= 0 && msg6.y >= 590 && msg6.x <= 34 && msg6.y <= 624)          //根据点击的不同的区域来改变控制
            { if (msg.is_left()) { cinst = 0; } }
            if (msg6.x >= 50 && msg6.y >= 590 && msg6.x <= 34+50 && msg6.y <= 624)      //对象的变量以控制输出的对象
            { if (msg.is_left()) { cinst = 1; } }
            if (msg6.x >= 100 && msg6.y >= 590 && msg6.x <= 34+100 && msg6.y <= 624)
            { if (msg.is_left()) { cinst = 2; } }
            if (msg6.x >= 150 && msg6.y >= 590 && msg6.x <= 34+150 && msg6.y <= 624)    
            { if (msg.is_left()) { cinst = 3; } }
            if (msg6.x >= 200 && msg6.y >= 590 && msg6.x <= 34+200 && msg6.y <= 624)    
            { if (msg.is_left()) { cinst = 4; } }
            if (msg6.x >= 250 && msg6.y >= 590 && msg6.x <= 34+250 && msg6.y <= 624)    
            { if (msg.is_left()) { cinst = 9; } }
    
            if (cinst == 0) allimg = bkzkd2;        //根据变量不同的值来改变cinst引用的对象
            if (cinst == 1) allimg = walimg2;        
            if (cinst == 2) allimg = tarimg2;
            if (cinst == 3) allimg = boximg2;
            if (cinst == 4) allimg = perimg2;
            if (cinst == 9) allimg = floimg2;
    
    
            int i, j;                               //用于循环和确定格子的变量
            //实现像素和网格意义对应的效果,544为网格总宽度
            if (msg6.x >= 9 * 34 && msg6.y >= 34 && msg6.x <= 544 + 9 * 34 && msg6.y <= 544 + 34)
            {
                for (i = 34; i < 544 + 34; i += 34)
                    for (j = 9 * 34; j < 544 + 9 * 34; j += 34) //确定像素对应的网格
                        if (msg6.x >= j && msg6.y >= i && msg6.x <= j + 34 && msg6.y <= i + 34)
                        {
                            x = j - 9 * 34;     //减去距离边界的像素
                            y = i - 34;
                        }
                if (msg6.is_left())
                {
                    putimage(x + 9 * 34, y + 34, allimg);
                    maptemp[y / 34][x / 34] = cinst;        //将工具对应的属性值赋给对应下标的地图数组内容
                }
            }
    
            bar(20, 0, 140, 50);        //清除痕迹
            xyprintf(20, 10, "%d  %d", x / 34, y / 34);
    
            if (msg6.x >= 0 && msg6.y >= 60 && msg6.x <= 50 && msg6.y <= 110)
                if(msg6.is_left())                  //点击返回按钮break
                    break;
    
            delay_fps(100);
        }
    
    
        FILE* fp = NULL;       //定义文件指针
        
        fopen_s(&fp, buff, "a+");
    
        fprintf(fp, "{\n");
    
        for (int i = 0; i < N; i++)     //将地图信息以数组专属格式写入文件
        {
            fprintf(fp, "{");
            for (int j = 0; j < N; j++)
            {
                if (j == N - 1)
                    fprintf(fp, "%d", maptemp[i][j]);
                else
                    fprintf(fp, "%d, ", maptemp[i][j]);
            }
            fprintf(fp, "},\n");
        }
        fprintf(fp, "},\n");
    
        fclose(fp);                     //操作完文件之后关闭文件
        //创建完新的地图后需要手动将保存到文件中的地图数据复制到代码的三维数组中
    
        //释放对象
        delimage(floimg2);      //释放图片对象
        delimage(walimg2); 
        delimage(perimg2); 
        delimage(boximg2); 
        delimage(tarimg2); 
        //delimage(allimg);     //释放这个的对象会导致程序错误原因不明
    
        void gamegoint();
        gamegoint();            //完成编辑后返回主菜单界面
    
    }
    //编辑器界面
    
    
    //主菜单界面
    void gamegoint()        //游戏开始界面
    {
        toddback("C:\\Users\\ASUS\\Desktop\\推箱子素材\\开局背景1_1.png", getwidth(), getheight(), 0, 0);
        //背景图片宽高为获取窗口界面宽高
    
        //推箱子文字
        setbkmode(TRANSPARENT);
        setcolor(YELLOW);
        setfont(120, 0, "微软雅黑");
        outtextxy(320, 80, " 推  箱  子");
        //推箱子文字
    
    
        //开始游戏文字
        PIMAGE gobuttback = newimage(); //为背景图片创建新的对象
        getimage(gobuttback, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\圆角2科技文本框.png");//步数信息文本背景图片
        setimage(gobuttback, 200, 50);  //设置背景图片大小
        putimage_withalpha(NULL, gobuttback, 432, 280);//输出位置
    
        setbkmode(TRANSPARENT);         //设置文字背景混合模式,一般使用文字背景色前都会加上
        setcolor(WHITE);                //文字颜色白色
        setfont(40, 0, "楷体");         //文字自号和字体,第二个参数默认0
        outtextxy(456, 286, "开始游戏");//输出“开始游戏”文字
        //开始游戏文字
    
        //游戏商城文字
        putimage_withalpha(NULL, gobuttback, 432, 380);
        outtextxy(456, 386, "游戏商城");  //输出“游戏商城”文字
        //游戏商城文字
    
        //地图编辑器文字
        putimage_withalpha(NULL, gobuttback, 432, 480);
        outtextxy(436, 486, "地图编辑器");  //输出“地图编辑器”文字
        //地图编辑器文字
    
        delimage(gobuttback);   //释放
    
        while (true)                       //鼠标点击开始游戏按钮时进入下一步
        {
            msg = getmouse();
    
            if (msg.x >= 432 && msg.y >= 280 && msg.x <= 432 + 200 && msg.y <= 280 + 50)//鼠标移动到指定范围时
                                                             //这个范围是背景图片xy到背景图片xy+背景图片的宽高                      
                if (msg.is_left())         //鼠标左键点击时  
                {
                    selsch();               //选择模式界面
                    break;
                }
            if (msg.x >= 432 && msg.y >= 380 && msg.x <= 432 + 200 && msg.y <= 380 + 50)                  
                if (msg.is_left())
                {
                    gamall();               //游戏商城界面
                    break;
                }
            if (msg.x >= 432 && msg.y >= 480 && msg.x <= 432 + 200 && msg.y <= 480 + 50)
                if (msg.is_left())
                {
                    clonum = 1;
                    editmap();               //地图编辑器界面
                    break;
                }
            delay_fps(100);     //平均延迟1000/fps毫秒,用于稳定帧率控制
        }
    
        //cleardevice();          //清除屏幕
    
    }
    //游戏主菜单界面结束
    
    
    
    void graminit()        //初始化
    {
        //setinitmode(INIT_NOBORDER, 0, 0);     //完全全屏
        //initgraph(-1, -1);
    
        initgraph(1050, 640);         //初始化图形界面
        setcaption("ege推箱子");      //初始化标题
    
        gamegoint();        //主菜单界面
    }
    
    
    //流程部分
    
    //0代表不可走空地,1代表墙,2代表未达成的目标,3代表箱子,4代表玩家,5代表已放箱子的目标,
    //6代表人暂时所在的未达成的目标,7代表人暂时所在的已达成的目标,8代表箱子暂时所在的已达成的目标
    //9代表可走空地
    
    //增添一个关卡应该做的事情:
    /*
    在关卡选择函数中将添加一个按钮并添加一个按钮点击事件:if-范围;
    将宏MAXP的值增加1,将关卡数组的值以恰当形式粘贴到三维数组最后一位
    将每关卡背景图片数组里面的图片对象加1
    */
    
    
    
    
    int i, j;                   //循环使用变量
    
    void tranmap(PIMAGE floimg, PIMAGE walimg, PIMAGE perimg, PIMAGE boximg, PIMAGE tarimg,
        PIMAGE tarimg_2,int map[N][N])//翻译并输出地图
    {//五个图片对象,空地,墙壁,箱子,目标
        for (i = 0; i < N; i++)
            for (j = 0; j < N; j++)
            {
                const int j_2 = LEUPINX + j * 40;
                const int i_2 = i * 40;
                switch (map[i][j])
                {
                case 1:
                    putimage_withalpha(NULL, walimg, j_2, i_2); //墙壁//坐标全部待定
                    break;
                case 2:
                    putimage_withalpha(NULL, tarimg, j_2, i_2); //目标
                    break;
                case 3:
                case 8:
                    putimage_withalpha(NULL, boximg, j_2, i_2); //箱子
                    break;
                case 4:
                case 6:
                case 7:
                    putimage(j_2, i_2,  perimg); //人物
                    break;
                case 5:
                    putimage_withalpha(NULL, tarimg_2, j_2, i_2); //已达成目标
                    break;
                case 9:
                    putimage_withalpha(NULL, floimg, j_2, i_2);   //9代表可走空地输出空白地板
                    break;
                default:
                    //putimage_withalpha(NULL, floimg, j_2, i_2); //0代表不可走空地,不输出
                    break;
                }
    
            }
    
    }
    
    int ststeabox(int map[][N])             //统计一张地图中未完成目标的个数
    {
        int boxternum = 0;
        for (i = 0; i < N; i++)
            for (j = 0; j < N; j++)
                if (map[i][j] == 2)
                    boxternum++;
    
        return boxternum;       //返回每一关目标的个数
    }
    
    int box_x, box_y;           //箱子的坐标
    int boxnext_x, boxnext_y;   //箱子前面的坐标
    int peonext_x, peonext_y;   //人前面的坐标
    int concustom;              //控制关卡变量
    int Boxternum;              //统计每一关目标个数变量
    int stepnum;                //统计每一关已经行走的步数
    int map_temp_last[N][N];    //用于储存人物的上一步的地图
    int degfir;                 //为0表示该关卡是第一次移动人物
    
    //0代表不可走空地,1代表墙,2代表未达成的目标,3代表箱子,4代表玩家,5代表已放箱子的目标,
    //6代表人暂时所在的未达成的目标,7代表人暂时所在的已达成的目标,8代表箱子暂时所在的已达成的目标
    //9代表可走空地
    void modarrva(int kch, int map[N][N])       //修改数组值函数,键盘值,地图
    {                                           //map地图为形参
    
        for (i = 0; i < N; i++)     //存储人物移动前上一步的地图信息
            for (j = 0; j < N; j++)
                map_temp_last[i][j] = map[i][j];
    
        int i, j;
        for (i = 0; i < N; i++)                 //遍历   i是y轴,j是x轴
            for (j = 0; j < N; j++)
            {
                if (map[i][j] != 4 && map[i][j] != 6 && map[i][j] != 7)    //找到人的位置
                    continue;
    
                switch (kch)        // 用于确定不同方向上 箱子、箱子前面、人前面的坐标
                {
                case 'w':
                    box_y = i - 1; box_x = j;           //箱子当前
                    boxnext_y = i - 2; boxnext_x = j;   //箱子前面
                    peonext_y = i - 1; peonext_x = j;   //人前面
                    break;
                case 'a':
                    box_y = i; box_x = j - 1;
                    boxnext_y = i; boxnext_x = j - 2;
                    peonext_y = i; peonext_x = j - 1;
                    break;
                case 's':
                    box_y = i + 1; box_x = j;
                    boxnext_y = i + 2; boxnext_x = j;
                    peonext_y = i + 1; peonext_x = j;
                    break;
                case 'd':
                    box_y = i; box_x = j + 1;
                    boxnext_y = i; boxnext_x = j + 2;
                    peonext_y = i; peonext_x = j + 1;
                    break;
                }
    
                //解决数组越界
                if (box_x < 0) box_x = 0; if (box_y < 0) box_y = 0; if (boxnext_x < 0) boxnext_x = 0; if (boxnext_y < 0) boxnext_y = 0;
                if (peonext_x < 0) peonext_x = 0; if (peonext_y < 0) peonext_y = 0; if (box_x > N) box_x = N; if (box_y > N) box_y = N;
                if (boxnext_x > N) boxnext_x = N; if (boxnext_y > N) boxnext_y = N; if (peonext_x > N) peonext_x = N; if (peonext_y > N) peonext_y = N;
    
                //排除大的错误
                if (map[box_y][box_x] == 3 || map[box_y][box_x] == 8)    //如果人的前边是箱子
                    if (map[boxnext_y][boxnext_x] == 1 || map[boxnext_y][boxnext_x] == 3 || map[boxnext_y][boxnext_x] == 8 || \
                        map[boxnext_y][boxnext_x] == 0)     //如果人的前边是不可行走的空地当做墙处理
                        return;     //如果箱子前边是墙或者是箱子直接结束修改函数
    
                if (map[box_y][box_x] == 1 || map[box_y][box_x] == 0)       //人的前边不能是墙
                    return;         //如果人的前边是墙直接结束修改
    
    
                stepnum++;          //人物成功移动一次则步数+1
                degfir = 1;         //成功移动后,为1,表示这一步已经不是这个关卡的第一步了
                
    
                //箱子改变
                if (map[box_y][box_x] == 3 || map[box_y][box_x] == 8)    //如果人的前边是箱子
                {
                    //箱子原地改变:
                    if (map[box_y][box_x] == 3)       //如果箱子所在的位置是 一般箱子 
                        map[box_y][box_x] = 9;        //改变为空地
                    else if (map[box_y][box_x] == 8)  //如果箱子所在的位置是 箱子暂时所在已达成的目标
                        map[box_y][box_x] = 5;        //改变为已达成的目标
    
                    //箱子的下一步改变:
    
                    if (map[boxnext_y][boxnext_x] == 2)         //如果箱子前面的格子是未放箱子的目标
                    {
                        map[boxnext_y][boxnext_x] = 5;          //则该格子变为已放箱子的目标
    
                        Boxternum--;                            //箱子移动到目标上则目标数自减
    
                        if (Boxternum == 0)                     //当当前关目标数为0的时候,concustom为1,则进入下一关
                            concustom = 1;
    
                    }
                    else if (map[boxnext_y][boxnext_x] == 9)  //如果箱子前面是空地                        
                        map[boxnext_y][boxnext_x] = 3;        //则变为普通箱子
                    else if (map[boxnext_y][boxnext_x] == 5)  //如果箱子前面是已经放过箱子的目标
                        map[boxnext_y][boxnext_x] = 8;        //则变为 箱子暂时所在已达成的目标
                }
    
                //原地改变
                if (map[i][j] == 6)
                    map[i][j] = 2;    //走出去之后原地又变回2 未达成的目标
                if (map[i][j] == 7)
                    map[i][j] = 5;    //走出去之后原地又变回5 已达成的目标
                if (map[i][j] == 4)
                    map[i][j] = 9;    //走出去之后原地变回4 人的原型
    
                
                //人下一步改变
                if (map[peonext_y][peonext_x] == 9 || map[peonext_y][peonext_y] == 3)//如果他的下一步是普通箱子或者空地
                    map[peonext_y][peonext_x] = 4;        //人是 普通的人
    
                if (map[peonext_y][peonext_x] == 2)       //如果他的下一步还是未达成的目标
                    map[peonext_y][peonext_x] = 6;        //人是 人暂时所在未达成的目标
    
                if (map[peonext_y][peonext_x] == 5)       //如果人的下一步是已经达成的目标
                    map[peonext_y][peonext_x] = 7;        //人是 人暂时所在已经达成的目标
    
                goto L1;    //修改完成后不需要遍历后面的数组,直接跳出所有循环
            }
                
            
            L1:;                        //用于跳出的标签
    
    }       //修改数组值函数
    
    int map_temp[N][N];     //每关的初始临时地图
    
    void peomove(PIMAGE floimg, PIMAGE walimg, PIMAGE perimg, PIMAGE boximg, PIMAGE tarimg,         \
        PIMAGE tarimg_2, int map[N][N])       //接收键盘值控制人物移动
    {
        int i, j;
        
        char k = 0;         //键盘值
        k = getch();        //等待从键盘输入一个值
    
        switch (k)
        {
        case 'w':
        case 'a':
        case 's':
        case 'd':
            modarrva(k, map); break;    //将键盘值、地图、每关未完成目标的个数传进操控函数中
        case 'r':
    
            for (i = 0; i < N; i++)     //按下r键重启本关
                for (j = 0; j < N; j++)
                    map[i][j] = map_temp[i][j];
            stepnum = 0;                //本关步数清0
            Boxternum = ststeabox(map); //重新刷新本关目标个数
            break;
        case 'z':
    
            if (degfir != 1)            //撤回时,如果这一步是这一关卡的第一步则无法撤回
                break;
            for (i = 0; i < N; i++)
                for (j = 0; j < N; j++)
                    map[i][j] = map_temp_last[i][j];
            
            break;
        }
    
        tranmap(floimg, walimg, perimg, boximg, tarimg, tarimg_2, map);    //输出地图
    
    }
    
    int clesta[MAXP] = { 0 };
    
    void display(int thpass)         //用于输出游戏内的显示信息
    {
        setfont(40, 0, "微软雅黑");  //设置文本属性
        setcolor(WHITE);             //设置文本颜色
    
        PIMAGE mestextback = newimage();        
        getimage(mestextback, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\科技文本框2.jpg");
        setimage(mestextback, 240, 60);
        putimage(720, 80, mestextback); 
    
        xyprintf(780, 90, "第 %d 关", thpass + 1);         //第几关thpass,因为读关卡是从0开始所以+1
    
        putimage(720, 180, mestextback);                 
        xyprintf(780, 190, "步数:%d",stepnum);            //在指定位置输出格式化字符串,步数
    
        putimage(720, 280, mestextback);
        xyprintf(740, 290, "目标数量:%d", Boxternum);     //本关剩余目标个数
    
        if (!Boxternum)
            clesta[thpass] = 1;            //如果本关目标数为0则,本关状态为已通过
    
        putimage(720, 380, mestextback);
        if(!clesta[thpass]) xyprintf(740, 390, "状态:未通过");//本关通关状态
        else        xyprintf(740, 390, "状态:已通过");    
    
        putimage(720, 480, mestextback);
        xyprintf(740, 490, "    下一关 ->");     //本关剩余目标个数
    
        delimage(mestextback);
    
        toddback("C:\\Users\\ASUS\\Desktop\\推箱子素材\\返回按钮.png", 50, 50, 0, 0);
        //返回主菜单按钮
    }
    
    void process()                      //流程函数
    {
        PIMAGE floimg = newimage();     //创建地板的图片对象
        PIMAGE walimg = newimage();     //创建墙壁的图片对象
        PIMAGE perimg = newimage();     //创建人物的图片对象
        PIMAGE boximg = newimage();     //创建箱子的图片对象
        PIMAGE tarimg = newimage();     //创建目标的图片对象
        PIMAGE tarimg_2 = newimage();   //目标已达成状态对象
    
        getimage(floimg, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\石质地板.png");     //从文件中获取图片
        getimage(walimg, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\手绘树木_3.png");   //墙壁,图片待定
    
        switch (figure)         //根据figure获取不同的人物形象
        {
        case 0:
            getimage(perimg, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\派大星实心.png"); break;   //人物
        case 1:
            getimage(perimg, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\喜洋洋2.png");    break;
        case 2:
            getimage(perimg, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\源氏皮肤.png");   break;
        }
    
        getimage(boximg, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\单个箱子.png");     //箱子
        getimage(tarimg, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\五角星实心.png");   //目标
        getimage(tarimg_2, "C:\\Users\\ASUS\\Desktop\\推箱子素材\\单个箱子已达成状态.png");   //目标
    
        setimage(floimg, 40, 40);           //设置图像对象的大小
        setimage(walimg, 40, 40);       
        setimage(perimg, 40, 40);       
        setimage(boximg, 40, 40);       
        setimage(tarimg, 40, 40);       
        setimage(tarimg_2, 40, 40);     
    
    
        PIMAGE backbox[MAXP] = {            //背景图片数组,将每一关背景放到数组中
        tdoimage("C:\\Users\\ASUS\\Desktop\\推箱子素材\\游戏背景1_1.jpg"),
        tdoimage("C:\\Users\\ASUS\\Desktop\\推箱子素材\\SC背景1.jpg"),
        tdoimage("C:\\Users\\ASUS\\Desktop\\推箱子素材\\SC背景2.jpg"),
        tdoimage("C:\\Users\\ASUS\\Desktop\\推箱子素材\\SC背景3.jpg"),
        tdoimage("C:\\Users\\ASUS\\Desktop\\推箱子素材\\SC背景4.jpg"),
        tdoimage("C:\\Users\\ASUS\\Desktop\\推箱子素材\\SC背景5.jpg"),
        tdoimage("C:\\Users\\ASUS\\Desktop\\推箱子素材\\SC背景6.jpg"),
        tdoimage("C:\\Users\\ASUS\\Desktop\\推箱子素材\\SC背景7.jpg"),
        tdoimage("C:\\Users\\ASUS\\Desktop\\推箱子素材\\SC背景8.jpg"),
        tdoimage("C:\\Users\\ASUS\\Desktop\\推箱子素材\\SC背景9.jpg"),
        tdoimage("C:\\Users\\ASUS\\Desktop\\推箱子素材\\OW背景1.jpg"),
        };
    
        //这里的i必须为局部变量
        for (int i = clonum - 1; i < MAXP; i++)     //小于当前最大关数
        {//从初始关数-1关开始游戏,因为从三维数组里读数据是从下标0开始读的
            putimage(0, 0, backbox[i]); //输出每关背景图片
        
            tranmap(floimg, walimg, perimg, boximg, tarimg, tarimg_2, mapbox[i]); //输出每关初始地图 
    
            concustom = 0;              //没到下一关关卡,控制关卡变量为0    控制关卡变量为全局
            Boxternum = ststeabox(mapbox[i]);//统计每一关未完成的目标个数
            stepnum = 0;                //下一关卡步数清0
            degfir = 0;                 //为0表示这是该关卡第一步
            
            for (int j = 0; j < N; j++) //在开始i关卡前存储前,存储i初始关卡,用于重启本关
                for (int k = 0; k < N; k++)
                    map_temp[j][k] = mapbox[i][j][k]; 
    
            money += 100;               //关卡开始前给100资金
    
            while (true)
            {
                flushmouse();           //清空鼠标缓冲区
                delay_fps(70);          //延时、帧率
    
                display(i);             //输出游戏信息
    
                if(kbhit())
                    peomove(floimg, walimg, perimg, boximg, tarimg, tarimg_2, mapbox[i]);    //人物移动主要函数
                //参数:所有图片对象、控制关卡变量、三维地图数组     
    
                if (mousemsg())
                {
                    msg3 = getmouse();      //返回主界面鼠标信息
                    msg4 = getmouse();      //进入下一关鼠标信息
                    if (msg3.x >= 0 && msg3.y >= 0 && msg3.x <= 50 && msg3.y <= 50)
                        if (msg3.is_left())
                            goto F1;
                    
                    if (msg4.x >= 720 && msg4.y >= 480 && msg4.x <= 720 + 240 && msg4.y <= 480 + 60)
                    {
                        while (!msg4.is_move()) break;
                        if (msg4.is_left())
                            break;
                    }
                }
                if (concustom)          //控制进入下一关卡变量
                    break;              //当这个变量被改变为1时break,进入下一关卡
    
                money -= 0.125;           //多走一步-0.125的资金
                delay_fps(70);          
            }
            money += 60;                //过一关资金加60
            delay_fps(70);
        }
    
    F1:
    
        delimage(floimg);
        delimage(walimg);
        delimage(perimg);
        delimage(boximg);
        delimage(tarimg);
        delimage(tarimg_2);
    
        
    }
    
    int main()          //主函数
    {
        
        graminit();     //程序初始化
    
        while (true)
        {
            process();   //流程函数
            gamegoint(); //主菜单界面
        }
    
        closegraph();           //关闭图形界面
        return 0;
    }
    
    PIMAGE tdoimage(const char charr[100])
    {
        PIMAGE txtbackstepnum = newimage();         //为文本背景图片创建新的对象
        getimage(txtbackstepnum, charr);            //步数信息文本背景图片
        setimage(txtbackstepnum, getwidth(), getheight());//设置背景图片大小
        return txtbackstepnum;
    }
    
    
    //自定义图片大小指定位置输出函数:toddback();
    //参数:背景图片路径,背景图片宽高, 背景图片位置xy
    void toddback(const char charr[100], int bawidth, int baheight, int backx, int backy)
    {
        PIMAGE txtbackstepnum = newimage();         //为文本背景图片创建新的对象
        getimage(txtbackstepnum, charr);            //步数信息文本背景图片
        setimage(txtbackstepnum, bawidth, baheight);//设置背景图片大小
        putimage(backx, backy, txtbackstepnum);     //在指定位置画出图片
        delimage(txtbackstepnum);
    }
    
    
    //设置图像对象图像大小函数:setimage();
    //参数:图片对象名称,需要修改的图片对象中图片的宽高
    void setimage(PIMAGE img, int pwidth, int pheight)      
    {
        int whidth = getwidth(img), height = getheight(img);//获取当前img图像对象的宽高
    
        PIMAGE img_2 = newimage(pwidth, pheight);           //创建一个新的图像对象,这个新的图像对象的宽高为
                                                            //要重新设置的图像的宽高
    
        putimage(img_2, 0, 0, pwidth, pheight, img, 0, 0, whidth, height);//将原本img中的图像拉伸绘制到img_2中
    
        getimage(img, img_2, 0, 0, pwidth, pheight);        //img再获取img_2中的图像
    
        delimage(img_2);  //使用完毕将释放掉
        //该函数可以直接修改图片对象,因为这是引用
    }
    
    

    不足之处和反思:
    关于内存管理方面的知识我掌握的并不是很好,因此在写程序的过程中还闹出过几次笑话。
    我在写程序的过程中遇到的两个我曾经认为比较大的问题,后来被证明全都是其他地方、并且我早已想到只是没有去解决的问题。

    虽然我解决了程序中大部分的问题,但是该程序在内存管理和其他方面还肯定存在着很多其他问题。

    ege的库函数大部分是使用c++写的,如:类、对象、函数重载等。这些概念在c语言中并不存在。
    在完成这么一个稍显复杂的小程序后,我发现用c面向过程的方法去写稍大的程序会非常复杂,且代码复用率低。且通过写这个程序又暴露了部分我在一些方面的不足。
    所以综上考虑,在巩固完基础知识和学习完面向对象程序设计方法之前,我不会再用C语言写一些其他花里胡哨的程序了。

    欢迎大家在评论区对我的程序提出意见和建议。


    感谢您阅读了这篇文章。

    最后,感谢所有愿意对我提出批评和建议的人,您的支持是我坚持下去的强大动力。

    展开全文
  • C语言实现推箱子游戏完整代码

    千次阅读 多人点赞 2020-12-17 17:28:43
    C语言实现推箱子游戏完整代码 前言 自己做的,可能有些代码不够工整,或者有些小问题,但游戏的基本操作是可以实现的 代码效果 代码一共分为8个部分,4个控制上下左右移动,2个判断输赢,1个统计归为的个数,一个...

    C语言实现推箱子游戏完整代码

    前言

    自己做的,可能有些代码不够工整,或者有些小问题,但游戏的基本操作是可以实现的

    代码效果

    在这里插入图片描述

    代码一共分为8个部分,4个控制上下左右移动,2个判断输赢,1个统计归为的个数,一个作图。

    手动设置地图

    用’0’表示空格,“1”表示墙,“2”表示箱子,“3”表示人,“4”表示终点

    这样可以提高代码的移植性

    如需改为手动输入地图可以直接定义一个二维数组,在给他赋值就可以了

    int screen[9][11]={
    	{0,1,1,1,1,1,1,1,1,0,0},
    	{0,1,0,0,0,1,0,0,0,1,0},
    	{0,1,0,2,2,2,2,2,0,1,0},
    	{0,1,0,2,0,2,0,2,0,1,1},
    	{0,1,0,0,0,3,0,0,2,0,1},
    	{1,1,0,1,1,1,1,0,2,0,1},
    	{1,0,4,4,4,4,4,1,0,0,1},
    	{1,0,4,4,4,4,4,0,0,1,1},
    	{1,1,1,1,1,1,1,1,1,1,0}
    };//定义为全局变量 (地图) i表示行,j表示列 
    

    计算地图中终点的个数

    这一步主要是为了后面判断游戏输赢的

    int cum(){
    	int i,j,k=0;
    	for(i=0;i<9;i++){
    		for(j=0;j<11;j++){
    			if(screen[i][j]==2){
    				k++;
    			}
    		}
    	}//遍历整个二维数组
    	return k;
    }//计算地图中有多少个终点
    

    打印地图函数

    通过switch函数对二维数组中的值进行可视化,也就是画出地图

    注意:这里还定义出了6和7,是通过重叠的关系来算的,就是箱子在终点上,这个位置又有箱子又有终点2个标识,所以让两个的数值加起来,方便理解,也方便后面的计算

    void print(){
    	int i,j;
    	printf("请用wsad代表上下左右来进行游戏\n");
    	for(i=0;i<9;i++){
    		for(j=0;j<11;j++){
    			switch(screen[i][j]){
    				case 0:
    					printf("  ");//空 
    					break;
    				case 1:
    					printf("■");//墙 
    					break;
    				case 2:
    					printf("★");//箱子 
    					break;
    				case 3:
    					printf("♀");//人 
    					break;
    				case 4:
    					printf("○");//终点 
    					break;
    				case 6:
    					printf("★");
    					break;//箱子和终点 
    				case 7://人和终点显示人
    					printf("♀");
    					break; 
    			}
    		}
    		printf("\n");
    	}
    }
    

    判断游戏输赢

    这里我写了2个函数,一个判断赢,一个判断输,并返回值,然后在主函数的最后面通过判断返回值来确定游戏的输赢

    判断赢

    int win(){
    	int i,j,k=0;
    	int t=0;
    	for(i=0;i<9;i++){
    		for(j=0;j<11;j++){
    			if(screen[i][j]==6){
    				k++;
    			}
    		}
    	}//遍历整个二维数组,计算箱子在终点上的个数
    	if(k==cum()){
    	t=1;
    	}//如果个数等于前面计算出的终点个数,则说明所有终点都放了箱子,说明游戏胜利
    	return t;
    } //判断赢 
    

    判断输

    int lose(){
    	int i,j;
    	int k=0;
    	for(i=0;i<9;i++){
    		for(j=0;j<11;j++){
    			if(i>0 && j>0 ){	
    			if(screen[i][j] == 2 || screen[i][j] == 6){
    				if(((screen[i-1][j] == 1 || screen[i-1][j] == 2 || screen[i-1][j] == 6) && (screen[i][j-1] == 1 || screen[i][j-1] == 2 || screen[i][j-1] == 6)) 
    				|| ((screen[i][j-1] == 1 || screen[i][j-1] == 2 || screen[i][j-1] == 6) && (screen[i+1][j] == 1 || screen[i+1][j] == 2 || screen[i+1][j] == 6))
    				|| ((screen[i+1][j] == 1 || screen[i+1][j] == 2 || screen[i+1][j] == 6) && (screen[i][j+1] == 1 || screen[i][j+1] == 2 || screen[i][j+1] == 6))
    				|| ((screen[i][j+1] == 1 || screen[i][j+1] == 2 || screen[i][j+1] == 6) && (screen[i-1][j] == 1 || screen[i-1][j] == 2 || screen[i-1][j] == 6))){
    					k++;
    				}
    			}
    		}
    		}/*这里也是遍历了整个数组,判断所有的箱子四个方向的情况,
    		如果有三个方向被堵住了说明箱子无法移动了,也表明这个箱子失效了,
    		用k来记录失效的个数,当全部失效时游戏失败
    		(这是游戏的玩法,其实有一个被堵住就已经不可能胜利了)*/
    	}
    	if(k==cum()){
    		k=1;
    	}
    	return k;//返回1说明游戏失败
    }
    

    接下来是最重要的四个控制函数

    向上移动

    通过数字的变化来控制二维数组的变化,进而控制地图的更新

    这里非常重要的就是要理解:加1,加2,加3减3都是什么意思

    加1:箱子的值是2,人的值是3,所以箱子的位置变成人需要加1来实现

    加2:空地的值是0,箱子的值是2,箱子和终点在一起的值是6,所以在推箱子的时候,前方的空格或者终点放上箱子后数值会加2

    加3减3:人的值是3,人要动的话,它原先在的格子就会因为人走了导致数值减3,走到的那个格子就会因为站了人而加3

    如果这个理解的话,代码就非常简单了

    void movew(){
    	if(x>0){
    		if(screen[x-1][y]==1){
    			return ;/*如果箱子的上面是墙,则地图不会发生变化,因为
    			推不动嘛*/
    		}else if(screen[x-1][y]==0){
    			screen[x-1][y]+=3;
    			screen[x][y]-=3;
    			x--;/*如果前面是空地,则需要向前移动一格,也就是原先人的位置
    			变成空地,前方的空地变成人,空地(0)变成人(3)需要加3,
    			人变成空地需要减3*/
    		}else if(screen[x-1][y]==4){
    			screen[x-1][y]+=3;
    			screen[x][y]-=3;
    			x--;
    		}//一样的
    		else if(screen[x-1][y]==2||screen[x-1][y]==6){
    				if(screen[x-2][y]==0){
    					screen[x-2][y]+=2;//箱子前面的格变成箱子(2)
    					screen[x-1][y]+=1;//箱子的位置变成人(3)
    					screen[x][y]-=3;/*如果前面是空地,则需要向前移动
    					一格,也就是原先是箱子的格子变成人,人的位置变成空
    					地,原先的空地变成箱子,箱子(2)变成人(3)需要减
    					3,空地变成人*/
    					x--;
    				}else if(screen[x-2][y]==1){
    					return ;
    				}else if(screen[x-2][y]==2){
    				return;//如果箱子的前面是墙或者其他的箱子,则箱子推不动
    				}else if(screen[x-2][y]==4){
    					screen[x-2][y]+=2;
    					screen[x-1][y]+=1;
    					screen[x][y]-=3;
    					x--;
    				}//这个情况别漏了
    			}
    	}
    }
    

    其他三个方向的代码思路和这个是一样的

    向下移动

    void moves(){
    	if(x<9){
    		if(screen[x+1][y]==1){
    			return ;
    		}else if(screen[x+1][y]==0){
    			screen[x+1][y]+=3;
    			screen[x][y]-=3;
    			x++;
    		}else if(screen[x+1][y]==4){
    			screen [x+1][y]+=3;
    			screen[x][y]-=3;
    			x++;
    		}
    		else if(screen[x+1][y]==2||screen[x+1][y]==6){ 
    				if(screen[x+2][y]==1){
    					return;
    				}else if(screen[x+2][y]==0){
    					screen[x+2][y]+=2;
    					screen[x+1][y]+=1;
    					screen[x][y]-=3;
    					x++;
    				}else if(screen[x+2][y]==2){
    					return ;
    				}else if(screen[x+2][y]==4){
    					screen[x+2][y]+=2;
    					screen[x+1][y]+=1;
    					screen[x][y]-=3;
    					x++;
    					}
    				}
    			}
    }
    

    向左移动

    void movea(){
    	if(y>0){
    	if(screen[x][y-1]==1){
    		return;
    	}else if(screen[x][y-1]==4){
    		screen[x][y-1]+=3;
    		screen[x][y]-=3;
    		y--;
    	}
    	else if(screen[x][y-1]==0){
    		screen[x][y-1]+=3;
    		screen[x][y]-=3;
    		y--;
    	}else if(screen[x][y-1]==2||screen[x][y-1]==6){
    			if(screen[x][y-2]==0){
    				screen[x][y-2]+=2;
    				screen[x][y-1]+=1;
    				screen[x][y]-=3;
    				y--;
    			}else if(screen[x][y-2]==1){
    				return;
    			}else if(screen[x][y-2]==2){
    				return;
    			}else if(screen[x][y-2]=4){
    				screen[x][y-2]+=2;
    				screen[x][y-1]+=1;
    				screen[x][y]-=3;
    				y--;
    			}
    		}
    }
    }
    

    向右移动

    void moved(){
    	if(y<9){
    		if(screen[x][y+1]==1){
    			return;
    		}else if(screen[x][y+1]==4){
    			screen[x][y+1]+=3;
    			screen[x][y]-=3;
    			y++;
    		}
    		else if(screen[x][y+1]==0){
    			screen[x][y+1]+=3;
    			screen[x][y]-=3;
    			y++;
    		}else 
    			if(screen[x][y+1]==2||screen[x][y+1]==6){
    				if(screen[x][y+2]==0){
    					screen[x][y+2]+=2;
    					screen[x][y+1]+=1;
    					screen[x][y]-=3;
    					y++;
    				}else if(screen[x][y+2]==4){
    					screen[x][y+2]+=2;
    					screen[x][y+1]+=1;
    					screen[x][y]-=3;
    					y++;
    				}else if(screen[x][y+2]==2){
    					return;
    				}else if(screen[x][y+2]==1){
    					return;
    				}
    			}
    		
    	}
    }
    

    主函数

    这个主函数写的有点乱,直接看注释吧

    
    int main(){
    	int n,t;
    	int j,k;
    	int b=1;
    	here:
    		system("cls");//
    	printf("开始游戏请按1\n退出游戏请按2\n"); 
    	scanf("%d",&j);
    	if(j==1){
    	printf("请用wsad代表上下左右来进行游戏\n");//这个就引导进入游戏
    	while(1){
    		system("cls");/*在每一次移动过后都清除上一个地图,不然就会每走
    		一步生成一个图*/
    		print();//先打印地图
    		scanf("%c",&n);//读入用户的操作
    		switch(n){
    			case 'w':
    				movew();
    				break;
    			case 's':
    				moves();
    				break;
    			case 'a':
    				movea();
    				break;
    			case 'd':
    				moved();
    				break;
    		} //控制人移动
    		t=win(); 
    		if(t==1){
    		goto there;
    	}//每次操作完先判断游戏是否胜利,如果胜利了直接跳到函数最后
    	if(b == lose()){
    		system("cls");
    		print();
    		printf("游戏失败");
    		return 0;
    	} //游戏失败提示
    }
    }else {
    	system("cls");
    	printf("您确认要退出游戏吗\n确认退出按1\t返回上一层按2\n"); 
    	scanf("%d",&k);
    		if(k==1){
    			printf("你已退出游戏,期待你的再次到来,谢谢"); 
    			return 0;
    		}else {
    			goto here;
    		}
    }//这一块是最前面用户进入游戏那里的,如果用户选择退出游戏执行的操作
    	there:
    		printf("恭喜你通过了游戏!");
    	return 0;
    }//主函数 
    

    所有的代码就到这里了,如果需要完整代码可以留言喔.

    展开全文
  • 推箱子这个游戏都很熟悉了,代码也熟悉了。正好我们下半学期学了栈,就尝试用栈做一个推箱子回退的功能。 返回上一步部分代码如下: if( Pop(S,x) ==1 )//若栈中有元素则Pop返回值为 1 { //若上一步是向上 if(x =...

    学校c语言设计的作业可以私信找我 我还是把完整版代码贴出来了,如果想完全省事,可以私信找我

    推箱子这个游戏都很熟悉了,代码也熟悉了。正好我们下半学期学了栈,就尝试用栈做一个推箱子回退的功能。

    返回上一步部分代码如下:

    if (Pop(S, x) == 1)
    	{
    		//若上一步是向上 
    		if (x == 'W' || x == 'w')
    		{
    			count--;
    			if (x == 'W')
    			{
    				a[i + 1][j] += 5;
    				a[i][j] -= 5;
    			}
    			else
    			{
    				a[i - 1][j] -= 4;
    				a[i + 1][j] += 5;
    				a[i][j] -= 1;
    			}
    		}
    

    其它方向的撤回类似。

    另外我的主页博客里面有添加了easyx库的推箱子,希望可以帮助大家。

    简易版推箱子全部代码如下:

    #include<stdio.h>
    #include<stdlib.h>
    #include<conio.h >
    #define maxlevel 3
    /*墙1
      目的地3 
      箱子4
      人5
      目的地上的箱子7
      站在目的地的人8*/          
    
    //所有地图
    int a1[maxlevel][13][13] = {
    	{
    				 {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,1,1,0,0,0,0,0,0},
    				 {0,0,1,0,0,0,1,0,0,0,0,0,0},
    				 {0,0,1,0,4,0,1,0,1,1,1,0,0},
    				 {0,0,1,0,4,0,1,0,1,3,1,0,0},
    				 {0,0,1,1,1,5,1,1,1,3,1,0,0},
    				 {0,0,0,1,1,4,0,0,0,3,1,0,0},
    				 {0,0,0,1,0,0,0,1,0,0,1,0,0},
    				 {0,0,0,1,0,0,0,1,1,1,1,0,0},
    				 {0,0,0,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,1,1,1,1,1,1,1,0,0,0},
    				 {1,1,1,1,0,0,0,0,0,1,0,0,0},
    				 {1,0,0,0,3,1,1,1,0,1,0,0,0},
    				 {1,0,1,0,1,0,0,0,0,1,1,0,0},
    				 {1,0,1,0,4,0,4,1,3,0,1,0,0},
    				 {1,0,1,0,0,7,0,0,1,0,1,0,0},
    				 {1,0,3,1,4,0,4,0,1,0,1,0,0},
    				 {1,1,0,0,0,0,1,0,1,0,1,1,1},
    				 {0,1,0,1,1,1,3,0,0,0,0,5,1},
    				 {0,1,0,0,0,0,0,1,1,0,0,0,1},
    				 {0,1,1,1,1,1,1,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,0,0,0,0,0,0,0,0,0},
    				 {0,0,0,0,1,1,1,1,1,1,1,0,0},
    				 {0,0,0,1,1,0,0,1,0,0,1,0,0},
    				 {0,0,0,1,0,0,0,1,0,5,1,0,0},
    				 {0,0,0,1,4,0,4,0,4,0,1,0,0},
    				 {0,0,0,1,0,4,1,1,0,0,1,0,0},
    				 {0,1,1,1,0,4,0,1,0,1,1,0,0},
    				 {0,1,3,3,3,3,3,0,0,1,0,0,0},
    				 {0,1,1,1,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},
    	}
    
    };
    int a[13][13];//当前地图
    
    
     //栈的操作,实现撤回功能
    typedef struct
    {
    	char str[1000];//最多支持1000步回退
    	int top;
    } Stack;
    //判断栈是否为空
    int IsEmpty(Stack& S)
    {
    	return (S.top == -1 ? 1 : 0);
    }
    //进栈
    void Push(Stack& S, char ch)
    {
    	S.top++;
    	S.str[S.top] = ch;
    }
    //出栈
    int Pop(Stack& S, char& x)
    {
    	if (IsEmpty(S) == 1)
    		return 0;
    	x = S.str[S.top];
    	S.top--;
    	return 1;
    }
    //以上是栈的操作
    
    //目的地的坐标
    typedef struct node
    {
    	int x, y;
    }Date;
    typedef struct
    {
    	Date d[10];//最多十个目的地。 
    	int num;//个数。 
    }Destination;
    //以上是目的地坐标的结构体
    
    Destination D;
    
    //找目的地
    void des(int a[13][13])
    {
    	int i, j, k = 0;
    	D.num = 0;
    	for (i = 0; i < 13; i++)
    		for (j = 0; j < 13; j++)
    			if (a[i][j] == 3)
    			{
    				D.num++;
    				D.d[k].x = i;
    				D.d[k++].y = j;
    			}
    }
    //以上找目的地坐标
    
    
    //制造地图
    void ditu(int a[13][13])
    {
    	int i, j;
    	for (i = 0; i < 13; i++)
    	{
    
    		for (j = 0; j < 13; j++)
    		{
    			switch (a[i][j])
    			{
    			case 0:printf("  "); break;
    			case 1:printf("■"); break;
    			case 3:printf("△"); break;
    			case 4:printf("○"); break;
    			case 5:printf("♀"); break;
    			case 7:printf("●");break;
    			case 8:printf("♀");break;
    			}
    		}
    		printf("\n");
    	}
    }
    
    //动作制造 
    int action(int a[13][13], Stack& S)
    {
    	char ch, x;
    	/*找出人5或者8()的位置*/
    	int i, j;
    	for (i = 0; i < 13; i++)
    	{
    		for (j = 0; j < 13; j++)
    		{
    			if (a[i][j] == 5 || a[i][j] == 8)
    				break;
    		}
    		if (a[i][j] == 5 || a[i][j] == 8)
    			break;
    	}
    
    	ch = getch();
    	switch (ch)
    	{
    		//撤回前一步
    	case 'R':
    	if (Pop(S, x) == 1)
    	{
    		//若上一步是向上 
    		if (x == 'W' || x == 'w')
    		{
    			if (x == 'W')
    			{
    				a[i + 1][j] += 5;
    				a[i][j] -= 5;
    			}
    			else
    			{
    				a[i - 1][j] -= 4;
    				a[i + 1][j] += 5;
    				a[i][j] -= 1;
    			}
    		}
    		//若上一步是向下 
    		if (x == 'S' || x == 's')
    		{
    			if (x == 'S')
    			{
    				a[i - 1][j] += 5;
    				a[i][j] -= 5;
    			}
    			else
    			{
    				a[i + 1][j] -= 4;
    				a[i - 1][j] += 5;
    				a[i][j] -= 1;
    			}
    		}
    		//若上一步是向左 
    		if (x == 'A' || x == 'a')
    		{
    			if (x == 'A')
    			{
    				a[i][j + 1] += 5;
    				a[i][j] -= 5;
    			}
    			else
    			{
    				a[i][j - 1] -= 4;
    				a[i][j + 1] += 5;
    				a[i][j] -= 1;
    			}
    		}
    		//若上一步是向右
    		if (x == 'D' || x == 'd')
    		{
    
    			if (x == 'D')
    			{
    				a[i][j - 1] += 5;
    				a[i][j] -= 5;
    			}
    			else
    			{
    				a[i][j + 1] -= 4;
    				a[i][j - 1] += 5;
    				a[i][j] -= 1;
    			}
    		}
    	}break;
    		//以上是撤回功能 
    
    		/*向前走*/
    	case 'W':
    		//人走
    		if (a[i - 1][j] == 0 || a[i - 1][j] == 3)
    		{
    			a[i - 1][j] += 5;
    			a[i][j] -= 5;
    			Push(S, 'W');
    		}
    		//人推箱子走 
    		if ( (a[i - 1][j] == 4 || a[i - 1][j] == 7) && (a[i - 2][j] == 0 || a[i - 2][j] == 3))
    		{
    			//if (a[i - 2][j] == 0 || a[i - 2][j] == 3)
    			//{
    				a[i - 2][j] += 4;
    				a[i - 1][j] += 1;
    				a[i][j] -= 5;
    				Push(S, 'w');
    			//}
    		} break;
    
    		/*向下走*/
    	case 'S':
    	
    		//人走
    		if (a[i + 1][j] == 0 || a[i + 1][j] == 3)
    		{
    			a[i + 1][j] += 5;
    			a[i][j] -= 5;
    			Push(S, 'S');
    		}
    		//人推箱子走 
    		if (a[i + 1][j] == 4 || a[i + 1][j] == 7)
    		{
    
    			if (a[i + 2][j] == 0 || a[i + 2][j] == 3)
    			{
    				a[i + 2][j] += 4;
    				a[i + 1][j] += 1;
    				a[i][j] -= 5;
    				Push(S, 's');
    			}
    		} break;
    
    		/*向左走*/
    	case 'A':
    		
    		//人走
    		if (a[i][j - 1] == 0 || a[i][j - 1] == 3)
    		{
    
    			a[i][j - 1] += 5;
    			a[i][j] -= 5;
    			Push(S, 'A');
    		}
    		//人推箱子走 
    		if (a[i][j - 1] == 4 || a[i][j - 1] == 7)
    		{
    			if (a[i][j - 2] == 0 || a[i][j - 2] == 3)
    			{
    				
    				a[i][j - 2] += 4;
    				a[i][j - 1] += 1;
    				a[i][j] -= 5;
    				Push(S, 'a');
    			}
    		} break;
    
    		/*向右走*/
    	case 'D':
    		
    		//人走
    		if (a[i][j + 1] == 0 || a[i][j + 1] == 3)
    		{
    			a[i][j + 1] += 5;
    			a[i][j] -= 5;
    			Push(S, 'D');
    		}
    		//人推箱子走 
    		if (a[i][j + 1] == 4 || a[i][j + 1] == 7)
    		{
    			if (a[i][j + 2] == 0 || a[i][j + 2] == 3)
    			{
    				a[i][j + 2] += 4;
    				a[i][j + 1] += 1;
    				a[i][j] -= 5;
    				Push(S, 'd');
    			}
    		} break;
    	}
    	//检测是否完成游戏
    	for (i = 0; i < D.num; i++)
    	{
    		if (a[D.d[i].x][D.d[i].y] != 7)
    			return 0;
    	}
    	return 1;
    }
    
    //开始菜单
    void startmenu()
    {
    	printf("    欢迎来到董宏浩开发的推箱子小游戏       \n");
    	printf("             更多新关卡正在开发主中...        \n");
    	printf("                  按回车开始游戏               \n");
    	getchar();
    	system("cls");
    }
    
    
    //普通模式
    void putong()
    {
    
    	int level = 0;
    
    	//普通模式
    	while (level < maxlevel)
    	{
    		//重置栈
    		Stack S = { {0},0 };
    		//给当前地图赋值
    		for (int i = 0; i < 13; i++)
    			for (int j = 0; j < 13; j++)
    				a[i][j] = a1[level][i][j];
    		//寻找目的地
    		des(a);
    	
    		while (1)
    		{	
    			ditu(a);
    			
    			if (action(a, S))
    				break;
    			
    			system("cls");
    		}
    		system("cls");
    		printf("恭喜通过次关,太厉害了,继续请按回车!!");
    		getchar();
    		system("cls");
    		
    		level++;
    	}
    	printf("恭喜你通过了所有关卡,真是太厉害了,作者都做不到!!");
    	getchar();
    	system("cls");
    }
    
    
    
    //主函数
    int main()
    {
    	//主菜单提示
    	startmenu();
    
    	putong();
    }
    
    
    
    
    展开全文
  • C语言推箱子,有地图,过关,保存,读取,选关
  • #include<stdio.h> #include<stdlib.h> #include<conio.h> /* 二维数组充当游戏地图的功能 人: ♀ 5 箱子: ★ 4 目的地: ☆ 3 箱子推到目的地: ● 7 墙: ■ 1 空地: 0
    #include<stdio.h>
    #include<stdlib.h>
    #include<conio.h>
    
    /*
        二维数组充当游戏地图的功能
        人:                ♀    5
        箱子:            ★    4
        目的地:            ☆    3
        箱子推到目的地:    ●    7
        墙:                ■    1
        空地:                0
    
        人在目的上显示:  5+3:8
    */
    int main()
    {
        //设计地图
        int cas = 0;
        int map[8][8] =
        {
            1,1,1,1,1,1,1,1,
            1,3,4,0,0,4,3,1,
            1,0,1,0,0,1,0,1,
            1,0,1,0,0,1,0,1,
            1,0,1,5,0,1,0,1,
            1,0,1,0,0,1,0,1,
            1,3,4,0,0,4,3,1,
            1,1,1,1,1,1,1,1
        };
    
        
    
        while (1)
        {
            //画地图
            for (int i = 0; i < 8; i++)
            {
                for (int j = 0;j < 8;j++)
                {
                    switch (map[i][j])
                    {
                    case 0:
                        printf("  ");    //汉字符号占用两个字节
                        break;
                    case 1:
                        printf("■");
                        break;
                    case 3:
                        printf("☆");
                        break;
                    case 4:
                        printf("★");
                        break;
                    case 5:
                    case 8:
                        printf("♀");
                        break;
                    case 7:
                        printf("●");
                        break;
                    }
                }
                printf("\n");
            }
            
            //找人的坐标---->数组的查找    5和8的值
            int i, j;
            for (i = 0;i < 8;i++)
            {
                for (j = 0;j < 8;j++)
                {
                    if (map[i][j] == 5 || map[i][j] == 8)
                    {
                        goto next;
                    }
                }
            }
        next:
            ;
    
            //胜负判断,采用标记法
            int flag = 1;
            for (int i = 0;i < 8;i++)
            {
                for (int j = 0;j < 8;j++)
                {
                    if (map[i][j] == 4)
                    {
                        flag = 0;
                        goto DOWN;
                    }
                }
            }
        DOWN:
            ;
            if (flag == 1)
            {
                printf("GameOver!\n");
                break;
            }
    
        
            //按键控制的框架
            char userKey = _getch();
            switch (userKey)
            {
            case 'W':
            case 'w':
            case 72:        //向上
                if (map[i - 1][j] == 0 || map[i - 1][j] == 3)
                {
                    map[i - 1][j] += 5;            //向上走的时候,人来啦
                    map[i][j] -= 5;                //原来的位置,人走啦
                }
                if (map[i - 1][j] == 4 || map[i - 1][j] == 7)        //箱子(4) 或者 箱子和目的地在一起(7)
                {
                    if (map[i - 2][j] == 0 || map[i - 2][j] == 3)    //空地(0) 或者 目的地(3)
                    {
                        map[i][j] -= 5;            // -5        人走啦
                        map[i - 1][j] += 1;        // +5 -4    人来啦,箱子走啦
                        map[i - 2][j] += 4;        // +4        箱子来啦
                    }
                }
                break;
            case 'S':
            case 's':
            case 80:        //向下
                if (map[i + 1][j] == 0 || map[i -+ 1][j] == 3)
                {
                    map[i + 1][j] += 5;            //向下走的时候,人来啦
                    map[i][j] -= 5;                //原来的位置,人走啦
                }
                if (map[i + 1][j] == 4 || map[i + 1][j] == 7)        //箱子(4) 或者 箱子和目的地在一起(7)
                {
                    if (map[i + 2][j] == 0 || map[i + 2][j] == 3)    //空地(0) 或者 目的地(3)
                    {
                        map[i][j] -= 5;            // -5        人走啦
                        map[i + 1][j] += 1;        // +5 -4    人来啦,箱子走啦
                        map[i + 2][j] += 4;        // +4        箱子来啦
                    }
                }
                break;
            case 'A':
            case 'a':
            case 75:        //向左
                if (map[i][j - 1] == 0 || map[i][j - 1] == 3)
                {
                    map[i][j - 1] += 5;            //向左走的时候,人来啦
                    map[i][j] -= 5;                //原来的位置,人走啦
                }
                if (map[i][j - 1] == 4 || map[i][j - 1] == 7)        //箱子(4) 或者 箱子和目的地在一起(7)
                {
                    if (map[i][j - 2] == 0 || map[i][j - 2] == 3)    //空地(0) 或者 目的地(3)
                    {
                        map[i][j] -= 5;            // -5        人走啦
                        map[i][j - 1] += 1;        // +5 -4    人来啦,箱子走啦
                        map[i][j - 2] += 4;        // +4        箱子来啦
                    }
                }
                break;
            case 'D':
            case 'd':
            case 77:        //向右
                if (map[i][j + 1] == 0 || map[i][j + 1] == 3)
                {
                    map[i][j + 1] += 5;            //向右走的时候,人来啦
                    map[i][j] -= 5;                //原来的位置,人走啦
                }
                if (map[i][j + 1] == 4 || map[i][j + 1] == 7)        //箱子(4) 或者 箱子和目的地在一起(7)
                {
                    if (map[i][j + 2] == 0 || map[i][j + 2] == 3)    //空地(0) 或者 目的地(3)
                    {
                        map[i][j] -= 5;            // -5        人走啦
                        map[i][j + 1] += 1;        // +5 -4    人来啦,箱子走啦
                        map[i][j + 2] += 4;        // +4        箱子来啦
                    }
                }
                break;
            }
    
            system("cls");
        }
    
        return 0;
    }
    

    **

    • 运行截图:

    **
    在这里插入图片描述
    **

    • 总结:

    **
    1.使用清屏cls语句时,需要引入stdlib.h头文件;

    2.使用_getch()函数时,需要引入conio.h头文件.
      getch()函数:从控制台获取一个字符,但不在控制台上显示,不用按下回车键就可以读取,区别于getchar()函数得按下回车键(enter)
      2.1. 上 下 左 右 键是两个字节的,getch()只能读取一个字节,所以得使用两次getch()
      2.2. 键盘上的上 下 左 右键的ASKII码对照: 上(72) 下(80) 左(75) 右(77)

    展开全文
  • C语言多关卡推箱子

    2018-07-02 15:15:40
    C语言多关卡推箱子,多关卡设计,胜负判断,非常适合新手得项目
  • C语言课程设计推箱子游戏报告.zip
  • C语言课程设计推箱子游戏报告.pdf
  • 自己写的推箱子游戏,用C语言写的,代码和文档都有,程序成功运行。
  • C语言编写的推箱子小游戏

    千次阅读 多人点赞 2019-06-17 18:28:26
    大一时候的期末大作业,一直没找到,...1.编写推箱子小游戏 2.使用C语言 3.使用Dev C++编程程序 4.实现小人移动判定 5.实现通关判定 实验分析 1.首先了解推箱子游戏的规则 2.使用代码完成基本的功能 3.判...
  • 推箱子地图编辑器 在写推箱子游戏程序的时候我苦于没有地图可以试验程序运行效果,去搜了好长时间都没有...但是,其他人写的推箱子地图编辑器大部分都不是C语言版本的,而我写的这一个是C版本的。 另外说明一下,...
  • C语言实现『推箱子

    2021-03-05 14:50:07
    推箱子 是我们小时候在电视机上常见的经典电子游戏,游戏要求玩家在一个狭小的仓库中,把木箱放到指定的位置,稍不小心就会出现箱子无法移动或者通道被堵住的情况,所以需要巧妙的利用有限的空间和通道,合理安排...
  • c语言小游戏之一看就会的推箱子

    万次阅读 多人点赞 2020-12-14 10:41:19
    文章目录1效果展示2:设计过程3代码 1效果展示 2:设计过程 3代码 #include "game.h" void ShowMap(char arr[][LINE])//打印地图 { for (int i = 0; i < ROW; i++) { for (int j = 0; j < LINE; j++)...
  • C语言多关卡推箱子

    千次阅读 多人点赞 2018-07-02 17:35:08
    C语言多关卡推箱子,兄台了解一下?没错,C语言完整简单项目实战 很高兴你能光临小编寒舍 首先感谢百忙之中你能从万千文章中点小编得专属页面。这不是娱乐篇,这是学习道场。开始前,小编就做一个简单得自我介绍...
  • C语言推箱子游戏.rar

    2021-01-26 09:13:19
    C语言推箱子游戏.rar
  • 班级信息093 姓名XXX 学号090810313 12 山东交通学院 C语言课程设计 推箱子游戏 院(系)别 信息工程系 班 级 信息* 学 号 * 姓 名 XXX 指导教师 * 时 间 20*-04-0620*-04-10 课 程 设 计 任 务 书 题 目 推箱子 系 ...
  • c语言实现推箱子小游戏

    千次阅读 多人点赞 2019-02-28 13:25:50
    c语言实现推箱子小游戏 下面是实现推箱子小游戏的全部代码 这个推箱子小游戏采用文件操作,通过图形库实现了图形界面,相对来说更具有玩游戏的感觉,给人以视觉盛宴。 说笑了,好了大家可以好好的看一下源代码 本...
  • 推箱子游戏.zip

    2019-09-08 09:42:13
    C语言外加资源文件写一个推箱子的游戏,带背景音乐,里边有详细的备注和设计,希望可以帮助更多的新手尽快的打好基础。(此文件仅供参考)
  • 基于Linux系统推箱子.c

    2021-01-26 11:30:13
    基于Linux系统环境下,在对标准I/O的熟练运用下,用C 语言程序设计出多关卡的推箱子小游戏。
  • 简易推箱子C语言代码

    2020-07-30 21:53:59
    在这里和大家分享一个简易的推箱子C语言代码。
  • C语言课程设计--推箱子

    千次阅读 2020-08-29 22:50:16
    C语言课程设计--推箱子一、游戏设计二、代码实现(1)方法声明(2)参数说明(3)函数的具体分析三、总结 一、游戏设计 游戏总共有分开始场景(游戏初始场景)、输入检测、碰撞检测、胜负判定、结束画面(关卡选择)...
  • 推箱子地图编辑器,供大家参考,具体内容如下 由于我在写推箱子的时候苦于没有地图可以试验程序运行效果,而且去搜了好长时间都没有找到一个储存16*16地图版本的推箱子关卡数据信息的文件。 于是想到了写了一个地图...
  • c语言推箱子小游戏

    千次阅读 多人点赞 2020-12-19 15:00:07
    文章目录1....这次代码的代码量稍微大一点,可读性没有那么强,如果看起来比较难理解,可以先看一下上次我写的比较简单的推箱子博客铺垫一下;链接: link. 2.效果展示 新添地图选择功能,返回一步功能,人
  • 1.1 C语言概述 2 1.2 Turbo C/C++ for Windows概述 2 2 程序总体设计 2 2.1 总体设计思想 2 2.2 总体设计流程图 3 3 程序详细设计 3 3.1 功能模块设计 3 3.2 数据结构设计 4 3.3 函数功能实现 4 4 程序测试 7 4.1 ...
  • 推箱子多关卡(C语言+easyX实现,详细)

    千次阅读 多人点赞 2019-09-22 23:57:14
    首先推箱子,我们最最最核心的就是怎么去推。也就是去实现移动功能,改变地图。那么,逻辑中只要考虑人怎么移动就行了。首先,人移动最简单的就是前面是空地或者目的地那么就直接把人移动过去就行了,还有一个就是...
  • C语言推箱子小程序

    2021-04-02 12:26:00
    一开始打算写象棋,后来还是觉得推箱子更经典一点。由于当时水平太差,还用的是DEV,结果肝了一天一夜才赶出来。。。各位将就着看,就图一乐就行。 代码部分 //注意本程序直接复制运行是无法实现的。原因是需要自己...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 646
精华内容 258
关键字:

c语言推箱子设计报告

c语言 订阅