一个适合初学者的C++推箱子小游戏
一个适合初学者的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)的下一个坐标的情况,还要考虑箱子的移动坐标是否超出了我们的地图,那么通过本人总结,那么箱子前进的时候,玩家和箱子会遇到如下的情况:
- 前方是墙壁
- 前方是箱子
- 前方是箱子目的地
- 前方是放好的箱子
- 前方是空地
玩家有两种情况:
- 玩家处于箱子目的地的时候推箱子
- 玩家处于箱子目的地,但是推动的方向是墙壁
于是,我们有如下代码:
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++推箱子小游戏相关推荐
- Python【小游戏合集】之自己做一个简单又好玩的推箱子小游戏
导语:哈喽铁汁们~今日游戏之旅开始! 想领取完整源码跟python学习资料可私信我或点击这行字体 这期就是带大家使用当前主流且易用的Python语言做一个简单的推箱子小游戏 现在小编的快乐源泉就是玩自 ...
- 手把手教你使用Python实现推箱子小游戏(附完整源码)
文章目录 项目介绍 项目规则 项目接口文档 项目实现过程 前置方法编写 move核心方法编写 项目收尾 项目完善 项目整体源码 项目缺陷分析 项目收获与反思 项目介绍 我们这个项目是一个基于Pytho ...
- C++ 简化 推箱子 小游戏 完整代码 参考网络资料 命令行运行 仅供初学者参考交流
C++ 简化 推箱子 小游戏 完整代码 参考网络资料 命令行运行 仅供初学者参考交流 说明:学做了4关推箱子, 仅供初学者参考可用g++ 编译,可以将内容复制到TXT文件,将后缀改为".cp ...
- python推箱子小游戏_小伙利用Python自制一个推箱子小游戏!
原标题:小伙利用Python自制一个推箱子小游戏! 导语 月初更波python制作小游戏系列吧用python写了个推箱子小游戏,在这里分享给大家,让我们愉快地开始吧 小伙利用Python自制一个推箱子 ...
- c++ 小游戏_C/C++编程笔记:C语言写推箱子小游戏,大一学习C语言练手项目
C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...
- c#推箱子小游戏代码_推箱子小游戏V1.0制作
小游戏实践 推箱子简易版 大家好,我是努力学习争取成为优秀的Game Producer的路人猿,今天来一起做一个推箱子的简易版本V1.0!下面跟我一起做吧~ 我们用到的软件如下: 编辑类 Visual ...
- 移动平台开发项目(推箱子小游戏)
项目目的:实现一个推箱子小游戏 项目架构:使用三个活动类 项目功能: 能在touch中的Action_down动作下,实现小人推着箱子走的效果,全部箱子到达旗帜为过关. 能使用底部Button键来前后 ...
- win32GDI函数编程实现推箱子小游戏
利用GDI绘图函数实现推箱子小游戏,代码源于上一篇博客 C语言控制台推箱子. 实现方法很简单,把字符用绘图函数绘出的图形替换即可. 从字符控制台到win32界面编程,更加形象化. 代码量大增,主程序就 ...
- PLC也能制作小游戏----Codesys编写推箱子小游戏
1.序言 前文已介绍,Codesys编程软件拥有的各种编译方式,以及强大的可视化功能,完全可以实现类似的小游戏程序编写,让疲惫的工控人员在调机的空闲之余可以休闲下,本文编写另一个小游戏,也是十几年前的 ...
最新文章
- c语言 程序 作文,编程之乐作文600字
- Java中使用mysqldump实现mysql数据库备份并将sql文件打成zip压缩包
- Xposed如何实现类中函数的调用
- ORA-04028: cannot generate diana for object xxx
- Dataset和DataLoader构建数据通道
- VUE:解决判断网页端与手机端情况下,横竖屏无法判断的问题
- linux putty 字体,putty修改字体配色
- qt 等待线程结束_实战PyQt5: 128-使用多线程进行并行处理
- PCB制板自学(三)_电容及封装
- IP变更导致fdfs文件上传服务不可用解决流程
- WPS 设置多级标题
- APS系统是什么意思?起什么作用
- win10取消微软帐户绑定使用本地账户登录的解决方法
- MySQL基础架构:一条SQL“查询语句”是如何执行的
- 【OpenGL 学习笔记】第 7 篇:绘制旋转立方体
- java实现头像上传 前后端
- Android高级编程.
- 完美解决django 在迁移数据库的时候出现的1146错误
- 获取壁纸网站第一页至第n页的壁纸
- font-family、font-style、font-weight、font-variant的区别「In CSS」