Merge branch 'master' of 192.168.1.106:/home/pi/data/git/dungeon-gunner
This commit is contained in:
commit
df94bad5e8
10 changed files with 64 additions and 37 deletions
|
@ -10,6 +10,7 @@ R: reload
|
||||||
Q: use left Gadget
|
Q: use left Gadget
|
||||||
E: use right Gadget
|
E: use right Gadget
|
||||||
F: pick up item or swap Gadgets
|
F: pick up item or swap Gadgets
|
||||||
|
Esc: exit
|
||||||
|
|
||||||
## Dependencies
|
## Dependencies
|
||||||
- SFML
|
- SFML
|
||||||
|
|
4
res/yaml/window.yaml
Normal file
4
res/yaml/window.yaml
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
resolution_width: 1024
|
||||||
|
resolution_height: 768
|
||||||
|
fullscreen: false
|
||||||
|
borderless: false
|
28
src/Game.cpp
28
src/Game.cpp
|
@ -66,12 +66,30 @@ Game::initPlayer() {
|
||||||
Weapon::WeaponType::PISTOL, Weapon::WeaponType::KNIFE,
|
Weapon::WeaponType::PISTOL, Weapon::WeaponType::KNIFE,
|
||||||
Gadget::GadgetType::NONE, Gadget::GadgetType::NONE
|
Gadget::GadgetType::NONE, Gadget::GadgetType::NONE
|
||||||
};
|
};
|
||||||
mGenerator.generateCurrentAreaIfNeeded(Vector2f(), playerItems);
|
auto enemySpawns = mGenerator.generateCurrentAreaIfNeeded(Vector2f());
|
||||||
mPlayer = std::shared_ptr<Player>(new Player(mWorld, mPathfinder,
|
mPlayer = std::shared_ptr<Player>(new Player(mWorld, mPathfinder,
|
||||||
mGenerator.getPlayerSpawn(), playerItems));
|
mGenerator.getPlayerSpawn(), playerItems));
|
||||||
mWorld.insertCharacter(mPlayer);
|
mWorld.insertCharacter(mPlayer);
|
||||||
|
insertEnemies(enemySpawns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts enemies at the given positions, if they are more than
|
||||||
|
* Character::VISION_DISTANCE away from the player's postion.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Game::insertEnemies(const std::vector<Vector2f>& positions) {
|
||||||
|
for (const auto& spawn : positions) {
|
||||||
|
if (thor::length(spawn - mPlayer->getPosition()) >
|
||||||
|
Character::VISION_DISTANCE)
|
||||||
|
mWorld.insertCharacter(std::make_shared<Enemy>(mWorld,
|
||||||
|
mPathfinder, spawn, mPlayer->getEquippedItems()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the lights held by the player and sets light system parameters.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
Game::initLight() {
|
Game::initLight() {
|
||||||
Yaml config("light.yaml");
|
Yaml config("light.yaml");
|
||||||
|
@ -132,7 +150,8 @@ Game::loop() {
|
||||||
|
|
||||||
render();
|
render();
|
||||||
|
|
||||||
mGenerator.generateCurrentAreaIfNeeded(mPlayer->getPosition(), mPlayer->getEquippedItems());
|
auto enemySpawns = mGenerator.generateCurrentAreaIfNeeded(mPlayer->getPosition());
|
||||||
|
insertEnemies(enemySpawns);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,7 +360,10 @@ Game::render() {
|
||||||
|
|
||||||
// Update light
|
// Update light
|
||||||
mPlayerAreaLight->SetCenter(mPlayer->getPosition().toVec2f());
|
mPlayerAreaLight->SetCenter(mPlayer->getPosition().toVec2f());
|
||||||
mPlayerDirectionLight->SetCenter(mPlayer->getPosition().toVec2f());
|
// Avoid light light drawing partially onto player sprite.
|
||||||
|
Vector2f playerLightPosition = mPlayer->getPosition() +
|
||||||
|
thor::rotatedVector(Vector2f(0, - 13), mPlayer->getDirection());
|
||||||
|
mPlayerDirectionLight->SetCenter(playerLightPosition.toVec2f());
|
||||||
mPlayerDirectionLight->SetDirectionAngle(degreeToRadian(90 - mPlayer->getDirection()));
|
mPlayerDirectionLight->SetDirectionAngle(degreeToRadian(90 - mPlayer->getDirection()));
|
||||||
|
|
||||||
mLightSystem.SetView(mWorldView);
|
mLightSystem.SetView(mWorldView);
|
||||||
|
|
|
@ -43,6 +43,7 @@ private:
|
||||||
void updateGui();
|
void updateGui();
|
||||||
void initPlayer();
|
void initPlayer();
|
||||||
void initLight();
|
void initLight();
|
||||||
|
void insertEnemies(const std::vector<Vector2f>& positions);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int FPS_GOAL = 60;
|
static const int FPS_GOAL = 60;
|
||||||
|
|
|
@ -121,9 +121,9 @@ World::applyMovement(std::shared_ptr<Sprite> sprite, int elapsed) {
|
||||||
void
|
void
|
||||||
World::think(int elapsed) {
|
World::think(int elapsed) {
|
||||||
for (auto it = mCharacters.begin(); it != mCharacters.end(); ) {
|
for (auto it = mCharacters.begin(); it != mCharacters.end(); ) {
|
||||||
if ((*it)->getDelete() && (*it)->getCategory() != Sprite::CATEGORY_ACTOR) {
|
if ((*it)->getDelete()) {
|
||||||
mCharacters.erase(it);
|
mCharacters.erase(it);
|
||||||
auto& d = mDrawables[(*it)->getCategory()];
|
auto& d = mDrawables[Sprite::CATEGORY_ACTOR];
|
||||||
d.erase(std::find(d.begin(), d.end(), *it));
|
d.erase(std::find(d.begin(), d.end(), *it));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -39,15 +39,17 @@ Generator::Generator(World& world, Pathfinder& pathfinder,
|
||||||
/**
|
/**
|
||||||
* Generates tiles near player position (maximum distance is determined by
|
* Generates tiles near player position (maximum distance is determined by
|
||||||
* GENERATE_AREA_SIZE and GENERATE_AREA_RANGE).
|
* GENERATE_AREA_SIZE and GENERATE_AREA_RANGE).
|
||||||
|
*
|
||||||
|
* @return Potential spawn points for enemies. Guaranteed to be on floor tiles.
|
||||||
*/
|
*/
|
||||||
void
|
std::vector<Vector2f>
|
||||||
Generator::generateCurrentAreaIfNeeded(const Vector2f& playerPosition,
|
Generator::generateCurrentAreaIfNeeded(const Vector2f& position) {
|
||||||
const Character::EquippedItems& playerItems) {
|
std::vector<Vector2f> enemySpawns;
|
||||||
std::map<Vector2i, float> open;
|
std::map<Vector2i, float> open;
|
||||||
std::set<Vector2i> closed;
|
std::set<Vector2i> closed;
|
||||||
|
|
||||||
Vector2i start((int) floor(playerPosition.x / Tile::TILE_SIZE.x),
|
Vector2i start((int) floor(position.x / Tile::TILE_SIZE.x),
|
||||||
(int) floor(playerPosition.y / Tile::TILE_SIZE.y));
|
(int) floor(position.y / Tile::TILE_SIZE.y));
|
||||||
start /= mAreaSize;
|
start /= mAreaSize;
|
||||||
auto makePair = [&start](const Vector2i& point) {
|
auto makePair = [&start](const Vector2i& point) {
|
||||||
return std::make_pair(point, thor::length(Vector2f(point - start)));
|
return std::make_pair(point, thor::length(Vector2f(point - start)));
|
||||||
|
@ -65,12 +67,8 @@ Generator::generateCurrentAreaIfNeeded(const Vector2f& playerPosition,
|
||||||
Vector2i(mAreaSize, mAreaSize) / 2,
|
Vector2i(mAreaSize, mAreaSize) / 2,
|
||||||
Vector2i(mAreaSize, mAreaSize));
|
Vector2i(mAreaSize, mAreaSize));
|
||||||
generateTiles(area);
|
generateTiles(area);
|
||||||
for (const auto& spawn : getEnemySpawns(area)) {
|
auto spawnTemp = getEnemySpawns(area);
|
||||||
float distance = thor::length(spawn - playerPosition);
|
enemySpawns.insert(enemySpawns.end(), spawnTemp.begin(), spawnTemp.end());
|
||||||
if (distance > Character::VISION_DISTANCE)
|
|
||||||
mWorld.insertCharacter(std::shared_ptr<Enemy>(new Enemy(
|
|
||||||
mWorld, mPathfinder, spawn, playerItems)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (mGenerated[current.x][current.y] && distance <= mMaxRange) {
|
if (mGenerated[current.x][current.y] && distance <= mMaxRange) {
|
||||||
if (closed.find(Vector2i(current.x + 1, current.y)) == closed.end())
|
if (closed.find(Vector2i(current.x + 1, current.y)) == closed.end())
|
||||||
|
@ -83,6 +81,7 @@ Generator::generateCurrentAreaIfNeeded(const Vector2f& playerPosition,
|
||||||
open.insert(makePair(Vector2i(current.x, current.y - 1)));
|
open.insert(makePair(Vector2i(current.x, current.y - 1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return enemySpawns;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,10 +28,8 @@ class Generator : public sf::Drawable {
|
||||||
public:
|
public:
|
||||||
explicit Generator(World& world, Pathfinder& pathfinder,
|
explicit Generator(World& world, Pathfinder& pathfinder,
|
||||||
ltbl::LightSystem& lightSystem, const Yaml& config);
|
ltbl::LightSystem& lightSystem, const Yaml& config);
|
||||||
void generateCurrentAreaIfNeeded(const Vector2f& position,
|
std::vector<Vector2f> generateCurrentAreaIfNeeded(const Vector2f& position);
|
||||||
const Character::EquippedItems& playerItems);
|
|
||||||
Vector2f getPlayerSpawn() const;
|
Vector2f getPlayerSpawn() const;
|
||||||
std::vector<Vector2f> getEnemySpawns(const sf::IntRect& area);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::map<int, std::map<int, Tile::Type> > array;
|
typedef std::map<int, std::map<int, Tile::Type> > array;
|
||||||
|
@ -43,6 +41,7 @@ private:
|
||||||
std::vector<Vector2i> createMinimalSpanningTree(
|
std::vector<Vector2i> createMinimalSpanningTree(
|
||||||
const Vector2i& start, const float limit);
|
const Vector2i& start, const float limit);
|
||||||
void connectRooms(const Vector2i& start);
|
void connectRooms(const Vector2i& start);
|
||||||
|
std::vector<Vector2f> getEnemySpawns(const sf::IntRect& area);
|
||||||
void draw(sf::RenderTarget& target, sf::RenderStates states) const;
|
void draw(sf::RenderTarget& target, sf::RenderStates states) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
16
src/main.cpp
16
src/main.cpp
|
@ -17,12 +17,22 @@
|
||||||
*/
|
*/
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
Yaml::setFolder("res/yaml/");
|
Yaml::setFolder("res/yaml/");
|
||||||
|
|
||||||
Loader::i().setFolder("res/");
|
Loader::i().setFolder("res/");
|
||||||
Loader::i().setSubFolder<sf::Texture>("textures/");
|
Loader::i().setSubFolder<sf::Texture>("textures/");
|
||||||
|
|
||||||
tgui::Window window(sf::VideoMode(1024, 768, 32), "Dungeon Gunner",
|
Yaml windowConfig("window.yaml");
|
||||||
sf::Style::Close | sf::Style::Titlebar);
|
sf::VideoMode mode(windowConfig.get("resolution_width", 800),
|
||||||
|
windowConfig.get("resolution_height", 600),
|
||||||
|
32);
|
||||||
|
sf::Uint32 style;
|
||||||
|
if (windowConfig.get("fullscreen", false))
|
||||||
|
style = sf::Style::Fullscreen;
|
||||||
|
else if (windowConfig.get("borderless", false))
|
||||||
|
style = sf::Style::None;
|
||||||
|
else
|
||||||
|
style = sf::Style::Titlebar;
|
||||||
|
tgui::Window window(mode, "Dungeon Gunner", style);
|
||||||
|
|
||||||
Vector2f::SCREEN_HEIGHT = window.getSize().y;
|
Vector2f::SCREEN_HEIGHT = window.getSize().y;
|
||||||
|
|
||||||
if (!window.globalFont.loadFromFile("res/DejaVuSans.ttf"))
|
if (!window.globalFont.loadFromFile("res/DejaVuSans.ttf"))
|
||||||
|
|
|
@ -34,7 +34,7 @@ Enemy::Enemy(World& world, Pathfinder& pathfinder,
|
||||||
Character::EquippedItems
|
Character::EquippedItems
|
||||||
Enemy::generateItems(EquippedItems playerItems) {
|
Enemy::generateItems(EquippedItems playerItems) {
|
||||||
// Uses cast from enum to int to enum in order to increment enum values.
|
// Uses cast from enum to int to enum in order to increment enum values.
|
||||||
switch (rand() % 4) {
|
switch (rand() % 2) {
|
||||||
case 0:
|
case 0:
|
||||||
if (playerItems.primary + 1 != Weapon::WeaponType::_LAST)
|
if (playerItems.primary + 1 != Weapon::WeaponType::_LAST)
|
||||||
playerItems.primary =
|
playerItems.primary =
|
||||||
|
@ -46,20 +46,12 @@ Enemy::generateItems(EquippedItems playerItems) {
|
||||||
playerItems.secondary =
|
playerItems.secondary =
|
||||||
(Weapon::WeaponType) (((int) (playerItems.secondary) + 1));
|
(Weapon::WeaponType) (((int) (playerItems.secondary) + 1));
|
||||||
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (playerItems.left + 1 != Gadget::GadgetType::_LAST)
|
|
||||||
playerItems.left = (Gadget::GadgetType) (((int) (playerItems.left)
|
|
||||||
+ 1));
|
|
||||||
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (playerItems.right + 1 != Gadget::GadgetType::_LAST)
|
|
||||||
playerItems.left = (Gadget::GadgetType) (((int) (playerItems.left)
|
|
||||||
+ 1));
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playerItems.left = (Gadget::GadgetType) (rand() % 4);
|
||||||
|
playerItems.right = (Gadget::GadgetType) (rand() % 4);
|
||||||
|
|
||||||
return playerItems;
|
return playerItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,7 @@ public:
|
||||||
NONE,
|
NONE,
|
||||||
SHIELD,
|
SHIELD,
|
||||||
HEAL,
|
HEAL,
|
||||||
RINGOFFIRE,
|
RINGOFFIRE
|
||||||
_LAST
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
Reference in a new issue