Removed TileManager.

This commit is contained in:
Felix Ableitner 2013-04-29 16:49:16 +02:00
parent 3ee0c71857
commit a2de030cbc
16 changed files with 178 additions and 241 deletions

View file

@ -20,17 +20,15 @@ const int Game::FPS_GOAL = 60;
Game::Game(sf::RenderWindow& window) :
mWindow(window),
mView(sf::Vector2f(0, 0), mWindow.getView().getSize()),
mTileManager(mWorld),
mGenerator(mWorld, mPathfinder),
mQuit(false),
mPaused(false) {
mWindow.setFramerateLimit(FPS_GOAL);
mWindow.setKeyRepeatEnabled(true);
Generator generator;
generator.generateTiles(mTileManager, mPathfinder,
sf::IntRect(-32, -32, 64, 64));
mPlayer = std::shared_ptr<Player>(new Player(mWorld, mTileManager, mPathfinder,
generator.getPlayerSpawn(), Yaml("player.yaml")));
mGenerator.generateTiles(sf::IntRect(-32, -32, 64, 64));
mPlayer = std::shared_ptr<Player>(new Player(mWorld, mPathfinder,
mGenerator.getPlayerSpawn(), Yaml("player.yaml")));
mWorld.insertCharacter(mPlayer);
}

View file

@ -8,14 +8,11 @@
#ifndef DG_GAME_H_
#define DG_GAME_H_
#include "sprites/TileManager.h"
#include "generator/Generator.h"
#include "Pathfinder.h"
#include "World.h"
class TileManager;
class Pathfinder;
class Player;
class World;
/*
* High level game managing, including game loop, input, high
@ -47,8 +44,8 @@ private:
sf::View mView;
World mWorld;
TileManager mTileManager;
Pathfinder mPathfinder;
Generator mGenerator;
std::shared_ptr<Player> mPlayer;
bool mQuit;

View file

@ -14,7 +14,7 @@
#include <Thor/Vectors.hpp>
#include "util/Interval.h"
#include "sprites/TileManager.h"
#include "sprites/Tile.h"
const float Pathfinder::WALL_DISTANCE_MULTIPLIER = 1.5f;
@ -156,10 +156,10 @@ Pathfinder::insertArea(const sf::IntRect& rect) {
Area a;
// Not sure why the offset of -50 is required, but with it, areas align
// with tiles perfectly.
a.area = sf::IntRect(rect.left * TileManager::TILE_SIZE.x - 50,
rect.top * TileManager::TILE_SIZE.y - 50,
rect.width * TileManager::TILE_SIZE.x,
rect.height * TileManager::TILE_SIZE.y);
a.area = sf::IntRect(rect.left * Tile::TILE_SIZE.x - 50,
rect.top * Tile::TILE_SIZE.y - 50,
rect.width * Tile::TILE_SIZE.x,
rect.height * Tile::TILE_SIZE.y);
a.center = sf::Vector2i(a.area.left + a.area.width / 2,
a.area.top + a.area.height / 2);
mAreas.push_back(a);

View file

@ -9,7 +9,7 @@
#include <Thor/Vectors.hpp>
#include "sprites/TileManager.h"
#include "sprites/Tile.h"
#include "util/Interval.h"
/**
@ -256,7 +256,7 @@ World::raycast(const sf::Vector2f& lineStart,
assert(lineStart != lineEnd);
sf::Vector2f lineCenter = lineStart + 0.5f * (lineEnd - lineStart);
for (const auto& it : mDrawables.at(Sprite::Category::CATEGORY_WORLD)) {
if (it->collisionEnabled(Sprite::Category::CATEGORY_WORLD))
if (dynamic_cast<Tile*>(it.get())->getType() != Tile::Type::WALL)
continue;
sf::Vector2f axis = it->getPosition() - lineCenter;
if (axis == sf::Vector2f())

View file

@ -11,7 +11,6 @@
#include "../items/Weapon.h"
#include "../sprites/Corpse.h"
#include "../sprites/TileManager.h"
#include "../util/Log.h"
#include "../util/Yaml.h"
#include "../World.h"
@ -22,11 +21,10 @@ const float Character::VISION_DISTANCE = 500.0f;
/**
* Saves pointer to this instance in static var for think().
*/
Character::Character(World& world, TileManager& tileManager, Pathfinder& pathfinder,
const Data& data, const Yaml& config) :
Character::Character(World& world, Pathfinder& pathfinder, const Data& data,
const Yaml& config) :
Sprite(data, config),
mWorld(world),
mTileManager(tileManager),
mPathfinder(pathfinder),
mMaxHealth(config.get(YAML_KEY::HEALTH, YAML_DEFAULT::HEALTH)),
mCurrentHealth(mMaxHealth),

View file

@ -11,7 +11,6 @@
#include "Sprite.h"
class Pathfinder;
class TileManager;
class World;
class Weapon;
class Yaml;
@ -21,8 +20,8 @@ class Yaml;
*/
class Character : public Sprite {
public:
explicit Character(World& world, TileManager& tileManager,
Pathfinder& pathfinder, const Data& data, const Yaml& config);
explicit Character(World& world, Pathfinder& pathfinder, const Data& data,
const Yaml& config);
virtual ~Character() = 0;
void onDamage(int damage);
@ -47,7 +46,6 @@ private:
friend class World;
World& mWorld;
TileManager& mTileManager;
Pathfinder& mPathfinder;
const int mMaxHealth;

View file

@ -17,8 +17,8 @@
#include <Thor/Vectors.hpp>
#include "simplexnoise.h"
#include "../sprites/TileManager.h"
#include "../Pathfinder.h"
#include "../World.h"
/// For usage with simplexnoise.h
uint8_t perm[512];
@ -26,7 +26,9 @@ uint8_t perm[512];
/**
* Generates new random seed.
*/
Generator::Generator() {
Generator::Generator(World& world, Pathfinder& pathfinder) :
mWorld(world),
mPathfinder(pathfinder) {
std::mt19937 mersenne(time(nullptr));
std::uniform_int_distribution<int> distribution(0, 255);
@ -36,24 +38,23 @@ Generator::Generator() {
}
/**
* Fill TileManager with procedurally generated tiles.
* Fill Tile with procedurally generated tiles.
*
* @param tm TileManager instance to set tiles in.
* @param tm Tile instance to set tiles in.
* @param area Size and position of area to generate tiles for. Must be
* power of two.
*/
void
Generator::generateTiles(TileManager& tm, Pathfinder& pathfinder,
const sf::IntRect& area) {
Generator::generateTiles(const sf::IntRect& area) {
// Check if width and height are power of two.
assert(area.width && !(area.width & (area.width - 1)));
assert(area.height && !(area.height & (area.height - 1)));
std::vector<std::vector<TileManager::Type> >
noise(area.width, std::vector<TileManager::Type>(area.height));
std::vector<std::vector<TileManager::Type> >
filtered(area.width, std::vector<TileManager::Type>(
area.height, TileManager::Type::FLOOR));
std::vector<std::vector<Tile::Type> >
noise(area.width, std::vector<Tile::Type>(area.height));
std::vector<std::vector<Tile::Type> >
filtered(area.width, std::vector<Tile::Type>(
area.height, Tile::Type::FLOOR));
for (int x = area.left; x < area.left + area.width; x++) {
for (int y = area.top; y < area.top + area.height; y++) {
@ -61,8 +62,8 @@ Generator::generateTiles(TileManager& tm, Pathfinder& pathfinder,
(scaled_octave_noise_2d(2, 2, 0.05f, 0.5f, -0.5f, x, y) +
scaled_octave_noise_2d(2, 2, 0.5f, 0.15f, -0.15f, x, y)
< -0.1f)
? TileManager::Type::WALL
: TileManager::Type::FLOOR;
? Tile::Type::WALL
: Tile::Type::FLOOR;
}
}
for (int x = 0; x < (int) noise.size(); x++) {
@ -74,13 +75,13 @@ Generator::generateTiles(TileManager& tm, Pathfinder& pathfinder,
}
for (int x = area.left; x < area.left + area.width; x++) {
for (int y = area.top; y < area.top + area.height; y++) {
tm.insertTile(TileManager::TilePosition(x, y),
filtered[x-area.left][y-area.top]);
mWorld.insert(std::shared_ptr<Sprite>(
new Tile(filtered[x-area.left][y-area.top], x, y)));
}
}
generateAreas(pathfinder, filtered, area,
generateAreas(filtered, area,
sf::Vector2f(area.left, area.top));
pathfinder.generatePortals();
mPathfinder.generatePortals();
mGenerated = filtered;
}
@ -92,8 +93,8 @@ Generator::generateTiles(TileManager& tm, Pathfinder& pathfinder,
* @param value The value to set.
*/
void
Generator::fill(std::vector<std::vector<TileManager::Type> >& image,
const sf::IntRect& area, TileManager::Type value) {
Generator::fill(std::vector<std::vector<Tile::Type> >& image,
const sf::IntRect& area, Tile::Type value) {
for (int x = area.left;
x < area.left + area.width && x < (int) image.size(); x++) {
for (int y = area.top;
@ -110,11 +111,11 @@ Generator::fill(std::vector<std::vector<TileManager::Type> >& image,
* @param tiles Array of tile values.
*/
int Generator::countWalls(const sf::IntRect& area,
std::vector<std::vector<TileManager::Type> >& tiles) {
std::vector<std::vector<Tile::Type> >& tiles) {
int count = 0;
for (int x = area.left; x < area.left + area.width; x++) {
for (int y = area.top; y < area.top + area.height; y++)
count += (int) (tiles[x][y] == TileManager::Type::WALL);
count += (int) (tiles[x][y] == Tile::Type::WALL);
}
return count;
}
@ -133,8 +134,8 @@ int Generator::countWalls(const sf::IntRect& area,
* tiles is not walls (tilecount >= longside * shortside - subtract).
*/
void
Generator::filterWalls(std::vector<std::vector<TileManager::Type> >& in,
std::vector<std::vector<TileManager::Type> >& out,
Generator::filterWalls(std::vector<std::vector<Tile::Type> >& in,
std::vector<std::vector<Tile::Type> >& out,
int x, int y, int longside, int shortside, int subtract) {
// Skip if we would go out of range.
if ((x + longside >= (int) in.size()) ||
@ -144,31 +145,30 @@ Generator::filterWalls(std::vector<std::vector<TileManager::Type> >& in,
// Filter in horizontal direction.
if (countWalls(sf::IntRect(x, y, longside, shortside), in) >=
shortside * longside - subtract)
fill(out, sf::IntRect(x, y, longside, shortside), TileManager::Type::WALL);
fill(out, sf::IntRect(x, y, longside, shortside), Tile::Type::WALL);
// Filter in vertical direction.
if (countWalls(sf::IntRect(x, y, shortside, longside), in) >=
shortside * longside - subtract)
fill(out, sf::IntRect(x, y, shortside, longside), TileManager::Type::WALL);
fill(out, sf::IntRect(x, y, shortside, longside), Tile::Type::WALL);
}
/**
* Inserts tile if all values within area are the same, otherwise divides area
* into four and continues recursively.
*
* @param tm World to insert areas into.
* @param tiles Array of tile values.
* @param area The area to generate areas for.
* @param offset Offset of tiles[0][0] from World coordinate (0, 0).
*/
void
Generator::generateAreas(Pathfinder& pathfinder,
std::vector<std::vector<TileManager::Type> >& tiles,
Generator::generateAreas(
std::vector<std::vector<Tile::Type> >& tiles,
const sf::IntRect& area, const sf::Vector2f& offset) {
assert(area.width > 0 && area.height > 0);
int count = countWalls(sf::IntRect(area.left - offset.y, area.top - offset.x,
area.width, area.height), tiles);
if (count == 0) {
pathfinder.insertArea(sf::IntRect(area));
mPathfinder.insertArea(sf::IntRect(area));
}
else if (count == area.width * area.height) {
return;
@ -176,13 +176,13 @@ Generator::generateAreas(Pathfinder& pathfinder,
else {
int halfWidth = area.width / 2.0f;
int halfHeight = area.height / 2.0f;
generateAreas(pathfinder, tiles, sf::IntRect(area.left,
generateAreas(tiles, sf::IntRect(area.left,
area.top, halfWidth, halfHeight), offset);
generateAreas(pathfinder, tiles, sf::IntRect(area.left + halfWidth,
generateAreas(tiles, sf::IntRect(area.left + halfWidth,
area.top, halfWidth, halfHeight), offset);
generateAreas(pathfinder, tiles, sf::IntRect(area.left,
generateAreas(tiles, sf::IntRect(area.left,
area.top + halfHeight, halfWidth, halfHeight), offset);
generateAreas(pathfinder, tiles, sf::IntRect(area.left + halfWidth,
generateAreas(tiles, sf::IntRect(area.left + halfWidth,
area.top + halfHeight, halfWidth, halfHeight), offset);
}
}
@ -195,8 +195,8 @@ Generator::getPlayerSpawn() const {
sf::Vector2i spawn = findClosestFloor(sf::Vector2i(mGenerated.size() / 2,
mGenerated[0].size() / 2));
return sf::Vector2f(
(spawn.x - mGenerated.size() / 2.0f) * TileManager::TILE_SIZE.x,
(spawn.y - mGenerated[0].size() / 2.0f) * TileManager::TILE_SIZE.y);
(spawn.x - mGenerated.size() / 2.0f) * Tile::TILE_SIZE.x,
(spawn.y - mGenerated[0].size() / 2.0f) * Tile::TILE_SIZE.y);
}
/**
@ -219,7 +219,7 @@ Generator::findClosestFloor(const sf::Vector2i& position) const {
const sf::Vector2i& current = open.begin()->first;
open.erase(current);
closed.insert(current);
if (mGenerated[current.x][current.y] == TileManager::Type::FLOOR)
if (mGenerated[current.x][current.y] == Tile::Type::FLOOR)
return current;
else {
if (closed.find(sf::Vector2i(current.x + 1, current.y)) == closed.end())

View file

@ -10,32 +10,33 @@
#include <SFML/Graphics.hpp>
#include "../sprites/TileManager.h"
#include "../sprites/Tile.h"
class World;
class Pathfinder;
class Generator {
public:
explicit Generator();
void generateTiles(TileManager& tm, Pathfinder& pathfinder,
const sf::IntRect& area);
explicit Generator(World& world, Pathfinder& pathfinder);
void generateTiles(const sf::IntRect& area);
sf::Vector2f getPlayerSpawn() const;
private:
sf::Vector2i findClosestFloor(const sf::Vector2i& position) const;
static void fill(std::vector<std::vector<TileManager::Type> >& image,
const sf::IntRect& area, TileManager::Type value);
static void filterWalls(std::vector<std::vector<TileManager::Type> >& in,
std::vector<std::vector<TileManager::Type> >& out,
static void fill(std::vector<std::vector<Tile::Type> >& image,
const sf::IntRect& area, Tile::Type value);
static void filterWalls(std::vector<std::vector<Tile::Type> >& in,
std::vector<std::vector<Tile::Type> >& out,
int x, int y, int longside, int shortside, int subtract);
static int countWalls(const sf::IntRect& area,
std::vector<std::vector<TileManager::Type> >& tiles);
static void generateAreas(Pathfinder& pathfinder,
std::vector<std::vector<TileManager::Type> >& tiles,
std::vector<std::vector<Tile::Type> >& tiles);
void generateAreas(std::vector<std::vector<Tile::Type> >& tiles,
const sf::IntRect& area, const sf::Vector2f& offset);
private:
std::vector<std::vector<TileManager::Type> > mGenerated;
World& mWorld;
Pathfinder& mPathfinder;
std::vector<std::vector<Tile::Type> > mGenerated;
};
#endif /* DG_GENERATOR_H_ */

View file

@ -9,9 +9,9 @@
#include <Thor/Vectors.hpp>
Enemy::Enemy(World& world, TileManager& tileManager, Pathfinder& pathfinder,
Enemy::Enemy(World& world, Pathfinder& pathfinder,
const sf::Vector2f& position, const Yaml& config) :
Character(world, tileManager, pathfinder, Data(position, CATEGORY_ACTOR, MASK_ALL),
Character(world, pathfinder, Data(position, CATEGORY_ACTOR, MASK_ALL),
config) {
}

View file

@ -15,9 +15,8 @@ class Yaml;
class Enemy : public Character {
public:
explicit Enemy(World& world, TileManager& tileManager,
Pathfinder& pathfinder, const sf::Vector2f& position,
const Yaml& config);
explicit Enemy(World& world, Pathfinder& pathfinder,
const sf::Vector2f& position, const Yaml& config);
protected:
virtual void onThink(int elapsed);

View file

@ -12,9 +12,9 @@
/**
* Initializes Sprite.
*/
Player::Player(World& world, TileManager& tileManager, Pathfinder& pathfinder,
Player::Player(World& world, Pathfinder& pathfinder,
const sf::Vector2f& position, const Yaml& config) :
Character(world, tileManager, pathfinder,
Character(world, pathfinder,
Data(position, CATEGORY_ACTOR, MASK_ALL), config),
mDirection(0) {
}

View file

@ -29,9 +29,8 @@ public:
};
public:
explicit Player(World& world, TileManager& tileManager,
Pathfinder& pathfinder, const sf::Vector2f& position,
const Yaml& config);
explicit Player(World& world, Pathfinder& pathfinder,
const sf::Vector2f& position, const Yaml& config);
void setCrosshairPosition(const sf::Vector2f& position);
void pullTrigger();

64
source/sprites/Tile.cpp Normal file
View file

@ -0,0 +1,64 @@
/*
* Tile.cpp
*
* Created on: 20.04.2013
* Author: Felix
*/
#include "Tile.h"
#include <Thor/Vectors.hpp>
#include "../util/Interval.h"
#include "../util/Loader.h"
#include "../util/Yaml.h"
#include "../World.h"
const sf::Vector2i Tile::TILE_SIZE = sf::Vector2i(75, 75);
/**
* Constructs a tile.
*
* @param pType Type of the tile to create.
* @param pPosition Position of the tile in tile coordinates.
* @param world Box2D world object.
*/
Tile::Tile(Type type, int x, int y) :
Sprite(Data(sf::Vector2f(x * TILE_SIZE.x, y * TILE_SIZE.y),
CATEGORY_WORLD, isSolid(type)), Yaml(getConfig(type))),
mType(type) {
}
/**
* Returns the YAML config file name for the tile type.
*/
std::string
Tile::getConfig(Type type) {
switch (type) {
case Type::FLOOR:
return "tile_floor.yaml";
case Type::WALL:
return "tile_wall.yaml";
default:
assert(false);
return "";
}
}
bool
Tile::isSolid(Type type) {
switch (type) {
case Type::FLOOR:
return false;
case Type::WALL: // falltrough
default:
return true;
}
}
/**
* Returns the Type of this tile.
*/
Tile::Type
Tile::getType() const {
return mType;
}

40
source/sprites/Tile.h Normal file
View file

@ -0,0 +1,40 @@
/*
* Tile.h
*
* Created on: 20.04.2013
* Author: Felix
*/
#ifndef DG_TILE_H_
#define DG_TILE_H_
#include "../abstract/Sprite.h"
/**
* Holds information about a single tile.
*/
class Tile : public Sprite {
public:
enum class Type : char {
FLOOR,
WALL
};
public:
explicit Tile(Type type, int x, int y);
Type getType() const;
public:
static const sf::Vector2i TILE_SIZE; //< Tile size in pixels.
public:
static std::string getConfig(Type type);
static bool isSolid(Type type);
private:
Type mType;
};
#endif /* DG_TILE_H_ */

View file

@ -1,98 +0,0 @@
/*
* TileManager.cpp
*
* Created on: 08.08.2012
* Author: Felix
*/
#include "TileManager.h"
#include <Thor/Vectors.hpp>
#include "../util/Interval.h"
#include "../util/Loader.h"
#include "../util/Yaml.h"
#include "../World.h"
const sf::Vector2i TileManager::TILE_SIZE = sf::Vector2i(75, 75);
/**
* Loads tile resources.
*
* @param world Box2D world to create (physical) tiles in.
*/
TileManager::TileManager(World& world) :
mWorld(world) {
}
/**
* Constructs a tile.
*
* @param pType Type of the tile to create.
* @param pPosition Position of the tile in tile coordinates.
* @param world Box2D world object.
*/
TileManager::Tile::Tile(Type type, const TilePosition& position) :
Sprite(Data(sf::Vector2f(position.x * TILE_SIZE.x, position.y * TILE_SIZE.y),
CATEGORY_WORLD, (type == Type::FLOOR) ? MASK_NONE : MASK_ALL),
Yaml(getConfig(type))),
mType(type) {
}
/**
* Returns a texture key for a certain tile type.
*
* @param type The type of tile to load a resource key for.
* @return Resource key to the correct texture.
*/
std::string
TileManager::Tile::getConfig(Type type) {
std::string filename;
switch (type) {
case Type::FLOOR:
filename = "tile_floor.yaml";
break;
case Type::WALL:
filename = "tile_wall.yaml";
break;
default:
throw new aurora::Exception("Invalid tile type.");
}
return filename;
}
/**
* Returns the Type of this tile.
*/
TileManager::Type
TileManager::Tile::getType() const {
return mType;
}
/**
* Returns the position of the tile with tile width/height as a unit.
*/
TileManager::TilePosition
TileManager::Tile::getTilePosition() const {
return TilePosition(getPosition().x / TILE_SIZE.x, getPosition().y / TILE_SIZE.y);
}
/**
* Insert a tile at the position. Deletes an existing tile first if one is at the position.
*
* @param position Grid coordinate of the tile (not pixel coordinate).
* @param type Type of tile to be inserted.
*/
void
TileManager::insertTile(const TilePosition& position, Type type) {
#ifndef NDEBUG
for (auto it = mTiles.begin(); it != mTiles.end(); it++) {
if ((*it)->getTilePosition() == position)
// Inserted multiple tiles at the same position.
assert(false);
}
#endif
std::shared_ptr<Tile> tile = std::shared_ptr<Tile>(new Tile(type, position));
mTiles.push_back(tile);
mWorld.insert(tile);
}

View file

@ -1,59 +0,0 @@
/*
* TileManager.h
*
* Created on: 08.08.2012
* Author: Felix
*/
#ifndef DG_TILEMANAGER_H_
#define DG_TILEMANAGER_H_
#include "../abstract/Sprite.h"
class World;
class TileManager {
public:
enum class Type : char {
FLOOR,
WALL
};
/**
* Uses the length/width of a tile as a unit.
*/
typedef sf::Vector2i TilePosition;
public:
static const sf::Vector2i TILE_SIZE; //< Tile size in pixels.
public:
explicit TileManager(World& world);
void insertTile(const TilePosition& position, Type type);
private:
class Tile;
private:
World& mWorld;
std::vector<std::shared_ptr<Tile> > mTiles;
};
/**
* Holds information about a single tile.
*/
class TileManager::Tile : public Sprite {
public:
explicit Tile(Type type, const TilePosition& position);
Type getType() const;
TilePosition getTilePosition() const;
static std::string getConfig(Type type);
private:
Type mType;
};
#endif /* DG_TILEMANAGER_H_ */