c++之简单的推箱子游戏
来源:互联网 发布:gif屏幕录像软件 编辑:程序博客网 时间:2024/05/29 21:36
c++推箱子小游戏(linux也可以运行)
C++一直都是游戏开发的主流语言,特别是游戏引擎的开发。学了半年C++,还是很懵逼,网上找了一些C++推箱子的小游戏,涉及到的知识面太广,从容器到BFS等等算法,尤其是推多个箱子的时候。本人水平有限,只做到了固定地图,并且只有一个箱子可以推。能基本的实现后退,重新开始,上下关卡切换的功能。因为大部分游戏都是在Windows C++平台下编写运行的,很少有linux下也可以运行的推箱子游戏,(可能是我写的太low)代码有点乱,用的思想还是C语言的思想,仅供新手参考。因为第一次发博客,写的不好,欢迎各位批评指正!
//Sokoban.hclass Sokoban{private: enum {L = 21,H = 10}; int Pex,Pey,OrgPex,OrgPey,OldPex,OldPey;//人的实时位置坐标,上一步人的坐标,人的初始位置坐标 int Boxx,Boxy,OrgBoxx,OrgBoxy,OldBoxx,OldBoxy;//箱子的实时位置,上一步箱子的初始位置坐标,箱子的初始位置坐标 int Tx,Ty; //目标位置的坐标 int Succeed; //判断成功的标志位 int dx[4],dy[4];//方向数组 int dir;public: Sokoban();//构造函数 ~Sokoban();//析构函数 void Initial();//地图初始化函数 void Show();//地图刷新函数 void Button();//按键判断函数 void Move();//箱子移动函数 bool Check(int x,int y);//验证越界函数 void Rest();//重新开始};
//Sokoban.cpp#include"Sokoban.h"int level = 1;//游戏关卡char map[10][22]={"0"};//用来时时更新地图char oldmap[10][22]={"0"};//前一步的地图char orgmap[10][22]={"0"};//最初的地图void OldMap(){ int i = 0,j = 0; for(i = 0;i<10;i++) { for(j = 0;j<21;j++) { oldmap[i][j] = map[i][j]; } }}void OrgMap(){ int i = 0,j = 0; for(i = 0;i<10;i++) { for(j = 0;j<21;j++) { orgmap[i][j] = map[i][j]; } }}void Back(){ int i = 0,j = 0; for(i = 0;i<10;i++) { for(j = 0;j<21;j++) { map[i][j] = oldmap[i][j]; } }}void Sokoban::Rest(){ int i = 0,j = 0; for(i = 0;i<10;i++) { for(j = 0;j<21;j++) { map[i][j] = orgmap[i][j]; } } Pex = OrgPex;//最初的地图恢复 Pey = OrgPey; Boxx = OrgBoxx; Boxy = OrgBoxy; }Sokoban::Sokoban(){ dir = -1; Succeed = 0; //0~3分别代表上右下左 dx[0] = -1; dx[1] = 0; dx[2] = 1; dx[3] = 0; dy[0] = 0; dy[1] = 1; dy[2] = 0; dy[3] = -1; }Sokoban::~Sokoban(){}void Sokoban::Initial(){char a[10][22]={//123456789012345678901 /*1*/ "#####################", /*2*/ "#X # # # #", /*3*/ "## # ###### O #", /*4*/ "## # # ##### #", /*5*/ "## # # ##### ###### #", /*6*/ "## # # T #", /*7*/ "#### # # ######## #", /*8*/ "## # # # #", /*9*/ "## # # #", /*10*/ "#####################" };char b[10][22]={//123456789012345678901 /*1*/ "#####################", /*2*/ "#X # #", /*3*/ "## # ############## #", /*4*/ "# # # # # # # #", /*5*/ "# # ## # ##", /*6*/ "# # # # #", /*7*/ "# ## # # ####### O #", /*8*/ "# T # # # #", /*9*/ "## # # #", /*10*/ "#####################" };char c[10][22]={//123456789012345678901 /*1*/ "#####################", /*2*/ "# # # # #", /*3*/ "## # # ##### #", /*4*/ "# # # O ## # # #", /*5*/ "## # ####### ## # #", /*6*/ "# X #", /*7*/ "#### ## ## ## ## ###", /*8*/ "## # # # # #", /*9*/ "##T #", /*10*/ "#####################" };char d[10][22]={//123456789012345678901 /*1*/ "X# ################", /*2*/ " # # # #", /*3*/ " # # # ###### # #", /*4*/ " # # # ## # # #", /*5*/ " # # ####### ## # #", /*6*/ " # #", /*7*/ " # # ## ##### ## # #", /*8*/ " # # # # # O# #", /*9*/ " #T# #", /*10*/ " ##################" };char e[10][22]={//123456789012345678901 /*1*/ "#####################", /*2*/ " # # # #", /*3*/ " ##### #", /*4*/ " # # # ## # # #", /*5*/ " # ### ## ## ## # #", /*6*/ " # #", /*7*/ " ##### # ## ## ###", /*8*/ " # # # # # # O #", /*9*/ "T# #", /*10*/ "X####################" };/********************地图初始化**************/ char (*pc)[22] = a; switch(level) { case 0: break; case 1: pc = a;break; case 2: pc = b;break; case 3: pc = c;break; case 4: pc = d;break; case 5: pc = e;break; }/**********************人,箱子,目标位置的初始化****************/ int i = 0,j = 0; for(;i<10;i++) { for(j = 0;j<21;j++) { map[i][j] = pc[i][j]; if(map[i][j] == 'X') { OrgPex = Pex = i; OrgPey = Pey = j; } else if(map[i][j] == 'O') { OrgBoxx = Boxx = i; OrgBoxy = Boxy = j; } else if(map[i][j] == 'T') { Tx = i; Ty = j; } } } OrgMap();//最初的地图 Sokoban::Show();}void Sokoban::Show(){ int i = 0,j = 0; int key = 0; while(true) { usleep(500000);//刷新 Sokoban::Button(); Sokoban::Move(); system("clear"); //打印地图 for(i = 0;i<10;i++) { for(j = 0;j<21;j++) { printf("%c",map[i][j]); } cout<<endl; } //画面 cout<<endl; cout << " _________________________________" << endl; cout << "| C++语言推箱子游戏 (共5关) |" << endl; cout << "| 游戏规则: 当前关卡: "<<level<<" |" << endl; cout << "| X:人 O:箱子 |" << endl; cout << "| #:障碍物 T:目的地 |" << endl; cout << "| 操作说明: Q:退出 | " << endl; cout << "| W:上 S:下 |"<<endl; cout << "| D:右 A:左 |"<<endl; cout << "| R:重新开始 B:后退 |"<<endl; cout << "| U:上张地图 N:下张地图 |"<<endl; cout << "|————————————————————————————————|" << endl; cout << "| 友请提示: |" << endl; cout << "| 每次移动过后只能后退一次! |" << endl; cout << "| 人将箱子推到目的地即过关! |" << endl; cout << "| 输入按键后按一次回车才能生效! |" << endl; cout << "|————————————————————————————————|" << endl; //箱子成功到达目的地 if(Succeed) { if(level == 5) { cout<<"太厉害了!!!你差点就和游戏开发者一样聪明了"<<endl; break; } else if(level == 0) { sleep(1); break; } else { cout<<" 恭喜你啊,智商可以啊,有本是来通关阿!"<<endl; cout<<"输入Q回车退出游戏,输入任意键回车等待2秒即可开启下一关卡"<<endl; sleep(1); if(kbhit() != 0) { while(kbhit() != 0) key = getchar(); if(key == 113)//按q break; else { usleep(500000); Succeed = 0; level++;//等级+1,地图就会更新 Sokoban::Initial(); } } } } }}void Sokoban::Button(){ int key = 0; if(kbhit() != 0) //检查当前是否有键盘输入,若有则返回一个非0值,否则返回0 { while(kbhit() != 0) //可能存在多个按键,要全部取完,以最后一个为主 key = getchar(); //将按键从控制台中取出并保存到key中 switch(key) { //上 case 119: dir = 0; break; //右 case 100: dir = 1; break; //下 case 115: dir = 2; break; //左 case 97: dir = 3; break; //后退 case 98: { Back(); Pex = OldPex; Pey = OldPey; Boxx = OldBoxx; Boxy = OldBoxy; break; } //重新开始 case 114: { Rest(); break; } //切换到下张图 case 110:{ level++; if(level == 6) level = 1; Sokoban::Initial(); break; } //切换到上张图 case 117:{ level--; if(level == 0) level = 5; Sokoban::Initial(); break; } //退出 case 113: { level = 0; Succeed = 1; break; } } } }//人推箱子移动函数void Sokoban::Move(){ int x,y; //有按键的时候 if(dir != -1) { OldPex = Pex; OldPey = Pey; OldBoxx = Boxx; OldBoxy = Boxy; //人所推向的坐标位置 x = Pex + dx[dir]; y = Pey + dy[dir]; //1.人所推位置为空,就走向该位置,并且人初始位置不在目标位置上 if(Check(x,y) && map[x][y] == ' ' && (Pex != Tx || Pey != Ty)) { OldMap(); map[Pex][Pey] = ' '; map[x][y] = 'X'; Pex = x; Pey = y; dir = -1; } else //2.人所推的位置是箱子,就将箱子移向人走的方向这点,并且初始位置不在目标位置上 if(Check(x,y) && map[x][y] == 'O' && Check( x+dx[dir],y+dy[dir] ) && map[ x+dx[dir] ][ y+dy[dir] ] == ' ' && (Pex != Tx || Pey != Ty)) { OldMap(); map[Pex][Pey] = ' '; //人的位置改变 Pex = x; Pey = y; map[Boxx][Boxy] = 'X'; //箱子位置改变,且人移动到箱子的位置 map[x+dx[dir]][y+dy[dir]] = 'O';//箱子移动的位置 Boxx = x + dx[dir]; Boxy = y + dy[dir]; dir = -1; } else //3.人将箱子推向的方向刚好是目的地 if(Check(x,y) && map[x][y] == 'O' && Check( x+dx[dir],y+dy[dir] ) && map[ x+dx[dir] ][ y+dy[dir] ] == 'T') { OldMap(); map[Pex][Pey] = ' '; //人的移动前位置改变 Pex = x; Pey = y; map[Boxx][Boxy] = 'X'; //箱子位置改变,且人移动到箱子的位置 map[x+dx[dir]][y+dy[dir]] = 'O';//箱子移动的位置 Boxx = x + dx[dir]; Boxy = y + dy[dir]; dir = -1; Succeed = 1; }else //4.人走到目标位置 if(Check(x,y) && map[x][y] == 'T') { OldMap(); map[Pex][Pey] = ' '; map[x][y] = 'X'; Pex = x; Pey = y; dir = -1; }else //5.人离开目标位置且推不到箱子 if(Pex == Tx && Pey == Ty && Check(x,y) && map[x][y] == ' ') { OldMap(); map[Tx][Ty] = 'T';//人的位置变成目标地址 map[x][y] = 'X'; //人移动后的位置 Pex = x; Pey = y; dir = -1; } else //6.人离开目标位置且能推到箱子 if(Pex == Tx && Pey == Ty && Check(x,y) && map[x][y] == 'O' && Check( x+dx[dir],y+dy[dir] ) && map[ x+dx[dir] ][ y+dy[dir] ] == ' ') { OldMap(); map[Pex][Pey] = 'T';//人的位置变成目标地址 map[x][y] = 'X'; //人的移动后的位置 Pex = x; Pey = y; map[Boxx][Boxy] = 'X'; //箱子位置改变,且人移动到箱子的位置 map[x+dx[dir]][y+dy[dir]] = 'O';//箱子移动的位置 Boxx = x + dx[dir]; Boxy = y + dy[dir]; dir = -1; } }}//判断越界情况bool Sokoban::Check(int x,int y){ if(x < 0 || x >= H || y < 0 || y >= L) return 0; else return 1;}
//-----------------------------------------------------//kbhit.h//按键的程序#ifndef KEY_H#define KEY_H#include <termios.h>#include <iostream>#include"kbhit.h"#include <stdio.h>#include <termios.h>#include <unistd.h>#include <sys/types.h>#include <sys/time.h>int kbhit(void);#endif
//---------------------------------------------//kbhit.cpp#include"kbhit.h"int kbhit (void){ struct timeval tv; fd_set rdfs; tv.tv_sec = 0; tv.tv_usec = 0; FD_ZERO(&rdfs); FD_SET (STDIN_FILENO, &rdfs); select(STDIN_FILENO+1, &rdfs, NULL, NULL, &tv); return FD_ISSET(STDIN_FILENO, &rdfs);}
//---------------------------------------------//main.cpp#include"Sokoban.h"using namespace std;int main(){ Sokoban s; s.Initial(); return 0;}
//运行方式
g++ -o main Sokoban.cpp hbit.cpp main.cpp
./main
游戏开始的界面
游戏结束的界面
0 0
- c++之简单的推箱子游戏
- C语言之推箱子游戏代码
- C 推箱子游戏
- 简单的推箱子游戏的实现
- 一个简单的推箱子游戏
- C游戏 推箱子游戏
- C语言,推箱子游戏
- c实现 推箱子游戏
- 黑马程序员——C基础之推箱子游戏
- C语言实践之推箱子游戏思路与代码
- Hdu1254-推箱子(经典的推箱子游戏)-bfs
- java 推箱子游戏 简单例子
- C语言实现推箱子游戏
- C语言-推箱子游戏代码
- C语言实现推箱子游戏
- C语言+EasyX编写推箱子游戏
- c语言的推箱子
- Android游戏开发之推箱子有感
- DLNA投影到局域网设备
- 2017年ETS解答新托福考生们最关注的难题
- 深入理解Java之线程池
- jasperReport+struts2+jatoolsPrinter打印
- 负载均衡一致性hash算法
- c++之简单的推箱子游戏
- ubuntu ping不通网时的设置
- LightOJ 1090 Trailing Zeroes (II)
- SqlServer--bat批处理执行sql语句1-osql
- Design Patterns in Android:单例模式
- three
- frameMarker之TemplateDirectiveModel
- Java修饰符小结
- JZOJ 3808 【NOIP2014模拟8.25】道路值守