c语言游戏实战(6):走迷宫之推箱子

前言:

在上一篇文章当中我介绍了一个走迷宫的写法,但是那个迷宫没什么可玩性和趣味性,所以我打算在迷宫的基础上加上一个推箱子,使之有更好的操作空间,从而增强了游戏的可玩性和趣味性。

1. 打印菜单

void menu()
{
	printf("|---------------------------------------|\n");
	printf("|                                       |\n");
	printf("|                走迷宫                 |\n");
	printf("|                1.Start                |\n");
	printf("|                2.Exit                 |\n");
	printf("|                e.Restart              |\n");
	printf("|                                       |\n");
	printf("|---------------------------------------|\n");
}
int main()
{
	int input = 0;
	do
	{
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
		case 1:
			game();
			break;
		case 0:
			printf("退出游戏!\n");
			break;
		default:
			printf("选择有误,请重新选择!\a\n");
		}
	} while (input);
}

2. 分析迷宫的组成要素

迷宫的组成要素无非就是:墙、路、入口、出口,根据这些要素我们可以设置一个数组然后随机给其赋值为0,1,2,3,当数组等于0时打印路(这里用空格代替),等于1时打印墙(这里用█代替),等于2打印入口(这里用S代替),等于3时打印出口(这里用E代替)。

3. 实现迷宫的组成要素

因为这些要素的生成都与随机数有关,所以这里就要使用到time函数、srand函数和rand函数来进行随机数的生成。

#include
srand((time(NULL))
int x = rand();

3.1 生成路

给数组初始化为0生成路,后面再用随机数生成。

  for (int i = 0; i < SIZE; i++)
  {
      for (int j = 0; j < SIZE; j++)
      {
          maze[i][j] = 0;
      }
  }

3.2 生成围墙

还需要设置围墙将我们的迷宫围起来,防止数组的越界访问。

for (int i = 0; i < SIZE; i++)
{
    maze[0][i] = 1;
    maze[i][0] = 1;
    maze[SIZE - 1][i] = 1;
    maze[i][SIZE - 1] = 1;
}

3.3 生成入口、出口和箱子

因为入口、出口和箱子(我在这里只设置了一个)都是只有一个,所以这里我们需要单独使用随机数生成入口、出口和箱子。

  //设置入口
 int start_x = rand() % SIZE;
 int start_y = rand() % SIZE;
 maze[start_y][start_x] = 2;
 //设置出口
 int end_x = rand() % SIZE;
 int end_y = rand() % SIZE;
 maze[end_y][end_x] = 3;
 //设置箱子
 int box_x = rand() % SIZE;
 int box_y = rand() % SIZE;
 maze[box_y][box_x] = 4;

3.4 防止入口、出口和箱子出现在错误的位置上

这里使用了goto语句

3.4.1 防止入口和出口出现在围墙上

 again:
 //防止入口或出口出现在围墙上
  if (start_x == 0 || start_x == SIZE - 1 || start_y == 0 || start_y == SIZE - 1
      || end_x == 0 || end_x == SIZE - 1 || end_y == 0 || end_y == SIZE - 1
      || box_x == 0 || box_x == SIZE - 1 || box_y == 0 || box_y == SIZE - 1)
      goto again;

3.41 防止箱子出现在围墙的边上

因为如果箱子出现在边上,这个箱子就推不了左右了。所以需要防止箱子出现在围墙的边上

again:
//防止箱子出现在边上
if (box_y == 1 || box_y == SIZE || box_x == 1 || box_x == SIZE)
    goto again;

3.5 生成墙

for (int i = 0; i < SIZE; i++)
{
    for (int j = 0; j < SIZE; j++)
    {
        if (maze[i][j] != 2 && maze[i][j] != 3)
        {
            if (rand() % 4 == 0)
            {
                maze[i][j] = 1;
            }
        }
    }
}

4. 操作移动

4.1 getch函数

在这里用到了getch()函数,这个函数需要用#include 来进行调用。

#include 
int main()
{
	while (1)
	{
		int x = getch(); 
		if (x == 'w')
			printf("上\n");
		if (x == 'a')
			printf("左\n");
		if (x == 's')
			printf("下\n");
		if (x == 'd')
			printf("右\n");
	}
	return 0;
}

4.2 操作S的移动: 

输入w向上移动,输入s向下移动,输入a向左移动,输入d向右移动。

以输入w向上移动为例:

需要满足S的上一个格子是路,也就是需要满足maze[start_y - 1][start_x] == 0才会接受向上移动的信息,而要想实现一个向上移动的效果,我们就需要将原来的位置变为路也就是使maze[start_y][start_x] = 0;,然后使原来位置的上一个变为S也就是 start_y--; maze[start_y][start_x] = 2;

完整的移动代码: 

if (x == 'w')//上
    {
        if (maze[start_y - 1][start_x] == 0)
        {
            maze[start_y][start_x] = 0;
            start_y--;
            maze[start_y][start_x] = 2;
        }
    }

其中system("cls")函数的作用是清屏,它需要使用#icnldue进行调用。 

4.3 操作箱子的移动: 

以向上移动为例:

箱子可以向上移动的前提是:

1.箱子出现在S的上面,也就是maze[start_y - 1][start_x] == 4

2.箱子的上面不是墙,也就是maze[box_y - 1][box_x] != 1

实现一个向上移动的效果:

实现这个移动效果的写法与移动S的写法相同

if (x == 'w')//上
{
    if (maze[start_y - 1][start_x] == 4)
    {
            if (maze[box_y - 1][box_x] != 1)
            {
                maze[box_y][box_x] = 0;
                box_y--;
                maze[box_y][box_x] = 4;
            }
    }

4.5 完整移动代码: 

do
{
    system("cls");
    print_maze(maze);
    int x = getch();
    if (x == 'w')//上
    {
        if (maze[start_y - 1][start_x] == 4)
        {
                if (maze[box_y - 1][box_x] != 1)
                {
                    maze[box_y][box_x] = 0;
                    box_y--;
                    maze[box_y][box_x] = 4;
                }
        }
        if (maze[start_y - 1][start_x] != 1 && maze[start_y - 1][start_x] != 4&& maze[start_y - 1][start_x] != 3)
        {
            maze[start_y][start_x] = 0;
            start_y--;
            maze[start_y][start_x] = 2;
        }
       
    }
    if (x == 'a')//左
    {
        if (maze[start_y][start_x - 1] == 4)
        {
            if (maze[box_y][box_x - 1] != 1)
            {
                maze[box_y][box_x] = 0;
                box_x--;
                maze[box_y][box_x] = 4;
            }
        }
        if (maze[start_y][start_x - 1] != 1 && maze[start_y][start_x - 1] != 4 && maze[start_y][start_x - 1] != 3)
        {
            maze[start_y][start_x] = 0;
            start_x--;
            maze[start_y][start_x] = 2;
        }
    }
    if (x == 's')//下
    {
        if (maze[start_y + 1][start_x] == 4)
        {
            if (maze[box_y + 1][box_x] != 1)
            {
                maze[box_y][box_x] = 0;
                box_y++;
                maze[box_y][box_x] = 4;
            }
        }
        if (maze[start_y + 1][start_x] != 1 && maze[start_y + 1][start_x] != 4 && maze[start_y + 1][start_x] != 3)
        {
            maze[start_y][start_x] = 0;
            start_y++;
            maze[start_y][start_x] = 2;
        }
    }
    if (x == 'd')//右
    {
        if (maze[start_y][start_x + 1] == 4)
        {
            if (maze[box_y][box_x + 1] != 1)
            {
                maze[box_y][box_x] = 0;
                box_x++;
                maze[box_y][box_x] = 4;
            }
        }
        if (maze[start_y][start_x + 1] != 1&& maze[start_y][start_x + 1] != 4 && maze[start_y][start_x + 1] != 3)
        {
            maze[start_y][start_x] = 0;
            start_x++;
            maze[start_y][start_x] = 2;
        }
    }
  
} while (1);

其中system("cls")函数的作用是清屏,它需要使用#icnldue进行调用。 

5. 游戏的结束与游戏的重开

当门的位置等于箱子也就是maze[end_y][end_x] == 4即为通关成功。

加一个e的指令重开游戏

 if (x == 'e')
        {
            system("cls");
            printf("重新开始游戏!\n");
            break;
        }

完整代码 :

#define _CRT_SECURE_NO_WARNINGS 1
#include
#include 
#include 
#include
#define SIZE 45
//打印迷宫
void print_maze(int maze[SIZE][SIZE])
{
    for (int i = 0; i < SIZE; i++)
    {
        for (int j = 0; j < SIZE; j++)
        {
            if (maze[i][j] == 1)
            {
                printf("█");
            }
            else if (maze[i][j] == 2)
            {
                printf("S");//入口
            }
            else if (maze[i][j] == 3)
            {
                printf("E");//出口
            }
            else if (maze[i][j] == 4)
            {
                printf("@");//箱子
            }
            else
            {
                printf(" ");
            }
        }
        printf("\n");
    }
    printf("\n");
}

void generate_maze(int maze[SIZE][SIZE])
{
again:
    for (int i = 0; i < SIZE; i++)
    {
        for (int j = 0; j < SIZE; j++)
        {
            maze[i][j] = 0;
        }
    }
    //围墙
    for (int i = 0; i < SIZE; i++)
    {
        maze[0][i] = 1;
        maze[i][0] = 1;
        maze[SIZE - 1][i] = 1;
        maze[i][SIZE - 1] = 1;
    }
    //设置入口
    int start_x = rand() % SIZE;
    int start_y = rand() % SIZE;
    maze[start_y][start_x] = 2;
    //设置出口
    int end_x = rand() % SIZE;
    int end_y = rand() % SIZE;
    maze[end_y][end_x] = 3;
    //设置箱子
    int box_x = rand() % SIZE;
    int box_y = rand() % SIZE;
    maze[box_y][box_x] = 4;

    //防止入口或出口出现在围墙上
    if (start_x == 0 || start_x == SIZE - 1 || start_y == 0 || start_y == SIZE - 1
        || end_x == 0 || end_x == SIZE - 1 || end_y == 0 || end_y == SIZE - 1
        || box_x == 0 || box_x == SIZE - 1 || box_y == 0 || box_y == SIZE - 1)
    {
        goto again;
    }
    //防止箱子出现在边上
    if (box_y == 1 || box_y == SIZE || box_x == 1 || box_x == SIZE)
        goto again;
    //设置迷宫
    for (int i = 0; i < SIZE; i++)
    {
        for (int j = 0; j < SIZE; j++)
        {
            if (maze[i][j] != 2 && maze[i][j] != 3 && maze[i][j] != 4)
            {
                if (rand() % 5 == 0)
                {
                    maze[i][j] = 1;
                }
            }
        }
    }
    //操作S移动
    do
    {
        system("cls");
        print_maze(maze);
        int x = getch();
        if (x == 'w')//上
        {
            if (maze[start_y - 1][start_x] == 4)
            {
                if (maze[box_y - 1][box_x] != 1)
                {
                    maze[box_y][box_x] = 0;
                    box_y--;
                    maze[box_y][box_x] = 4;
                }
            }
            if (maze[start_y - 1][start_x] != 1 && maze[start_y - 1][start_x] != 4 && maze[start_y - 1][start_x] != 3)
            {
                maze[start_y][start_x] = 0;
                start_y--;
                maze[start_y][start_x] = 2;
            }

        }
        if (x == 'a')//左
        {
            if (maze[start_y][start_x - 1] == 4)
            {
                if (maze[box_y][box_x - 1] != 1)
                {
                    maze[box_y][box_x] = 0;
                    box_x--;
                    maze[box_y][box_x] = 4;
                }
            }
            if (maze[start_y][start_x - 1] != 1 && maze[start_y][start_x - 1] != 4 && maze[start_y][start_x - 1] != 3)
            {
                maze[start_y][start_x] = 0;
                start_x--;
                maze[start_y][start_x] = 2;
            }
        }
        if (x == 's')//下
        {
            if (maze[start_y + 1][start_x] == 4)
            {
                if (maze[box_y + 1][box_x] != 1)
                {
                    maze[box_y][box_x] = 0;
                    box_y++;
                    maze[box_y][box_x] = 4;
                }
            }
            if (maze[start_y + 1][start_x] != 1 && maze[start_y + 1][start_x] != 4 && maze[start_y + 1][start_x] != 3)
            {
                maze[start_y][start_x] = 0;
                start_y++;
                maze[start_y][start_x] = 2;
            }
        }
        if (x == 'd')//右
        {
            if (maze[start_y][start_x + 1] == 4)
            {
                if (maze[box_y][box_x + 1] != 1)
                {
                    maze[box_y][box_x] = 0;
                    box_x++;
                    maze[box_y][box_x] = 4;
                }
            }
            if (maze[start_y][start_x + 1] != 1 && maze[start_y][start_x + 1] != 4 && maze[start_y][start_x + 1] != 3)
            {
                maze[start_y][start_x] = 0;
                start_x++;
                maze[start_y][start_x] = 2;
            }
        }

        if (maze[end_y][end_x] == 4)
        {
            system("cls");
            print_maze(maze);
            printf("恭喜你成功通关!\n");
            break;
        }
        if (x == 'e')
        {
            system("cls");
            printf("重新开始游戏!\n");
            break;
        }
    } while (1);

}
void menu()
{
    printf("|---------------------------------------|\n");
    printf("|                                       |\n");
    printf("|                走迷宫                 |\n");
    printf("|                1.play                 |\n");
    printf("|                2.exit                 |\n");
    printf("|                                       |\n");
    printf("|---------------------------------------|\n");
}



void game()
{
    srand(time(NULL));
    int maze[SIZE][SIZE];
    //打印迷宫
    generate_maze(maze);
}

int main()
{
    int input = 0;
    do
    {
        menu();
        printf("请选择:");
        scanf("%d", &input);
        switch (input)
        {
        case 1:
            game();
            break;
        case 0:
            printf("退出游戏!\n");
            break;
        default:
            printf("选择有误,请重新选择!\a\n");
        }
    } while (input);
}

效果图: 

以上就是《走迷宫之推箱子》的全部内容啦,如果上述内容对你有帮助的话不要忘记点上一个关注支持一下小编呦,期待我们下次再见。

你可能感兴趣的:(c语言,游戏,开发语言,学习)