精华内容
下载资源
问答
  • C语言游戏菜单界面设计游戏整合

    千次阅读 多人点赞 2020-04-22 15:53:23
    游戏菜单界面设计游戏整合 旧文档 2019.11 小时候一直觉得4399小游戏的那些游戏菜单好low,现在做完我的菜单界面回去去看看感觉还不错。。。 菜单制作过程 完整代码 https://paste.ubuntu.com/p/HZBWXMWT8K/ ...

    游戏菜单界面设计 与 游戏整合

    旧文档 2019.11

    小时候一直觉得4399小游戏的那些游戏菜单好low,现在做完我的菜单界面回去去看看感觉还不错。。。

    菜单制作过程

    完整代码

    博客代码链接
    https://paste.ubuntu.com/p/HZBWXMWT8K/

    img

    img

    img

    详细介绍:

    前言

    从走迷宫起,到五子棋,再到做完象棋,再到去学下图书馆管理系统程序设计。其实我对做游戏或管理系统不是有很大兴趣,之前觉得设计界面麻烦,觉得c语言书上那个图书馆管理系统程序好无聊,还觉得做游戏又麻烦又累,然后自从那天学会简单的wasd移动得知原来可以这么巧妙地控制小球移动后,就真香了。。。

    可能是主动去做就比被动要求去做更有兴趣些。

    菜单设计:

    • 游戏菜单系统参考:C语言书上的图书馆管理系统
    while (1) //主体程序
    {
        menu();
        char choise;
        choise = getch();
        switch (choise)
        {
        case '1':
            xiangqi(), break;   //进入象棋
        case '2':
            wuziqi(), break;    //进入五子棋
        case '3':
            more(),break;       //进入更多信息
        case '4':
            return 0;           //退出
        }
    }
    
    • 新增功能:页面加入加载效果(Sleep),实现“按任意键继续”功能(getch)。
    for (i = 0; i < 37; i++) //实现起来都挺简单
    {
        puts(map[i]);
        Sleep(100);
    }
    printf("任意键继续\n");
    getch();
    

    游戏整合:

    • 主函数只负责调用菜单界面和循环选择;
    • 菜单界面负责循环选择进入多个独立的自定义游戏函数;
    • 原来的游戏若没有调用函数则直接打包扔进自定义游戏函数里去(把main函数去了)
    • 原来游戏若调用了函数则游戏主程序放相应的游戏函数,调用函数放外面。若需要改变实参,则还需调整。

    中国象棋 五子棋

    整体这里难度都没有象棋那边大。

    但给了后面写系统程序做了铺垫

    待更ing

    展开全文
  • 湖南文理学院课程设计报告湖南文理学院课程设计报告课程名称: 计算机软件技术基础课程名称: 计算机软件技术基础学 院: 电气与信息工程学院学 院: 电气与信息工程学院专业班级: 通信 08101专业班级: 通信 081.....

    湖南文理学院课程设计报告

    湖南文理学院课程设计报告

    课程名称: 计算机软件技术基础

    课程名称: 计算机软件技术基础

    学 院: 电气与信息工程学院

    学 院: 电气与信息工程学院

    专业班级: 通信 08101

    专业班级: 通信 08101

    姓 名: 吴 春 香

    姓 名: 吴 春 香

    学 号: 200816020110

    学 号: 200816020110

    指导教师 : 曹玲玲

    指导教师 : 曹玲玲

    完成时间: 2010 年 12 月 27 日

    完成时间: 2010 年 12 月 27 日

    报告成绩 :

    报告成绩 :

    评阅意见:

    评阅意见:

    评阅老师: 评阅时间:

    评阅老师: 评阅时间:

    目录

    目录

    一 程序功能 3

    一 程序功能 3

    二 设计目的 3

    二 设计目的 3

    三 程序设计 3

    三 程序设计 3

    3.1 游戏界面 3

    3.1 游戏界面 3

    3.2 设计思路 3

    3.2 设计思路 3

    3.3 源程序 5

    3.3 源程序 5

    3.4 程序流程图 11

    3.4 程序流程图 11

    四 上机测试 12

    四 上机测试 12

    4.1 用 turbo C 运行 C 程序步骤 12

    4.1 用 turbo C 运行 C 程序步骤 12

    五 运行结果 13

    五 运行结果 13

    5.1 游戏界面图 13

    5.1 游戏界面图 13

    六 小结 14

    六 小结 14

    6.1 知识点 14

    6.1 知识点 14

    七 心得体会 15

    七 心得体会 15

    八 参考文献 15

    八 参考文献 15

    2

    2

    贪吃蛇游戏课程设计

    贪吃蛇游戏课程设计

    一 程序功能

    一 程序功

    展开全文
  • C语言界面版数独游戏(带计算器)源码,欢迎您的下下载。软件用WINTC编写。欢迎修改
  • 打砖块小游戏的课程设计C语言编写,有图形界面,是在win-tc里调试运行成功的,如果要在TC2.0里运行应该要改有些图形函数
  • C语言自主设计迷宫类游戏实例

    万次阅读 多人点赞 2018-05-26 18:17:59
    C语言自主设计迷宫类游戏实例

    附:

    C语言实现计算器完整代码:https://blog.csdn.net/qq_41915690/article/details/80466865

    (破败圣迹之逃出生天)使用设计说明

    Design By 海上的雨

     

     

     

     

                                                                                                                                                                                                          

    1 软件介绍(使用说明)

    用w、a、s、d或者W、A、S、D分别控制角色的移动(上、左、下、右),使目标向○处逃生!触碰◎则死亡!逃生或死亡则游戏结束。

    游戏开始界面↓

    死亡界面↓

    逃生界面↓

    2 函数设计(设计思路)

    图形构成

    破败圣迹之逃出生天由主角、墙壁、道路、逃生标志、死亡标志、装饰符以及文字构成。自建一个txt文档储存数据,用数字1代替墙壁"▓",2代表角色"♀" ,3代表道路"  ",4代表文字"破败圣迹之逃出生天"、5代表装饰符"卐"、6代表装饰符"卍"、7代表逃生标志"○"、*代表死亡标志"◎"来构成图形化界面。

    使用voidshuru(char shuju[29][26],int *a,int *b);以及      void shuchu(char shuju[29][26],int *a,int*b);这两个函数对txt文档进行提取和显示。其中voidshuru(char shuju[29][26],int *a,int *b)函数作用是从文件中读取信息,并将数据存放于二维数组shuju[29][26]中,*a与*b记录角色的位置。void shuchu(char shuju[29][26],int *a,int *b)函数的作用是从二维数组shuju[29][26]中读信息,并根据shuju[29][26]中的各个值输出相应的符号。

    以下为实现代码:

    void shuru(char shuju[29][26],int *a,int*b)

    {

             inti=0,j=0;

             FILE*fp;

       char ch;

             if((fp=fopen("破败圣迹之逃出生天.txt","r"))==NULL)

             {

                       printf("文件路径不正确!");

                       exit(1);

             }

             ch=fgetc(fp);

             while(ch!=EOF)

             {  

                       if(ch=='1')

           {

                               

                                shuju[i][j]=ch;

                                j++;

                                if(j==26)

                                {

                                         i++;

                                         j=0;

                                }       

                       }

                       elseif(ch=='2')

                       {

                               

                                shuju[i][j]=ch;

                                (*a)=i;

                                (*b)=j;

               j++;

                                if(j==26)

                                {

                                         i++;

                                         j=0;

                                }

                       }

                       elseif(ch=='3')

                       {

                                shuju[i][j]=ch;

               j++;

                                if(j==26)

                                {

                                         i++;

                                         j=0;

                                }

                       }

                       else

                       {       

               shuju[i][j]=ch;

               j++;

                                if(j==26)

                                {

                                         i++;

                                         j=0;

                                }

                       }

           ch=fgetc(fp);

             }

             fclose(fp);

    }

    void shuchu(char shuju[29][26],int *a,int*b)

    {

             inti,j;

             system("cls");

             for(i=0;i<29;i++)

                       for(j=0;j<26;j++)

                       {

                                if(shuju[i][j]=='1')

                                         printf("▓");

                                elseif(shuju[i][j]=='2')

                                {  

                                         printf("♀");

                                         (*a)=i;

                    (*b)=j;

                                }

                                elseif(shuju[i][j]=='3')

                                {

                                         printf("  ");

                                }

                                elseif(shuju[i][j]=='4')

                                {

                                         printf("破败圣迹之逃出生天");

                                }

                                elseif(shuju[i][j]=='5')

                                {

                                         printf("卐");

                                }

                                elseif(shuju[i][j]=='6')

                                {

                                         printf("卍");

                                }

                                elseif(shuju[i][j]=='7')

                                {

                                         printf("○");

                                }

                                elseif(shuju[i][j]=='*')

                                {

                                         printf("◎");

                                }

                                elseif(shuju[i][j]=='8')

                                {

                                         printf("W:向上移动\tS:向下移动");

                                }

                                elseif(shuju[i][j]=='9')

                                {

                                         printf("A:向左移动\tD:向右移动");

                                }

                                /*elseif(shuju[i][j]=='*')

                                {

                                         printf("A:向左移动");

                                }*/

                                /*elseif(shuju[i][j]=='/')

                                {

                                         printf("D:向右移动");

                                }*/

                                elseif(shuju[i][j]=='+')

                                {

                                         printf("向○处逃生!触碰◎则死亡!");

                                }

                                else

                                {

                                         putchar(shuju[i][j]);

                                }

                       }

                       printf("\n");

    }

    主角移动、死亡、逃生的实现

    定义二维数组用来记录各个位置。可以理解为用坐标表示位置,当键入w/a/s/d通过getch()对玩家输入的控制键进行不显示的读取,然后对shuju [i][j]进行相应的改变,之后运行shuchu(shuju,&a,&b)进行输出绘图,从而完成了角色"♀"的移动。为了保证角色不向墙壁移动,在调换shuju [i][j]的内容时调用if语句进行相关设定。同理,当主角走入死亡标记"◎"或逃生标记"○"时通过调制if语句对游戏进行死亡或逃生的展现。

    以下为对应代码:

    ch=getch();

        while(1)

           {

                  switch(ch)

                  {

                  case 'w':

                  case 'W':

                         {

                                if(shuju[a-1][b]=='3'||shuju[a-1][b]=='*')

                                { 

                                       c=shuju[a-1][b];

                                       shuju[a-1][b]=shuju[a][b];

                                       shuju[a][b]=c;

                                       shuchu(shuju,&a,&b);

                                }

                                break;

                         }

                  case 'a':

                  case 'A':

                         {

                                if(shuju[a][b-1]=='3'||shuju[a][b-1]=='*')

                                {

                                       c=shuju[a][b-1];

                                       shuju[a][b-1]=shuju[a][b];

                                       shuju[a][b]=c;

                                       shuchu(shuju,&a,&b);

                                }

                                break;

                         }

                  case 's':

                  case 'S':

                         {

                                if(shuju[a+1][b]=='3'||shuju[a+1][b]=='*')

                                {

                                       c=shuju[a+1][b];

                                       shuju[a+1][b]=shuju[a][b];

                                       shuju[a][b]=c;

                                       shuchu(shuju,&a,&b);

                                }

                                break;

                         }

                  case 'd':

                  case 'D':

                         {

                                if(shuju[a][b+1]=='3'||shuju[a][b+1]=='*')

                                {

                                       c=shuju[a][b+1];

                                       shuju[a][b+1]=shuju[a][b];

                                       shuju[a][b]=c;

                                       shuchu(shuju,&a,&b);

                                }

                                break;

                         }

                  }

                  if(shuju[22][23]=='2')

                  {

                         printf("你已逃出生天!\n");

                         break;

                  }

           if(shuju[3][13]=='2'||shuju[3][19]=='2'||shuju[9][5]=='2'||shuju[7][20]=='2'||shuju[12][19]=='2'||shuju[17][13]=='2'||shuju[23][19]=='2')

                  {

                         printf("你已死亡!\n");

                         break;

                  }

                  ch=getch();

           }

    }       

    数据的读取

    由”图形构成”部分可知,我们已经将有代表意义的1.2.3···等数据排列在一个txt文档里。然后通过(fp=fopen("破败圣迹之逃出生天.txt","r"))==NULL确认文件是否存在,并读取数据存入fp中。然后对fp进行操作,实现数据的读取。

    以下为实现代码:

    void shuru(char shuju[29][26],int *a,int*b)

    {

             inti=0,j=0;

             FILE*fp;

       char ch;

             if((fp=fopen("破败圣迹之逃出生天.txt","r"))==NULL)

             {

                       printf("文件路径不正确!");

                       exit(1);

             }

             ch=fgetc(fp);

             while(ch!=EOF)

             {  

                       if(ch=='1')

           {

                               

                                shuju[i][j]=ch;

                                j++;

                                if(j==26)

                                {

                                         i++;

                                         j=0;

                                }       

                       }

                       elseif(ch=='2')

                       {

                               

                                shuju[i][j]=ch;

                                (*a)=i;

                                (*b)=j;

               j++;

                                if(j==26)

                                {

                                         i++;

                                         j=0;

                                }

                       }

                       elseif(ch=='3')

                       {

                                shuju[i][j]=ch;

               j++;

                                if(j==26)

                                {

                                         i++;

                                         j=0;

                                }

                       }

                       else

                       {       

               shuju[i][j]=ch;

               j++;

                                if(j==26)

                                {

                                         i++;

                                         j=0;

                                }

                       }

           ch=fgetc(fp);

             }

             fclose(fp);

    游戏结束

    通过while(1)语句当满足设定的if语句并break出时则游戏接触。

    以下为实现代码:

    while(1)

    {

    if(shuju[22][23]=='2')

                       {

                                printf("你已逃出生天!\n");

                                break;

                       }

             if(shuju[3][13]=='2'||shuju[3][19]=='2'||shuju[9][5]=='2'||shuju[7][20]=='2'||shuju[12][19]=='2'||shuju[17][13]=='2'||shuju[23][19]=='2')

                       {

                                printf("你已死亡!\n");

                                break;

                       }

                       ch=getch();

             }

    }

    3 数据结构

    Ø  void shuru(char shuju[29][26],int *a,int *b);函数用与对储存数字以及字符的txt文档进行读取、转化、存储。

    Ø  void shuchu(char shuju[29][26],int *a,int *b);函数用于通过设定不用的数字及字符代表相应的意义,对shuju[i][j]进行绘制。

    Ø  getch();函数用于对输入的数据不进行显示而是直接保存,使游戏界面清洁。

    Ø  while(1)

             {

             switch(ch)

                       {

    If()

    {

    }

    If()

    {

    }

    Ch=getch();

    }

    }  函数用于设定通过键入的案件对shuju[a][b]内的数据进行相应的改变并进行游戏胜利与失败的设定。

    Ø           FILE *fp;

        char ch;

             if((fp=fopen("破败圣迹之逃出生天.txt","r"))==NULL)

    {

    }  函数对存放数据的txt文档进行读取并保存于fp。

    Ø  while(ch!=EOF)

           { 

    If()

    {

    }

    }   函数表示当ch不是标准输入的结尾时运行if语句。

    Ø           system("cls");函数用于清屏,使用户在操作后能够使用一个新的界面。

    4 最后

    设计感悟

    ²  C语言程序图形化界面的行程可以先用数字或字符替代,然后进行读取操作。方便快捷,可修改性强。

    ²  把文件中的数据读到数组中,可以减少文本的读取次数。

    C语言感悟

    ²  设计程序时多运行测试,多以用户的角度进行思考,对程序源代码进行不断地完善。

    ²  程序工程量大时在源代码中做好注释,可以在浏览时能够更直观、快速的浏览代码。

    ²  程序工程量较大时需要考虑先编写整体结构,然后对源代码进行改善。

    ²  编程中有许多类似的代码行,善于运用复制粘贴可以加快编程速度。

    ²  遇到无法实现的地方多运用网络资源或向先导求知,能够快速丰富自己的C语言知识库。

     

     

     

     

     

     

    #include<stdio.h>
    #include<stdlib.h> 
    #include<conio.h>  
    void main()
    {
    	void shuru(char shuju[29][26],int *a,int *b);
    	void shuchu(char shuju[29][26],int *a,int *b);
    	int a,b;
    	char ch,c;
    	char shuju[29][26];
    	shuru(shuju,&a,&b);
    	shuchu(shuju,&a,&b);
        ch=getch();
        while(1)
    	{
    		switch(ch)
    		{
    		case 'w':
    		case 'W':
    			{
    				if(shuju[a-1][b]=='3'||shuju[a-1][b]=='*')
    				{  
    					c=shuju[a-1][b];
    					shuju[a-1][b]=shuju[a][b];
    					shuju[a][b]=c;
    					shuchu(shuju,&a,&b);
    				}
    				break;
    			}
    		case 'a':
    		case 'A':
    			{
    				if(shuju[a][b-1]=='3'||shuju[a][b-1]=='*')
    				{
    					c=shuju[a][b-1];
    					shuju[a][b-1]=shuju[a][b];
    					shuju[a][b]=c;
    					shuchu(shuju,&a,&b);
    				}
    				break;
    			}
    		case 's':
    		case 'S':
    			{
    				if(shuju[a+1][b]=='3'||shuju[a+1][b]=='*')
    				{
    					c=shuju[a+1][b];
    					shuju[a+1][b]=shuju[a][b];
    					shuju[a][b]=c;
    					shuchu(shuju,&a,&b);
    				}
    				break;
    			}
    		case 'd':
    		case 'D':
    			{
    				if(shuju[a][b+1]=='3'||shuju[a][b+1]=='*')
    				{
    					c=shuju[a][b+1];
    					shuju[a][b+1]=shuju[a][b];
    					shuju[a][b]=c;
    					shuchu(shuju,&a,&b);
    				}
    				break;
    			}
    		}
    		if(shuju[22][23]=='2')
    		{
    			printf("你已逃出生天!\n");
    			break;
    		}
    		if(shuju[3][13]=='2'||shuju[3][19]=='2'||shuju[9][5]=='2'||shuju[7][20]=='2'||shuju[12][19]=='2'||shuju[17][13]=='2'||shuju[23][19]=='2')
    		{
    			printf("你已死亡!\n");
    			break;
    		}
    		ch=getch();
    	}
    }
    void shuru(char shuju[29][26],int *a,int *b)
    {
    	int i=0,j=0;
    	FILE *fp;
        char ch;
    	if((fp=fopen("破败圣迹之逃出生天.txt","r"))==NULL)
    	{
    		printf("文件路径不正确!");
    		exit(1);
    	}
    	ch=fgetc(fp);
    	while(ch!=EOF)
    	{   
    		if(ch=='1')
            {
    			
    			shuju[i][j]=ch;
    			j++;
    			if(j==26)
    			{
    				i++;
    				j=0;
    			}	
    		}
    		else if(ch=='2')
    		{
    			
    			shuju[i][j]=ch;
    			(*a)=i;
    			(*b)=j;
                j++;
    			if(j==26)
    			{
    				i++;
    				j=0;
    			}
    		}
    		else if(ch=='3')
    		{
    			shuju[i][j]=ch;
                j++;
    			if(j==26)
    			{
    				i++;
    				j=0;
    			}
    		}
    		else 
    		{	
                shuju[i][j]=ch;
                j++;
    			if(j==26)
    			{
    				i++;
    				j=0;
    			}
    		}
            ch=fgetc(fp);
    	}
    	fclose(fp);
    }
    void shuchu(char shuju[29][26],int *a,int *b)
    {
    	int i,j;
    	system("cls"); 
    	for(i=0;i<29;i++)
    		for(j=0;j<26;j++)
    		{
    			if(shuju[i][j]=='1')
    				printf("▓");
    			else if(shuju[i][j]=='2')
    			{   
    				printf("♀");
    				(*a)=i;
                    (*b)=j;
    			}
    			else if(shuju[i][j]=='3')
    			{
    				printf("  ");
    			}
    			else if(shuju[i][j]=='4')
    			{
    				printf("破败圣迹之逃出生天");
    			}
    			else if(shuju[i][j]=='5')
    			{
    				printf("卐");
    			}
    			else if(shuju[i][j]=='6')
    			{
    				printf("卍");
    			}
    			else if(shuju[i][j]=='7')
    			{
    				printf("○");
    			}
    			else if(shuju[i][j]=='*')
    			{
    				printf("◎");
    			}
    			else if(shuju[i][j]=='8')
    			{
    				printf("W:向上移动\tS:向下移动");
    			}
    			else if(shuju[i][j]=='9')
    			{
    				printf("A:向左移动\tD:向右移动");
    			}
    			/*else if(shuju[i][j]=='*')
    			{
    				printf("A:向左移动");
    			}*/
    			/*else if(shuju[i][j]=='/')
    			{
    				printf("D:向右移动");
    			}*/
    			else if(shuju[i][j]=='+')
    			{
    				printf("向○处逃生!触碰◎则死亡!");
    			}
    			else
    			{
    				putchar(shuju[i][j]);
    			}
    		}
    		printf("\n");
    }

     

     

    展开全文
  • 用图形库打造有图形界面的推箱子游戏界面 这款基于easy-x开发的《推箱子》游戏,首先将玩家熟悉的主角换成了一艘宇宙飞船,游戏的场景也相应地移到了浩瀚的宇宙空间中,而被推动的箱子则变成了不断闪烁的能量块。...
  • 课程设计,利用C语言设计一个贪吃蛇游戏。 1. 巩固和加深学生对C语言课程的基本知识的理解和掌握 2. 掌握C语言编程和程序调试的基本技能 3. 利用C语言进行基本的软件设计 4. 掌握书写程序设计说明文档的能力 5. ...
  • 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语言实现的一个简单的小游戏,飞机大战,界面还算完美,功能还算齐全。最主要是能够直接运行。
  • C语言界面实现2048小游戏

    千次阅读 多人点赞 2018-11-02 21:33:23
    这是我在大一第二学期(两年前)为了参加比赛,自学后写的一个Demo,拿出来和大家分享一下,代码为两年前的代码,未改动,优化以及各式可能很一般,请见谅...#define WIN 2048//游戏获胜目标 void output(int (*a)...
  • 对于循环,指针,结构体,文件读写以及图形化界面设计C语言设计的要点,难点有一个综合使用,初步掌握写具有一定综合性的软件系统的本领,掌握软件设计的基本方法,强化上机动手能力,闯过编程,调试关。...
  • C语言程序设计 | 扫雷游戏

    千次阅读 2019-10-16 23:40:17
    《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。 以上就是扫雷的介绍,来源百度百科。 我在网上找了几...
  • 设计游戏菜单,通过选择进入或者退出游戏 int main() { int select = 0; int quit = 0; while (!quit) { Menu(); printf("请输入你的选择\n"); scanf("%d", &select); switch (select) { ...
  • 俄罗斯方块程序设计报告 要求支持键盘操作和7种不同类型方块的旋转变换,并且界面上显示下一个方块的提示以及当前的玩家的得分,随着游戏的进行,等级越高,游戏难度越大,即方块的下落速度越快,相应的等级,等级越...
  • 16个C语言课程设计实验源代码 - C语言课程设计源码 - C语言课程设计案例精编源代码 课程设计实验源代码源代码包括: 基本语法操作实例; 小游戏; 管理系统; 网络编程; 仿视窗小工具; 图形用户界面等。。。 ...
  • 实验报告课程名称 : C语言程序设计实验项目 : 21点扑克牌游戏设计专业班级 : 电子信息工程实验室号 : 信息 205 实验组号 : xx实验时间 : 2010-5-4 批...
  • 基于C语言的双人贪吃蛇游戏程序设计 实现目标 制作一个两个两个人一起同时玩的双人贪吃蛇游戏,有比分并记录历史成绩 (1) 打开游戏时能够自动播放背景音乐 (2) 开始菜单,显示历史用户名及其对应的成绩 (3) 开始菜单...
  • C语言上学期期末答辩设计了三款游戏贪吃蛇、推箱子、小鸟飞飞,并使用windows设计了其窗口,一直想将讲解代码发表在CSDN博客,写了一半却因为一些事情耽搁,这里先将项目文件上传在这,请实时关注我的博客,将在不久...
  • c语言
  • 猜数字游戏规则: 1. 电脑随机产生100—999之间的数字(包括100、999); 提示:用rand函数,该函数在stdlib.h库中,并保证多次运行产生不同的随机数 2. 玩家每轮有七次猜数的机会,如果七次都没有猜到,则失败,判...
  • 文章目录前言一、背景知识二、实验分析和理解三、头文件四、设计流程五、流程图六、算法设计(1)相关变量(2)创建链表(3)随机出现食物并记录食物出现的坐标(4)绘制初始界面游戏地图(5)创建节点,初始化...
  • 利用c语言实现的2048小游戏。 可以用来当做结课项目,毕业设计,代码注释写的很详细,保证各位可以看懂。 程序的主要使用的相关数据类型:2维数组,枚举,指针 程序运行界面如下图: 开始时随机生成 结束 程序...
  • 文章目录C语言实现2048小游戏(图形界面)——版本1实现思路 若本文章为原创文章,转载本文时需加上本文原地址 C语言实现2048小游戏(图形界面)——版本1 广东好冷,动都不想动,只能玩玩小游戏这个样子 版本一已经...
  • 软件介绍 Visual Studio 2019(简称VS2019)是微软公司旗下最重要的软件集成开发工具产品。是目前最流行的 Windows 平台应用程序开发环境,也是...EasyX 是针对 Visual C++ 的绘图库,在初学 C 语言实现图形和游戏编程
  • 扫雷是生活中接触比较多的一块小游戏,那么我们该如何通过C语言来实现呢? 姐先来的代码能够实现基本的扫雷功能,只是缺少了界面化,鼠标操作等,日后有待改善,不过基本功能还是可以实现的,比如:第一步绝对不会踩...
  • 经过半年多的写作、修改、校样、印制,我们的实践教材《C语言课程设计游戏开发实践教程》终于出版了。这本书可以看成是“做游戏,学编程(C语言)专栏”的详细版本,以下为书中部分案例的运行效果,本书所有案例均...
  • C 语言课程设计报告 C语言课程设计报告 贪 吃 蛇 专 业 学生姓名 班 级 学 号 完成日期 C 语言课程设计报告 一游戏规则需求 1 在打开程序后出现选择界面里面包含难度选择其中难度选择能够使程序出现相应 的游戏难度 ...
  • 此项目总共文件3个文件 main.c、fiveChess.h 和 fiveChess.c,需要放到同一目录下编译 main.c .../*****************************************... * 工程描述: 实现字符界面的五子棋游戏,支持光标控制位置 * ...
  • 跳棋程序设计 李雄志 学号2012214157 数学与应用数学12-1班 问题描述 程序分析 程序算法 思考感悟 一问题描述 题目要求设计一个跳棋程序要求界面友好可以实现人机对弈 游戏规则 玩家要先确定自己的棋子坐标 确定完...
  • 震惊!!!一个关于c语言图形化界面编程的小游戏

    万次阅读 多人点赞 2018-12-04 11:54:54
    关于C语言的图形化界面编程 第一个小程序《飞翔的小鸟》 本人也是小白,大家轻点喷!!!! 下面是源码 作者: @追风 #include&amp;amp;amp;lt;graphics.h&amp;amp;amp;gt; #include&amp;amp;...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 16,754
精华内容 6,701
关键字:

c语言游戏界面设计

c语言 订阅