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 TeleportCellmaster
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
|
Loading…
Reference in New Issue