【c语言】推箱子

简介: 【c语言】推箱子

所需知识:c语言枚举,数组,for循环,while循环,switch,case语句,图形库相关函数

1.调整控制台窗口大小

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
int main()
{
  system("mode con lines=15 cols=25");//调整窗口大小
  return 0;
}

2.清掉控制台屏幕上的字

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
int main()
{
  system("mode con lines=15 cols=25");
  system("cls");//清屏操作
  getchar();//不让程序退出,等待读字符
  return 0;
}

3. 枚举类型定义地图中空地,墙,目的地,箱子,玩家

enum  Mine
{
  SPACE,  //空地
  WALL,//墙
  DEST,  //目的地
  BOX,  //箱子
  PLAYER//玩家
};

4.定义二维数组做地图,并且打印出来看看效果

//定义一个二维数组,做地图 空地0  墙1  目的地2  箱子3  玩家4    箱子在目的地 5  玩家在目的地6,与枚举类型对应上了
int map[10][10] =
{
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,0,1,1,1,0,0,0,0},
  {0,0,0,1,2,1,1,1,1,0},
  {0,1,1,1,3,0,3,2,1,0},
  {0,1,2,3,4,0,1,1,1,0},
  {0,1,1,1,1,3,1,0,0,0},
  {0,0,0,0,1,2,1,0,0,0},
  {0,0,0,0,1,1,1,0,0,0},
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0,0,0}
};
void printmap()
{for(int i=0;i<10;i++)
{
  for (int j = 0; j < 10; j++)
  {
    printf("%d ", map[i][j]);
  }
  printf("\n");
}
}

将printmap()在main中调用

为了让程序不会输入字符后退出,加上while循环

int main()
{
  while (1)
  {
    system("mode con lines=15 cols=25");
    system("cls");//清屏操作
    printmap();
    getchar();//不让程序退出,等待读字符
  }
  return 0;
}

5.修改printmap函数为gamedraw()函数

为了保证游戏的美观性,我们将对应的数字转化为好看的图案

使用两层循环遍历二维数组,在使用switch已经将对应的数字用图案代替,此时我们要下载搜狗输入法

void gamedraw()
{
  for (int i = 0; i < 10; i++)
  {
    for (int j = 0; j < 10; j++)
    {
        switch (map[i][j])
        {case SPACE://如果二维数组元素为0
          printf("  ");  //空地        //一个中文字符相当于二个英文字符
          break;
        case WALL://如果二维数组元素为1
          printf("■");//墙
          break;
        case DEST://如果二维数组元素为2
          printf("☆");//目的地
          break;
        case BOX://如果二维数组元素为3
          printf("□");//箱子
          break;
        case PLAYER://如果二维数组元素为4
          printf("♀");//玩家
          break;
        case PLAYER+DEST://如果二维数组元素为6
          printf("♂");//玩家在目的地
          break;
        case BOX+DEST://如果二维数组元素为5
          printf("★");箱子在目的地
          break;
                }
    }
printf("\n");
  }
}

对应数字和枚举变量类型对应上,PLAYER+DEST表示玩家如果出现在目的地的话对应数字为6,BOX+DEST表示箱子在目的地,将主函数中的printmap用gamedraw()换掉。

6.按键控制移动

要想使玩家移动,就先得确定玩家的坐标,通过遍历二维数组,找到数组中数字等于4的和4+2的,后者表示玩家在目的地,也要获取坐标,当找到玩家坐标时,要跳出循环,而break只能跳出一次循环,所以使用goto函数,可以直接跳出多层循环.

int i = 0; int j = 0;//定义不要在for循环里面,要不然出作用域就会被销毁
  for (i = 0; i < 10; i++)
  {
    for (j = 0; j < 10; j++)
    {
      if (map[i][j] == PLAYER||map[i][j] == PLAYER+DEST)
      {
        goto end;
      }
    }
  }
end:;//找到直接来这里

在使用_getch()函数将按键的信息放入ch字符变量中,如果不知道上下左右对应的键值,我们可以打印出ch看看,我们把这些都封装成一个函数 keyevent()获取玩家坐标,并且读取键盘按下的信息

void keyevent()
{
  int i = 0; int j = 0;
  for (i = 0; i < 10; i++)
  {
    for (j = 0; j < 10; j++)
    {
      if (map[i][j] == PLAYER || map[i][j] == PLAYER + DEST)
      {
        goto end;
      }
    }
  }
end:;
  char ch = _getch();
  printf("%d    %c", ch, ch);//w 119 a 97 s 115  d 100
}

通过printf("%d %c", ch, ch);

得到虚拟键值为//w 119 a 97 s 115 d 100,然后注释掉printf("%d %c", ch, ch);然后通过swich,case 语句分别处理上下左右按键按下后的处理,

switch (ch)
  {
  case 119:
  case 'w ':
  case 'W':
    break;
  case 97:
  case 'a ':
  case'A':
    break;
  case 115:
  case 's ':
  case'S':
    break;
  case 100:
  case 'd ':
  case'D':
    break;
  }

比如说按下w键,如果玩家上面是空地或者是目的地的话,玩家可以直接挪过去,因为没有障碍物阻碍,如果玩家的坐标为map[i][j];则玩家上面的的坐标就是map[i-1][j];要做的是

if (map[i - 1][j] == SPACE||map[i - 1][j] == DEST)
     {
       map[i - 1][j] += PLAYER;
       map[i][j] -= PLAYER;
     }

如果map[i][j]只有玩家的话,上移动玩家就会map[i][j]=0,该位置变为空地,如果map[i][j]是玩家加目的地,上移动玩家就会map[i][j]=DEST,变为单纯的目的地.

如果玩家上面一个位置是箱子或者是箱子加目的地,就要看玩家上面的上面是什么了,如果是空地,或者是目的地,就可以推动,map[i - 2][j]是玩家上面的上面的坐标要做的是

else  if(map[i-1][j]==BOX||map[i-1][j]==BOX+DEST)
     {
       if (map[i - 2][j] == SPACE || map[i - 2][j] == DEST)
       {//完成玩家上面有箱子,箱子的上面是空地或者是目的地都可以推动
         map[i - 2][j] += BOX;//玩家上面的上面加一个箱子
         map[i - 1][j] = map[i - 1][j] - BOX + PLAYER;//玩家的上面减去一个箱子加上一个玩家
         map[i][j] -= PLAYER;//玩家消失在原来位置
       }
     }

处理完的函数上键

case 119:
  case 'w ':
  case 'W':
    if (map[i - 1][j] == SPACE || map[i - 1][j] == DEST)
    {
      map[i - 1][j] += 4;
      map[i][j] -= 4;
    }
    else  if (map[i - 1][j] == BOX || map[i - 1][j] == BOX + DEST)
    {
      if (map[i - 2][j] == SPACE || map[i - 2][j] == DEST)
      {
        map[i - 2][j] += BOX;
        map[i - 1][j] = map[i - 1][j] - BOX + PLAYER;
        map[i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;

向上推了一下,如果懂了上键怎么移动,别的也就会处理了

整体的keyevent()

void keyevent()
{
  int i = 0; int j = 0;
  for (i = 0; i < 10; i++)
  {
    for (j = 0; j < 10; j++)
    {
      if (map[i][j] == PLAYER || map[i][j] == PLAYER + DEST)
      {
        goto end;
      }
    }
  }
end:;
  char ch = _getch();
  switch (ch)
  {
  case 119:
  case 'w ':
  case 'W':
    if (map[i - 1][j] == SPACE || map[i - 1][j] == DEST)
    {
      map[i - 1][j] += PLAYER;
      map[i][j] -=  PLAYER;
    }
    else  if (map[i - 1][j] == BOX || map[i - 1][j] == BOX + DEST)
    {
      if (map[i - 2][j] == SPACE || map[i - 2][j] == DEST)
      {
        map[i - 2][j] += BOX;
        map[i - 1][j] = map[i - 1][j] - BOX + PLAYER;
        map[i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  case 97:
  case 'a ':
  case'A':
    if (map[i][j - 1] == SPACE || map[i][j - 1] == DEST)
    {
      map[i][j - 1] += PLAYER;
      map[i][j] -=  PLAYER;
    }
    else  if (map[i][j - 1] == BOX || map[i][j - 1] == BOX + DEST)
    {
      if (map[i][j - 2] == SPACE || map[i][j - 2] == DEST)
      {
        map[i][j - 2] += BOX;
        map[i][j - 1] = map[i][j - 1] - BOX + PLAYER;
        map[i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  case 115:
  case 's ':
  case'S':
    if (map[i + 1][j] == SPACE || map[i + 1][j] == DEST)
    {
      map[i + 1][j] += PLAYER;
      map[i][j] -= PLAYER;
    }
    else  if (map[i + 1][j] == BOX || map[i + 1][j] == BOX + DEST)
    {
      if (map[i + 2][j] == SPACE || map[i + 2][j] == DEST)
      {
        map[i + 2][j] += BOX;
        map[i + 1][j] = map[i + 1][j] - BOX + PLAYER;
        map[i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  case 100:
  case 'd ':
  case'D':
    if (map[i][j + 1] == SPACE || map[i][j + 1] == DEST)
    {
      map[i][j + 1] +=  PLAYER;
      map[i][j] -=  PLAYER;
    }
    else  if (map[i][j + 1] == BOX || map[i][j + 1] == BOX + DEST)
    {
      if (map[i][j + 2] == SPACE || map[i][j + 2] == DEST)
      {
        map[i][j + 2] += BOX;
        map[i][j + 1] = map[i][j + 1] - BOX + PLAYER;
        map[i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  }
}

7.多组地图的制作,修改map数组

定义全局变量level=0;表示关数,

将二维数组改为三维数组,三维数组的每一个元素就是二维数组,就是一个地图.

int map[3][10][10] =
{
  {
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,0,1,1,1,0,0,0,0},
  {0,0,0,1,2,1,1,1,1,0},
  {0,1,1,1,3,0,3,2,1,0},
  {0,1,2,3,4,0,1,1,1,0},
  {0,1,1,1,1,3,1,0,0,0},
  {0,0,0,0,1,2,1,0,0,0},
  {0,0,0,0,1,1,1,0,0,0},
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0,0,0}
  },
  {
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,1,1,0,0,1,1,0,0},
  {0,1,0,2,1,1,2,0,1,0},
  {1,0,0,0,3,0,0,0,0,1},
  {1,0,0,0,4,3,0,0,0,1},
  {0,1,0,0,3,3,0,0,1,0},
  {0,0,1,0,0,0,0,1,0,0},
  {0,0,0,1,2,2,1,0,0,0},
  {0,0,0,0,1,1,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,1,0,1,0,0,0,0},
  {0,0,1,2,3,0,1,0,0,0},
  {0,1,0,0,0,0,0,1,0,0},
  {1,2,3,0,4,0,0,0,1,0},
  {0,1,0,0,0,0,0,3,2,1},
  {0,0,1,0,3,0,0,0,1,0},
  {0,0,0,1,2,0,0,1,0,0},
  {0,0,0,0,1,0,1,0,0,0},
  {0,0,0,0,0,1,0,0,0,0}
  }
};

将所有map[][]改成map[level][][];每通过一关,level++;

8.通关判断

循环遍历二维数组,如果有map[level][i][j]==BOX,说明有箱子没有推到目的地,返回false ,循环结束如果没有的话,说明通过此关,返回true,该判断函数返回布尔类型的值

bool jude()
{
  for (int i = 0; i < 10; i++)
  {
    for (int j = 0; j < 10; j++)
    {
      if (map[level][i][j] == BOX)
      {
        return false;
      }
    }
  }
}
if (jude())
    {
      level++;
      if (level > 2)
      {
        printf("oioioioioioioioi奥哈呦学妹你通过了!");
        _getch();
        break;
      }
    }

主函数添加如果jude()返回1,然后就是通关,然后level++;

变成三维数组中的第二个元素,也就是换了地图,当level>2,表示通关,因为只设置了三个图

9.程序源码(无图形库)

#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
enum  Mine
{
  SPACE,  //空地
  WALL,//墙
  DEST,  //目的地
  BOX,  //箱子
  PLAYER//玩家
};
int level = 0;
//定义一个二维数组,做地图 空地0  墙1  目的地2  箱子3  玩家4    箱子在目的地 5  玩家在目的地6,与枚举类型对应上了
int map[3][10][10] =
{
  {
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,0,1,1,1,0,0,0,0},
  {0,0,0,1,2,1,1,1,1,0},
  {0,1,1,1,3,0,3,2,1,0},
  {0,1,2,3,4,0,1,1,1,0},
  {0,1,1,1,1,3,1,0,0,0},
  {0,0,0,0,1,2,1,0,0,0},
  {0,0,0,0,1,1,1,0,0,0},
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0,0,0}
  },
  {
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,1,1,0,0,1,1,0,0},
  {0,1,0,2,1,1,2,0,1,0},
  {1,0,0,0,3,0,0,0,0,1},
  {1,0,0,0,4,3,0,0,0,1},
  {0,1,0,0,3,3,0,0,1,0},
  {0,0,1,0,0,0,0,1,0,0},
  {0,0,0,1,2,2,1,0,0,0},
  {0,0,0,0,1,1,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,1,0,1,0,0,0,0},
  {0,0,1,2,3,0,1,0,0,0},
  {0,1,0,0,0,0,0,1,0,0},
  {1,2,3,0,4,0,0,0,1,0},
  {0,1,0,0,0,0,0,3,2,1},
  {0,0,1,0,3,0,0,0,1,0},
  {0,0,0,1,2,0,0,1,0,0},
  {0,0,0,0,1,0,1,0,0,0},
  {0,0,0,0,0,1,0,0,0,0}
  }
};
void gamedraw()
{
  for (int i = 0; i < 10; i++)
  {
    for (int j = 0; j < 10; j++)
    {
        switch (map[level][i][j])
        {case SPACE:
          printf("  ");          //一个中文字符相当于二个英文字符
          break;
        case WALL:
          printf("■");
          break;
        case DEST:
          printf("☆");
          break;
        case BOX:
          printf("□");
          break;
        case PLAYER:
          printf("♀");
          break;
        case PLAYER+DEST:
          printf("♂");
          break;
        case BOX+DEST:
          printf("★");
          break;
                }
    }
printf("\n");
  }
}
void keyevent()
{
  int i = 0; int j = 0;
  for (i = 0; i < 10; i++)
  {
    for (j = 0; j < 10; j++)
    {
      if (map[level][i][j] == PLAYER || map[level][i][j] == PLAYER + DEST)
      {
        goto end;
      }
    }
  }
end:;
  char ch = _getch();
  switch (ch)
  {
  case 119:
  case 'w ':
  case 'W':
    if (map[level][i - 1][j] == SPACE || map[level][i - 1][j] == DEST)
    {
      map[level][i - 1][j] += 4;
      map[level][i][j] -= 4;
    }
    else  if (map[level][i - 1][j] == BOX || map[level][i - 1][j] == BOX + DEST)
    {
      if (map[level][i - 2][j] == SPACE || map[level][i - 2][j] == DEST)
      {
        map[level][i - 2][j] += BOX;
        map[level][i - 1][j] = map[level][i - 1][j] - BOX + PLAYER;
        map[level][i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  case 97:
  case 'a ':
  case'A':
    if (map[level][i][j - 1] == SPACE || map[level][i][j - 1] == DEST)
    {
      map[level][i][j - 1] += 4;
      map[level][i][j] -= 4;
    }
    else  if (map[level][i][j - 1] == BOX || map[level][i][j - 1] == BOX + DEST)
    {
      if (map[level][i][j - 2] == SPACE || map[level][i][j - 2] == DEST)
      {
        map[level][i][j - 2] += BOX;
        map[level][i][j - 1] = map[level][i][j - 1] - BOX + PLAYER;
        map[level][i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  case 115:
  case 's ':
  case'S':
    if (map[level][i + 1][j] == SPACE || map[level][i + 1][j] == DEST)
    {
      map[level][i + 1][j] += PLAYER;
      map[level][i][j] -= PLAYER;
    }
    else  if (map[level][i + 1][j] == BOX || map[level][i + 1][j] == BOX + DEST)
    {
      if (map[level][i + 2][j] == SPACE || map[level][i + 2][j] == DEST)
      {
        map[level][i + 2][j] += BOX;
        map[level][i + 1][j] = map[level][i + 1][j] - BOX + PLAYER;
        map[level][i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  case 100:
  case 'd ':
  case'D':
    if (map[level][i][j + 1] == SPACE || map[level][i][j + 1] == DEST)
    {
      map[level][i][j + 1] += 4;
      map[level][i][j] -= 4;
    }
    else  if (map[level][i][j + 1] == BOX || map[level][i][j + 1] == BOX + DEST)
    {
      if (map[level][i][j + 2] == SPACE || map[level][i][j + 2] == DEST)
      {
        map[level][i][j + 2] += BOX;
        map[level][i][j + 1] = map[level][i][j + 1] - BOX + PLAYER;
        map[level][i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  }
}
bool jude()
{
  for (int i = 0; i < 10; i++)
  {
    for (int j = 0; j < 10; j++)
    {
      if (map[level][i][j] == BOX)
      {
        return false;
      }
    }
  }
}
int main()
{
  system("mode con lines=15 cols=25");
  //system("cls");//清屏操作
  while (1)
  {
    gamedraw();
    //_getch();
    if (jude())
    {
      level++;
      if (level > 2)
      {
        printf("oioioioioioioioi奥哈呦学妹你通过了!");
        _getch();
        break;
      }
    }keyevent();
  }
  getchar();//不让程序退出,等待读字符
  return 0;
}

10.演示1

20231002_124830

11.加图形库版本

12.头文件增加

#include <graphics.h >

13.定义保存空地,目的地,玩家,箱子,墙,箱子推到目的地图片的类

IMAGE  ima_all[6];

14.将图片image文件放在.cpp文件同目录下

image文件夹是自己创建的,用于放推箱子的素材,就是图片,图片可以在网上自己找推箱子的图片

15.加载图片函数

void loadimg()
{
  for (int i = 0; i < 6; i++)
  {
    char file[20] = "";
    sprintf(file,"./images/%d.png", i);
    loadimage(ima_all + i,file, 40, 40);
  }
}

为什么这么加载图片,这里我们将照片命名为了0,1,2,3,4,5,要将这六个照片都加载进去,六个照片的相对路径里面只有照片名字不一样,我们可以循环将每个照片对应的相对路径的字符串放入到file字符串数组file中去,使用sprintf,如果这里不知道sprintf的用法,可以去看看我文件操作那一篇,文件操作,使用loadimage函数将六个图片加载进去,loadimage第一个参数是图片的首地址,第二个参数是该图片的相对路径,第三个,第四个参数是分辨率,也就是大小,后两个可以在

可以看到4241,这里统一用4040;

16. gamedraw函数的修改

因为使用图形库的话就不用之前的gamedraw函数打印图案,而是将图片贴上去

void gamedraw()
{
  for (int i = 0; i < 10; i++)
  {
    for (int j = 0; j < 10; j++)
    {
      int x = j * 40;
      int y = i * 40;
      switch (map[level][i][j])
      {
      case SPACE:
        putimage(x, y, ima_all+2);         //一个中文字符相当于二个英文字符
        break;
      case WALL:
        putimage(x, y, ima_all+1);
        break;
      case DEST:
        putimage(x, y, ima_all+4);
        break;
      case BOX:
        putimage(x, y, ima_all+3);
        break;
      case PLAYER:
        putimage(x, y, ima_all);
        break;
      case PLAYER + DEST:
        putimage(x, y, ima_all);
        break;
      case BOX + DEST://就是箱子推到目的地
        putimage(x, y, ima_all+5);
        break;
      }
    }
  }
}

由上图可知i,j和x,y反了过来,使用putimage函数将每个图片贴上去,putimage前两个参数为图片要贴在界面上左上角的坐标,第三个参数是要贴图片对应的地址,之前命名的照片在数组ima_all[6];是对应上的,就是说ima_all+3地址对应的就是对应的这个图片

17.主函数修改

int main()
{
  initgraph(400, 400);
  loadimg();
  //system("mode con lines=15 cols=25");
  //system("cls");//清屏操作
  while (1)
  {
    gamedraw();
    //_getch();
    if (jude())
    {
      level++;
      if (level > 2)
      {
        //printf("oioioioioioioioi奥哈呦学妹你通过了!");
        _getch();
        break;
      }
    }keyevent();
  }
  getchar();//不让程序退出,等待读字符
  return 0;
}

不使用控制台显示地图,初始化界面,在界面上显示地图,由于一个图片是40乘40的,二维数组是10乘10的,所以界面行列都应该是400,所以initgraph(400, 400);由于不用控制台,所以也就不使用printf函数,也不用将控制台大小改变,也不要清屏.

当你此时开始编译运行的时候会出现下列错误

解决方案:调试-》属性-》高级-》字符集-》多字符集

18.游戏通关显示

如果level>2

settextcolor(BLACK);//字体颜色
        settextstyle(25, 0, "微软雅黑");//字体风格
        setbkmode(TRANSPARENT);//字体背景透明
        outtextxy(100, 100, "oioioioioioioioi奥哈呦学妹你通过了!");//字体显示位置,以及内容
        _getch();
        break;

19.程序源码(带图形库版)

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>//_getch()函数头文件
#include <stdbool.h>//bool类型的头函数
#include <graphics.h >//图形库头文件
//定义一个二维数组,做地图
//空地0  墙1  目的地2  箱子3  玩家4    箱子在目的地 5  玩家在目的地6
IMAGE  ima_all[6];
int level = 0;
void loadimg()
{
  for (int i = 0; i < 6; i++)
  {
    char file[20] = "";
    sprintf(file,"./images/%d.png", i);
    loadimage(ima_all + i,file, 40, 40);
  }
}
enum  Mine
{
  SPACE,  //空地
  WALL,//墙
  DEST,  //目的地
  BOX,  //箱子
  PLAYER//玩家
};
int map[3][10][10] =
{
  {
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,0,1,1,1,0,0,0,0},
  {0,0,0,1,2,1,1,1,1,0},
  {0,1,1,1,3,0,3,2,1,0},
  {0,1,2,3,4,0,1,1,1,0},
  {0,1,1,1,1,3,1,0,0,0},
  {0,0,0,0,1,2,1,0,0,0},
  {0,0,0,0,1,1,1,0,0,0},
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0,0,0}
  },
  {
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,1,1,0,0,1,1,0,0},
  {0,1,0,2,1,1,2,0,1,0},
  {1,0,0,0,3,0,0,0,0,1},
  {1,0,0,0,4,3,0,0,0,1},
  {0,1,0,0,3,3,0,0,1,0},
  {0,0,1,0,0,0,0,1,0,0},
  {0,0,0,1,2,2,1,0,0,0},
  {0,0,0,0,1,1,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,1,0,1,0,0,0,0},
  {0,0,1,2,3,0,1,0,0,0},
  {0,1,0,0,0,0,0,1,0,0},
  {1,2,3,0,4,0,0,0,1,0},
  {0,1,0,0,0,0,0,3,2,1},
  {0,0,1,0,3,0,0,0,1,0},
  {0,0,0,1,2,0,0,1,0,0},
  {0,0,0,0,1,0,1,0,0,0},
  {0,0,0,0,0,1,0,0,0,0}
  }
};
void gamedraw()
{
  for (int i = 0; i < 10; i++)
  {
    for (int j = 0; j < 10; j++)
    {
      int x = j * 40;
      int y = i * 40;
      switch (map[level][i][j])
      {
      case SPACE:
        putimage(x, y, ima_all+2);         //一个中文字符相当于二个英文字符
        break;
      case WALL:
        putimage(x, y, ima_all+1);
        break;
      case DEST:
        putimage(x, y, ima_all+4);
        break;
      case BOX:
        putimage(x, y, ima_all+3);
        break;
      case PLAYER:
        putimage(x, y, ima_all);
        break;
      case PLAYER + DEST:
        putimage(x, y, ima_all);
        break;
      case BOX + DEST:
        putimage(x, y, ima_all+5);
        break;
      }
    }
  }
}
void keyevent()
{
  int i = 0; int j = 0;
  for (i = 0; i < 10; i++)
  {
    for (j = 0; j < 10; j++)
    {
      if (map[level][i][j] == PLAYER||map[level][i][j] == PLAYER+DEST)
      {
        goto end;
      }
    }
  }
end:;
  char ch = _getch();
  //printf("%d    %c", ch, ch);//w 119 a 97 s 115  d 100
  switch (ch)
  {case 119:
   case 'w ':
   case 'W':
     if (map[level][i - 1][j] == SPACE||map[level][i - 1][j] == DEST)
     {
       map[level][i - 1][j] += 4;
       map[level][i][j] -= 4;
     }
     else  if(map[level][i-1][j]==BOX||map[level][i-1][j]==BOX+DEST)
     {
       if (map[level][i - 2][j] == SPACE || map[level][i - 2][j] == DEST)
       {
         map[level][i - 2][j] += BOX;
         map[level][i - 1][j] = map[level][i - 1][j] - BOX + PLAYER;
         map[level][i][j] -= PLAYER;//玩家消失在原来位置
       }
     }
    break;
  case 97:
  case 'a ':
  case'A':
    if (map[level][i][j-1] == SPACE || map[level][i][j-1] == DEST)
    {
      map[level][i][j-1] += 4;
      map[level][i][j] -= 4;
    }
    else  if (map[level][i][j-1] == BOX || map[level][i][j-1] == BOX + DEST)
    {
      if (map[level][i][j-2] == SPACE || map[level][i][j-2] == DEST)
      {
        map[level][i][j-2] += BOX;
        map[level][i][j-1] = map[level][i][j-1] - BOX + PLAYER;
        map[level][i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  case 115:
  case 's ':
  case'S':
    if (map[level][i+1][j] == SPACE || map[level][i+1][j] == DEST)
    {
      map[level][i+1][j] += 4;
      map[level][i][j] -= 4;
    }
    else  if (map[level][i+1][j] == BOX || map[level][i+1][j] == BOX + DEST)
    {
      if (map[level][i+2][j] == SPACE || map[level][i+2][j] == DEST)
      {
        map[level][i+2][j] += BOX;
        map[level][i+1][j] = map[level][i+1][j] - BOX + PLAYER;
        map[level][i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  case 100:
  case 'd ':
  case'D':
    if (map[level][i][j+1] == SPACE || map[level][i][j+1] == DEST)
    {
      map[level][i][j+1] += 4;
      map[level][i][j] -= 4;
    }
    else  if (map[level][i][j+1] == BOX || map[level][i][j+1] == BOX + DEST)
    {
      if (map[level][i][j+2] == SPACE || map[level][i][j +2] == DEST)
      {
        map[level][i][j+2] += BOX;
        map[level][i][j+1] = map[level][i][j+1] - BOX + PLAYER;
        map[level][i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  }
}
bool jude()
{
  for (int i = 0; i < 10; i++)
  {
    for (int j = 0; j < 10; j++)
    {
      if (map[level][i][j] == BOX)
      {
        return false;
      }
    }
  }
}
int main()
{
  initgraph(10 * 40, 10 * 40);
  loadimg();
  system("mode con lines=15 cols=25");//调整窗口大小
  while (1)
  {
    //system("cls");
    gamedraw();
    if (jude())
    {
      level++;
      if (level > 2)
      {
        settextcolor(BLACK);
        settextstyle(25, 0, "微软雅黑");
        setbkmode(TRANSPARENT);
        outtextxy(100, 100, "oioioioioioioioi奥哈呦学妹你通过了!");
        _getch();
        break;
      }
    }
      keyevent();
    }
  getchar();//不让程序退出
  return 0;
  }

20.演示2

20231002_153153

21.关卡的增加

只需要将定义的全局变量map[3][10][10],中3改成你想要的关卡数,然后在三维数组中增加像上面的二维数组即可,全部通关的level需要>关卡数-1即可

22.关卡重开

需要再定义一个和map[][][]三维数组相同的数组用来保存每一关的初始情况resetmap[][][],

int mapreset[3][10][10] =
{
  {
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,0,1,1,1,0,0,0,0},
  {0,0,0,1,2,1,1,1,1,0},
  {0,1,1,1,3,0,3,2,1,0},
  {0,1,2,3,4,0,1,1,1,0},
  {0,1,1,1,1,3,1,0,0,0},
  {0,0,0,0,1,2,1,0,0,0},
  {0,0,0,0,1,1,1,0,0,0},
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,0,0,0,0,0,0,0,0}
  },
  {
  {0,0,0,0,0,0,0,0,0,0},
  {0,0,1,1,0,0,1,1,0,0},
  {0,1,0,2,1,1,2,0,1,0},
  {1,0,0,0,3,0,0,0,0,1},
  {1,0,0,0,4,3,0,0,0,1},
  {0,1,0,0,3,3,0,0,1,0},
  {0,0,1,0,0,0,0,1,0,0},
  {0,0,0,1,2,2,1,0,0,0},
  {0,0,0,0,1,1,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,1,0,1,0,0,0,0},
  {0,0,1,2,3,0,1,0,0,0},
  {0,1,0,0,0,0,0,1,0,0},
  {1,2,3,0,4,0,0,0,1,0},
  {0,1,0,0,0,0,0,3,2,1},
  {0,0,1,0,3,0,0,0,1,0},
  {0,0,0,1,2,0,0,1,0,0},
  {0,0,0,0,1,0,1,0,0,0},
  {0,0,0,0,0,1,0,0,0,0}
  }
};

注意还是全局变量,我们设置当r键按下重置本关,所以我们要修改 keyevent()函数,当r按下我们遍历map数组将他赋值为原来的地图

void keyevent()
{
  int i = 0; int j = 0;
  for (i = 0; i < 10; i++)
  {
    for (j = 0; j < 10; j++)
    {
      if (map[level][i][j] == PLAYER || map[level][i][j] == PLAYER + DEST)
      {
        goto end;
      }
    }
  }
end:;
  char ch = _getch();
  //printf("%d    %c", ch, ch);//w 119 a 97 s 115  d 100
  switch (ch)
  {
  case 119:
  case 'w ':
  case 'W':
    if (map[level][i - 1][j] == SPACE || map[level][i - 1][j] == DEST)
    {
      map[level][i - 1][j] += 4;
      map[level][i][j] -= 4;
    }
    else  if (map[level][i - 1][j] == BOX || map[level][i - 1][j] == BOX + DEST)
    {
      if (map[level][i - 2][j] == SPACE || map[level][i - 2][j] == DEST)
      {
        map[level][i - 2][j] += BOX;
        map[level][i - 1][j] = map[level][i - 1][j] - BOX + PLAYER;
        map[level][i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  case 97:
  case 'a ':
  case'A':
    if (map[level][i][j - 1] == SPACE || map[level][i][j - 1] == DEST)
    {
      map[level][i][j - 1] += 4;
      map[level][i][j] -= 4;
    }
    else  if (map[level][i][j - 1] == BOX || map[level][i][j - 1] == BOX + DEST)
    {
      if (map[level][i][j - 2] == SPACE || map[level][i][j - 2] == DEST)
      {
        map[level][i][j - 2] += BOX;
        map[level][i][j - 1] = map[level][i][j - 1] - BOX + PLAYER;
        map[level][i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  case 115:
  case 's ':
  case'S':
    if (map[level][i + 1][j] == SPACE || map[level][i + 1][j] == DEST)
    {
      map[level][i + 1][j] += 4;
      map[level][i][j] -= 4;
    }
    else  if (map[level][i + 1][j] == BOX || map[level][i + 1][j] == BOX + DEST)
    {
      if (map[level][i + 2][j] == SPACE || map[level][i + 2][j] == DEST)
      {
        map[level][i + 2][j] += BOX;
        map[level][i + 1][j] = map[level][i + 1][j] - BOX + PLAYER;
        map[level][i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  case 100:
  case 'd ':
  case'D':
    if (map[level][i][j + 1] == SPACE || map[level][i][j + 1] == DEST)
    {
      map[level][i][j + 1] += 4;
      map[level][i][j] -= 4;
    }
    else  if (map[level][i][j + 1] == BOX || map[level][i][j + 1] == BOX + DEST)
    {
      if (map[level][i][j + 2] == SPACE || map[level][i][j + 2] == DEST)
      {
        map[level][i][j + 2] += BOX;
        map[level][i][j + 1] = map[level][i][j + 1] - BOX + PLAYER;
        map[level][i][j] -= PLAYER;//玩家消失在原来位置
      }
    }
    break;
  case 'r':///新增
  case'R' :///新增
    for (int i = 0; i < 10; i++)///新增
    {///新增
      for (int j = 0; j < 10; j++)///新增
      {
        map[level][i][j] = mapreset[level][i][j];///新增
      }///新增
    }///新增
    break;///新增
  }///新增
}
目录
相关文章
|
7月前
|
算法 C语言 C++
【c语言】飞机大战(1)
【c语言】飞机大战(1)
65 1
|
7月前
|
Linux C语言
俄罗斯方块(c语言)
俄罗斯方块(c语言)
|
C语言
c语言小游戏-推箱子
c语言小游戏-推箱子
|
7月前
|
存储 定位技术 API
c语言——俄罗斯方块
c语言——俄罗斯方块
139 0
|
7月前
|
存储 C语言
【c语言】飞机大战2
【c语言】飞机大战2
58 0
|
7月前
|
C语言
C语言游戏——三字棋
C语言游戏——三字棋
73 0
|
C语言
C语言写一个2048游戏
C语言写一个2048游戏
60 0
|
C语言
C语言实现小游戏之井字棋(上)
C语言实现小游戏之井字棋
156 0
|
C语言
C语言实现小游戏之井字棋(中)
C语言实现小游戏之井字棋
57 0