C++实现推箱子游戏

时间:2022-11-22 16:21:03

一、项目简介

用两天闲余时间回顾了推箱子这款经典的小游戏,目前设置了5关,只能实现基本的人物移动。判断胜利条件,其他功能还未实现(例:撤回到上一步,*选择关卡等),也顺便复习了C++的相关知识。

二、 代码区

Class Map(地图类)

Map.h:

  1. #pragma once
  2. #define N 10
  3. #define M 10
  4. //地图类
  5. class Map
  6. {
  7. public:
  8. Map();
  9. ~Map();
  10. void Init();
  11.  
  12. void ReadMapFile(int map[M][N], int size,const char* filename );
  13. void WriteMapFile(int map[M][N], int size, const char* filename);
  14. private:
  15.  
  16. };

Map.cpp:

  1. #include "Map.h"
  2. #include<iostream>
  3. #include<fstream>
  4. using namespace std;
  5.  
  6. Map::Map()
  7. {
  8.  
  9. }
  10. //地图初始化方法
  11. void Map::Init()
  12. {
  13. int Map[10][10] =
  14. {
  15. { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
  16. { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
  17. { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
  18. { 1, 0, 0, 4, 3, 0, 1, 1, 1, 1 },
  19. { 1, 0, 4, 3, 4, 3, 0, 0, 1, 1 },
  20. { 1, 7, 3, 4, 3, 4, 2, 0, 1, 1 },
  21. { 1, 0, 4, 3, 4, 3, 0, 1, 1, 1 },
  22. { 1, 0, 0, 4, 3, 0, 0, 1, 1, 1 },
  23. { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
  24. { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
  25. };
  26. WriteMapFile(Map, 10, "map/map_05.txt");
  27.  
  28. }
  29. //读取地图文件
  30. void Map::ReadMapFile(int map[M][N], int size, const char* filename)
  31. {
  32. FILE* pfile = nullptr;
  33. fopen_s(&pfile, filename, "rb");
  34. fread(map, 10 * size * 4, 1, pfile);
  35. fclose(pfile);
  36. }
  37. //写入地图文件
  38. void Map::WriteMapFile(int map[M][N], int size, const char* filename)
  39. {
  40. FILE* pfile = nullptr;
  41. fopen_s(&pfile, filename, "wb");
  42. fwrite(map, 10 * size * 4, 1, pfile);
  43. fclose(pfile);
  44. }
  45. Map::~Map()
  46. {
  47.  
  48. }

Class Game (游戏类)

Game.h:

  1. #define _GAEM_H__
  2. #ifdef _GAEM_H__
  3.  
  4. #include <iostream>
  5. using namespace std;
  6. #include <string.h>
  7. #include <conio.h>
  8. #pragma warning (disable:4996)
  9. #define N 10
  10. #define M 10
  11.  
  12. /***************************建立一个推箱子相关操作的类***********************/
  13. /*--------------------------Game类编写-----------------------------------*/
  14. /****************************************************************************/
  15. class Game
  16. {
  17. public:
  18. int Move(int map[M][N], char ch);
  19. void Drop(int map[M][N],int c);
  20. int juide(int map[M][N]);
  21. private:
  22. int push(int map[M][N], int offsetX,int offsetY);
  23. void Postion(int map[M][N]);
  24. int posX;
  25. int posY;
  26. };
  27. #endif /*_GAME_H__*/

Game.cpp:

  1. #include "Game.h"
  2.  
  3. //按键控制人物移动
  4. int Game::Move(int map[M][N], char ch)
  5. {
  6. static int step = 0;
  7. int offsetx = 0;
  8. int offsety = 0;
  9. switch (ch)
  10. {
  11. //向上移动
  12. case 'w':case 'W':
  13. offsetx = -1;
  14. offsety = 0;
  15. if (push(map, offsetx, offsety) == 1)
  16. step++;
  17. break;
  18. //向下移动
  19. case 's':case 'S':
  20. offsetx = 1;
  21. offsety = 0;
  22. if (push(map, offsetx, offsety) == 1)
  23. step++;
  24. break;
  25. //向左移动
  26. case 'a':case 'A':
  27. offsetx = 0;
  28. offsety = -1;
  29. if (push(map, offsetx, offsety) == 1)
  30. step++;
  31. break;
  32. //向右移动
  33. case 'd':case 'D':
  34. offsetx = 0;
  35. offsety = 1;
  36. if (push(map, offsetx, offsety) == 1)
  37. step++;
  38. break;
  39. default:
  40. break;
  41. }
  42. return step;
  43. }
  44. //界面打印
  45. void Game::Drop(int map[M][N], int c)
  46. {
  47. cout <<"\t\t"<<"**********************第 "<<c<<" 关**************************" << endl;
  48. cout <<"\t\t"<<"***************W-w:向上 S-s:向下*****************" << endl;
  49. cout <<"\t\t"<<"***************A-a:向左 D-d:向右*****************" << endl;
  50. cout << endl;
  51. for (int i = 0; i < M; i++)
  52. {
  53. cout << " ";
  54. for (int j = 0; j < N; j++)
  55. {
  56. switch (map[i][j])
  57. {
  58. //打印空地
  59. case 0:
  60. cout << " ";
  61. break;
  62. //打印墙壁
  63. case 1:
  64. cout << "■";
  65. break;
  66. //打印玩家
  67. case 2:
  68. cout << "♀";
  69. posX = i;
  70. posY = j;
  71. break;
  72. //打印箱子
  73. case 3:
  74. cout << "□";
  75. break;
  76. //打印终点
  77. case 4:
  78. cout << "○";
  79. break;
  80. //人 + 终点
  81. case 6:
  82. cout << "★";
  83. posX = i;
  84. posY = j;
  85. break;
  86. //箱子 + 终点
  87. case 7:
  88. cout << "●";
  89. break;
  90. default:
  91. break;
  92. }
  93. }
  94. cout << endl; //换行
  95. }
  96. }
  97. //判断游戏胜利条件
  98. int Game::juide(int map[M][N])
  99. {
  100. for (int i = 0; i < M; i++)
  101. {
  102. for (int j = 0; j < N; j++)
  103. {
  104. if (4 == map[i][j] || 6 == map[i][j]) //地图中还存在终点/终点+人
  105. return 1;
  106. }
  107. }
  108. return 0;
  109. }
  110. //更新游戏
  111. int Game::push(int map[M][N], int offsetX, int offsetY)
  112. {
  113. Postion(map); //确定人物坐标
  114. if (map[posX + offsetX][posY + offsetY] == 0) //下一格是空地
  115. {
  116. map[posX][posY] -= 2; //上一格变为空地或终点
  117. map[posX + offsetX][posY + offsetY] += 2; //下一格变为人或人+终点
  118. //改变人的坐标
  119. posX += offsetX;
  120. posY += offsetY;
  121. }
  122. else if (map[posX + offsetX][posY + offsetY] == 3) //下一格是箱子
  123. {
  124. if (map[posX + offsetX * 2][posY + offsetY * 2] == 0
  125. || map[posX + offsetX * 2][posY + offsetY * 2] == 4) //下两格是空地/终点
  126. {
  127. map[posX][posY] -= 2; //上一格变为空地/终点
  128. map[posX + offsetX][posY + offsetY] = 2; //下一格变为人
  129. map[posX + offsetX * 2][posY + offsetY * 2] += 3; //下两格变为箱子/箱子+终点
  130. posX += offsetX;
  131. posY += offsetY;
  132. }
  133. }
  134. else if (map[posX + offsetX][posY + offsetY] == 4) //下一格是终点
  135. {
  136. map[posX][posY] -= 2; //上一格变为空地/终点
  137. map[posX + offsetX][posY + offsetY] = 6; //下一格变为人+终点
  138. posX += offsetX;
  139. posY += offsetY;
  140. }
  141. else if (map[posX + offsetX][posY + offsetY] == 7) //下一格是箱子+终点
  142. {
  143. if (map[posX + offsetX * 2][posY + offsetY * 2] == 0
  144. || map[posX + offsetX * 2][posY + offsetY * 2] == 4) //下两格是空地/终点
  145. {
  146. map[posX][posY] -= 2; //上一格变为空地/终点
  147. map[posX + offsetX][posY + offsetY] = 6; //下一格变为人+终点
  148. map[posX + offsetX * 2][posY + offsetY * 2] += 3; //下两格变为箱子/箱子+终点
  149. posX += offsetX;
  150. posY += offsetY;
  151. }
  152. }
  153. else //人物不能移动
  154. return 0;
  155. return 1;
  156.  
  157. }
  158. //找到人物坐标
  159. void Game::Postion(int map[M][N])
  160. {
  161. for (int i = 0; i < M; i++)
  162. {
  163. for (int j = 0; j < N; j++)
  164. {
  165. if (2 == map[i][j] || 6 == map[i][j]) //地图中存在终点/终点+人
  166. {
  167. //给人物坐标赋值
  168. posX = i;
  169. posY = j;
  170. }
  171. }
  172. }
  173. }

Main:

  1. #include<iostream>
  2. #include<string.h>
  3. using namespace std;
  4. #pragma warning (disable:4996)
  5. #define M 10
  6. #define N 10
  7.  
  8. //定义一个10*10地图,1表示墙,0表示空地,2表示人
  9. //3表示箱子,4表示成功点
  10. //1.人物可以站到成功点中,显示人
  11. //2.箱子推入成功点后,可以推出来
  12. //3.记录步数,显示在控制台上
  13. //4.界面:提示(■代表墙....)/游戏开始界面
  14. //5.最终提示全部推入,提示成功
  15. //周围都是墙,中间都是空地
  16. #include"Map.h"
  17. #include"Game.h"
  18. int main()
  19. {
  20. Map _map;
  21. //_map.Init();
  22. int map[M][N];
  23. char filename[] = "map/map_0";
  24. int custom = 2;
  25. while (custom <= 5)
  26. {
  27. char buffer[80];
  28. sprintf(buffer, "%s%d", filename, custom); //连接filename和custom,以字符串保存到buffer中
  29. strcat(buffer, ".txt"); //字符串连接
  30. _map.ReadMapFile(map, N, buffer);
  31. Game game;
  32. int step = 0;
  33. while (game.juide(map)) //游戏胜利,跳出循环
  34. {
  35. system("cls");
  36. game.Drop(map, custom);
  37. char ch = _getch(); //按键输入
  38. step = game.Move(map, ch);
  39. system("cls");
  40. }
  41. custom++; //关卡+1
  42. cout << "你赢了!" << endl;
  43. cout << "共走:" << step << "步" << endl;;
  44. system("pause");
  45.  
  46. }
  47.  
  48. return 0;
  49. }

三、实现效果

项目目录图片

C++实现推箱子游戏

地图文件图片

C++实现推箱子游戏

实现效果

C++实现推箱子游戏

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/Amumu12138/article/details/79041421