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