一个适合初学者的C++推箱子小游戏

博主最近在学习关于C++的一些基础,这是本人突发奇想做的一个小游戏,编程其实并不难,重要的是,你的思路,以及优化,当然,这个小游戏,本人也是基于一个学习者编写的

本篇文章会教大家用C++基本语句来实现一个推箱子的小游戏。

展示

这是游戏开始时的界面。


当然,如果你喜欢,你可以任意更改地图:

当把所有箱子推到目的地,就完成游戏

思路:

当有一个问题出现的时候,我们首先应该先考虑这个问题有可能的解法:
这里博主想到的方法是

1. 通过二维数组来存储地图信息
2. 通过交换数组元素,来达到角色移动的目的
3. 而推箱子,则让箱子和角色同步移动便可。
4. 移动控制:_getch()

ps:_getch()方法需要头文件conio.h的支持,功能是不需要按回车键便可以得到输入的字符

那么这里我们有了大概的思路,但是再实际操作中,我们发现二维数组并不方便,因为它有两个下标,会加剧问题的复杂度,这里我们用一维数组便可。
移动:我们知道地图是一个方形:要么是m*n,要么就是m^2(正方形);

这里我们简单绘制一个长4,宽4的长方体来说明:

如果我在5的位置,那么我要左移,应该是当前位置 -1,同样,向右便是 +1,向上 -4,向下 +4。

地图:

有了这些知识,我们便可以开始编程了,首先写出地图:

int map[100] =                   //玩家地图{1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,3,0,4,0,0,1,1,2,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,3,0,4,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,3,0,0,0,0,1,1,0,0,0,0,0,0,4,0,1,1,1,1,1,1,1,1,1,1,1};

上面地图中:0代表空地,1代表墙壁,2代表玩家,3代表箱子,4代表箱子目的地,5代表当人和箱子目的地重合的时候显示的图标,6代表箱子放在正确位置时候的图标

for (int i = 0; i < 100; i++){switch (map[i]){case 1:std::cout << "□"; break;     //墙壁case 0:std::cout << "  "; break;     //空地case 2:std::cout << "Pe"; break;     //人case 3:std::cout << "■"; break;    //箱子case 4:std::cout << "**"; break;    //箱子目的地case 5:std::cout << "×"; break;    //和人重合case 6:std::cout << "√"; break;    //和箱子重合}if (i % w == 9)std::cout << '\n';}

我们打印一下:
我们发现和我们一维数组里的数字所代表的意义是一样的!

移动:

移动需要记录当前位置和移动的目标位置,比如你向上,那么
当前坐标=(当前坐标-地图宽度)

我们声明如下变量:

    int input;                       //输入常数int nowpoint=31;             //玩家现在的地点int shift;                       //玩家目标点const int w=10;                  //地图宽度

移动方法如下:

                    shift = map[nowpoint-w];         //把目标点赋值给shiftmap[nowpoint - w] = map[nowpoint];     map[nowpoint] = shift;                   //移动目标点nowpoint -= w;                              //移动当前所处的坐标位置

当然,我们要保证它不会“穿墙”:于是:

         shift = map[nowpoint-w];if (shift == 0)              //目标点必须是空地才能移动!{map[nowpoint - w] = map[nowpoint];map[nowpoint] = shift;nowpoint -= w;}

但是我们的推箱子人物都是可以穿过箱子的目标地点,也就是:


于是有如下代码:

shift = map[nowpoint-w];         //下一个移动的目标点设置给shiftif (shift ==0)                    //当下一个目标是空地的时候{if (map[nowpoint] == 5)       //当和箱子目标点重合的时候且需要移动到空地{map[nowpoint] = 2;               //当前坐标设置为玩家map[nowpoint - w] = map[nowpoint];    //下一个坐标为玩家map[nowpoint] = 4;              //当前坐标为箱子目标点nowpoint -= w;                  //移动当前坐标}else                        //如果没有和箱子目标点重合,则正常移动{map[nowpoint - w] = map[nowpoint];     map[nowpoint] = shift;nowpoint -= w;}}if (shift == 4)                  //当下一个个目标点为箱子目标点时{map[nowpoint - w] = 5;            //目标点变为人和箱子重合的图案map[nowpoint] = 0;                //当前点变为空地nowpoint -= w;                    //移动人物的坐标}

那么有了这么一个开头,剩下的三个方向也就以此类推了。

接下来是推箱子部分:

这里我们需要注意的是,推箱子的时候,我们不仅仅要考虑玩家(2)的下一个坐标的情况,还要考虑箱子的移动坐标是否超出了我们的地图,那么通过本人总结,那么箱子前进的时候,玩家和箱子会遇到如下的情况:

  1. 前方是墙壁
  2. 前方是箱子
  3. 前方是箱子目的地
  4. 前方是放好的箱子
  5. 前方是空地

玩家有两种情况:

  1. 玩家处于箱子目的地的时候推箱子
  2. 玩家处于箱子目的地,但是推动的方向是墙壁

于是,我们有如下代码:

           if (shift == 3)                    //目标点为箱子{if (map[nowpoint- 2 * w]!=1&& map[nowpoint - 2 * w] != 3 && map[nowpoint - 2 * w] != 6)         //箱子的下一个目标点不能是墙壁,或者箱子{if (map[nowpoint - 2 * w] == 4)                     //箱子的下一个目标点是箱子目的地{map[nowpoint - 2*w] = 6;                       //箱子的下一个目标点变为和箱子重合map[nowpoint - w] = map[nowpoint];             //箱子的位置变为玩家位置map[nowpoint] = 0;                             //玩家为之变为空地nowpoint -=   w;                                 //移动玩家坐标}else if (map[nowpoint] == 5)                       //目标点为箱子,并且玩家处在箱子目标点里面{map[nowpoint -w] = map[nowpoint - 2*w];         //箱子向上map[nowpoint - 2*w] = shift;                  // 箱子目标点变为人物目标点map[nowpoint - w ]= 2;                        //箱子位置变为玩家map[nowpoint] = 4;                            //玩家上一个点变为箱子目的地nowpoint -= w;}else                                          //其他情况自由移动{map[nowpoint - 2*w] = shift;             //箱子的目标点变为箱子map[nowpoint - w] = map[nowpoint];       //玩家目标点变为玩家map[nowpoint] = 0;                      //玩家下面的点变为空地nowpoint -= w;                         //移动玩家点}}}

我们不仅仅要把它推到目标点,还要能够推出来,所以:

if (shift == 6&& map[nowpoint - 2 * w] != 1)                  //如果下一个点为重合点,且前方不是墙壁{map[nowpoint - 2*w] = 3;                     //目标点的下一个点变为箱子map[nowpoint - w] = 5;                       //下一个点变为和人重合map[nowpoint] = 0;                           //人物当前点变为空地nowpoint -= w;                                //变换当前坐标}

我们解决了一个方向的移动问题,那么接下来的移动,和前面类似,只需要改变移动变量就可以了。

向下:当前坐标=(当前坐标+地图宽度)
向左:当前坐标=(当前坐标-1)
向右:当前坐标=(当前坐标+1)

当你需要修改地图的时候,只需要修改数组里面的的1就可以了,如果觉得图案自己不喜欢,那么在switch里面就可以更换。

游戏结束判断:

我们做了移动和推箱子,但是并没有游戏成功的判定:我们加上如下判断成功的语句:

bool Isgameover(int *map,int Rbox)     //Rbox  为了方便拓展,此参数为目的地个数
{int n=0;for (int i = 0; i < 100; i++){if (*(map+i)==6){n++;}}if (Rbox == n){std::cout << "恭喜通关!!!\n";return true;}else{return false;}
}

再于循环体里加入如下代码:

if (Isgameover(map, 3)){break;}

完整源码,基于Vs2017:

#include <iostream>
#include<conio.h>
bool Isgameover(int *map,int Rbox)     //Rbox  为了方便拓展,此参数为目的地个数
{int n=0;for (int i = 0; i < 100; i++){if (*(map+i)==6){n++;}}if (Rbox == n){std::cout << "恭喜通关!!!\n";return true;}else{return false;}
}int main()
{int input;                     //输入常数int nowpoint=31;             //玩家现在的地点int shift;                       //玩家目标点const int w=10;                  //地图宽度int map[100] =                   //玩家地图{1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,3,0,4,0,0,1,1,2,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,3,0,4,0,0,0,1,1,0,0,0,0,0,0,0,0,1,1,0,0,0,3,0,0,0,0,1,1,0,0,0,0,0,0,4,0,1,1,1,1,1,1,1,1,1,1,1};while (true){system("cls");for (int i = 0; i < 100; i++){switch (map[i]){case 1:std::cout << "□"; break;     //墙壁case 0:std::cout << "  "; break;     //空地case 2:std::cout << "Pe"; break;     //人case 3:std::cout << "■"; break;    //箱子case 4:std::cout << "**"; break;    //箱子目的地case 5:std::cout << "×"; break;    //和人重合case 6:std::cout << "√"; break;    //和箱子重合}if (i % w == 9)std::cout << '\n';}if (Isgameover(map, 3)){break;}input=_getch();//往上if (input=='w'||input=='W'){shift = map[nowpoint-w];         //下一个移动的目标点设置给shiftif (shift ==0)                    //当下一个目标是空地的时候{if (map[nowpoint] == 5)       //当和箱子目标点重合的时候且需要移动到空地{map[nowpoint] = 2;               //当前坐标设置为玩家map[nowpoint - w] = map[nowpoint];    //下一个坐标为玩家map[nowpoint] = 4;              //当前坐标为箱子目标点nowpoint -= w;                  //移动当前坐标}else                        //如果没有和箱子目标点重合,则正常移动{map[nowpoint - w] = map[nowpoint];     map[nowpoint] = shift;nowpoint -= w;}}else if (shift == 4)                  //当下一个个目标点为箱子目标点时{map[nowpoint - w] = 5;            //目标点变为人和箱子重合的图案map[nowpoint] = 0;                //当前点变为空地nowpoint -= w;                    //移动人物的坐标}else if (shift == 6&& map[nowpoint - 2 * w] != 1)                  //如果下一个点为箱子和箱子的目标点重合{map[nowpoint - 2*w] = 3;                     //目标点的下一个点变为箱子map[nowpoint - w] = 5;                       //下一个点变为和人重合map[nowpoint] = 0;                           //人物当前点变为空地nowpoint -= w;}else if (shift == 3)                    //目标点为箱子{if (map[nowpoint- 2 * w]!=1&& map[nowpoint - 2 * w] != 3 && map[nowpoint - 2 * w] != 6)         //箱子的下一个目标点不能是墙壁,或者箱子{if (map[nowpoint - 2 * w] == 4)                     //箱子的下一个目标点是箱子目的地{map[nowpoint - 2*w] = 6;                       //箱子的下一个目标点变为和箱子重合map[nowpoint - w] = map[nowpoint];             //箱子的位置变为玩家位置map[nowpoint] = 0;                             //玩家为之变为空地nowpoint -=  w;                                 //移动玩家坐标}else if (map[nowpoint] == 5)                       //目标点为箱子,并且玩家处在箱子目标点里面{map[nowpoint -w] = map[nowpoint - 2*w];         //箱子向上map[nowpoint - 2*w] = shift;                  // 箱子目标点变为人物目标点map[nowpoint - w ]= 2;                        //箱子位置变为玩家map[nowpoint] = 4;                            //玩家上一个点变为箱子目的地nowpoint -= w;}else                                          //其他情况自由移动{map[nowpoint - 2*w] = shift;             //箱子的目标点变为箱子map[nowpoint - w] = map[nowpoint];       //玩家目标点变为玩家map[nowpoint] = 0;                      //玩家下面的点变为空地nowpoint -= w;                         //移动玩家点}}}}//往下else if (input == 's' || input == 'S'){shift = map[nowpoint+w];if (shift == 0){if (map[nowpoint]==5){map[nowpoint] = 2;map[nowpoint + w] = map[nowpoint];map[nowpoint] = 4;nowpoint += w;}else{map[nowpoint + w] = map[nowpoint];map[nowpoint] = shift;nowpoint += w;}}else if (shift==4){map[nowpoint + w] = 5;map[nowpoint] = 0;nowpoint += w;}else if (shift == 6 && map[nowpoint + 2 * w] != 1){map[nowpoint + 2*w] = 3;map[nowpoint + w] = 5;map[nowpoint] = 0;nowpoint += w;}else if (shift == 3){if (map[nowpoint+2*w]!=1 && map[nowpoint + 2 * w] != 3 && map[nowpoint + 2 * w] != 6){if (map[nowpoint + 2 * w] == 4){map[nowpoint + 2 * w] = 6;map[nowpoint + w] = map[nowpoint];map[nowpoint] = 0;nowpoint += w;}else if (map[nowpoint] == 5){map[nowpoint + w] = map[nowpoint + 2 * w];map[nowpoint + 2 * w] = shift;map[nowpoint + w] = 2;map[nowpoint] = 4;nowpoint += w;}else{map[nowpoint + 2 * w] = shift;map[nowpoint + w] = map[nowpoint];map[nowpoint] = 0;nowpoint += w;}}}}//往左else if (input == 'a' || input == 'A'){shift = map[nowpoint-1];if (shift == 0){if (map[nowpoint] == 5){map[nowpoint] = 2;map[nowpoint - 1] = map[nowpoint];map[nowpoint] = 4;nowpoint -= 1;}else{map[nowpoint - 1] = map[nowpoint];map[nowpoint] = shift;nowpoint -= 1;}}else if (shift == 4){map[nowpoint -1] = 5;map[nowpoint] = 0;nowpoint -= 1;}else if (shift == 6 && map[nowpoint - 2] != 1){map[nowpoint - 2] = 3;map[nowpoint - 1] = 5;map[nowpoint] = 0;nowpoint -= 1;}else if (shift == 3){if (map[nowpoint - 2]!=1 && map[nowpoint - 2] != 3 && map[nowpoint - 2] != 6){if (map[nowpoint - 2]==4){map[nowpoint - 1] = map[nowpoint - 2];map[nowpoint - 2] = 6;map[nowpoint - 1] = map[nowpoint];map[nowpoint] = 0;nowpoint -= 1;}else if (map[nowpoint] == 5){map[nowpoint - 1] = map[nowpoint - 2];map[nowpoint - 2] = shift;map[nowpoint - 1] = 2;map[nowpoint] = 4;nowpoint -= 1;}else{map[nowpoint - 2] = shift;map[nowpoint - 1] = map[nowpoint];map[nowpoint] = 0;nowpoint -= 1;}}}}//往右else if (input == 'd' || input == 'D'){shift = map[nowpoint+1];if (shift == 0){if (map[nowpoint] == 5){map[nowpoint] = 2;map[nowpoint + 1] = map[nowpoint];map[nowpoint] = 4;nowpoint += 1;}else{map[nowpoint + 1] = map[nowpoint];map[nowpoint] = shift;nowpoint += 1;}}else if (shift == 4){map[nowpoint + 1] = 5;map[nowpoint] = 0;nowpoint += 1;}else if (shift == 6 && map[nowpoint +2] != 1){map[nowpoint + 2] = 3;map[nowpoint + 1] = 5;map[nowpoint] = 0;nowpoint += 1;}else if (shift == 3){if (map[nowpoint + 2]!=1 && map[nowpoint + 2] != 3 && map[nowpoint + 2 ] != 6){if (map[nowpoint + 2] == 4){map[nowpoint + 1] = map[nowpoint + 2];map[nowpoint + 2] = 6;map[nowpoint + 1] = map[nowpoint];map[nowpoint] = 0;nowpoint += 1;std::cout << "!!!";}else if (map[nowpoint] == 5){map[nowpoint + 1] = map[nowpoint + 2];map[nowpoint + 2] = shift;map[nowpoint + 1] = 2;map[nowpoint] = 4;nowpoint += 1;std::cout << "!!";}else{map[nowpoint + 2] = shift;map[nowpoint + 1] = map[nowpoint];map[nowpoint] = 0;nowpoint += 1;std::cout << "!";}}}}}system("pause");return 0;}

这里由于博主的编程水平处于学习阶段,此代码并不够高效,如果对代码有任何建议,都可以给博主发邮件,我很欢迎大家来讨论。

一个适合初学者的C++推箱子小游戏相关推荐

  1. Python【小游戏合集】之自己做一个简单又好玩的推箱子小游戏

    导语:哈喽铁汁们~今日游戏之旅开始! 想领取完整源码跟python学习资料可私信我或点击这行字体 这期就是带大家使用当前主流且易用的Python语言做一个简单的推箱子小游戏 现在小编的快乐源泉就是玩自 ...

  2. 手把手教你使用Python实现推箱子小游戏(附完整源码)

    文章目录 项目介绍 项目规则 项目接口文档 项目实现过程 前置方法编写 move核心方法编写 项目收尾 项目完善 项目整体源码 项目缺陷分析 项目收获与反思 项目介绍 我们这个项目是一个基于Pytho ...

  3. C++ 简化 推箱子 小游戏 完整代码 参考网络资料 命令行运行 仅供初学者参考交流

    C++ 简化 推箱子 小游戏 完整代码 参考网络资料 命令行运行 仅供初学者参考交流 说明:学做了4关推箱子, 仅供初学者参考可用g++ 编译,可以将内容复制到TXT文件,将后缀改为".cp ...

  4. python推箱子小游戏_小伙利用Python自制一个推箱子小游戏!

    原标题:小伙利用Python自制一个推箱子小游戏! 导语 月初更波python制作小游戏系列吧用python写了个推箱子小游戏,在这里分享给大家,让我们愉快地开始吧 小伙利用Python自制一个推箱子 ...

  5. c++ 小游戏_C/C++编程笔记:C语言写推箱子小游戏,大一学习C语言练手项目

    C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...

  6. c#推箱子小游戏代码_推箱子小游戏V1.0制作

    小游戏实践 推箱子简易版 大家好,我是努力学习争取成为优秀的Game Producer的路人猿,今天来一起做一个推箱子的简易版本V1.0!下面跟我一起做吧~ 我们用到的软件如下: 编辑类 Visual ...

  7. 移动平台开发项目(推箱子小游戏)

    项目目的:实现一个推箱子小游戏 项目架构:使用三个活动类 项目功能: 能在touch中的Action_down动作下,实现小人推着箱子走的效果,全部箱子到达旗帜为过关. 能使用底部Button键来前后 ...

  8. win32GDI函数编程实现推箱子小游戏

    利用GDI绘图函数实现推箱子小游戏,代码源于上一篇博客 C语言控制台推箱子. 实现方法很简单,把字符用绘图函数绘出的图形替换即可. 从字符控制台到win32界面编程,更加形象化. 代码量大增,主程序就 ...

  9. PLC也能制作小游戏----Codesys编写推箱子小游戏

    1.序言 前文已介绍,Codesys编程软件拥有的各种编译方式,以及强大的可视化功能,完全可以实现类似的小游戏程序编写,让疲惫的工控人员在调机的空闲之余可以休闲下,本文编写另一个小游戏,也是十几年前的 ...

最新文章

  1. c语言 程序 作文,编程之乐作文600字
  2. Java中使用mysqldump实现mysql数据库备份并将sql文件打成zip压缩包
  3. Xposed如何实现类中函数的调用
  4. ORA-04028: cannot generate diana for object xxx
  5. Dataset和DataLoader构建数据通道
  6. VUE:解决判断网页端与手机端情况下,横竖屏无法判断的问题
  7. linux putty 字体,putty修改字体配色
  8. qt 等待线程结束_实战PyQt5: 128-使用多线程进行并行处理
  9. PCB制板自学(三)_电容及封装
  10. IP变更导致fdfs文件上传服务不可用解决流程
  11. WPS 设置多级标题
  12. APS系统是什么意思?起什么作用
  13. win10取消微软帐户绑定使用本地账户登录的解决方法
  14. MySQL基础架构:一条SQL“查询语句”是如何执行的
  15. 【OpenGL 学习笔记】第 7 篇:绘制旋转立方体
  16. java实现头像上传 前后端
  17. Android高级编程.
  18. 完美解决django 在迁移数据库的时候出现的1146错误
  19. 获取壁纸网站第一页至第n页的壁纸
  20. font-family、font-style、font-weight、font-variant的区别「In CSS」

热门文章

  1. Vim怎么跳到最后一行和首行
  2. Linux-固定USB转串口名称
  3. epson应用程序Android,Epson Run Connect
  4. 显存爆炸和pin_memory
  5. 微众银行与广电运通达成战略合作,共同推进区块链国产化进程
  6. DW06D二合一锂电池保护 IC
  7. 原油硫含量测定仪硫含量测定方法流程
  8. H3C IPsec实验
  9. latex中如何加粗字体?
  10. Blocks(poj 1390) 动态规划 方盒游戏 (升维——三维)