Refactor cells structure
Now each cell is an object of a specific class representing logic and behavior of how game should behave when player tries to move onto the following cell. Also add TeleportCell
This commit is contained in:
parent
8823543d4e
commit
f24193b309
|
@ -0,0 +1,130 @@
|
||||||
|
#include "cell.h"
|
||||||
|
|
||||||
|
#include "hero.h"
|
||||||
|
#include "level.h"
|
||||||
|
|
||||||
|
#define UNUSED(expr) (void)(expr);
|
||||||
|
|
||||||
|
Cell::Cell(coordinate cell_x, coordinate cell_y, const sf::Color &color) :
|
||||||
|
Entity(cell_x, cell_y),
|
||||||
|
cell_color(color)
|
||||||
|
{}
|
||||||
|
|
||||||
|
sf::Color Cell::color() const noexcept
|
||||||
|
{
|
||||||
|
return cell_color;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
PassableCell::PassableCell(coordinate cell_x, coordinate cell_y, const sf::Color &color) :
|
||||||
|
Cell(cell_x, cell_y, color)
|
||||||
|
{}
|
||||||
|
|
||||||
|
PassableCell::~PassableCell()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool PassableCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
||||||
|
{
|
||||||
|
UNUSED(hero)
|
||||||
|
UNUSED(level)
|
||||||
|
|
||||||
|
// Hero just moves on.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
WaterCell::WaterCell(coordinate cell_x, coordinate cell_y, const sf::Color &color) :
|
||||||
|
Cell(cell_x, cell_y, color)
|
||||||
|
{}
|
||||||
|
|
||||||
|
WaterCell::~WaterCell()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool WaterCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
||||||
|
{
|
||||||
|
// Try to use one charge to place a bridge
|
||||||
|
if (hero->useCharge()) {
|
||||||
|
level->placeBridge(pos_x, pos_y);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If hero doesn't have enough charges, we move Hero back
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
WallCell::WallCell(coordinate cell_x, coordinate cell_y, const sf::Color &color) :
|
||||||
|
Cell(cell_x, cell_y, color)
|
||||||
|
{}
|
||||||
|
|
||||||
|
WallCell::~WallCell()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool WallCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
||||||
|
{
|
||||||
|
UNUSED(hero)
|
||||||
|
UNUSED(level)
|
||||||
|
|
||||||
|
// Hero never passes this cell.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
ChargeCell::ChargeCell(coordinate cell_x, coordinate cell_y, int has_charges, const sf::Color &color) :
|
||||||
|
Cell(cell_x, cell_y, color),
|
||||||
|
cell_charges(has_charges)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ChargeCell::~ChargeCell()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool ChargeCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
||||||
|
{
|
||||||
|
// Hero picks up the charge; remove it from the map
|
||||||
|
hero->refillCharges(cell_charges);
|
||||||
|
level->removeCharge(pos_x, pos_y);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
ExitCell::ExitCell(coordinate cell_x, coordinate cell_y, const sf::Color &color) :
|
||||||
|
Cell(cell_x, cell_y, color)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ExitCell::~ExitCell()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool ExitCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
||||||
|
{
|
||||||
|
UNUSED(level)
|
||||||
|
|
||||||
|
// Level is over.
|
||||||
|
hero->reachExit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
TeleportCell::TeleportCell(coordinate cell_x, coordinate cell_y, coordinate new_cell_x, coordinate new_cell_y, const sf::Color &color) :
|
||||||
|
Cell(cell_x, cell_y, color),
|
||||||
|
new_x(new_cell_x),
|
||||||
|
new_y(new_cell_y)
|
||||||
|
{}
|
||||||
|
|
||||||
|
TeleportCell::~TeleportCell()
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool TeleportCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
||||||
|
{
|
||||||
|
UNUSED(level)
|
||||||
|
|
||||||
|
// Hero jumps into teleport!
|
||||||
|
hero->setPosition(new_x, new_y);
|
||||||
|
return true;
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
#ifndef CELL_H
|
||||||
|
#define CELL_H
|
||||||
|
|
||||||
|
#include "entity.h"
|
||||||
|
#include <memory>
|
||||||
|
#include <SFML/Graphics/Color.hpp>
|
||||||
|
|
||||||
|
class Hero;
|
||||||
|
class Level;
|
||||||
|
|
||||||
|
using HeroPtr = std::unique_ptr<Hero>;
|
||||||
|
using LevelPtr = std::unique_ptr<Level>;
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
/// Represents interface for all level cells
|
||||||
|
class Cell : public Entity
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
sf::Color cell_color;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Cell(coordinate cell_x = 0,
|
||||||
|
coordinate cell_y = 0,
|
||||||
|
const sf::Color &color = sf::Color::White);
|
||||||
|
|
||||||
|
virtual ~Cell() = 0;
|
||||||
|
|
||||||
|
inline sf::Color color() const noexcept;
|
||||||
|
|
||||||
|
/// Determine if Hero can move onto this cell or not
|
||||||
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
/// Any cell where Hero is free to move
|
||||||
|
class PassableCell : public Cell
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PassableCell(coordinate cell_x = 0,
|
||||||
|
coordinate cell_y = 0, // Brown
|
||||||
|
const sf::Color &color = sf::Color(165, 42, 42));
|
||||||
|
|
||||||
|
virtual ~PassableCell() override;
|
||||||
|
|
||||||
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
/// A cell which requires Hero to spend a charge for bridge to move on
|
||||||
|
class WaterCell : public Cell
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WaterCell(coordinate cell_x = 0,
|
||||||
|
coordinate cell_y = 0,
|
||||||
|
const sf::Color &color = sf::Color::Blue);
|
||||||
|
|
||||||
|
virtual ~WaterCell() override;
|
||||||
|
|
||||||
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
/// A cell which is impossible to move on
|
||||||
|
class WallCell : public Cell
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
WallCell(coordinate cell_x = 0,
|
||||||
|
coordinate cell_y = 0, // Gray
|
||||||
|
const sf::Color &color = sf::Color(125, 125, 125));
|
||||||
|
|
||||||
|
virtual ~WallCell() override;
|
||||||
|
|
||||||
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
/// A cell which gives hero a charge
|
||||||
|
class ChargeCell : public Cell
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
int cell_charges;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ChargeCell(coordinate cell_x = 0,
|
||||||
|
coordinate cell_y = 0,
|
||||||
|
int has_charges = 1,
|
||||||
|
const sf::Color &color = sf::Color::Green);
|
||||||
|
|
||||||
|
virtual ~ChargeCell() override;
|
||||||
|
|
||||||
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
/// A cell which moves hero to next level
|
||||||
|
class ExitCell : public Cell
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ExitCell(coordinate cell_x = 0,
|
||||||
|
coordinate cell_y = 0,
|
||||||
|
const sf::Color &color = sf::Color::Red);
|
||||||
|
|
||||||
|
virtual ~ExitCell() override;
|
||||||
|
|
||||||
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
/// A cell which teleports hero to following coordinates
|
||||||
|
class TeleportCell : public Cell
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
coordinate new_x, new_y;
|
||||||
|
|
||||||
|
public:
|
||||||
|
TeleportCell(coordinate cell_x = 0,
|
||||||
|
coordinate cell_y = 0,
|
||||||
|
coordinate new_cell_x = 0,
|
||||||
|
coordinate new_cell_y = 0, // Purple
|
||||||
|
const sf::Color &color = sf::Color(128, 0, 128));
|
||||||
|
|
||||||
|
virtual ~TeleportCell() override;
|
||||||
|
|
||||||
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CELL_H
|
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef ENTITY_H
|
||||||
|
#define ENTITY_H
|
||||||
|
|
||||||
|
using coordinate = unsigned int;
|
||||||
|
|
||||||
|
/// Interface representing entity which can be placed on the map
|
||||||
|
class Entity
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
coordinate pos_x, pos_y;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Entity(coordinate _x = 0, coordinate _y = 0) :
|
||||||
|
pos_x(_x), pos_y(_y)
|
||||||
|
{}
|
||||||
|
|
||||||
|
virtual ~Entity() = 0;
|
||||||
|
|
||||||
|
/// Get current Entity position
|
||||||
|
void position(coordinate &x, coordinate &y) const noexcept
|
||||||
|
{
|
||||||
|
x = pos_x;
|
||||||
|
y = pos_y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set Entity position explicitly
|
||||||
|
void setPosition(coordinate x, coordinate y)
|
||||||
|
{
|
||||||
|
pos_x = x;
|
||||||
|
pos_y = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get current x of the Entity position
|
||||||
|
coordinate x() const noexcept
|
||||||
|
{
|
||||||
|
return pos_x;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get current y of the Entity position
|
||||||
|
coordinate y() const noexcept
|
||||||
|
{
|
||||||
|
return pos_y;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // ENTITY_H
|
132
src/game.cpp
132
src/game.cpp
|
@ -101,42 +101,12 @@ void Game::onMoving(sf::Keyboard::Key &key)
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
switch (level->cellOfType(attempt_x, attempt_y))
|
if (!level->mapArray()[attempt_x][attempt_y]->onMovingTo(hero, level))
|
||||||
{
|
|
||||||
case CellType::Water:
|
|
||||||
|
|
||||||
// Try to use one charge to place a bridge
|
|
||||||
if (hero->useCharge())
|
|
||||||
level->placeBridge(attempt_x, attempt_y);
|
|
||||||
// If hero doesn't have enough charges, we move Hero back
|
|
||||||
else
|
|
||||||
hero->setPosition(initial_x, initial_y);
|
hero->setPosition(initial_x, initial_y);
|
||||||
|
|
||||||
break;
|
if (hero->onExit())
|
||||||
|
|
||||||
case CellType::Charge:
|
|
||||||
|
|
||||||
// Hero picks up the charge; remove it from the map
|
|
||||||
hero->refillCharges(1);
|
|
||||||
level->removeCharge(attempt_x, attempt_y);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CellType::Exit:
|
|
||||||
|
|
||||||
// Hero exists the level!
|
|
||||||
loadLevel(++current_level);
|
loadLevel(++current_level);
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CellType::Wall:
|
|
||||||
|
|
||||||
// You can't pass through wall. Hero goes back to inital coordinates
|
|
||||||
hero->setPosition(initial_x, initial_y);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::renderMap()
|
void Game::renderMap()
|
||||||
|
@ -165,30 +135,10 @@ void Game::renderMap()
|
||||||
// Draw map from 2D array
|
// Draw map from 2D array
|
||||||
for (const Row &row : map)
|
for (const Row &row : map)
|
||||||
{
|
{
|
||||||
for (const CellType &cell : row)
|
for (const std::unique_ptr<Cell> &cell : row)
|
||||||
{
|
{
|
||||||
rectangle_brush.setPosition(painter_y, painter_x);
|
rectangle_brush.setPosition(painter_y, painter_x);
|
||||||
switch (cell)
|
rectangle_brush.setFillColor(cell->color());
|
||||||
{
|
|
||||||
case CellType::Ground:
|
|
||||||
rectangle_brush.setFillColor(sf::Color(165, 42, 42)); // Brown
|
|
||||||
break;
|
|
||||||
case CellType::Charge:
|
|
||||||
rectangle_brush.setFillColor(sf::Color::Green);
|
|
||||||
break;
|
|
||||||
case CellType::Bridge:
|
|
||||||
rectangle_brush.setFillColor(sf::Color::Black);
|
|
||||||
break;
|
|
||||||
case CellType::Exit:
|
|
||||||
rectangle_brush.setFillColor(sf::Color::Red);
|
|
||||||
break;
|
|
||||||
case CellType::Wall:
|
|
||||||
rectangle_brush.setFillColor(sf::Color(60, 60, 60)); // Gray
|
|
||||||
break;
|
|
||||||
case CellType::Water:
|
|
||||||
default:
|
|
||||||
rectangle_brush.setFillColor(sf::Color::Blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
main_window.draw(rectangle_brush);
|
main_window.draw(rectangle_brush);
|
||||||
|
|
||||||
|
@ -214,14 +164,12 @@ void Game::renderMap()
|
||||||
|
|
||||||
void Game::loadLevel(int level_index)
|
void Game::loadLevel(int level_index)
|
||||||
{
|
{
|
||||||
Map map;
|
Map &map = level->mapArray();
|
||||||
|
|
||||||
// Fill the level with water
|
// Fill the level with water
|
||||||
for (Row &row : map)
|
for (coordinate x = 0; x < side; ++x)
|
||||||
{
|
for (coordinate y = 0; y < side; ++y)
|
||||||
for (CellType &cell : row)
|
map[x][y] = std::make_unique<WaterCell>(x, y);
|
||||||
cell = CellType::Water;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (level_index)
|
switch (level_index)
|
||||||
{
|
{
|
||||||
|
@ -229,51 +177,25 @@ void Game::loadLevel(int level_index)
|
||||||
// Hardcoding is temporary!
|
// Hardcoding is temporary!
|
||||||
hero->setPosition(1, 1);
|
hero->setPosition(1, 1);
|
||||||
hero->setCharges(2);
|
hero->setCharges(2);
|
||||||
map[0][0] = CellType::Wall;
|
map[0][0] = std::make_unique<WallCell>(0, 0);
|
||||||
map[0][1] = CellType::Wall;
|
map[0][1] = std::make_unique<WallCell>(0, 1);
|
||||||
map[1][0] = CellType::Wall;
|
map[1][0] = std::make_unique<WallCell>(1, 0);
|
||||||
map[1][1] = CellType::Ground;
|
map[1][1] = std::make_unique<PassableCell>(1, 1);
|
||||||
map[1][2] = CellType::Ground;
|
map[1][2] = std::make_unique<PassableCell>(1, 2);
|
||||||
map[1][3] = CellType::Ground;
|
map[1][3] = std::make_unique<PassableCell>(1, 3);
|
||||||
map[1][4] = CellType::Ground;
|
map[1][4] = std::make_unique<PassableCell>(1, 4);
|
||||||
map[2][2] = CellType::Ground;
|
map[2][1] = std::make_unique<TeleportCell>(2, 1, 6, 6);
|
||||||
map[3][2] = CellType::Ground;
|
map[2][2] = std::make_unique<PassableCell>(2, 2);
|
||||||
map[3][3] = CellType::Ground;
|
map[3][2] = std::make_unique<PassableCell>(3, 2);
|
||||||
map[3][3] = CellType::Ground;
|
map[3][3] = std::make_unique<PassableCell>(3, 3);
|
||||||
map[6][3] = CellType::Ground;
|
map[6][3] = std::make_unique<PassableCell>(6, 3);
|
||||||
map[6][4] = CellType::Ground;
|
map[6][4] = std::make_unique<PassableCell>(6, 4);
|
||||||
map[6][5] = CellType::Ground;
|
map[6][5] = std::make_unique<PassableCell>(6, 5);
|
||||||
map[6][6] = CellType::Ground;
|
map[6][6] = std::make_unique<PassableCell>(6, 6);
|
||||||
map[7][6] = CellType::Ground;
|
map[7][6] = std::make_unique<PassableCell>(7, 6);
|
||||||
map[9][6] = CellType::Ground;
|
map[9][6] = std::make_unique<PassableCell>(9, 6);
|
||||||
map[8][7] = CellType::Exit;
|
map[8][7] = std::make_unique<ExitCell>(8, 7);
|
||||||
map[2][3] = CellType::Charge;
|
map[2][3] = std::make_unique<ChargeCell>(2, 3, 5);
|
||||||
level->setMap(map);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
// Hardcoding is temporary!
|
|
||||||
hero->setPosition(5, 5);
|
|
||||||
hero->setCharges(10);
|
|
||||||
map[5][6] = CellType::Ground;
|
|
||||||
map[5][5] = CellType::Ground;
|
|
||||||
map[5][4] = CellType::Ground;
|
|
||||||
map[4][5] = CellType::Ground;
|
|
||||||
map[4][6] = CellType::Ground;
|
|
||||||
map[4][4] = CellType::Ground;
|
|
||||||
map[6][6] = CellType::Ground;
|
|
||||||
map[6][5] = CellType::Ground;
|
|
||||||
map[6][4] = CellType::Ground;
|
|
||||||
map[6][7] = CellType::Ground;
|
|
||||||
map[6][8] = CellType::Ground;
|
|
||||||
map[5][8] = CellType::Ground;
|
|
||||||
map[8][8] = CellType::Ground;
|
|
||||||
map[8][9] = CellType::Ground;
|
|
||||||
map[8][10] = CellType::Exit;
|
|
||||||
map[8][11] = CellType::Wall;
|
|
||||||
map[7][11] = CellType::Wall;
|
|
||||||
map[4][3] = CellType::Wall;
|
|
||||||
map[4][7] = CellType::Charge;
|
|
||||||
level->setMap(map);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
main_window.close();
|
main_window.close();
|
||||||
|
|
21
src/hero.cpp
21
src/hero.cpp
|
@ -1,9 +1,8 @@
|
||||||
#include "hero.h"
|
#include "hero.h"
|
||||||
|
|
||||||
Hero::Hero(coordinate position_x, coordinate position_y, int initial_charges) :
|
Hero::Hero(coordinate position_x, coordinate position_y, int initial_charges) :
|
||||||
hero_charges(initial_charges),
|
Entity(position_x, position_y),
|
||||||
pos_x(position_x),
|
hero_charges(initial_charges)
|
||||||
pos_y(position_y)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void Hero::refillCharges(int append_charges)
|
void Hero::refillCharges(int append_charges)
|
||||||
|
@ -32,12 +31,6 @@ void Hero::setCharges(int charges) noexcept
|
||||||
hero_charges = charges;
|
hero_charges = charges;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hero::position(coordinate &x, coordinate &y) const noexcept
|
|
||||||
{
|
|
||||||
x = pos_x;
|
|
||||||
y = pos_y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Hero::move(const Direction &direction)
|
void Hero::move(const Direction &direction)
|
||||||
{
|
{
|
||||||
switch (direction)
|
switch (direction)
|
||||||
|
@ -55,8 +48,12 @@ void Hero::move(const Direction &direction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hero::setPosition(coordinate x, coordinate y)
|
void Hero::reachExit() noexcept
|
||||||
{
|
{
|
||||||
pos_x = x;
|
on_exit = true;
|
||||||
pos_y = y;
|
}
|
||||||
|
|
||||||
|
bool Hero::onExit() const noexcept
|
||||||
|
{
|
||||||
|
return on_exit;
|
||||||
}
|
}
|
||||||
|
|
20
src/hero.h
20
src/hero.h
|
@ -1,6 +1,8 @@
|
||||||
#ifndef HERO_H
|
#ifndef HERO_H
|
||||||
#define HERO_H
|
#define HERO_H
|
||||||
|
|
||||||
|
#include "entity.h"
|
||||||
|
|
||||||
enum class Direction
|
enum class Direction
|
||||||
{
|
{
|
||||||
Left,
|
Left,
|
||||||
|
@ -10,14 +12,12 @@ enum class Direction
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
using coordinate = unsigned int;
|
|
||||||
|
|
||||||
/// Represents a controlable by player game character
|
/// Represents a controlable by player game character
|
||||||
class Hero
|
class Hero : public Entity
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
int hero_charges;
|
int hero_charges;
|
||||||
coordinate pos_x, pos_y;
|
bool on_exit;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Hero(coordinate position_x = 0, coordinate position_y = 0, int initial_charges = 0);
|
explicit Hero(coordinate position_x = 0, coordinate position_y = 0, int initial_charges = 0);
|
||||||
|
@ -34,14 +34,14 @@ public:
|
||||||
/// Set amount of hero charges explicitly
|
/// Set amount of hero charges explicitly
|
||||||
void setCharges(int charges) noexcept;
|
void setCharges(int charges) noexcept;
|
||||||
|
|
||||||
/// Get current Hero position
|
|
||||||
void position(coordinate &x, coordinate &y) const noexcept;
|
|
||||||
|
|
||||||
/// Set Hero position explicitly
|
|
||||||
void setPosition(coordinate x, coordinate y);
|
|
||||||
|
|
||||||
/// Move hero by one cell to any direction
|
/// Move hero by one cell to any direction
|
||||||
void move(const Direction &direction);
|
void move(const Direction &direction);
|
||||||
|
|
||||||
|
/// Sets on_exit flag to true, game will load next level
|
||||||
|
void reachExit() noexcept;
|
||||||
|
|
||||||
|
/// Are we exiting level?
|
||||||
|
bool onExit() const noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // HERO_H
|
#endif // HERO_H
|
||||||
|
|
|
@ -5,25 +5,15 @@ Level::Level()
|
||||||
|
|
||||||
void Level::placeBridge(coordinate x, coordinate y)
|
void Level::placeBridge(coordinate x, coordinate y)
|
||||||
{
|
{
|
||||||
map[x][y] = CellType::Bridge;
|
map[x][y] = std::make_unique<PassableCell>(x, y, sf::Color::Black);
|
||||||
}
|
|
||||||
|
|
||||||
CellType Level::cellOfType(coordinate x, coordinate y) const
|
|
||||||
{
|
|
||||||
return map[x][y];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Level::removeCharge(coordinate x, coordinate y)
|
void Level::removeCharge(coordinate x, coordinate y)
|
||||||
{
|
{
|
||||||
map[x][y] = CellType::Ground;
|
map[x][y] = std::make_unique<PassableCell>(x, y /* Brown Color */);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map& Level::mapArray()
|
Map& Level::mapArray()
|
||||||
{
|
{
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Level::setMap(const Map &new_map)
|
|
||||||
{
|
|
||||||
map = std::move(new_map);
|
|
||||||
}
|
|
||||||
|
|
21
src/level.h
21
src/level.h
|
@ -1,23 +1,12 @@
|
||||||
#ifndef LEVEL_H
|
#ifndef LEVEL_H
|
||||||
#define LEVEL_H
|
#define LEVEL_H
|
||||||
|
|
||||||
|
#include "cell.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
enum class CellType
|
|
||||||
{
|
|
||||||
Water = '.',
|
|
||||||
Ground = '-',
|
|
||||||
Charge = '$',
|
|
||||||
Bridge = char(177),
|
|
||||||
Hero = '@',
|
|
||||||
Exit = '#',
|
|
||||||
Wall = 'X'
|
|
||||||
};
|
|
||||||
|
|
||||||
using coordinate = unsigned int;
|
|
||||||
constexpr coordinate side = 32;
|
constexpr coordinate side = 32;
|
||||||
|
|
||||||
using Row = std::array<CellType, side>;
|
using Row = std::array<std::unique_ptr<Cell>, side>;
|
||||||
using Map = std::array<Row, side>;
|
using Map = std::array<Row, side>;
|
||||||
|
|
||||||
/// Abstraction over 2D array to quickly get access to level cells
|
/// Abstraction over 2D array to quickly get access to level cells
|
||||||
|
@ -35,14 +24,8 @@ public:
|
||||||
/// Get the 2D array of level map
|
/// Get the 2D array of level map
|
||||||
Map& mapArray();
|
Map& mapArray();
|
||||||
|
|
||||||
/// Returns type of requested map cell
|
|
||||||
CellType cellOfType(coordinate x, coordinate y) const;
|
|
||||||
|
|
||||||
/// Replace a charge cell with a ground cell
|
/// Replace a charge cell with a ground cell
|
||||||
void removeCharge(coordinate x, coordinate y);
|
void removeCharge(coordinate x, coordinate y);
|
||||||
|
|
||||||
/// Set new map for the level
|
|
||||||
void setMap(const Map& new_map);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LEVEL_H
|
#endif // LEVEL_H
|
||||||
|
|
|
@ -4,12 +4,15 @@ CONFIG -= console app_bundle
|
||||||
CONFIG -= qt
|
CONFIG -= qt
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
cell.cpp \
|
||||||
game.cpp \
|
game.cpp \
|
||||||
hero.cpp \
|
hero.cpp \
|
||||||
level.cpp \
|
level.cpp \
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
cell.h \
|
||||||
|
entity.h \
|
||||||
game.h \
|
game.h \
|
||||||
hero.h \
|
hero.h \
|
||||||
level.h
|
level.h
|
||||||
|
|
Loading…
Reference in New Issue