Added Generator::getPlayerSpawn to find a valid spawn position.
This commit is contained in:
parent
39cfb89f5e
commit
0fc271495d
3 changed files with 63 additions and 5 deletions
|
@ -30,7 +30,7 @@ Game::Game(sf::RenderWindow& window) :
|
||||||
generator.generateTiles(mTileManager, mPathfinder,
|
generator.generateTiles(mTileManager, mPathfinder,
|
||||||
sf::IntRect(-32, -32, 64, 64));
|
sf::IntRect(-32, -32, 64, 64));
|
||||||
mPlayer = std::shared_ptr<Player>(new Player(mWorld, mTileManager, mPathfinder,
|
mPlayer = std::shared_ptr<Player>(new Player(mWorld, mTileManager, mPathfinder,
|
||||||
sf::Vector2f(0.0f, 0.0f), Yaml("player.yaml")));
|
generator.getPlayerSpawn(), Yaml("player.yaml")));
|
||||||
mWorld.insertCharacter(mPlayer);
|
mWorld.insertCharacter(mPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,10 +9,15 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include <SFML/System.hpp>
|
||||||
|
|
||||||
|
#include <Thor/Vectors.hpp>
|
||||||
|
|
||||||
#include "simplexnoise.h"
|
#include "simplexnoise.h"
|
||||||
#include "../sprites/TileManager.h"
|
#include "../sprites/TileManager.h"
|
||||||
#include "../util/Log.h"
|
|
||||||
#include "../Pathfinder.h"
|
#include "../Pathfinder.h"
|
||||||
|
|
||||||
/// For usage with simplexnoise.h
|
/// For usage with simplexnoise.h
|
||||||
|
@ -39,7 +44,7 @@ Generator::Generator() {
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
Generator::generateTiles(TileManager& tm, Pathfinder& pathfinder,
|
Generator::generateTiles(TileManager& tm, Pathfinder& pathfinder,
|
||||||
const sf::IntRect& area) const {
|
const sf::IntRect& area) {
|
||||||
// Check if width and height are power of two.
|
// Check if width and height are power of two.
|
||||||
assert(area.width && !(area.width & (area.width - 1)));
|
assert(area.width && !(area.width & (area.width - 1)));
|
||||||
assert(area.height && !(area.height & (area.height - 1)));
|
assert(area.height && !(area.height & (area.height - 1)));
|
||||||
|
@ -76,6 +81,7 @@ Generator::generateTiles(TileManager& tm, Pathfinder& pathfinder,
|
||||||
generateAreas(pathfinder, filtered, area,
|
generateAreas(pathfinder, filtered, area,
|
||||||
sf::Vector2f(area.left, area.top));
|
sf::Vector2f(area.left, area.top));
|
||||||
pathfinder.generatePortals();
|
pathfinder.generatePortals();
|
||||||
|
mGenerated = filtered;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -180,3 +186,52 @@ Generator::generateAreas(Pathfinder& pathfinder,
|
||||||
area.top + halfHeight, halfWidth, halfHeight), offset);
|
area.top + halfHeight, halfWidth, halfHeight), offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a valid position (floor) for the player to spawn at.
|
||||||
|
*/
|
||||||
|
sf::Vector2f
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the point array index closest to position which has a floor tile.
|
||||||
|
*/
|
||||||
|
sf::Vector2i
|
||||||
|
Generator::findClosestFloor(const sf::Vector2i& position) const {
|
||||||
|
auto compare = [](const sf::Vector2i& a, const sf::Vector2i& b) {
|
||||||
|
return a.x < b.x || (a.x == b.x && a.y < b.y);
|
||||||
|
};
|
||||||
|
std::map<sf::Vector2i, float, decltype(compare)> open(compare);
|
||||||
|
std::set<sf::Vector2i, decltype(compare)> closed(compare);
|
||||||
|
sf::Vector2i start = position;
|
||||||
|
auto makePair = [&start](const sf::Vector2i& point) {
|
||||||
|
return std::make_pair(point, thor::length(sf::Vector2f(point - start)));
|
||||||
|
};
|
||||||
|
|
||||||
|
open.insert(makePair(start));
|
||||||
|
while (!open.empty()) {
|
||||||
|
const sf::Vector2i& current = open.begin()->first;
|
||||||
|
open.erase(current);
|
||||||
|
closed.insert(current);
|
||||||
|
if (mGenerated[current.x][current.y] == TileManager::Type::FLOOR)
|
||||||
|
return current;
|
||||||
|
else {
|
||||||
|
if (closed.find(sf::Vector2i(current.x + 1, current.y)) == closed.end())
|
||||||
|
open.insert(makePair(sf::Vector2i(current.x + 1, current.y)));
|
||||||
|
if (closed.find(sf::Vector2i(current.x, current.y + 1)) == closed.end())
|
||||||
|
open.insert(makePair(sf::Vector2i(current.x, current.y + 1)));
|
||||||
|
if (closed.find(sf::Vector2i(current.x - 1, current.y)) == closed.end())
|
||||||
|
open.insert(makePair(sf::Vector2i(current.x - 1, current.y)));
|
||||||
|
if (closed.find(sf::Vector2i(current.x, current.y - 1)) == closed.end())
|
||||||
|
open.insert(makePair(sf::Vector2i(current.x, current.y - 1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert(false);
|
||||||
|
return sf::Vector2i();
|
||||||
|
}
|
||||||
|
|
|
@ -18,11 +18,11 @@ class Generator {
|
||||||
public:
|
public:
|
||||||
explicit Generator();
|
explicit Generator();
|
||||||
void generateTiles(TileManager& tm, Pathfinder& pathfinder,
|
void generateTiles(TileManager& tm, Pathfinder& pathfinder,
|
||||||
const sf::IntRect& area) const;
|
const sf::IntRect& area);
|
||||||
//void generateCharacters(World& world, const sf::IntRect& area) const;
|
|
||||||
sf::Vector2f getPlayerSpawn() const;
|
sf::Vector2f getPlayerSpawn() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
sf::Vector2i findClosestFloor(const sf::Vector2i& position) const;
|
||||||
static void fill(std::vector<std::vector<TileManager::Type> >& image,
|
static void fill(std::vector<std::vector<TileManager::Type> >& image,
|
||||||
const sf::IntRect& area, TileManager::Type value);
|
const sf::IntRect& area, TileManager::Type value);
|
||||||
static void filterWalls(std::vector<std::vector<TileManager::Type> >& in,
|
static void filterWalls(std::vector<std::vector<TileManager::Type> >& in,
|
||||||
|
@ -33,6 +33,9 @@ private:
|
||||||
static void generateAreas(Pathfinder& pathfinder,
|
static void generateAreas(Pathfinder& pathfinder,
|
||||||
std::vector<std::vector<TileManager::Type> >& tiles,
|
std::vector<std::vector<TileManager::Type> >& tiles,
|
||||||
const sf::IntRect& area, const sf::Vector2f& offset);
|
const sf::IntRect& area, const sf::Vector2f& offset);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::vector<std::vector<TileManager::Type> > mGenerated;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DG_GENERATOR_H_ */
|
#endif /* DG_GENERATOR_H_ */
|
||||||
|
|
Reference in a new issue