C++新手,用OOP思想编写的推箱子小游戏,请多赐教


1.main函数

#include"Controller.h"

void main()
{
 CController controller;
 controller.Init();
 controller.MainLoop();
 controller.GameOver();
}

2.Tools头文件

#pragma once

#include<iostream>
#include<conio.h>
#include<time.h>
using namespace std;

const int c_iHEIGHT = 10;//行
const int c_iWIDTH = 10;//列
const int c_iHOLE_NUM = 3;//洞数量


3.Map头文件

#pragma once
#include"Tools.h"

enum Map_Element{ EMPTY, WALL, HOLE, BOX, HUMAN };//地图中的元素


class CMap
{
private:
 Map_Element m_iMap[c_iHEIGHT][c_iWIDTH];//地图数组
private:
 //输出地图元素
 void Print(int x, int y);
public:
 
 //构造函数,初始化地图数组
 CMap();

 //获取地图元素
 Map_Element GetMapData(int x ,int y);

 //设置地图元素
 void SetMapData(int x, int y, Map_Element value);

 //显示地图
 void Show();
};

Map类的实现

#include"Map.h"

//构造函数,初始化地图数组
CMap::CMap()
{
 for (int i = 0; i < c_iHEIGHT; ++i)
 {
  for (int j = 0; j < c_iWIDTH; ++j)
  {
   if (i == 0 || i == c_iHEIGHT - 1 || j == 0 || j == c_iWIDTH-1)
   {
    m_iMap[i][j] = WALL;
   }
   else m_iMap[i][j] = EMPTY;
  }
 }
}

//获取地图数据
Map_Element CMap::GetMapData(int x, int y)
{
 return m_iMap[y][x];
}

//设置地图数据
void CMap::SetMapData(int x, int y, Map_Element value)
{
 m_iMap[y][x] = value;
}

//根据地图元素作出相应的输出
void CMap::Print(int x, int y)
{
 switch (m_iMap[y][x])
 {
 case WALL:
  cout << "■";
  break;
 case EMPTY:
  cout << "  ";
  break;
 case HOLE:
  cout << "★";
  break;
 case BOX:
  cout << "※";
  break;
 case HUMAN:
  cout << "♀";
  break;
 }
}

//显示地图
void CMap::Show()
{
 for (int i = 0; i < c_iHEIGHT; ++i)
 {
  for (int j = 0; j < c_iWIDTH; ++j)
  {
   Print(j, i);
  }
  cout << endl;
 }
}


4、Hole类头文件

#pragma once
#include"Tools.h"

class CHole
{
 int m_iHoleX;//洞的X坐标
 int m_iHoleY;//洞的Y坐标
 int m_iHole[c_iHOLE_NUM][2];//保存箱子坐标
public:
 CHole(){};
 void CreateHole();
 int GetHoleX(){ return m_iHoleX; }
 int GetHoleY(){ return m_iHoleY; }
 int GetHoleCoord(int holeXY, int holeIndex){ return m_iHole[holeXY][holeIndex]; }
 void SetHoleCoord(int x, int y, int value){ m_iHole[x][y] = value; }
};

Hole类的实现


#include"Hole.h"
#include"Tools.h"

void CHole::CreateHole()
{
 m_iHoleX = rand() % (c_iWIDTH - 2) + 1;
 m_iHoleY = rand() % (c_iHEIGHT - 2) + 1;
}


5、箱子类的头文件及实现

#pragma once

class CBox
{
 int m_iBoxX;//箱子X坐标
 int m_iBoxY;//箱子Y坐标
public:
 CBox(){}
 int GetBoxX(){ return m_iBoxX; }
 int GetBoxY(){ return m_iBoxY; }
 void CreateBox();
};


#include"Box.h"
#include"Tools.h"

void CBox::CreateBox()
{
 m_iBoxX = rand() % (c_iWIDTH - 5) + 2;
 m_iBoxY = rand() % (c_iHEIGHT - 4) + 2;
}


6.Controller类的声明和实现

#pragma once
#include"Map.h"
#include"Hole.h"
#include"Box.h"

enum Direction{ UP = 72, DOWN = 80, LEFT = 75, RIGHT = 77 };//方向枚举值

class CController
{
 int m_iHumanX;//人物X坐标
 int m_iHumanY;//人物Y坐标
 bool m_bIsGameOver;
 CHole* pHole;
 CBox* pBox;
 CMap* pMap;
 Direction m_dir;//方向
private:
 bool CanMove(int x, int y);//判断能否移动
 void Move();
 void CheckHole();//矫正洞坐标
 void Refresh();
 bool IsWin();//判断胜负
public:
 CController();
 ~CController();
 void Init();//初始化游戏数据
 void MainLoop();//游戏主循环
 void GameOver();//游戏结束
};


#include"Controller.h"

CController::CController()
{
 m_iHumanX = 2;
 m_iHumanY = 2;

 pMap = new CMap();
 pHole = new CHole();
 pBox = new CBox();

 m_bIsGameOver = false;

 srand((unsigned)time(NULL));
}
CController::~CController()
{
 delete pMap;
 delete pHole;
 delete pBox;
}
bool CController::IsWin()
{
 for (int i = 0; i < c_iHOLE_NUM; ++i)
 {
  int holeX = pHole->GetHoleCoord(i, 0);
  int holeY = pHole->GetHoleCoord(i, 1);
  if (pMap->GetMapData(holeX, holeY) != BOX)
  {
   return false;
  }
 }
 return true;
}
void CController::Init()
{
 //1.在地图中生成人物
 pMap->SetMapData(m_iHumanX, m_iHumanY, HUMAN);
 
 //2.在地图中生成洞
 for (int i = 0; i < c_iHOLE_NUM; ++i)
 {
  while (true)
  {
   pHole->CreateHole();
   if (pMap->GetMapData(pHole->GetHoleX(),pHole->GetHoleY())==EMPTY)
   {
    pMap->SetMapData(pHole->GetHoleX(), pHole->GetHoleY(), HOLE);
    pHole->SetHoleCoord(i, 0, pHole->GetHoleX());
    pHole->SetHoleCoord(i, 1, pHole->GetHoleY());
    break;
   }
  }
 }

 //3.在地图中生成箱子
 for (int i = 0; i < c_iHOLE_NUM; ++i)
 {
  while (true)
  {
   pBox->CreateBox();
   if (pMap->GetMapData(pBox->GetBoxX(), pBox->GetBoxY()) == EMPTY)
   {
    pMap->SetMapData(pBox->GetBoxX(), pBox->GetBoxY(), BOX);
    break;
   }
  }
 }
}

bool CController::CanMove(int x, int y)
{
 if (pMap->GetMapData(x, y) == EMPTY || pMap->GetMapData(x, y) == HOLE)
 {
  return true;
 }
 else return false;
}

void CController::Refresh()
{
 system("cls");
}

void CController::Move()
{
 switch (m_dir)
 {
 case UP:
  if (CanMove(m_iHumanX, m_iHumanY - 1))
  {
   pMap->SetMapData(m_iHumanX, m_iHumanY - 1, HUMAN);
   pMap->SetMapData(m_iHumanX, m_iHumanY, EMPTY);
   --m_iHumanY;
  }
  else if (pMap->GetMapData(m_iHumanX, m_iHumanY - 1) == BOX)
  {
   if (CanMove(m_iHumanX, m_iHumanY - 2))
   {
    pMap->SetMapData(m_iHumanX, m_iHumanY - 2, BOX);
    pMap->SetMapData(m_iHumanX, m_iHumanY - 1, HUMAN);
    pMap->SetMapData(m_iHumanX, m_iHumanY, EMPTY);
    --m_iHumanY;
   }
  }
  break;
 case DOWN:
  if (CanMove(m_iHumanX, m_iHumanY + 1))
  {
   pMap->SetMapData(m_iHumanX, m_iHumanY + 1, HUMAN);
   pMap->SetMapData(m_iHumanX, m_iHumanY, EMPTY);
   ++m_iHumanY;
  }
  else if (pMap->GetMapData(m_iHumanX, m_iHumanY + 1) == BOX)
  {
   if (CanMove(m_iHumanX, m_iHumanY + 2))
   {
    pMap->SetMapData(m_iHumanX, m_iHumanY + 2, BOX);
    pMap->SetMapData(m_iHumanX, m_iHumanY + 1, HUMAN);
    pMap->SetMapData(m_iHumanX, m_iHumanY, EMPTY);
    ++m_iHumanY;
   }
  }
  break;
 case LEFT:
  if (CanMove(m_iHumanX-1, m_iHumanY))
  {
   pMap->SetMapData(m_iHumanX-1, m_iHumanY, HUMAN);
   pMap->SetMapData(m_iHumanX, m_iHumanY, EMPTY);
   --m_iHumanX;
  }
  else if (pMap->GetMapData(m_iHumanX-1, m_iHumanY) == BOX)
  {
   if (CanMove(m_iHumanX-2, m_iHumanY))
   {
    pMap->SetMapData(m_iHumanX-2, m_iHumanY, BOX);
    pMap->SetMapData(m_iHumanX-1, m_iHumanY, HUMAN);
    pMap->SetMapData(m_iHumanX, m_iHumanY, EMPTY);
    --m_iHumanX;
   }
  }
  break;
 case RIGHT:
  if (CanMove(m_iHumanX + 1, m_iHumanY))
  {
   pMap->SetMapData(m_iHumanX + 1, m_iHumanY, HUMAN);
   pMap->SetMapData(m_iHumanX, m_iHumanY, EMPTY);
   ++m_iHumanX;
  }
  else if (pMap->GetMapData(m_iHumanX + 1, m_iHumanY) == BOX)
  {
   if (CanMove(m_iHumanX + 2, m_iHumanY))
   {
    pMap->SetMapData(m_iHumanX + 2, m_iHumanY, BOX);
    pMap->SetMapData(m_iHumanX + 1, m_iHumanY, HUMAN);
    pMap->SetMapData(m_iHumanX, m_iHumanY, EMPTY);
    ++m_iHumanX;
   }
  }
  break;
 }
}

void CController::CheckHole()
{
 for (int i = 0; i < c_iHOLE_NUM; ++i)
 {
  int holeX = pHole->GetHoleCoord(i, 0);
  int holeY = pHole->GetHoleCoord(i, 1);
  if (pMap->GetMapData(holeX, holeY) == EMPTY)
  {
   pMap->SetMapData(holeX, holeY, HOLE);
  }
 }
}

void CController::MainLoop()
{
 while (!m_bIsGameOver)
 {
  pMap->Show();
  int input = _getch();
  switch (input)
  {
  case UP:
   m_dir = UP;
   Move();
   break;
  case DOWN:
   m_dir = DOWN;
   Move();
   break;
  case LEFT:
   m_dir = LEFT;
   Move();
   break;
  case RIGHT:
   m_dir = RIGHT;
   Move();
   break;
  } 
  if (IsWin())
  {
   m_bIsGameOver = true;
  }
  Refresh();
  CheckHole();
  
 }
}
void CController::GameOver()
{
 cout <<"恭喜获胜!" << endl;
 cout << "按任意键退出游戏" << endl;
 _getch();
}





























评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值