0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

C语言编程学习基地 来源:C语言编程学习基地 2022-12-27 10:38 次阅读

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

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

效果展示:

2ff3889c-84f8-11ed-bfe3-dac502259ad0.png

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

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

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

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

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

3020c0b4-84f8-11ed-bfe3-dac502259ad0.png

本项目编译环境: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;
}

大家赶紧去动手试试吧!

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 游戏
    +关注

    关注

    2

    文章

    697

    浏览量

    26041
  • C语言
    +关注

    关注

    180

    文章

    7534

    浏览量

    128852
  • 编程
    +关注

    关注

    88

    文章

    3441

    浏览量

    92425
  • 源码
    +关注

    关注

    8

    文章

    574

    浏览量

    28594

原文标题:C语言零基础项目:推箱子游戏!详细思路+源码分享

文章出处:【微信号:cyuyanxuexi,微信公众号:C语言编程学习基地】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    C语言零基项目:涂格子(点灯)游戏详细思路+源码分享

    点灯游戏是一个十分有趣的智力游戏:有一行N行N列的灯,开始时全部是灭的,当你点击其中一盏灯时他的上下左右(若存在的话)状态全部改变,现在要求你在限定的时间内以最少地步数,将全部的灯点亮。
    发表于 12-16 09:47 692次阅读

    C语言零基项目:贪吃蛇!详细思路+源码分享

    每天一个C语言项目,提升你的编程能力!
    发表于 12-19 11:04 444次阅读

    单片机箱子游戏程序模拟仿真

    单片机箱子游戏程序模拟仿真本程序仿真了ks0108驱动芯片的12864液晶屏,独立的5个按键,程序的主要部分是箱子的部分的逻辑。增加计时
    发表于 11-06 20:41

    基于PROTEUS的箱子游戏(proteus仿真电路+汇编源程序)

    基于PROTEUS的箱子游戏
    发表于 07-06 17:26

    基于单片机箱子游戏设计与制作

    请问基于单片机箱子游戏设计与制作。
    发表于 12-14 19:34

    零基础怎样学习C语言呢?

    零基础学c语言如何开始
    发表于 05-15 10:23

    LabView资料分享:箱子游戏

    `附件为LabView编写的箱子游戏源码来自网络,分享给大家,仅供学习用途,不得用于商业用途。如涉及侵权,请联系删除谢谢。另外:对物联网感兴趣的童鞋,可以关注公众号"玩转
    发表于 06-14 16:25

    C语言游戏源码分享

    C语言游戏源码24点火柴人俄罗斯等等等35个游戏源码网盘分享链接:https://pan.ba
    发表于 04-12 17:11

    如何利用STM32制作贪吃蛇和箱子游戏

    如何利用STM32制作贪吃蛇和箱子游戏
    发表于 09-27 08:07

    基于C语言设计编写的ARM箱子

    ARM箱子的原型是基于C语言设计编写的箱子游戏
    发表于 12-14 08:09

    如何用C语言实现推箱子游戏项目

      这篇文章主要为大家详细介绍了 C语言实现——《推箱子项目》 ,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下! 本
    的头像 发表于 11-09 16:28 2351次阅读

    C语言零基项目:打字母游戏详细思路+源码分享

    今天就用C语言写了这么个打字母的小程序,就是以前学习机上那种字母往下掉,然后按相应键字母消失的游戏
    发表于 12-15 15:02 456次阅读

    C语言零基项目:迷宫游戏详细思路+源码分享

    每天一个C语言项目,提升你的编程能力!
    的头像 发表于 12-21 10:08 629次阅读

    C语言零基项目:自制军棋游戏详细思路+源码分享

    每天一个C语言项目,提升你的编程能力!
    的头像 发表于 12-29 17:14 7700次阅读

    C语言零基项目:吃豆人小游戏详细思路+源码分享

    《吃豆游戏》是一款休闲小游戏,和贪吃蛇,球球大作战吃食物都是有差不多的游戏逻辑。
    的头像 发表于 01-03 11:38 991次阅读