Global refactoring; add level builder
This commit is contained in:
parent
e8f06c3929
commit
6eac3c84f6
106
src/cell.cpp
106
src/cell.cpp
|
@ -3,10 +3,10 @@
|
||||||
#include "hero.h"
|
#include "hero.h"
|
||||||
#include "level.h"
|
#include "level.h"
|
||||||
|
|
||||||
#define UNUSED(expr) (void)(expr);
|
#define UNUSED(expr) (void)(expr)
|
||||||
|
|
||||||
Cell::Cell(coordinate cell_x, coordinate cell_y, const sf::Color &color) :
|
Cell::Cell(coordinate cell_row, coordinate cell_col, const sf::Color &color) :
|
||||||
Entity(cell_x, cell_y),
|
Entity(cell_row, cell_col),
|
||||||
cell_color(color)
|
cell_color(color)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -20,8 +20,8 @@ sf::Color Cell::color() const noexcept
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
PassableCell::PassableCell(coordinate cell_x, coordinate cell_y, const sf::Color &color) :
|
PassableCell::PassableCell(coordinate cell_row, coordinate cell_col, const sf::Color &color) :
|
||||||
Cell(cell_x, cell_y, color)
|
Cell(cell_row, cell_col, color)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
PassableCell::~PassableCell()
|
PassableCell::~PassableCell()
|
||||||
|
@ -29,17 +29,21 @@ PassableCell::~PassableCell()
|
||||||
|
|
||||||
bool PassableCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
bool PassableCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
||||||
{
|
{
|
||||||
UNUSED(hero)
|
UNUSED(hero), UNUSED(level);
|
||||||
UNUSED(level)
|
|
||||||
|
|
||||||
// Hero just moves on.
|
// Hero just moves on.
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cell *PassableCell::getDefaultInstance()
|
||||||
|
{
|
||||||
|
return new PassableCell();
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
WaterCell::WaterCell(coordinate cell_x, coordinate cell_y, const sf::Color &color) :
|
WaterCell::WaterCell(coordinate cell_row, coordinate cell_col, const sf::Color &color) :
|
||||||
Cell(cell_x, cell_y, color)
|
Cell(cell_row, cell_col, color)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
WaterCell::~WaterCell()
|
WaterCell::~WaterCell()
|
||||||
|
@ -48,19 +52,21 @@ WaterCell::~WaterCell()
|
||||||
bool WaterCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
bool WaterCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
||||||
{
|
{
|
||||||
// Try to use one charge to place a bridge
|
// Try to use one charge to place a bridge
|
||||||
if (hero->useCharge()) {
|
if (hero->useCharge())
|
||||||
level->placeBridge(pos_x, pos_y);
|
level->placeBridge(entity_row, entity_col);
|
||||||
return true;
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If hero doesn't have enough charges, we move Hero back
|
Cell *WaterCell::getDefaultInstance()
|
||||||
return false;
|
{
|
||||||
|
return new WaterCell();
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
WallCell::WallCell(coordinate cell_x, coordinate cell_y, const sf::Color &color) :
|
WallCell::WallCell(coordinate cell_row, coordinate cell_col, const sf::Color &color) :
|
||||||
Cell(cell_x, cell_y, color)
|
Cell(cell_row, cell_col, color)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
WallCell::~WallCell()
|
WallCell::~WallCell()
|
||||||
|
@ -68,17 +74,21 @@ WallCell::~WallCell()
|
||||||
|
|
||||||
bool WallCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
bool WallCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
||||||
{
|
{
|
||||||
UNUSED(hero)
|
UNUSED(hero), UNUSED(level);
|
||||||
UNUSED(level)
|
|
||||||
|
|
||||||
// Hero never passes this cell.
|
// Hero never passes this cell.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cell *WallCell::getDefaultInstance()
|
||||||
|
{
|
||||||
|
return new WallCell();
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
ChargeCell::ChargeCell(coordinate cell_x, coordinate cell_y, int has_charges, const sf::Color &color) :
|
ChargeCell::ChargeCell(coordinate cell_row, coordinate cell_col, int has_charges, const sf::Color &color) :
|
||||||
Cell(cell_x, cell_y, color),
|
Cell(cell_row, cell_col, color),
|
||||||
cell_charges(has_charges)
|
cell_charges(has_charges)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
@ -89,15 +99,20 @@ bool ChargeCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
||||||
{
|
{
|
||||||
// Hero picks up the charge; remove it from the map
|
// Hero picks up the charge; remove it from the map
|
||||||
hero->refillCharges(cell_charges);
|
hero->refillCharges(cell_charges);
|
||||||
level->removeCharge(pos_x, pos_y);
|
level->removeCharge(entity_row, entity_col);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cell *ChargeCell::getDefaultInstance()
|
||||||
|
{
|
||||||
|
return new ChargeCell();
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
ExitCell::ExitCell(coordinate cell_x, coordinate cell_y, const sf::Color &color) :
|
ExitCell::ExitCell(coordinate cell_row, coordinate cell_col, const sf::Color &color) :
|
||||||
Cell(cell_x, cell_y, color)
|
Cell(cell_row, cell_col, color)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
ExitCell::~ExitCell()
|
ExitCell::~ExitCell()
|
||||||
|
@ -105,19 +120,24 @@ ExitCell::~ExitCell()
|
||||||
|
|
||||||
bool ExitCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
bool ExitCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
||||||
{
|
{
|
||||||
UNUSED(level)
|
UNUSED(level);
|
||||||
|
|
||||||
// Level is over.
|
// Level is over.
|
||||||
hero->reachExit();
|
hero->reachExit();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cell *ExitCell::getDefaultInstance()
|
||||||
|
{
|
||||||
|
return new ExitCell();
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
TeleportCell::TeleportCell(coordinate cell_x, coordinate cell_y, coordinate new_cell_x, coordinate new_cell_y, const sf::Color &color) :
|
TeleportCell::TeleportCell(coordinate cell_row, coordinate cell_col, coordinate new_cell_row, coordinate new_cell_col, const sf::Color &color) :
|
||||||
Cell(cell_x, cell_y, color),
|
Cell(cell_row, cell_col, color),
|
||||||
new_x(new_cell_x),
|
new_x(new_cell_row),
|
||||||
new_y(new_cell_y)
|
new_y(new_cell_col)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
TeleportCell::~TeleportCell()
|
TeleportCell::~TeleportCell()
|
||||||
|
@ -125,19 +145,24 @@ TeleportCell::~TeleportCell()
|
||||||
|
|
||||||
bool TeleportCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
bool TeleportCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
||||||
{
|
{
|
||||||
UNUSED(level)
|
UNUSED(level);
|
||||||
|
|
||||||
// Hero jumps into teleport!
|
// Hero jumps into teleport!
|
||||||
hero->setPosition(new_x, new_y);
|
hero->setPosition(new_x, new_y);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cell *TeleportCell::getDefaultInstance()
|
||||||
|
{
|
||||||
|
return new TeleportCell();
|
||||||
|
}
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
TriggerCell::TriggerCell(std::vector<CellPtr> &&cells_to_change, coordinate cell_x, coordinate cell_y, const sf::Color &color) :
|
TriggerCell::TriggerCell(/*std::vector<CellPtr> &&cells_to_change,*/ coordinate cell_row, coordinate cell_col, const sf::Color &color) :
|
||||||
Cell(cell_x, cell_y, color)
|
Cell(cell_row, cell_col, color)
|
||||||
{
|
{
|
||||||
cells = std::move(cells_to_change);
|
//cells = std::move(cells_to_change);
|
||||||
}
|
}
|
||||||
|
|
||||||
TriggerCell::~TriggerCell()
|
TriggerCell::~TriggerCell()
|
||||||
|
@ -145,20 +170,25 @@ TriggerCell::~TriggerCell()
|
||||||
|
|
||||||
bool TriggerCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
bool TriggerCell::onMovingTo(HeroPtr &hero, LevelPtr &level)
|
||||||
{
|
{
|
||||||
UNUSED(hero)
|
UNUSED(hero);
|
||||||
|
|
||||||
Map &map = level->mapArray();
|
Map &map = level->mapArray();
|
||||||
|
|
||||||
// We replace needed cells with the ones that the trigger provides.
|
// We replace needed cells with the ones that the trigger provides.
|
||||||
for (CellPtr &cell : cells)
|
for (Cell *cell : cells)
|
||||||
{
|
{
|
||||||
const coordinate &y = cell->y();
|
const coordinate &row = cell->row();
|
||||||
const coordinate &x = cell->x();
|
const coordinate &col = cell->col();
|
||||||
|
|
||||||
map[x][y].release();
|
delete map[row][col];
|
||||||
map[x][y] = std::move(cell);
|
map[row][col] = cell;
|
||||||
}
|
}
|
||||||
|
|
||||||
// It's an impassable object, so player can't move to here.
|
// It's an impassable object, so player can't move to here.
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cell *TriggerCell::getDefaultInstance()
|
||||||
|
{
|
||||||
|
return new TriggerCell();
|
||||||
|
}
|
||||||
|
|
71
src/cell.h
71
src/cell.h
|
@ -16,6 +16,18 @@ const sf::Color Blue = sf::Color(0, 255, 255);
|
||||||
const sf::Color Gray = sf::Color(125, 125, 125);
|
const sf::Color Gray = sf::Color(125, 125, 125);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum CELL_TYPES {
|
||||||
|
PASSABLE_CELL = 0,
|
||||||
|
WATER_CELL,
|
||||||
|
WALL_CELL,
|
||||||
|
CHARGE_CELL,
|
||||||
|
EXIT_CELL,
|
||||||
|
TELEPORT_CELL,
|
||||||
|
TRIGGER_CELL,
|
||||||
|
|
||||||
|
N_CELLS
|
||||||
|
};
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
class Hero;
|
class Hero;
|
||||||
|
@ -24,7 +36,6 @@ class Cell;
|
||||||
|
|
||||||
using HeroPtr = std::unique_ptr<Hero>;
|
using HeroPtr = std::unique_ptr<Hero>;
|
||||||
using LevelPtr = std::unique_ptr<Level>;
|
using LevelPtr = std::unique_ptr<Level>;
|
||||||
using CellPtr = std::unique_ptr<Cell>;
|
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
|
||||||
|
@ -35,8 +46,8 @@ protected:
|
||||||
sf::Color cell_color;
|
sf::Color cell_color;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Cell(coordinate cell_x = 0,
|
Cell(coordinate cell_row = 0,
|
||||||
coordinate cell_y = 0,
|
coordinate cell_col = 0,
|
||||||
const sf::Color &color = palette::White);
|
const sf::Color &color = palette::White);
|
||||||
|
|
||||||
virtual ~Cell() override;
|
virtual ~Cell() override;
|
||||||
|
@ -45,6 +56,8 @@ public:
|
||||||
|
|
||||||
/// Determine if Hero can move onto this cell or not
|
/// Determine if Hero can move onto this cell or not
|
||||||
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) = 0;
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) = 0;
|
||||||
|
|
||||||
|
virtual Cell *getDefaultInstance() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
@ -53,13 +66,15 @@ public:
|
||||||
class PassableCell : public Cell
|
class PassableCell : public Cell
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PassableCell(coordinate cell_x = 0,
|
PassableCell(coordinate cell_row = 0,
|
||||||
coordinate cell_y = 0, // Brown
|
coordinate cell_col = 0, // Brown
|
||||||
const sf::Color &color = palette::Brown);
|
const sf::Color &color = palette::Brown);
|
||||||
|
|
||||||
virtual ~PassableCell() override;
|
virtual ~PassableCell() override;
|
||||||
|
|
||||||
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
||||||
|
|
||||||
|
virtual Cell *getDefaultInstance() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
@ -68,13 +83,15 @@ public:
|
||||||
class WaterCell : public Cell
|
class WaterCell : public Cell
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WaterCell(coordinate cell_x = 0,
|
WaterCell(coordinate cell_row = 0,
|
||||||
coordinate cell_y = 0,
|
coordinate cell_col = 0,
|
||||||
const sf::Color &color = palette::Blue);
|
const sf::Color &color = palette::Blue);
|
||||||
|
|
||||||
virtual ~WaterCell() override;
|
virtual ~WaterCell() override;
|
||||||
|
|
||||||
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
||||||
|
|
||||||
|
virtual Cell *getDefaultInstance() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
@ -83,13 +100,15 @@ public:
|
||||||
class WallCell : public Cell
|
class WallCell : public Cell
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WallCell(coordinate cell_x = 0,
|
WallCell(coordinate cell_row = 0,
|
||||||
coordinate cell_y = 0, // Gray
|
coordinate cell_col = 0, // Gray
|
||||||
const sf::Color &color = );
|
const sf::Color &color = palette::Gray);
|
||||||
|
|
||||||
virtual ~WallCell() override;
|
virtual ~WallCell() override;
|
||||||
|
|
||||||
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
||||||
|
|
||||||
|
virtual Cell *getDefaultInstance() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
@ -101,14 +120,16 @@ private:
|
||||||
int cell_charges;
|
int cell_charges;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ChargeCell(coordinate cell_x = 0,
|
ChargeCell(coordinate cell_row = 0,
|
||||||
coordinate cell_y = 0,
|
coordinate cell_col = 0,
|
||||||
int has_charges = 1,
|
int has_charges = 1,
|
||||||
const sf::Color &color = sf::Color::Green);
|
const sf::Color &color = sf::Color::Green);
|
||||||
|
|
||||||
virtual ~ChargeCell() override;
|
virtual ~ChargeCell() override;
|
||||||
|
|
||||||
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
||||||
|
|
||||||
|
virtual Cell *getDefaultInstance() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
@ -117,13 +138,15 @@ public:
|
||||||
class ExitCell : public Cell
|
class ExitCell : public Cell
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ExitCell(coordinate cell_x = 0,
|
ExitCell(coordinate cell_row = 0,
|
||||||
coordinate cell_y = 0,
|
coordinate cell_col = 0,
|
||||||
const sf::Color &color = sf::Color::Red);
|
const sf::Color &color = sf::Color::Red);
|
||||||
|
|
||||||
virtual ~ExitCell() override;
|
virtual ~ExitCell() override;
|
||||||
|
|
||||||
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
||||||
|
|
||||||
|
virtual Cell *getDefaultInstance() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
@ -135,15 +158,17 @@ private:
|
||||||
coordinate new_x, new_y;
|
coordinate new_x, new_y;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TeleportCell(coordinate cell_x = 0,
|
TeleportCell(coordinate cell_row = 0,
|
||||||
coordinate cell_y = 0,
|
coordinate cell_col = 0,
|
||||||
coordinate new_cell_x = 0,
|
coordinate new_cell_row = 0,
|
||||||
coordinate new_cell_y = 0, // Purple
|
coordinate new_cell_col = 0, // Purple
|
||||||
const sf::Color &color = sf::Color(128, 0, 128));
|
const sf::Color &color = sf::Color(128, 0, 128));
|
||||||
|
|
||||||
virtual ~TeleportCell() override;
|
virtual ~TeleportCell() override;
|
||||||
|
|
||||||
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
||||||
|
|
||||||
|
virtual Cell *getDefaultInstance() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
///////////////////////////////////////
|
///////////////////////////////////////
|
||||||
|
@ -153,17 +178,19 @@ class TriggerCell : public Cell
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
// Vector of cells to place on map
|
// Vector of cells to place on map
|
||||||
std::vector<CellPtr> cells;
|
std::vector<Cell *> cells;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TriggerCell(std::vector<CellPtr> &&cells_to_change,
|
TriggerCell(//std::vector<CellPtr> &&cells_to_change,
|
||||||
coordinate cell_x = 0,
|
coordinate cell_row = 0,
|
||||||
coordinate cell_y = 0, // Pink
|
coordinate cell_col = 0, // Pink
|
||||||
const sf::Color &color = sf::Color(255, 192, 203));
|
const sf::Color &color = sf::Color(255, 192, 203));
|
||||||
|
|
||||||
virtual ~TriggerCell() override;
|
virtual ~TriggerCell() override;
|
||||||
|
|
||||||
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
virtual bool onMovingTo(HeroPtr &hero, LevelPtr &level) override;
|
||||||
|
|
||||||
|
virtual Cell *getDefaultInstance() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CELL_H
|
#endif // CELL_H
|
||||||
|
|
|
@ -1,31 +1,31 @@
|
||||||
#include "entity.h"
|
#include "entity.h"
|
||||||
|
|
||||||
Entity::Entity(coordinate _x, coordinate _y) :
|
Entity::Entity(coordinate _row, coordinate _col) :
|
||||||
pos_x(_x), pos_y(_y)
|
entity_row(_row), entity_col(_col)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Entity::~Entity()
|
Entity::~Entity()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/// Get current Entity position
|
/// Get current Entity position
|
||||||
void Entity::position(coordinate &x, coordinate &y) const noexcept
|
void Entity::position(coordinate &row, coordinate &col) const noexcept
|
||||||
{
|
{
|
||||||
x = pos_x;
|
row = entity_row;
|
||||||
y = pos_y;
|
col = entity_col;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Entity::setPosition(coordinate x, coordinate y)
|
void Entity::setPosition(coordinate row, coordinate col)
|
||||||
{
|
{
|
||||||
pos_x = x;
|
entity_row = row;
|
||||||
pos_y = y;
|
entity_col = col;
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinate Entity::x() const noexcept
|
coordinate Entity::row() const noexcept
|
||||||
{
|
{
|
||||||
return pos_x;
|
return entity_row;
|
||||||
}
|
}
|
||||||
|
|
||||||
coordinate Entity::y() const noexcept
|
coordinate Entity::col() const noexcept
|
||||||
{
|
{
|
||||||
return pos_y;
|
return entity_col;
|
||||||
}
|
}
|
||||||
|
|
14
src/entity.h
14
src/entity.h
|
@ -1,30 +1,30 @@
|
||||||
#ifndef ENTITY_H
|
#ifndef ENTITY_H
|
||||||
#define ENTITY_H
|
#define ENTITY_H
|
||||||
|
|
||||||
using coordinate = unsigned int;
|
using coordinate = unsigned long;
|
||||||
|
|
||||||
/// Interface representing entity which can be placed on the map
|
/// Interface representing entity which can be placed on the map
|
||||||
class Entity
|
class Entity
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
coordinate pos_x, pos_y;
|
coordinate entity_row, entity_col;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Entity(coordinate _x = 0, coordinate _y = 0);
|
Entity(coordinate _row = 0, coordinate _col = 0);
|
||||||
|
|
||||||
virtual ~Entity() = 0;
|
virtual ~Entity() = 0;
|
||||||
|
|
||||||
/// Get current Entity position
|
/// Get current Entity position
|
||||||
void position(coordinate &x, coordinate &y) const noexcept;
|
void position(coordinate &row, coordinate &col) const noexcept;
|
||||||
|
|
||||||
/// Set Entity position explicitly
|
/// Set Entity position explicitly
|
||||||
void setPosition(coordinate x, coordinate y);
|
void setPosition(coordinate row, coordinate col);
|
||||||
|
|
||||||
/// Get current x of the Entity position
|
/// Get current x of the Entity position
|
||||||
coordinate x() const noexcept;
|
coordinate row() const noexcept;
|
||||||
|
|
||||||
/// Get current y of the Entity position
|
/// Get current y of the Entity position
|
||||||
coordinate y() const noexcept;
|
coordinate col() const noexcept;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // ENTITY_H
|
#endif // ENTITY_H
|
||||||
|
|
86
src/game.cpp
86
src/game.cpp
|
@ -8,7 +8,7 @@ constexpr int cell_width = 60;
|
||||||
constexpr int cell_height = 35;
|
constexpr int cell_height = 35;
|
||||||
constexpr int cell_deviation = 25;
|
constexpr int cell_deviation = 25;
|
||||||
|
|
||||||
constexpr int window_side = cell_width * side;
|
constexpr int window_side = cell_width * 4;
|
||||||
|
|
||||||
Game::Game()
|
Game::Game()
|
||||||
{
|
{
|
||||||
|
@ -18,11 +18,11 @@ Game::Game()
|
||||||
// Generate level
|
// Generate level
|
||||||
level = std::make_unique<Level>();
|
level = std::make_unique<Level>();
|
||||||
|
|
||||||
main_window.create(sf::VideoMode(window_side, window_side), "SFML-Test Application", sf::Style::Default);
|
main_window.create(sf::VideoMode(window_side * 2, window_side * 2), "SFML-Test Application", sf::Style::Default);
|
||||||
main_window.setActive();
|
main_window.setActive();
|
||||||
|
|
||||||
current_level = 1;
|
current_level = 1;
|
||||||
loadLevel(current_level);
|
//loadLevel(current_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Game::run()
|
int Game::run()
|
||||||
|
@ -54,7 +54,6 @@ int Game::run()
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
|
|
||||||
Direction Game::getDirection(sf::Keyboard::Key &key) const
|
Direction Game::getDirection(sf::Keyboard::Key &key) const
|
||||||
{
|
{
|
||||||
switch (key)
|
switch (key)
|
||||||
|
@ -93,24 +92,20 @@ void Game::onMoving(sf::Keyboard::Key &key)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Save the initial coordinates
|
// Save the initial coordinates
|
||||||
coordinate initial_x, initial_y;
|
coordinate initial_row, initial_col;
|
||||||
hero->position(initial_x, initial_y);
|
hero->position(initial_row, initial_col);
|
||||||
|
|
||||||
// Try to move hero
|
// Try to move hero
|
||||||
hero->move(direction);
|
hero->move(direction);
|
||||||
|
|
||||||
// Save the new coordinates after moving
|
// Save the new coordinates after moving
|
||||||
coordinate attempt_x, attempt_y;
|
coordinate attempt_row, attempt_col;
|
||||||
hero->position(attempt_x, attempt_y);
|
hero->position(attempt_row, attempt_col);
|
||||||
|
|
||||||
//////////////////////////
|
//////////////////////////
|
||||||
|
|
||||||
if (!level->mapArray()[attempt_x][attempt_y]->onMovingTo(hero, level))
|
if (!level->mapArray()[attempt_row][attempt_col]->onMovingTo(hero, level))
|
||||||
hero->setPosition(initial_x, initial_y);
|
hero->setPosition(initial_row, initial_col);
|
||||||
|
|
||||||
if (hero->onExit())
|
|
||||||
loadLevel(++current_level);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::renderMap()
|
void Game::renderMap()
|
||||||
|
@ -142,22 +137,22 @@ void Game::renderMap()
|
||||||
text.setString("Available bridge cells: " + std::to_string(hero->charges()));
|
text.setString("Available bridge cells: " + std::to_string(hero->charges()));
|
||||||
|
|
||||||
// Where is hero
|
// Where is hero
|
||||||
coordinate hero_x, hero_y;
|
coordinate hero_row, hero_col;
|
||||||
hero->position(hero_x, hero_y);
|
hero->position(hero_row, hero_col);
|
||||||
|
|
||||||
// Draw map from 2D array
|
// Draw map from 2D array
|
||||||
for (coordinate x = 0; x < side; ++x)
|
for (coordinate x = 0; x < level->width(); ++x)
|
||||||
{
|
{
|
||||||
shift = side * cell_deviation;
|
shift = static_cast<float>(level->width()) * cell_deviation;
|
||||||
|
|
||||||
for (coordinate y = 0; y < side; ++y)
|
for (coordinate y = 0; y < level->height(); ++y)
|
||||||
{
|
{
|
||||||
convex_brush.setPosition(shift + painter_x, painter_y);
|
convex_brush.setPosition(shift + painter_x, painter_y);
|
||||||
convex_brush.setFillColor(map[x][y]->color());
|
convex_brush.setFillColor(map[y][x]->color());
|
||||||
|
|
||||||
main_window.draw(convex_brush);
|
main_window.draw(convex_brush);
|
||||||
|
|
||||||
if (hero_x == x && hero_y == y)
|
if (hero_row == y && hero_col == x)
|
||||||
{
|
{
|
||||||
// Place the hero sprite
|
// Place the hero sprite
|
||||||
convex_brush.setFillColor(sf::Color::White);
|
convex_brush.setFillColor(sf::Color::White);
|
||||||
|
@ -176,52 +171,3 @@ void Game::renderMap()
|
||||||
|
|
||||||
main_window.draw(text);
|
main_window.draw(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::loadLevel(int level_index)
|
|
||||||
{
|
|
||||||
Map &map = level->mapArray();
|
|
||||||
|
|
||||||
// Fill the level with water
|
|
||||||
for (coordinate x = 0; x < side; ++x)
|
|
||||||
for (coordinate y = 0; y < side; ++y)
|
|
||||||
map[x][y] = std::make_unique<WaterCell>(x, y);
|
|
||||||
|
|
||||||
std::vector<CellPtr> trigger_cells;
|
|
||||||
trigger_cells.emplace_back(std::make_unique<PassableCell>(0, 0));
|
|
||||||
trigger_cells.emplace_back(std::make_unique<PassableCell>(1, 0));
|
|
||||||
trigger_cells.emplace_back(std::make_unique<PassableCell>(0, 1));
|
|
||||||
|
|
||||||
switch (level_index)
|
|
||||||
{
|
|
||||||
case 1:
|
|
||||||
// Hardcoding is temporary!
|
|
||||||
hero->setPosition(1, 1);
|
|
||||||
hero->setCharges(2);
|
|
||||||
|
|
||||||
level->setDefaultGroundColor(sf::Color(165, 42, 42));
|
|
||||||
|
|
||||||
map[0][0] = std::make_unique<WallCell>(0, 0);
|
|
||||||
map[0][1] = std::make_unique<WallCell>(0, 1);
|
|
||||||
map[1][0] = std::make_unique<WallCell>(1, 0);
|
|
||||||
map[1][1] = std::make_unique<PassableCell>(1, 1);
|
|
||||||
map[1][2] = std::make_unique<PassableCell>(1, 2);
|
|
||||||
map[1][3] = std::make_unique<PassableCell>(1, 3);
|
|
||||||
map[1][4] = std::make_unique<PassableCell>(1, 4);
|
|
||||||
map[2][1] = std::make_unique<TeleportCell>(2, 1, 6, 6);
|
|
||||||
map[2][2] = std::make_unique<PassableCell>(2, 2);
|
|
||||||
map[3][2] = std::make_unique<PassableCell>(3, 2);
|
|
||||||
map[3][3] = std::make_unique<PassableCell>(3, 3);
|
|
||||||
map[6][3] = std::make_unique<PassableCell>(6, 3);
|
|
||||||
map[6][4] = std::make_unique<PassableCell>(6, 4);
|
|
||||||
map[6][5] = std::make_unique<PassableCell>(6, 5);
|
|
||||||
map[6][6] = std::make_unique<PassableCell>(6, 6);
|
|
||||||
map[7][6] = std::make_unique<PassableCell>(7, 6);
|
|
||||||
map[9][6] = std::make_unique<PassableCell>(9, 6);
|
|
||||||
map[8][7] = std::make_unique<ExitCell>(8, 7);
|
|
||||||
map[2][3] = std::make_unique<ChargeCell>(2, 3, 5);
|
|
||||||
map[3][3] = std::make_unique<TriggerCell>(std::move(trigger_cells), 3, 3);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
main_window.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ private:
|
||||||
void renderMap();
|
void renderMap();
|
||||||
|
|
||||||
/// Prepare map and hero for a game level
|
/// Prepare map and hero for a game level
|
||||||
void loadLevel(int level_index = 1);
|
//void loadLevel(int level_index = 1);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Game();
|
explicit Game();
|
||||||
|
|
12
src/hero.cpp
12
src/hero.cpp
|
@ -1,7 +1,7 @@
|
||||||
#include "hero.h"
|
#include "hero.h"
|
||||||
|
|
||||||
Hero::Hero(coordinate position_x, coordinate position_y, int initial_charges) :
|
Hero::Hero(coordinate row, coordinate col, int initial_charges) :
|
||||||
Entity(position_x, position_y),
|
Entity(row, col),
|
||||||
hero_charges(initial_charges),
|
hero_charges(initial_charges),
|
||||||
on_exit(false)
|
on_exit(false)
|
||||||
{}
|
{}
|
||||||
|
@ -37,13 +37,13 @@ void Hero::move(const Direction &direction)
|
||||||
switch (direction)
|
switch (direction)
|
||||||
{
|
{
|
||||||
case Direction::Up:
|
case Direction::Up:
|
||||||
--pos_y; break;
|
--entity_row; break;
|
||||||
case Direction::Down:
|
case Direction::Down:
|
||||||
++pos_y; break;
|
++entity_row; break;
|
||||||
case Direction::Left:
|
case Direction::Left:
|
||||||
--pos_x; break;
|
--entity_col; break;
|
||||||
case Direction::Right:
|
case Direction::Right:
|
||||||
++pos_x; break;
|
++entity_col; break;
|
||||||
case Direction::None:
|
case Direction::None:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ private:
|
||||||
bool on_exit;
|
bool on_exit;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Hero(coordinate position_x = 0, coordinate position_y = 0, int initial_charges = 0);
|
explicit Hero(coordinate row = 0, coordinate col = 0, int initial_charges = 0);
|
||||||
|
|
||||||
/// Add more charges for hero to use
|
/// Add more charges for hero to use
|
||||||
void refillCharges(int append_charges);
|
void refillCharges(int append_charges);
|
||||||
|
|
|
@ -1,16 +1,98 @@
|
||||||
#include "level.h"
|
#include "level.h"
|
||||||
|
|
||||||
Level::Level()
|
#include <fstream>
|
||||||
{}
|
#include <cstring>
|
||||||
|
|
||||||
void Level::placeBridge(coordinate x, coordinate y)
|
void Level::prepareCellInstances()
|
||||||
{
|
{
|
||||||
map[x][y] = std::make_unique<PassableCell>(x, y, sf::Color::Black);
|
default_cells[PASSABLE_CELL] = new PassableCell();
|
||||||
|
default_cells[WATER_CELL] = new WaterCell();
|
||||||
|
default_cells[WALL_CELL] = new WallCell();
|
||||||
|
default_cells[CHARGE_CELL] = new ChargeCell();
|
||||||
|
default_cells[EXIT_CELL] = new ExitCell();
|
||||||
|
default_cells[TELEPORT_CELL] = new TeleportCell();
|
||||||
|
default_cells[TRIGGER_CELL] = new TriggerCell();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Level::removeCharge(coordinate x, coordinate y)
|
void Level::readMap(std::ifstream &file)
|
||||||
{
|
{
|
||||||
map[x][y] = std::make_unique<PassableCell>(x, y, color_ground);
|
int i;
|
||||||
|
for (coordinate j = 0; j < map.size(); ++j)
|
||||||
|
{
|
||||||
|
for (coordinate k = 0; k < map[j].size(); ++k)
|
||||||
|
{
|
||||||
|
file >> i;
|
||||||
|
map[j][k] = default_cells[i]->getDefaultInstance();
|
||||||
|
map[j][k]->setPosition(j, k);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Level::Level(const std::string &map_file)
|
||||||
|
{
|
||||||
|
prepareCellInstances();
|
||||||
|
|
||||||
|
std::ifstream file;
|
||||||
|
file.open(map_file);
|
||||||
|
|
||||||
|
std::string cur_line;
|
||||||
|
while (getline(file, cur_line))
|
||||||
|
{
|
||||||
|
// need fix; see std::string.compare
|
||||||
|
if (strstr(cur_line.data(), "size") != NULL)
|
||||||
|
{
|
||||||
|
file >> level_width >> level_height;
|
||||||
|
map.resize(level_height);
|
||||||
|
for (Row &row : map)
|
||||||
|
row.resize(level_width);
|
||||||
|
}
|
||||||
|
else if (strstr(cur_line.data(), "map") != NULL)
|
||||||
|
{
|
||||||
|
readMap(file);
|
||||||
|
}
|
||||||
|
else if (strstr(cur_line.data(), "teleport") != NULL)
|
||||||
|
{
|
||||||
|
coordinate src_row, src_col;
|
||||||
|
coordinate dest_row, dest_col;
|
||||||
|
|
||||||
|
file >> src_row >> src_col >> dest_row >> dest_col;
|
||||||
|
// reinterpret_cast<TeleportCell *>(map[src_row][src_col])->setDestination(dest_row, dest_col);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Level::~Level()
|
||||||
|
{
|
||||||
|
for (Cell *cell : default_cells)
|
||||||
|
delete cell;
|
||||||
|
|
||||||
|
for (Row &row : map)
|
||||||
|
for (Cell *cell : row)
|
||||||
|
delete cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Level::width() const
|
||||||
|
{
|
||||||
|
return level_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t Level::height() const
|
||||||
|
{
|
||||||
|
return level_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Level::placeBridge(coordinate row, coordinate col)
|
||||||
|
{
|
||||||
|
Cell *buf = map[row][col];
|
||||||
|
map[row][col] = new PassableCell(row, col, sf::Color::Black);
|
||||||
|
delete buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Level::removeCharge(coordinate row, coordinate col)
|
||||||
|
{
|
||||||
|
Cell *buf = map[row][col];
|
||||||
|
map[row][col] = new PassableCell(row, col, color_ground);
|
||||||
|
delete buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
Map& Level::mapArray()
|
Map& Level::mapArray()
|
||||||
|
|
17
src/level.h
17
src/level.h
|
@ -4,10 +4,10 @@
|
||||||
#include <array>
|
#include <array>
|
||||||
#include "cell.h"
|
#include "cell.h"
|
||||||
|
|
||||||
constexpr coordinate side = 32;
|
const std::string default_file_name = "test_map";
|
||||||
|
|
||||||
using Row = std::array<CellPtr, side>;
|
using Row = std::vector<Cell *>;
|
||||||
using Map = std::array<Row, side>;
|
using Map = std::vector<Row>;
|
||||||
|
|
||||||
/// Abstraction over 2D array to quickly get access to level cells
|
/// Abstraction over 2D array to quickly get access to level cells
|
||||||
class Level
|
class Level
|
||||||
|
@ -15,9 +15,18 @@ class Level
|
||||||
private:
|
private:
|
||||||
Map map;
|
Map map;
|
||||||
sf::Color color_ground;
|
sf::Color color_ground;
|
||||||
|
size_t level_width, level_height;
|
||||||
|
std::array<Cell *, N_CELLS> default_cells;
|
||||||
|
|
||||||
|
void prepareCellInstances();
|
||||||
|
void readMap(std::ifstream &file);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Level();
|
Level(const std::string &map_file = default_file_name);
|
||||||
|
~Level();
|
||||||
|
|
||||||
|
size_t width() const;
|
||||||
|
size_t height() const;
|
||||||
|
|
||||||
/// Place a bridge cell
|
/// Place a bridge cell
|
||||||
void placeBridge(coordinate x, coordinate y);
|
void placeBridge(coordinate x, coordinate y);
|
||||||
|
|
Loading…
Reference in New Issue