当前位置 主页 > 网站技术 > 代码类 >

    C++实现推箱子游戏

    栏目:代码类 时间:2019-10-24 21:05

    一、项目简介

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

    二、 代码区

    Class Map(地图类)

    Map.h:

    #pragma once
    #define N 10
    #define M 10
    //地图类
    class Map
    {
    public:
     Map();
     ~Map();
     void Init();
     
     void ReadMapFile(int map[M][N], int size,const char* filename );
     void WriteMapFile(int map[M][N], int size, const char* filename);
    private:
     
    };

    Map.cpp:

    #include "Map.h"
    #include<iostream>
    #include<fstream>
    using namespace std;
     
     
    Map::Map()
    {
     
    }
    //地图初始化方法
    void Map::Init()
    {
     int Map[10][10] =
     {
     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
     { 1, 0, 0, 4, 3, 0, 1, 1, 1, 1 },
     { 1, 0, 4, 3, 4, 3, 0, 0, 1, 1 },
     { 1, 7, 3, 4, 3, 4, 2, 0, 1, 1 },
     { 1, 0, 4, 3, 4, 3, 0, 1, 1, 1 },
     { 1, 0, 0, 4, 3, 0, 0, 1, 1, 1 },
     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
     { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
     };
     WriteMapFile(Map, 10, "map/map_05.txt");
     
    }
    //读取地图文件
    void Map::ReadMapFile(int map[M][N], int size, const char* filename)
    {
     FILE* pfile = nullptr;
     fopen_s(&pfile, filename, "rb");
     fread(map, 10 * size * 4, 1, pfile);
     fclose(pfile);
    }
    //写入地图文件
    void Map::WriteMapFile(int map[M][N], int size, const char* filename)
    {
     FILE* pfile = nullptr;
     fopen_s(&pfile, filename, "wb");
     fwrite(map, 10 * size * 4, 1, pfile);
     fclose(pfile);
    }
    Map::~Map()
    {
     
    }

    Class Game (游戏类)

    Game.h:

    #define _GAEM_H__
    #ifdef _GAEM_H__
     
    #include <iostream>
    using namespace std;
    #include <string.h>
    #include <conio.h>
    #pragma warning (disable:4996)
    #define N 10
    #define M 10
     
    /***************************建立一个推箱子相关操作的类***********************/
    /*--------------------------Game类编写-----------------------------------*/
    /****************************************************************************/
    class Game
    {
    public:
     int Move(int map[M][N], char ch);
     void Drop(int map[M][N],int c);
     int juide(int map[M][N]);
    private:
     int push(int map[M][N], int offsetX,int offsetY);
     void Postion(int map[M][N]);
     int posX;
     int posY;
    };
    #endif /*_GAME_H__*/

     Game.cpp:

    #include "Game.h"
     
    //按键控制人物移动
    int Game::Move(int map[M][N], char ch)
    {
     static int step = 0;
     int offsetx = 0;
     int offsety = 0;
     switch (ch)
     {
     //向上移动
     case 'w':case 'W':
     offsetx = -1;
     offsety = 0;
     if (push(map, offsetx, offsety) == 1)
      step++;
     break;
     //向下移动
     case 's':case 'S':
     offsetx = 1;
     offsety = 0;
     if (push(map, offsetx, offsety) == 1)
      step++;
     break;
     //向左移动
     case 'a':case 'A':
     offsetx = 0;
     offsety = -1;
     if (push(map, offsetx, offsety) == 1)
      step++;
     break;
     //向右移动
     case 'd':case 'D':
     offsetx = 0;
     offsety = 1;
     if (push(map, offsetx, offsety) == 1)
      step++;
     break;
     default:
     break;
     }
     return step;
    }
    //界面打印
    void Game::Drop(int map[M][N], int c)
    {
     cout <<"\t\t"<<"**********************第 "<<c<<" 关**************************" << endl;
     cout <<"\t\t"<<"***************W-w:向上    S-s:向下*****************" << endl;
     cout <<"\t\t"<<"***************A-a:向左    D-d:向右*****************" << endl;
     cout << endl;
     for (int i = 0; i < M; i++)
     {
     cout << "             ";
     for (int j = 0; j < N; j++)
     {
      switch (map[i][j])
      {
      //打印空地
      case 0:
      cout << " ";
      break;
      //打印墙壁
      case 1:
      cout << "■";
      break;
      //打印玩家
      case 2:
      cout << "♀";
      posX = i;
      posY = j;
      break;
      //打印箱子
      case 3:
      cout << "□";
      break;
      //打印终点
      case 4:
      cout << "○";
      break;
      //人 + 终点
      case 6:
      cout << "★";
      posX = i;
      posY = j;
      break;
      //箱子 + 终点
      case 7:
      cout << "●";
      break;
      default:
      break;
      }
     }
     cout << endl;      //换行
     }
    }
    //判断游戏胜利条件
    int Game::juide(int map[M][N])
    {
     for (int i = 0; i < M; i++)
     {
     for (int j = 0; j < N; j++)
     {
      if (4 == map[i][j] || 6 == map[i][j])   //地图中还存在终点/终点+人
      return 1;
     }
     }
     return 0;
    }
    //更新游戏
    int Game::push(int map[M][N], int offsetX, int offsetY)
    {
     Postion(map);                    //确定人物坐标
     if (map[posX + offsetX][posY + offsetY] == 0)    //下一格是空地
     {
     map[posX][posY] -= 2;              //上一格变为空地或终点
     map[posX + offsetX][posY + offsetY] += 2;    //下一格变为人或人+终点
     //改变人的坐标
     posX += offsetX;
     posY += offsetY;
     }
     else if (map[posX + offsetX][posY + offsetY] == 3)      //下一格是箱子
     {
     if (map[posX + offsetX * 2][posY + offsetY * 2] == 0
      || map[posX + offsetX * 2][posY + offsetY * 2] == 4) //下两格是空地/终点
     {
      map[posX][posY] -= 2;                 //上一格变为空地/终点
      map[posX + offsetX][posY + offsetY] = 2;       //下一格变为人
      map[posX + offsetX * 2][posY + offsetY * 2] += 3;   //下两格变为箱子/箱子+终点
      posX += offsetX;
      posY += offsetY;
     }
     }
     else if (map[posX + offsetX][posY + offsetY] == 4)      //下一格是终点
     {
     map[posX][posY] -= 2;                  //上一格变为空地/终点
     map[posX + offsetX][posY + offsetY] = 6;         //下一格变为人+终点
     posX += offsetX;
     posY += offsetY;
     }
     else if (map[posX + offsetX][posY + offsetY] == 7)      //下一格是箱子+终点
     {
     if (map[posX + offsetX * 2][posY + offsetY * 2] == 0
      || map[posX + offsetX * 2][posY + offsetY * 2] == 4) //下两格是空地/终点
     {
      map[posX][posY] -= 2;      //上一格变为空地/终点
      map[posX + offsetX][posY + offsetY] = 6;       //下一格变为人+终点
      map[posX + offsetX * 2][posY + offsetY * 2] += 3;   //下两格变为箱子/箱子+终点
      posX += offsetX;
      posY += offsetY;
     }
     }
     else    //人物不能移动
     return 0;
     return 1;
     
    }
    //找到人物坐标
    void Game::Postion(int map[M][N])
    {
     for (int i = 0; i < M; i++)
     {
     for (int j = 0; j < N; j++)
     {
      if (2 == map[i][j] || 6 == map[i][j])   //地图中存在终点/终点+人
      {
      //给人物坐标赋值
      posX = i;
      posY = j;
      }
     }
     }
    }