前面记录了贪吃蛇的代码实现以及一些用到的小知识点,现在记录一下推箱子,大体框架是相同的,知识点可前往此处:
贪吃蛇C++实现

接下来是推箱子的一些运行截图及代码,只是相较于贪吃蛇多设置了几个关卡,加个条件判断语句,多建立两张游戏地图即可实现关卡跳换。

箱子是让它们连着生成的,因为比较方便调试,别为难自己,可以在代码处改成真正的随机,像贪吃蛇的食物一样。

游戏菜单:

第一关:

把箱子推到空格位置,则判断进入下一关
第二关:

第三关:

结束:

菜单里的游戏设置,游戏信息等也做了跳转,比如点击游戏设置,会跳转至:

内容随意,这是个基础游戏框架,就没有加入各种设置,貌似推箱子游戏也没什么设置可以加,贪吃蛇还可以在界面渲染一个控制台,显示分数,关卡等。

关闭运行窗口则使用 exit(0)函数。

感觉到了C++的类的基石作用,生成对象方便,对象,就是类的实例化

下面是代码:

// PushBoxComeTrue.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include<Windows.h>
#include<iostream>using namespace std;
#define KEY_DOWN(vk_code)GetAsyncKeyState(vk_code)&0x8000?1:0
enum
{E_MENU_START,E_MENU_SETTING,E_MENU_EXIT,E_MENU_INFORMATION
};
enum
{E_GAME_MENU,E_GAME_MAP,E_GAME_RESULT,E_GAME_SETTINGINFORMATION,E_GAME_INFOR
};
int g_arrMap1[15][20]={{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,1,1,1,0,0,0,0,0,0,0,0,1},{1,0,0,0,1,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,1,0,0,0,0,0,0,0,1,1,1},{1,0,0,1,1,1,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,0,1,1,1},{1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},{1,0,1,1,1,1,1,0,0,0,0,0,0,0,1},{1,0,0,0,1,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,1,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,1,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,1,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
int g_arrMap2[15][20]={{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,0,0,0,0,0,0,0,0,0,1,0,1,0,1},{1,0,0,0,0,0,0,0,0,0,1,1,1,0,1},{1,0,0,1,0,1,0,0,0,0,1,1,1,0,1},{1,0,0,1,0,1,0,0,0,0,0,1,0,0,1},{1,1,1,1,0,1,1,1,0,0,0,0,0,0,1},{1,1,0,0,0,0,0,1,0,0,0,0,0,0,1},{1,1,1,0,0,0,1,1,0,0,0,0,0,0,1},{1,0,1,0,0,0,1,0,0,0,0,0,0,0,1},{1,0,1,0,0,0,1,0,0,0,0,0,0,0,1},{1,0,1,0,0,0,1,0,0,0,0,1,1,1,1},{1,0,1,0,0,0,1,0,0,0,0,0,0,0,1},{1,0,0,1,1,1,0,0,0,0,0,1,1,1,1},{1,0,0,0,1,0,0,0,0,0,0,0,0,0,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
int g_arrMap3[15][20]={{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},{1,0,0,0,1,1,1,0,1,1,1,0,0,0,1},{1,0,0,1,0,0,0,1,0,0,0,1,0,0,1},{1,0,1,0,0,0,0,0,0,0,0,0,1,0,1},{1,0,0,1,0,0,0,0,0,0,0,1,0,0,1},{1,0,0,0,1,0,0,0,0,0,1,0,0,0,1},{1,0,0,0,0,1,0,0,0,1,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,1,0,0,0,0,0,0,1},{1,0,0,0,0,0,0,0,0,0,0,0,0,0,1},{1,0,1,0,1,0,0,0,0,0,0,0,0,0,1},{1,0,0,1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,1,0,0,0,0,0,0,0,0,0,0,1},{1,0,0,1,0,0,0,0,0,0,0,0,0,0,1},{1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
};
int g_arrMap[15][20] ={};//地图数组的初始化,为接下来的地图切换做准备struct SData//结构体声明
{SData(){nRow = 0;nCol = 0;nRowBk = 0;nColBk = 0;}SData(int nInRow,int nInCol){nRow = nInRow;nCol = nInCol;nRowBk = nInRow;nColBk = nInCol;}void backUp()//备份坐标{nRowBk = nRow;nColBk = nCol;}void restore()//储存的坐标释放{nRow = nRowBk;nCol = nColBk;}int nRow;int nCol;int nRowBk;int nColBk;};int _tmain(int argc, _TCHAR* argv[])
{int nMenuState=E_MENU_START;//表示菜单状态,0游戏开始,1设置,2结束,3游戏信息int nGameState=E_GAME_MENU;//表示游戏状态,0菜单,1地图,2游戏结果,3设置信息界面,4游戏信息界面memcpy(g_arrMap,g_arrMap1,sizeof(g_arrMap) );SData sPlayer = SData(7,7);//声明一个结构体对象--玩家sPlayerSData arrBox[3];//声明一个箱子数组SData arrHole[3];//声明一个坑数组int nLevel=1;//定义游戏关卡关数for(int i =0;i < 3;i++){arrBox[i] = SData(9,9+i);arrHole[i]=SData(11,10+i);}while(true){system("cls");if(E_GAME_MENU==nGameState)//菜单{if(KEY_DOWN(VK_RETURN))//菜单数据更新按下enter键进入游戏地图{/*按下enter键时要判断当前箭头是否指示在游戏开始的位置判断nMenuState的值是否是0,是则切换,不是则不管*/if(E_MENU_START==nMenuState){nGameState=E_GAME_MAP;}else if(E_MENU_SETTING==nMenuState){nGameState=E_GAME_SETTINGINFORMATION;}else if(E_MENU_INFORMATION==nMenuState){nGameState=E_GAME_INFOR;}else if(E_MENU_EXIT==nMenuState){exit(0);}}//指令数据更新if(KEY_DOWN(VK_UP)){nMenuState--;if(nMenuState<E_MENU_START){nMenuState=E_MENU_INFORMATION;}//当箭头指到第一行时,跳到第三行}else if(KEY_DOWN(VK_DOWN)){nMenuState++;if(nMenuState>E_MENU_INFORMATION){nMenuState=E_MENU_START;}}//游戏界面渲染if(E_MENU_START==nMenuState){cout<<"->游戏开始"<<endl;cout<<"  游戏设置"<<endl;cout<<"  游戏结束"<<endl;cout<<"  游戏信息"<<endl;}else if(E_MENU_SETTING==nMenuState){cout<<"  游戏开始"<<endl;cout<<"->游戏设置"<<endl;cout<<"  游戏结束"<<endl;cout<<"  游戏信息"<<endl;}else if(E_MENU_EXIT==nMenuState){cout<<"  游戏开始"<<endl;cout<<"  游戏设置"<<endl;cout<<"->游戏结束"<<endl;cout<<"  游戏信息"<<endl;}else if(E_MENU_INFORMATION==nMenuState){cout<<"  游戏开始"<<endl;cout<<"  游戏设置"<<endl;cout<<"  游戏结束"<<endl;cout<<"->游戏信息"<<endl;}//else if(E_MENU_EXIT==nMenuState)//{//  exit(0);//}}else if(E_GAME_MAP==nGameState)//地图显示{if(KEY_DOWN(VK_ESCAPE)){nGameState=E_GAME_MENU;}//移动之前把玩家的坐标先存储起来,每次移动之前备份玩家坐标sPlayer.backUp();//玩家移动的按键控制:只需要按键之后根据相应的方向去更改玩家的坐标即可if(KEY_DOWN(VK_UP)){sPlayer.nRow--;}else if(KEY_DOWN(VK_DOWN)){sPlayer.nRow++;}else if(KEY_DOWN(VK_LEFT)){sPlayer.nCol--;}else if(KEY_DOWN(VK_RIGHT)){sPlayer.nCol++;}//玩家移动后进入墙,玩家进入墙的时候,玩家应该静止不动(其实是快速回到上一步位置,视觉暂留而不可见)//判断玩家撞墙,获取玩家玩家所在位置坐标对应于地图数组里面的值是否为1if(1 == g_arrMap[sPlayer.nRow][sPlayer.nCol])//条件成立,则玩家即将陷到墙里面,玩家应该回到移动前的位置{sPlayer.restore();}//备份箱子坐标for(int i = 0;i < 3;i++){arrBox[i].backUp();}for(int i = 0;i < 3;i++)//3个箱子都检测一遍{//比较玩家是否碰到第i个箱子,玩家坐标 == 第i个箱子的坐标if(arrBox[i].nRow == sPlayer.nRow && arrBox[i].nCol == sPlayer.nCol){int nOffsetRow = sPlayer.nRow - sPlayer.nRowBk;int nOffsetCol = sPlayer.nCol - sPlayer.nColBk;arrBox[i].nRow += nOffsetRow;arrBox[i].nCol += nOffsetCol;break;}}//箱子之间的碰撞for(int i = 0;i < 3;i++){int nBoxRow = arrBox[i].nRow;int nBoxCol = arrBox[i].nCol;//如果成立,那么表示第i个箱子与墙体会重合,箱子“消失”if(1 == g_arrMap[nBoxRow][nBoxCol]){//还原箱子进入墙壁之前一步的坐标arrBox[i].restore();//玩家坐标的还原sPlayer.restore();break;}}for(int i = 0;i < 3;i++)//被推箱子的自我检测{//被推的所有箱子自我挨个检测for(int j = 0;j < 3;j++){//i!=j,这样将导致玩家无法行动,因为当箱子比较自己时,一直还原if(arrBox[i].nRow == arrBox[j].nRow &&arrBox[i].nCol == arrBox[j].nCol&&i!=j)//条件成立表示推着的箱子与其他箱子接触了,无法推动{//当条件成立时还原游戏玩家与箱子的坐标arrBox[i].restore();sPlayer.restore();}}}//游戏胜利的判断int count=0;for(int i=0;i<3;i++)//判断地图的箱子是否都已经推到坑里?{for(int j=0;j<3;j++){if(arrBox[i].nRow  == arrHole[j].nRow && arrBox[i].nCol == arrHole[j].nCol){count++;break;}}}//游戏关卡的切换//int nLevel=1;如果在这里定义游戏关卡,那么每次判断完游戏胜利又会刷新为1,则一直重复第二关int nBoxNumber=sizeof(arrBox)/sizeof(SData);if(count>=nBoxNumber){nLevel++;if(nLevel==2){memcpy(g_arrMap,g_arrMap2,sizeof(g_arrMap));//地图切换至第二张sPlayer=SData(2,2);//重新定义玩家初始位置for(int i = 0;i < 3;i++)//重新定义箱子的位置{arrBox[i] = SData(7+i,9);}for(int i = 0;i < 3;i++)//重新定义坑的位置{arrHole[i] = SData(11,11+i);}}else if(nLevel==3){memcpy(g_arrMap,g_arrMap3,sizeof(g_arrMap));//地图切换至第三张sPlayer=SData(6,1);for(int i = 0;i < 3;i++){arrBox[i] = SData(12,10+i);}for(int i = 0;i < 3;i++){arrHole[i] = SData(9,9+i);}}//将游戏状态切换到游戏结果处else{nGameState = E_GAME_RESULT;}}//行列字符的输出,游戏地图的渲染for(int i=0;i<15;i++){for(int j=0;j<20;j++){bool bDrawBox = false;for(int m = 0;m < 3;m++){if(i == arrBox[m].nRow && j == arrBox[m].nCol){bDrawBox = true;break;}}bool bDrawHole = false;for(int m = 0;m < 3;m++){if(i == arrHole[m].nRow && j == arrHole[m].nCol){bDrawHole = true;break;}}if(1 == g_arrMap[i][j]){cout <<"■";}else if(i == sPlayer.nRow&& j==sPlayer.nCol){cout <<"♀";}else if(bDrawBox){cout <<"箱";}else if(bDrawHole){cout<<"□";}else{cout<<"  ";}} cout<<endl;//一个for内循环,i*j次,每行输出后换行继续下一行的循环输出}}else if(E_GAME_SETTINGINFORMATION==nGameState)//进入游戏设置界面{if(KEY_DOWN(VK_ESCAPE))//按ESC退出返回菜单界面{nGameState=E_GAME_MENU;}if(E_MENU_SETTING==nMenuState){cout<<"抱歉, 这款游戏目前不配拥有游戏设置,我们老板将会去搬砖赚钱来请程序员开发"<<endl;cout<<"                 请按‘Esc’键返回主菜单";}}else if(E_GAME_INFOR==nGameState)//进入游戏信息界面{if(KEY_DOWN(VK_ESCAPE))//按ESC退出返回菜单界面{nGameState=E_GAME_MENU;}if(E_MENU_INFORMATION==nMenuState){cout<<"666"<<endl;cout<<"666"<<endl;cout<<"666"<<endl;cout<<"谢谢您的使用,祝您生活愉快!";}}//退出地图界面else if(nGameState == E_GAME_RESULT)//==2{if(KEY_DOWN(VK_RETURN)){nGameState = E_GAME_MENU;}cout <<"恭喜过关!"<< endl;}}return 0;
}

推箱子C++实现 实训认识小游戏相关推荐

  1. C语言实训——经典小游戏马里奥开发day 1

    C语言实训--经典小游戏马里奥开发day 1 卷轴式地图 一.关于卷轴式地图 ​ 在之前的开发尝试之中,我曾经使用的是地图移动但是马里奥保持在一个固定的点来实现马里奥的移动,但是我发现了几个问题: 1 ...

  2. java实训扫雷小程序设计项目_《Java程序设计实训教程》实训一扫雷游戏.ppt

    实训一 扫雷游戏 1.1 系统设计 需求分析 随机布雷 实现扫雷功能 标记小方块 选择游戏的难度 显示剩余雷数 显示已使用时间 最好成绩记录 重新开始 加快扫雷进程 加入声音 1.1 系统设计 类的设 ...

  3. 华衫科技-实训课程-小滴服务(Html-Css-Javascript)

    前端时间的两周的校内实训课程上学习了关于前端的一些知识,课上也跟着做了基础项目并进行了完善和整理,具体如下. 项目结构  1.DropleService.html <!-- html5标准网页声 ...

  4. HNU软件能力实训2-17. 小A的计算器

    写在前面 你好!欢迎来到我的博客,希望我的思路能够帮到你! 问题描述 以往的操作系统内部的数据表示都是二进制方式,小A新写了一个操作系统,系统内部的数据表示为26进制,其中0-25分别由a-z表示. ...

  5. 项目实训---微信小程序选座之7.7日报

    从昨天7.6开始实行日报周报制度 这两天我负责的选座界面雏形已经形成,下面要做的就是与后台进行交互,补充逻辑函数. 成果如下: 分析: 界面的难点主要在于根据后台给的数据进行动态的生成座次表,并且要实 ...

  6. java实训扫雷小程序设计项目_扫雷小程序!Java的

    /** * @(#)Block.java *该类用于创建Block对象,将其放到游戏区的每个格子里面,里面存放着该"格子"的一些属性: * ******************** ...

  7. 实训九(游戏退出按钮的实现)

    主要是涉及引擎中menu的使用 常见的几种使用方法 1.可变换图标 auto closeItem = MenuItemImage::create(                            ...

  8. C语言小游戏 ——推箱子

    文章目录 (1)内容描述 (2)功能 (3)设计目的 (4)总体设计 (5)明显缺点 (6)个人总结 7. 实例 实例一 实例二 实例三 实例四 实例五: (1)内容描述 描述:用户进入页面后可以进行 ...

  9. 172. 立体推箱子

    立体推箱子是一个风靡世界的小游戏. 游戏地图是一个 N 行 M 列的矩阵,每个位置可能是硬地(用 . 表示).易碎地面(用 E 表示).禁地(用 # 表示).起点(用 X 表示)或终点(用 O 表示) ...

最新文章

  1. 使用ORM数据库:greenDao
  2. 剑指OFFER之跳台阶(九度OJ1388)
  3. matlab中gatbx工具箱的添加
  4. 1083. List Grades (25)
  5. Android studio 2.3版本出现的问题: Please select at least one of the signature versions to use
  6. android computescroll_Android Scroller与computeScroll的调用机制关系
  7. Tricks(二十一)—— 随机数
  8. [幽默漫画]对于程序猿来说deadline很容易搞定!
  9. 廖雪峰python博客_廖雪峰python实战
  10. 耿楠《LaTeX 中文教程》随堂学习记录
  11. docker mac linux镜像制作,Docker镜像制作方法
  12. Linux操作系统———李纳斯
  13. 光学系统像差的计算机模拟实验报告,RLE-ME01-光学系统像差测量实验-实验讲义要点.doc...
  14. hazelcast 搭建_Hazelcast 配置教程
  15. 程序员必备的思维能力:抽象思维
  16. git恢复某个文件到上一个提交版本
  17. 最新美团-青龙——5-25
  18. Ubuntu 22.04 修改IP
  19. 优惠券系统:优惠券分发微服务功能编码实现
  20. 上车短视频赛道:基于uniapp框架快速搭建自己的仿抖音短视频APP

热门文章

  1. PDF编辑方法,怎么把PDF其中一页删除
  2. Uml 类图 stereotype的值含义,该怎么解决
  3. javaScript中值传递和引用传递
  4. **将古典融汇到现代(二)一座连接蕴涵式和三段论的桥--皮尔斯逻辑之五**
  5. Vue的计算属性computed和监听属性watch
  6. 交换机和路由器的基本配置
  7. C# 参数1:值参数----值类型和引用类型及特例string
  8. C++实现OPT最佳页面替换算法,结果简明扼要
  9. Highcharts 操作series 的data里的数据
  10. 句子改写器在线转换v.1.2.3