每天一个C语言小项目,提升你的编程能力!
推箱子是一个来自日本的古老游戏,目的是在训练你的逻辑思考能力。在一个狭小的仓库中,要求把木箱放到指定的位置,稍不小心就会出现箱子无法移动或者通道被堵住的情况,所以需要巧妙的利用有限的空间和通道,合理安排移动的次序和位置,才能顺利的完成任务。
效果展示:
1、游戏同时支持鼠标和键盘操作,鼠标操作时,可点击任意你想去的地方。
2、提供回复上一步的功能,可以回到任何一步走过的路径,可以给用户足够的思考空间,使用户的智力在游戏的乐趣中得到充分的锻炼。也可以一退到底。
3、屏幕上方显示当前的关数,您可以方便地选关进行游戏。
4、在目标文件夹里,可以用记事本打开文件,自行设计游戏关卡,加载界面及元素,添加后再次打开程序才能更新。
游戏中使用了图片
本项目编译环境:Visual Studio 2019/2022,EasyX插件
代码展示:
////////////////////////////////////////////////////////////
//游戏中用0表示空地,1表示人物,2表示箱子,3表示目的地,6表示围墙
//
//画素材的x1和y1都是反的,因为x表示行,但是画出来x表示列,y同
////////////////////////////////////////////////////////////
#include
#include
#include
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语言的道路上披荆斩棘!
编程学习书籍分享:
编程学习视频分享:
整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)最重要的是你可以在群里面交流提问编程问题哦!
对于C/C++感兴趣可以关注小编在后台私信我:【编程交流】一起来学习哦!可以领取一些C/C++的项目学习视频资料哦!已经设置好了关键词自动回复,自动领取就好了!
哈喽大家好,我是周小输。五一假期大家是怎么过的呢?出去玩耍还是窝在家里打游戏?反正对于小输这种宅男,肯定妥妥得卧在被窝打游戏。最近三国杀移动版也推出的五一活动也非常的奈斯,游戏通关就可以拿到史诗宝珠。在家躺着玩玩小游戏就能拿到两个史诗宝珠和五个招募令五十个盒子,是不是会让这个假期更加的快乐呢?
此次移动官方的公众号有一个简单的小游戏推箱子,通关后就可以获得史诗宝珠,这次活动也可以说是游卡做的最良心的一次了。虽然整体游戏不是特别难,但还是有几关需要费费脑子的。于是小输今天奉上这个小游戏中比较难点关卡的攻略,希望大家都能拿到史诗宝珠。
由于全部粘图加攻略会让平台判定水文,所以这次小输带来的攻略也是挑出其中两个比较绕一点的关卡,希望能给大家带来帮助。
这关是小输看到网友找攻略最多的一关,解题思路就是两边往下推,中间的箱子再往左推一下打开道路就比较容易了。具体的解法是:下上右右下左下下右上上左下下左左上右右下右上左上上左下右下下左左上右。
这关也会衍生出很多类似的关卡,其实解题思路还是差不多的,只要把两边的往下推一下,打开道路就容易过关了。
这个关卡也非常的经典,你应该会遇上好几次的。解题思路:先把一号箱子向上推下,然后再把二号箱子向左推一下,再绕到上面把一号推到三号的位置,再把二号箱子向右推到原来一号的位置就能解开了。
整体游戏没有几个难点的关卡,但是有时候就是看着有点懵,但是动手之后慢慢就有了思路了。这次推箱子游戏每局没有时间和步数的限制,只要看着比较难,就可以先思考一下再动手,也是比较容易一天就通关的。
如果小伙伴们实在是不愿意动脑子的话,小输就在这里放个大招:在网上找一个推箱子计算器,遇见不会的关卡直接自己动手做一个相同的关卡让电脑解题,解开以后根据提示操作自己完成就行,用这个方法直接就可以一体力通关了。
游戏通关后就可以获得一个史诗宝珠,再加上集卡活动可以拿到共计两个史诗宝珠,而且每关都可以拿到一个牛年大吉盒子,偶尔的关卡中还能拿到招募令,这次的游卡真的是有点大放血的意思。
本次的活动虽然是截止到5月16号,但是我相信大家小输的攻略一天就可以完成了,这么多盒子和招募令,希望大家都能开出自己想要的武将!如果小伙伴们开出来什么喜欢的武将欢迎来评论区留言哦!