C语言简单游戏编程学习入门之推箱子

运行结果预览图

在这里插入图片描述

源代码

#include<stdio.h>
#include<conio.h>
#include<windows.h>

//定义地图信息
#define row 8
#define col 8 
int map[row][col]={
	{0,0,1,1,1,0,0,0},
	{0,0,1,4,1,0,0,0},
	{0,0,1,0,1,1,1,1},
	{1,1,1,2,0,2,4,1},
	{1,4,0,2,5,1,1,1},
	{1,1,1,1,2,1,0,0},
	{0,0,0,1,4,1,0,0},
	{0,0,0,1,1,1,0,0}
};

//人物位置 
int person_x=4;
int person_y=4; 

//定义代号
#define PERSON 5		//注意 人进了空地也显示人,所以9也是人的代号 
#define PERSON_DESTINATION 9
#define person "人"
#define FLOOR 0			//空地 
#define floor "  "
#define WALL 1			//墙壁 
#define wall "■"
#define BOX 2 			//箱子 
#define box "●"
#define DESTINATION 4 	//目的地 
#define destination "☆"
#define PERFECT 6 		//箱子进了目的地 
#define perfect "★"

//打印地图 
void PrintMap();
//判断是否已经完成了游戏
int IsWin(); 
//gotoxy函数的实现,把光标移到到指定位置 
void gotoxy(int x,int y);
//人物移动 
void turn();

int main()
{
	while(1)
	{
		PrintMap();
		if(IsWin())
		{
			break;
		}
		turn();
	}
	printf("恭喜啦!\n");
	return 0;
}

//打印地图 
void PrintMap()
{
	int i,j;
	gotoxy(0,0);
	for(i=0;i<row;i++)
	{
		for(j=0;j<col;j++)
		{
			switch(map[i][j])
			{
				case PERSON:
				case PERSON_DESTINATION:
					printf("%s",person);break;
				case FLOOR:
					printf("%s",floor);break;
				case WALL:
					printf("%s",wall);break;
				case BOX:
					printf("%s",box);break;
				case DESTINATION:
					printf("%s",destination);break;
				case PERFECT:
					printf("%s",perfect);break;
				default:
					printf("error!");
			}	
		}	
		printf("\n");
	} 
	printf("\n");
} 

//判断是否已经完成了游戏(当没有箱子时,游戏成功) 
int IsWin()
{
	int i,j;
	for(i=0;i<row;i++)
	{
		for(j=0;j<col;j++)
		{
			if(map[i][j]==BOX)
			{
				return 0;
			}
		}
	}
	return 1;
}

//gotoxy函数的实现,把光标移到到指定位置 
void gotoxy(int x,int y)
{
	COORD pos;
	pos.X=y;
	pos.Y=x;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),pos); 
} 

//人物移动 
void turn()
{
	char c=getch();
	switch(c)
	{
		case 'w':
			//上面是空地或目的地 
			if(person_x-1>=0&&(map[person_x-1][person_y]==FLOOR||map[person_x-1][person_y]==DESTINATION))
			{
				map[person_x-1][person_y]+=PERSON;
				map[person_x][person_y]-=PERSON; 
				person_x--;
			}
			//上面是箱子,再上面是空地或目的地 
			else if(person_x-2>=0&&(map[person_x-1][person_y]==BOX||map[person_x-1][person_y]==PERFECT)&&(map[person_x-2][person_y]==FLOOR||map[person_x-2][person_y]==DESTINATION))
			{
				map[person_x-2][person_y]+=BOX;
				map[person_x-1][person_y]-=BOX;
				map[person_x-1][person_y]+=PERSON;
				map[person_x][person_y]-=PERSON;
				person_x--;
			} 
			break;
		case 's':
			//下面是空地或者目的地
			if(person_x+1<row&&(map[person_x+1][person_y]==FLOOR||map[person_x+1][person_y]==DESTINATION)) 
			{
				map[person_x+1][person_y]+=PERSON;
				map[person_x][person_y]-=PERSON;
				person_x++;
			}
			//下面是箱子,再下面是空地或者目的地 
			else if(person_x+2<row&&(map[person_x+1][person_y]==BOX||map[person_x+1][person_y]==PERFECT)&&(map[person_x+2][person_y]==FLOOR||map[person_x+2][person_y]==DESTINATION)) 
			{
				map[person_x+2][person_y]+=BOX;
				map[person_x+1][person_y]-=BOX;
				map[person_x+1][person_y]+=PERSON;
				map[person_x][person_y]-=PERSON;
				person_x++;
			}
			break;
		case 'a':
			//左边是空地或者目的地
			if(person_y-1>=0&&(map[person_x][person_y-1]==FLOOR||map[person_x][person_y-1]==DESTINATION)) 
			{
				map[person_x][person_y-1]+=PERSON;
				map[person_x][person_y]-=PERSON;
				person_y--;
			}
			//左边是箱子,再左边是空地或者目的地
			else if(person_y-2>=0&&(map[person_x][person_y-1]==BOX||map[person_x][person_y-1]==PERFECT)&&(map[person_x][person_y-2]==FLOOR||map[person_x][person_y-2]==DESTINATION))
			{
				map[person_x][person_y-2]+=BOX;
				map[person_x][person_y-1]-=BOX;
				map[person_x][person_y-1]+=PERSON;
				map[person_x][person_y]-=PERSON;
				person_y--;	
			} 
			break;
		case 'd':
			//右边是空地或者目的地
			if(person_y+1<col&&(map[person_x][person_y+1]==FLOOR||map[person_x][person_y+1]==DESTINATION)) 
			{
				map[person_x][person_y+1]+=PERSON;
				map[person_x][person_y]-=PERSON;
				person_y++;
			}
			//右边是箱子,再右边是空地或者目的地
			else if(person_y+2<col&&(map[person_x][person_y+1]==BOX||map[person_x][person_y+1]==PERFECT)&&(map[person_x][person_y+2]==FLOOR||map[person_x][person_y+2]==DESTINATION))
			{
				map[person_x][person_y+2]+=BOX;
				map[person_x][person_y+1]-=BOX;
				map[person_x][person_y+1]+=PERSON;
				map[person_x][person_y]-=PERSON;
				person_y++;
			} 
			break;
		default:
			break;	
	} 
} 

设计介绍

首先我们需要知道自己要做哪个关卡,我从网上搜了最简单的第一关。
其次呢我们需要给关卡的每个图片定义一个代号的数字,比如0表示空地,1表示墙壁,2表示箱子,4表示箱子需要推到的目的地,6(2+4)表示箱子推进目的地,5表示玩家,9(5+4)表示玩家进入了目的地。我们选取数字代号虽然说是任意的,但是要注意不能用一样的代号代表不同的图形(这里也是为啥目的地不选3的原因,选3的话,箱子进了目的地的结果是2+3=5,和玩家一样了)。当然大家可以根据自己喜好换别的数字当做玩家。
接下来我们按照代号将地图用一个二维数组表示(map[row][col]),并且设置好行列的宏定义(row,col)。
前期工作都准备好了,我们要开始设计游戏的逻辑实现了。我们先要把关卡内容展示出来,所以需要一个打印地图的函数(PrintMap());展示出来之后呢,玩家可以根据自己看到的关卡地图进行操作嘛,所以我们需要一个操作函数(turn());玩家每次操作完之后,都有可能已经通关了,所以我们需要一个判断玩家是否已经通关的函数(IsWin())。最后再把这几个函数拼凑在主函数中调用,这样一个简单的推箱子游戏就完成啦。如果想设置多层关卡,可以结合文件操作哦!先将地图信息都保存在文件中,将文件名设置为关卡名,如1.txt表示第一关的关卡内容。地图信息包括行、列、详细图形代号。在我们需要读取关卡时,只需要设置一个函数读取即可,然后需要将玩家的坐标计算出来,再进行以上操作。

设计总结

	这个推箱子可以加深我们的二维数组应用经验,同时判断玩家移动的过程也让我们的逻辑思维能力得到了提高,对事情的多角度思考有莫大的帮助。
	有兴趣的话还可以添加撤销功能,思路如下:每次玩家移动,都记录下来存在一个数组中(直接记录玩家的移动方向即可,当收到玩家的撤销请求时,先把地图还原为关卡初始状态,然后依次读入记录数组的移动方向,读取到倒数第二个即可,然后把数组的长度减一)。
	对于添加关卡,我们还可以用到文件操作,加深文件操作的理解和运用能力。
	总的来说,推箱子的设计可以多方面巩固我们的已有知识,甚至有的小伙伴想要设计让电脑自动推箱子的话,我们还得需要用到人工智能的知识,这样还会激发我们的求知欲。闲暇之余设计一下简单游戏,无疑是有百利而无一害的。
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值