C语言零基础项目:推箱子游戏,详细思路+源码分享

每天一个C语言小项目,提升你的编程能力!

推箱子是一个来自日本的古老游戏,目的是在训练你的逻辑思考能力。在一个狭小的仓库中,要求把木箱放到指定的位置,稍不小心就会出现箱子无法移动或者通道被堵住的情况,所以需要巧妙的利用有限的空间和通道,合理安排移动的次序和位置,才能顺利的完成任务。

效果展示:

1、游戏同时支持鼠标和键盘操作,鼠标操作时,可点击任意你想去的地方。

2、提供回复上一步的功能,可以回到任何一步走过的路径,可以给用户足够的思考空间,使用户的智力在游戏的乐趣中得到充分的锻炼。也可以一退到底。

3、屏幕上方显示当前的关数,您可以方便地选关进行游戏。

4、在目标文件夹里,可以用记事本打开文件,自行设计游戏关卡,加载界面及元素,添加后再次打开程序才能更新。

游戏中使用了图片,【点击这里下载完整项目

本项目编译环境:Visual Studio 2019/2022,EasyX插件

代码展示:


//游戏中用0表示空地,1表示人物,2表示箱子,3表示目的地,6表示围墙
//
//画素材的x1和y1都是反的,因为x表示行,但是画出来x表示列,y同



#include <graphics.h>
#include <conio.h>
#include <stdlib.h>

int x, y;							//人物坐标
int loop;							//控制是否重新开始
IMAGE img[8];                     	//定义IMAGE对象数组来保存图片


/*******************函数声明*******************/
void blank(int x1, int y1);	                //画空地
void man  (int x1, int y1);                	//画皮卡丘
void box  (int x1, int y1);	                //画箱子
void dest (int x1, int y1);					//画目的地
void man1 (int x1, int y1);	                //画在目的地上的皮卡丘
void box1 (int x1, int y1);					//画在目的地上的箱子
void wall (int x1, int y1);	                //画围墙
void man1 (int x1, int y1);					//画在胜利的皮卡丘
void print(int a[15][15]);	                //把数组里的全画出来
void move (int a[15][15], int x1, int y1);	//移动
void find (int a[15][15]);	                //找人物坐标
int  win  (int a[15][15]);					//判断游戏是否结束
int  play (int a[15][15]);	                //游戏过程
void play1 (void);	                        //游戏关卡


/*******************函数定义*******************/
//画空地
void blank(int x1, int y1)	
{
	putimage(y1, x1, &img[0]);         // 在坐标 (y1, x1) 位置显示 IMAGE 对象
}

//画皮卡丘
void man(int x1, int y1)	
{
	putimage(y1, x1, &img[1]);         // 在坐标 (y1, x1) 位置显示 IMAGE 对象
}

//画箱子
void box(int x1, int y1)
{
	putimage(y1, x1, &img[2]);         // 在坐标 (y1, x1) 位置显示 IMAGE 对象
}

//画目的地
void dest(int x1, int y1)
{
	putimage(y1, x1, &img[3]);         // 在坐标 (y1, x1) 位置显示 IMAGE 对象
}

//画在目的地上的皮卡丘
void man1(int x1, int y1)
{
	putimage(y1, x1, &img[4]);         // 在坐标 (y1, x1) 位置显示 IMAGE 对象
}

//画在目的地上的箱子
void box1(int x1, int y1)
{
	putimage(y1, x1, &img[5]);         // 在坐标 (y1, x1) 位置显示 IMAGE 对象
}

//画围墙
void wall(int x1, int y1)
{
	putimage(y1, x1, &img[6]);         // 在坐标 (y1, x1) 位置显示 IMAGE 对象
}

//画胜利的皮卡丘
void man2(int x1, int y1)
{
	putimage(y1, x1, &img[7]);         // 在坐标 (y1, x1) 位置显示 IMAGE 对象
}

//把数组里的全画出来
void print(int a[][10])
{
	for(int x1 = 0; x1 < 10; x1++)
		for(int y1 = 0; y1 < 10; y1++)
			putimage(60 * y1, 60 * x1, &img[a[x1][y1]]); 
}

//移动
void move(int a[][10], int x1, int y1)
{
	if(a[x + x1][y + y1] == 0 || a[x + x1][y + y1] == 3)
	{
		a[x][y]--;
		a[x + x1][y + y1]++;
		for(int i = 0; i < 60; i++)
		{
			blank(60 * x + i * x1, 60 * y + i * y1);				//擦掉
			man(60 * x + (i + 1) * x1, 60 * y + (i + 1) * y1);
			Sleep(1);												//为了降低CPU且保存流畅
		}
		if(a[x][y] == 3)
			dest(60 * x, 60 * y);
		x += x1;
		y += y1;
		if(a[x][y] == 4)
			man1(60 * x, 60 * y);
	}
	else if((a[x + x1][y + y1] == 2 || a[x + x1][y + y1] == 5) && (a[x + 2 * x1][y + 2 * y1] == 0 || a[x + 2 * x1][y + 2 * y1] == 3))
	{
		a[x][y]--;
		a[x + x1][y + y1]--;
		a[x + 2 * x1][y + 2 * y1] += 2;
		for(int i = 0; i < 60; i++)
		{
			blank(60 * (x + x1) + i * x1, 60 * (y + y1) + i * y1);	        //擦掉
			box(60 * (x + x1) + (i + 1) * x1, 60 * (y + y1) + (i + 1) * y1);
			blank(60 * x + i * x1, 60 * y + i * y1);						//擦掉
			man(60 * x + (i + 1) * x1, 60 * y + (i + 1) * y1);
			Sleep(1);														//为了降低CPU且保存流畅
		}
		if(a[x][y] == 3)
			dest(60 * x, 60 * y);
		x += x1;
		y += y1;
		if(a[x][y] == 4)
			man1(60 * x, 60 * y);
		if(a[x+x1][y+y1] == 5)
			box1(60 * (x + x1), 60 * (y + y1));
	}
}

//找人物坐标想x,y 
void find(int a[][10])
{
	for(x = 0; x < 10; x++)
		for(y = 0; y < 10; y++)
			if(a[x][y] == 1) return;
}

//判断游戏是否结束
int win(int a[][10])
{
	for(int x1 = 0; x1 < 10; x1++)
		for(int y1 = 0; y1 < 10; y1++)
			if(a[x1][y1] == 2) return 0;					//如果还有箱子返回假
	return 1;												//如果没有箱子返回真
}


/************************游戏过程**********************/
//游戏过程
int play(int a[][10])
{
	loop = 0;
	print(a);
	find(a);												//通过find函数寻找人物的x, y坐标
	do
	{
		switch(getch())										//获取键盘
		{
			case 'w':
			case 'W':move(a, -1, 0);	break;				//上移 
			case 'a':
			case 'A':move(a, 0, -1);	break;				//左移 
			case 'd':
			case 'D':move(a, 0, 1);		break;				//右移 
			case 's':
			case 'S':move(a, 1, 0);		break;				//下移 
			case 'r':
			case 'R':
			case ' ':loop = 1;		return 0;				//重新开始当前关 
			case  27:exit(0);		break;					//结束游戏 
			case 0:
			case 0xE0:										//如果是方向键 
				switch(getch())								//再次获取键盘 
				{
					case 72:move(a, -1, 0);	break;
					case 75:move(a, 0, -1);	break;
					case 77:move(a, 0, 1); 	break;
					case 80:move(a, 1 , 0);
				}
		}
	}while(!win(a));										//通过win函数判断是否通过
	man2(60 * x, 60 * y);									//画一个开心的皮卡丘
	getch();
	return 0;
}

//游戏关卡
void play1(void)
{
	int a[5][10][10]={										//定义三维地图数组
					{	{0},
						{0, 0, 6, 6, 6},
						{0, 0, 6, 3, 6},
						{0, 0, 6, 0, 6, 6, 6, 6},
						{6, 6, 6, 2, 0, 2, 3, 6},
						{6, 3, 0, 2, 1, 6, 6, 6},
						{6, 6, 6, 6, 2, 6},
						{0, 0, 0, 6, 3, 6},
						{0, 0, 0, 6, 6, 6} },
					
					{	{6, 6, 6, 6, 6},
						{6, 1, 0, 0, 6},
						{6, 0, 2, 2, 6, 0, 6, 6, 6},
						{6, 0, 2, 0, 6, 0, 6, 3, 6},
						{6, 6, 6, 0, 6, 6, 6, 3, 6},
						{0, 6, 6, 0, 0, 0, 0, 3, 6},
						{0, 6, 0, 0, 0, 6, 0, 0, 6},
						{0, 6, 0, 0, 0, 6, 6, 6, 6},
						{0, 6, 6, 6, 6, 6} },
					
					{	{0, 6, 6, 6, 6},
						{0, 6, 1, 0, 6, 6, 6},
						{0, 6, 0, 2, 0, 0, 6},
						{6, 6, 6, 0, 6, 0, 6, 6},
						{6, 3, 6, 0, 6, 0, 0, 6},
						{6, 3, 2, 0, 0, 6, 0, 6},
						{6, 3, 0, 0, 0, 2, 0, 6},
						{6, 6, 6, 6, 6, 6, 6, 6} },

					{	{0, 6, 6, 6, 6, 6, 6, 6},
						{0, 6, 0, 1, 3, 3, 3, 6},
						{0, 6, 0, 0, 0, 6, 6, 6, 6},
						{6, 6, 6, 2, 0, 0, 0, 0, 6},
						{6, 0, 0, 0, 6, 2, 6, 0, 6},
						{6, 0, 2, 0, 6, 0, 0, 0, 6},
						{6, 0, 0, 0, 6, 6, 6, 6, 6},
						{6, 6, 6, 6, 6} },
	
					{	{0, 6, 6, 6, 6, 6},
						{0, 6, 0, 1, 0, 6, 6, 6},
						{6, 6, 0, 6, 2, 0, 0, 6},
						{6, 0, 5 ,3, 0, 3, 0, 6},
						{6, 0, 0, 2, 2, 0, 6, 6},
						{6, 6, 6, 0, 6, 3, 6},
						{0, 0, 6, 0, 0, 0, 6},
						{0, 0, 6, 6, 6, 6, 6} } };
	int b[10][10];										//设置当前地图数组 
	for(int i = 0; i < 5; i++)
	{
		do
        {
			loop=0;										//loop置为0
    		for(int x1 = 0; x1 < 10; x1++)
    			for(int y1 = 0; y1 < 10; y1++)
    				b[x1][y1] = a[i][x1][y1];			//对当前地图数组分别赋值 
    		play(b);
		}while(loop);									//如果loop被置为1则重新开始
	}
}


/************************主函数***********************/
int main(void)
{
	initgraph(600, 600);
	setbkcolor(WHITE);
	cleardevice();
	loadimage(&img[0], "图片\\0.jpg");
	loadimage(&img[1], "图片\\1.jpg");
	loadimage(&img[2], "图片\\2.jpg");
	loadimage(&img[3], "图片\\3.jpg");
	loadimage(&img[4], "图片\\4.jpg");
	loadimage(&img[5], "图片\\5.jpg");
	loadimage(&img[6], "图片\\6.jpg");
	loadimage(&img[7], "图片\\7.jpg");
	play1();
	closegraph();
	return 0;
}

大家赶紧去动手试试吧!

此外,我也给大家分享我收集的其他资源,从最零基础开始的教程到C语言C++项目案例,帮助大家在学习C语言的道路上披荆斩棘!

整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)最重要的是你可以在群里面交流提问编程问题哦!

欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!(↓↓↓↓↓↓)

  • 3
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这是一个简单的 C 语言实现推箱子游戏代码项目。游戏中有一个玩家和多个箱子,玩家需要将所有箱子推到目标位置才能过关。 首先,我们需要定义游戏地图。在这个例子中,我们将使用一个二维数组来表示地图。其中,0 表示空格,1 表示墙壁,2 表示箱子,3 表示目标位置,4 表示玩家。 ``` int map[8][8] = { {1, 1, 1, 1, 1, 1, 1, 1}, {1, 0, 0, 0, 0, 0, 0, 1}, {1, 0, 2, 0, 3, 0, 0, 1}, {1, 0, 0, 0, 2, 0, 0, 1}, {1, 0, 3, 2, 0, 0, 0, 1}, {1, 0, 0, 0, 2, 0, 0, 1}, {1, 0, 0, 0, 0, 0, 0, 1}, {1, 1, 1, 1, 1, 1, 1, 1}, }; ``` 然后,我们需要定义玩家和箱子的位置。在这个例子中,我们将使用两个整数变量来表示玩家的横向位置和纵向位置,以及一个二维数组来表示箱子的位置。 ``` int playerX = 4; int playerY = 4; int boxes[3][2] = {{2, 2}, {3, 3}, {4, 2}}; ``` 接下来,我们需要定义游戏主循环。在游戏主循环中,我们需要不断地读取玩家的输入,并根据输入移动玩家和箱子的位置。 ``` while (1) { // 显示游戏地图 displayMap(); // 读取玩家的输入 char input = getch(); // 移动玩家和箱子的位置 switch (input) { case 'w': movePlayer(-1, 0); break; case 's': movePlayer(1, 0); break; case 'a': movePlayer(0, -1); break; case 'd': movePlayer(0, 1); break; default: break; } // 检查箱子是否到达目标位置 checkBoxes(); // 检查是否通关 if (isFinished()) { printf("Congratulations! You Win!\n"); break; } } ``` 在游戏主循环中,我们还需要实现显示游戏地图、移动玩家和箱子的位置、检查箱子是否到达目标位置以及检查是否通关的功能。 ``` void displayMap() { for (int i = 0; i < 8; i++) { for (int j = 0; j < 8; j++) { if (i == playerX && j == playerY) { printf("4"); } else if (map[i][j] == 1) { printf("#"); } else if (map[i][j] == 2) { // 判断该箱子是否在目标位置上 int isOnTarget = 0; for (int k = 0; k < 3; k++) { if (boxes[k][0] == i && boxes[k][1] == j) { isOnTarget = map[i][j] == 3; break; } } printf("%c", isOnTarget ? 'O' : 'X'); } else if (map[i][j] == 3) { printf("o"); } else { printf(" "); } } printf("\n"); } } void movePlayer(int dx, int dy) { // 判断玩家是否可以移动到目标位置 int targetX = playerX + dx; int targetY = playerY + dy; if (map[targetX][targetY] == 0 || map[targetX][targetY] == 3) { // 移动玩家 playerX = targetX; playerY = targetY; } else if (map[targetX][targetY] == 2) { // 判断箱子是否可以被移动到目标位置 int targetBoxX = targetX + dx; int targetBoxY = targetY + dy; if (map[targetBoxX][targetBoxY] == 0 || map[targetBoxX][targetBoxY] == 3) { // 移动箱子和玩家 for (int i = 0; i < 3; i++) { if (boxes[i][0] == targetX && boxes[i][1] == targetY) { boxes[i][0] = targetBoxX; boxes[i][1] = targetBoxY; break; } } playerX = targetX; playerY = targetY; } } } void checkBoxes() { for (int i = 0; i < 3; i++) { int boxX = boxes[i][0]; int boxY = boxes[i][1]; if (map[boxX][boxY] == 3) { map[boxX][boxY] = 2; } } } int isFinished() { for (int i = 0; i < 3; i++) { int boxX = boxes[i][0]; int boxY = boxes[i][1]; if (map[boxX][boxY] != 3) { return 0; } } return 1; } ``` 这样,我们就完成了一个简单的 C 语言实现推箱子游戏代码项目。在实际应用中,可以使用更复杂的地图和更多的箱子来增加游戏难度。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值