Added lighting using ltbl library.
This commit is contained in:
parent
7df94496e0
commit
e0b0db8cf7
18 changed files with 202 additions and 26 deletions
26
res/shaders/light_attenuation_shader.frag
Normal file
26
res/shaders/light_attenuation_shader.frag
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
uniform vec2 lightPos;
|
||||||
|
|
||||||
|
uniform vec3 lightColor;
|
||||||
|
|
||||||
|
uniform float radius;
|
||||||
|
|
||||||
|
uniform float bleed;
|
||||||
|
|
||||||
|
uniform float linearizeFactor;
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
float dist = length(lightPos - gl_FragCoord.xy);
|
||||||
|
|
||||||
|
float distFromFalloff = radius - dist;
|
||||||
|
|
||||||
|
// Still has absolute falloff point
|
||||||
|
float attenuation = distFromFalloff * (bleed / pow(dist, 2.0) + linearizeFactor / radius);
|
||||||
|
|
||||||
|
// Optional, clamp it to prevent overcoloring
|
||||||
|
attenuation = clamp(attenuation, 0.0, 1.0);
|
||||||
|
|
||||||
|
vec4 color = vec4(attenuation, attenuation, attenuation, 1.0) * vec4(lightColor.r, lightColor.g, lightColor.b, 1.0);
|
||||||
|
|
||||||
|
gl_FragColor = color;
|
||||||
|
}
|
BIN
res/textures/light_fin.png
Normal file
BIN
res/textures/light_fin.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
7
res/yaml/light.yaml
Normal file
7
res/yaml/light.yaml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# Color values for player lights, each between 0 and 255
|
||||||
|
color_red: 255
|
||||||
|
color_green: 255
|
||||||
|
color_blue: 127
|
||||||
|
|
||||||
|
# Total angle of the player light cone
|
||||||
|
light_cone_angle: 90.0
|
67
src/Game.cpp
67
src/Game.cpp
|
@ -13,6 +13,7 @@
|
||||||
#include "sprites/Enemy.h"
|
#include "sprites/Enemy.h"
|
||||||
#include "sprites/Player.h"
|
#include "sprites/Player.h"
|
||||||
#include "sprites/items/HealthOrb.h"
|
#include "sprites/items/HealthOrb.h"
|
||||||
|
#include "util/Angles.h"
|
||||||
#include "util/Loader.h"
|
#include "util/Loader.h"
|
||||||
#include "util/Yaml.h"
|
#include "util/Yaml.h"
|
||||||
|
|
||||||
|
@ -22,12 +23,15 @@
|
||||||
Game::Game(tgui::Window& window) :
|
Game::Game(tgui::Window& window) :
|
||||||
mWindow(window),
|
mWindow(window),
|
||||||
mWorldView(Vector2f(0, 0), mWindow.getView().getSize()),
|
mWorldView(Vector2f(0, 0), mWindow.getView().getSize()),
|
||||||
mGenerator(mWorld, mPathfinder, Yaml("generation.yaml")) {
|
mLightSystem(AABB(Vec2f(-100000, -100000), Vec2f(100000, 10000)), &window,
|
||||||
|
"res/textures/light_fin.png", "res/shaders/light_attenuation_shader.frag"),
|
||||||
|
mGenerator(mWorld, mPathfinder, mLightSystem, Yaml("generation.yaml")) {
|
||||||
mWindow.setFramerateLimit(FPS_GOAL);
|
mWindow.setFramerateLimit(FPS_GOAL);
|
||||||
mWindow.setKeyRepeatEnabled(false);
|
mWindow.setKeyRepeatEnabled(false);
|
||||||
srand(time(nullptr));
|
srand(time(nullptr));
|
||||||
|
|
||||||
initPlayer();
|
initPlayer();
|
||||||
|
initLight();
|
||||||
|
|
||||||
mCrosshairTexture = Loader::i().fromFile<sf::Texture>("crosshair.png");
|
mCrosshairTexture = Loader::i().fromFile<sf::Texture>("crosshair.png");
|
||||||
mCrosshair.setTexture(*mCrosshairTexture, true);
|
mCrosshair.setTexture(*mCrosshairTexture, true);
|
||||||
|
@ -47,7 +51,15 @@ Game::Game(tgui::Window& window) :
|
||||||
mPickupInstruction->setTextSize(14);
|
mPickupInstruction->setTextSize(14);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Game::initPlayer() {
|
/**
|
||||||
|
* Closes window.
|
||||||
|
*/
|
||||||
|
Game::~Game() {
|
||||||
|
mWindow.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Game::initPlayer() {
|
||||||
Character::EquippedItems playerItems = {
|
Character::EquippedItems playerItems = {
|
||||||
Weapon::WeaponType::PISTOL, Weapon::WeaponType::KNIFE,
|
Weapon::WeaponType::PISTOL, Weapon::WeaponType::KNIFE,
|
||||||
Gadget::GadgetType::NONE, Gadget::GadgetType::NONE
|
Gadget::GadgetType::NONE, Gadget::GadgetType::NONE
|
||||||
|
@ -58,11 +70,37 @@ void Game::initPlayer() {
|
||||||
mWorld.insertCharacter(mPlayer);
|
mWorld.insertCharacter(mPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void
|
||||||
* Closes window.
|
Game::initLight() {
|
||||||
*/
|
Yaml config("light.yaml");
|
||||||
Game::~Game() {
|
Color3f lightColor(config.get("color_red", 0) / 255.0f,
|
||||||
mWindow.close();
|
config.get("color_green", 0) / 255.0f,
|
||||||
|
config.get("color_blue", 0) / 255.0f);
|
||||||
|
mLightSystem.m_checkForHullIntersect = false;
|
||||||
|
mLightSystem.m_useBloom = false;
|
||||||
|
|
||||||
|
mPlayerAreaLight->m_radius = 250.0f;
|
||||||
|
mPlayerAreaLight->m_size = 1.0f;
|
||||||
|
mPlayerAreaLight->m_softSpreadAngle = 0;
|
||||||
|
mPlayerAreaLight->m_spreadAngle = 2.0f * M_PI;
|
||||||
|
mPlayerAreaLight->m_intensity = 1.1f;
|
||||||
|
mPlayerAreaLight->m_bleed = 0;
|
||||||
|
mPlayerAreaLight->m_color = lightColor;
|
||||||
|
mPlayerDirectionLight->m_linearizeFactor = 0.5;
|
||||||
|
mPlayerAreaLight->CalculateAABB();
|
||||||
|
mLightSystem.AddLight(mPlayerAreaLight);
|
||||||
|
|
||||||
|
mPlayerDirectionLight->m_radius = 500.0f;
|
||||||
|
mPlayerDirectionLight->m_size = 25.0f;
|
||||||
|
mPlayerDirectionLight->m_softSpreadAngle = 0.1f * M_PI;
|
||||||
|
mPlayerDirectionLight->m_spreadAngle =
|
||||||
|
degreeToRadian(config.get("light_cone_angle", 0.0f));
|
||||||
|
mPlayerDirectionLight->m_intensity = 5;
|
||||||
|
mPlayerDirectionLight->m_bleed = 0;
|
||||||
|
mPlayerDirectionLight->m_color = lightColor;
|
||||||
|
mPlayerDirectionLight->m_linearizeFactor = 1;
|
||||||
|
mPlayerDirectionLight->CalculateAABB();
|
||||||
|
mLightSystem.AddLight(mPlayerDirectionLight);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,9 +111,9 @@ Game::loop() {
|
||||||
while (!mQuit) {
|
while (!mQuit) {
|
||||||
input();
|
input();
|
||||||
|
|
||||||
int elapsed = mClock.restart().asMilliseconds();
|
int elapsed = (mPaused)
|
||||||
if (mPaused)
|
? 0
|
||||||
elapsed = 0;
|
: mClock.restart().asMilliseconds();
|
||||||
|
|
||||||
mWorld.think(elapsed);
|
mWorld.think(elapsed);
|
||||||
if (mPlayer->getHealth() == 0) {
|
if (mPlayer->getHealth() == 0) {
|
||||||
|
@ -301,6 +339,15 @@ Game::render() {
|
||||||
mWindow.setView(mWorldView);
|
mWindow.setView(mWorldView);
|
||||||
mWindow.draw(mWorld);
|
mWindow.draw(mWorld);
|
||||||
|
|
||||||
|
// Update light
|
||||||
|
mPlayerAreaLight->SetCenter(mPlayer->getPosition().toVec2f());
|
||||||
|
mPlayerDirectionLight->SetCenter(mPlayer->getPosition().toVec2f());
|
||||||
|
mPlayerDirectionLight->SetDirectionAngle(degreeToRadian(90 - mPlayer->getDirection()));
|
||||||
|
|
||||||
|
mLightSystem.SetView(mWorldView);
|
||||||
|
mLightSystem.RenderLights();
|
||||||
|
mLightSystem.RenderLightTexture();
|
||||||
|
|
||||||
// Render GUI and static stuff.
|
// Render GUI and static stuff.
|
||||||
mWindow.setView(mWindow.getDefaultView());
|
mWindow.setView(mWindow.getDefaultView());
|
||||||
mWindow.drawGUI();
|
mWindow.drawGUI();
|
||||||
|
|
|
@ -10,6 +10,9 @@
|
||||||
|
|
||||||
#include <TGUI/TGUI.hpp>
|
#include <TGUI/TGUI.hpp>
|
||||||
|
|
||||||
|
#include <LTBL/Light/LightSystem.h>
|
||||||
|
#include <LTBL/Light/Light_Point.h>
|
||||||
|
|
||||||
#include "generator/Generator.h"
|
#include "generator/Generator.h"
|
||||||
#include "Pathfinder.h"
|
#include "Pathfinder.h"
|
||||||
#include "World.h"
|
#include "World.h"
|
||||||
|
@ -39,6 +42,7 @@ private:
|
||||||
Vector2<float> convertCoordinates(int x, int y);
|
Vector2<float> convertCoordinates(int x, int y);
|
||||||
void updateGui();
|
void updateGui();
|
||||||
void initPlayer();
|
void initPlayer();
|
||||||
|
void initLight();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int FPS_GOAL = 60;
|
static const int FPS_GOAL = 60;
|
||||||
|
@ -57,7 +61,11 @@ private:
|
||||||
|
|
||||||
World mWorld;
|
World mWorld;
|
||||||
Pathfinder mPathfinder;
|
Pathfinder mPathfinder;
|
||||||
|
ltbl::LightSystem mLightSystem;
|
||||||
Generator mGenerator;
|
Generator mGenerator;
|
||||||
|
ltbl::Light_Point* mPlayerAreaLight = new ltbl::Light_Point();
|
||||||
|
ltbl::Light_Point* mPlayerDirectionLight = new ltbl::Light_Point();
|
||||||
|
|
||||||
std::shared_ptr<Player> mPlayer;
|
std::shared_ptr<Player> mPlayer;
|
||||||
|
|
||||||
bool mQuit = false;
|
bool mQuit = false;
|
||||||
|
|
|
@ -24,14 +24,16 @@
|
||||||
/**
|
/**
|
||||||
* Generates new random seed.
|
* Generates new random seed.
|
||||||
*/
|
*/
|
||||||
Generator::Generator(World& world, Pathfinder& pathfinder, const Yaml& config) :
|
Generator::Generator(World& world, Pathfinder& pathfinder,
|
||||||
|
ltbl::LightSystem& lightSystem, const Yaml& config) :
|
||||||
mAreaSize(config.get("generate_area_size", 1)),
|
mAreaSize(config.get("generate_area_size", 1)),
|
||||||
mMaxRange((config.get("generate_area_range", 1.0f) / mAreaSize) / Tile::TILE_SIZE.x),
|
mMaxRange((config.get("generate_area_range", 1.0f) / mAreaSize) / Tile::TILE_SIZE.x),
|
||||||
mRoomSizeValue(config.get("room_size_value", 1.0f)),
|
mRoomSizeValue(config.get("room_size_value", 1.0f)),
|
||||||
mRoomConnectionValue(config.get("room_connection_value", 1.0f)),
|
mRoomConnectionValue(config.get("room_connection_value", 1.0f)),
|
||||||
mEnemyGenerationChance(config.get("enemy_generation_chance", 0.0f) * 2 - 1),
|
mEnemyGenerationChance(config.get("enemy_generation_chance", 0.0f) * 2 - 1),
|
||||||
mWorld(world),
|
mWorld(world),
|
||||||
mPathfinder(pathfinder) {
|
mPathfinder(pathfinder),
|
||||||
|
mLightSystem(lightSystem) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -188,6 +190,12 @@ Generator::connectRooms(const Vector2i& start) {
|
||||||
for (const auto& p : path) {
|
for (const auto& p : path) {
|
||||||
mTiles[p.x][p.y] = Tile::Type::FLOOR;
|
mTiles[p.x][p.y] = Tile::Type::FLOOR;
|
||||||
Tile::setTile(p, Tile::Type::FLOOR, mWorld);
|
Tile::setTile(p, Tile::Type::FLOOR, mWorld);
|
||||||
|
for (auto it = mHulls.begin(); it != mHulls.end(); it++)
|
||||||
|
if ((*it)->GetWorldCenter() == Tile::toPosition(Vector2i(p.x, p.y)).toVec2f()) {
|
||||||
|
mLightSystem.RemoveConvexHull(*it);
|
||||||
|
mHulls.erase(it);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -245,11 +253,24 @@ Generator::generateTiles(const sf::IntRect& area) {
|
||||||
mTiles[x][y] = Tile::Type::FLOOR;
|
mTiles[x][y] = Tile::Type::FLOOR;
|
||||||
|
|
||||||
connectRooms(start);
|
connectRooms(start);
|
||||||
|
|
||||||
for (int x = area.left; x < area.left + area.width; x++)
|
for (int x = area.left; x < area.left + area.width; x++)
|
||||||
for (int y = area.top; y < area.top + area.height; y++)
|
for (int y = area.top; y < area.top + area.height; y++) {
|
||||||
mWorld.insert(std::shared_ptr<Sprite>(
|
mWorld.insert(std::shared_ptr<Sprite>(
|
||||||
new Tile(Vector2i(x, y), mTiles[x][y])));
|
new Tile(Vector2i(x, y), mTiles[x][y])));
|
||||||
|
if (mTiles[x][y] == Tile::Type::WALL) {
|
||||||
|
ltbl::ConvexHull* tileHull = new ltbl::ConvexHull();
|
||||||
|
tileHull->m_vertices.push_back(Vec2f(-37.5f, 37.5f));
|
||||||
|
tileHull->m_vertices.push_back(Vec2f(-37.5f, -37.5f));
|
||||||
|
tileHull->m_vertices.push_back(Vec2f( 37.5f, -37.5f));
|
||||||
|
tileHull->m_vertices.push_back(Vec2f( 37.5f, 37.5f));
|
||||||
|
tileHull->m_renderLightOverHull = false;
|
||||||
|
tileHull->CalculateNormals();
|
||||||
|
tileHull->CalculateAABB();
|
||||||
|
tileHull->SetWorldCenter(Tile::toPosition(Vector2i(x, y)).toVec2f());
|
||||||
|
mLightSystem.AddConvexHull(tileHull);
|
||||||
|
mHulls.push_back(tileHull);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
generateAreas(area);
|
generateAreas(area);
|
||||||
mPathfinder.generatePortals();
|
mPathfinder.generatePortals();
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
#include <SFML/Graphics.hpp>
|
#include <SFML/Graphics.hpp>
|
||||||
|
|
||||||
|
#include <LTBL/Light/LightSystem.h>
|
||||||
|
|
||||||
#include "../sprites/abstract/Character.h"
|
#include "../sprites/abstract/Character.h"
|
||||||
#include "../sprites/Tile.h"
|
#include "../sprites/Tile.h"
|
||||||
#include "SimplexNoise.h"
|
#include "SimplexNoise.h"
|
||||||
|
@ -24,7 +26,8 @@ class Yaml;
|
||||||
*/
|
*/
|
||||||
class Generator : public sf::Drawable {
|
class Generator : public sf::Drawable {
|
||||||
public:
|
public:
|
||||||
explicit Generator(World& world, Pathfinder& pathfinder, const Yaml& config);
|
explicit Generator(World& world, Pathfinder& pathfinder,
|
||||||
|
ltbl::LightSystem& lightSystem, const Yaml& config);
|
||||||
void generateCurrentAreaIfNeeded(const Vector2f& position,
|
void generateCurrentAreaIfNeeded(const Vector2f& position,
|
||||||
const Character::EquippedItems& playerItems);
|
const Character::EquippedItems& playerItems);
|
||||||
Vector2f getPlayerSpawn() const;
|
Vector2f getPlayerSpawn() const;
|
||||||
|
@ -51,6 +54,7 @@ private:
|
||||||
|
|
||||||
World& mWorld;
|
World& mWorld;
|
||||||
Pathfinder& mPathfinder;
|
Pathfinder& mPathfinder;
|
||||||
|
ltbl::LightSystem& mLightSystem;
|
||||||
/// Contains values of all tiles that have yet been generated.
|
/// Contains values of all tiles that have yet been generated.
|
||||||
array mTiles;
|
array mTiles;
|
||||||
/// Stores where tiles have already been generated.
|
/// Stores where tiles have already been generated.
|
||||||
|
@ -59,6 +63,7 @@ private:
|
||||||
SimplexNoise mTileNoise;
|
SimplexNoise mTileNoise;
|
||||||
/// Perlin noise used for character placement.
|
/// Perlin noise used for character placement.
|
||||||
SimplexNoise mCharacterNoise;
|
SimplexNoise mCharacterNoise;
|
||||||
|
std::vector<ltbl::ConvexHull*> mHulls;
|
||||||
/// Used only for debug drawing.
|
/// Used only for debug drawing.
|
||||||
std::vector<std::vector<Vector2i> > mPaths;
|
std::vector<std::vector<Vector2i> > mPaths;
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#include "util/Yaml.h"
|
#include "util/Yaml.h"
|
||||||
#include "util/Log.h"
|
#include "util/Log.h"
|
||||||
|
|
||||||
|
#include "util/Vector.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates Game object.
|
* Creates Game object.
|
||||||
*/
|
*/
|
||||||
|
@ -21,6 +23,7 @@ int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
tgui::Window window(sf::VideoMode(1024, 768, 32), "Dungeon Gunner",
|
tgui::Window window(sf::VideoMode(1024, 768, 32), "Dungeon Gunner",
|
||||||
sf::Style::Close | sf::Style::Titlebar);
|
sf::Style::Close | sf::Style::Titlebar);
|
||||||
|
Vector2f::SCREEN_HEIGHT = window.getSize().y;
|
||||||
|
|
||||||
if (!window.globalFont.loadFromFile("res/DejaVuSans.ttf"))
|
if (!window.globalFont.loadFromFile("res/DejaVuSans.ttf"))
|
||||||
LOG_W("Failed to load font at 'res/DejaVuSans.ttf'");
|
LOG_W("Failed to load font at 'res/DejaVuSans.ttf'");
|
||||||
|
|
|
@ -22,8 +22,8 @@ const Vector2i Tile::TILE_SIZE = Vector2i(75, 75);
|
||||||
*
|
*
|
||||||
* @param pType Type of the tile to create.
|
* @param pType Type of the tile to create.
|
||||||
*/
|
*/
|
||||||
Tile::Tile(const Vector2i& position, Type type) :
|
Tile::Tile(const Vector2i& tilePosition, Type type) :
|
||||||
Rectangle(Vector2f(thor::cwiseProduct(position, TILE_SIZE)),
|
Rectangle(toPosition(tilePosition),
|
||||||
CATEGORY_WORLD, (isSolid(type)) ? 0xffff : 0,
|
CATEGORY_WORLD, (isSolid(type)) ? 0xffff : 0,
|
||||||
Yaml(getConfig(type))), mType(type) {
|
Yaml(getConfig(type))), mType(type) {
|
||||||
}
|
}
|
||||||
|
@ -42,8 +42,7 @@ Tile::setTile(const Vector2i& position, Type type, World& world) {
|
||||||
std::shared_ptr<Tile> converted = std::dynamic_pointer_cast<Tile>(c);
|
std::shared_ptr<Tile> converted = std::dynamic_pointer_cast<Tile>(c);
|
||||||
// Direct comparison of floats as both are from the same generation
|
// Direct comparison of floats as both are from the same generation
|
||||||
// on the same CPU.
|
// on the same CPU.
|
||||||
if (converted.get() != nullptr &&
|
if (converted && converted->getPosition() == worldPosition &&
|
||||||
converted->getPosition() == worldPosition &&
|
|
||||||
converted->getType() != type) {
|
converted->getType() != type) {
|
||||||
world.remove(converted);
|
world.remove(converted);
|
||||||
break;
|
break;
|
||||||
|
@ -78,6 +77,14 @@ Tile::isSolid(Type type) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts a tile position to world/pixel position.
|
||||||
|
*/
|
||||||
|
Vector2f
|
||||||
|
Tile::toPosition(const Vector2i& tilePosition) {
|
||||||
|
return Vector2f(thor::cwiseProduct(tilePosition, TILE_SIZE));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Type of this tile.
|
* Returns the Type of this tile.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -24,12 +24,13 @@ public:
|
||||||
static const Vector2i TILE_SIZE; //< Tile size in pixels.
|
static const Vector2i TILE_SIZE; //< Tile size in pixels.
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Tile(const Vector2i& position, Type type);
|
explicit Tile(const Vector2i& tilePosition, Type type);
|
||||||
Type getType() const;
|
Type getType() const;
|
||||||
|
|
||||||
static void setTile(const Vector2i& position, Type type, World& world);
|
static void setTile(const Vector2i& position, Type type, World& world);
|
||||||
static std::string getConfig(Type type);
|
static std::string getConfig(Type type);
|
||||||
static bool isSolid(Type type);
|
static bool isSolid(Type type);
|
||||||
|
static Vector2f toPosition(const Vector2i& tilePosition);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type mType;
|
Type mType;
|
||||||
|
|
|
@ -45,10 +45,15 @@ Sprite::getSpeed() const {
|
||||||
* Returns the angle of the sprite.
|
* Returns the angle of the sprite.
|
||||||
*/
|
*/
|
||||||
Vector2f
|
Vector2f
|
||||||
Sprite::getDirection() const {
|
Sprite::getDirectionVector() const {
|
||||||
return thor::rotatedVector(Vector2f(0, - 1), mShape.getRotation());
|
return thor::rotatedVector(Vector2f(0, - 1), mShape.getRotation());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float
|
||||||
|
Sprite::getDirection() const {
|
||||||
|
return mShape.getRotation();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if this object should be deleted.
|
* Returns true if this object should be deleted.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -48,7 +48,8 @@ public:
|
||||||
|
|
||||||
Vector2f getPosition() const;
|
Vector2f getPosition() const;
|
||||||
Vector2f getSpeed() const;
|
Vector2f getSpeed() const;
|
||||||
Vector2f getDirection() const;
|
Vector2f getDirectionVector() const;
|
||||||
|
float getDirection() const;
|
||||||
bool getDelete() const;
|
bool getDelete() const;
|
||||||
Category getCategory() const;
|
Category getCategory() const;
|
||||||
Vector2f getSize() const;
|
Vector2f getSize() const;
|
||||||
|
|
|
@ -35,7 +35,7 @@ void
|
||||||
RingOfFire::onThink(int elapsed) {
|
RingOfFire::onThink(int elapsed) {
|
||||||
if (mCurrentWave < mWavesPerUse && mTimer.isExpired()) {
|
if (mCurrentWave < mWavesPerUse && mTimer.isExpired()) {
|
||||||
for (int angle = mCurrentWave * 10; angle <= 360; angle += 360 / mBulletsPerWave) {
|
for (int angle = mCurrentWave * 10; angle <= 360; angle += 360 / mBulletsPerWave) {
|
||||||
Vector2f direction(thor::rotatedVector(mCharacter->getDirection(), (float) angle) *
|
Vector2f direction(thor::rotatedVector(mCharacter->getDirectionVector(), (float) angle) *
|
||||||
mCharacter->getRadius());
|
mCharacter->getRadius());
|
||||||
|
|
||||||
std::shared_ptr<Sprite> projectile(new Bullet(mCharacter->getPosition() + direction,
|
std::shared_ptr<Sprite> projectile(new Bullet(mCharacter->getPosition() + direction,
|
||||||
|
|
|
@ -22,7 +22,7 @@ Shield::onUse(Character& character) {
|
||||||
mCharacter = &character;
|
mCharacter = &character;
|
||||||
if (mRotatingShield)
|
if (mRotatingShield)
|
||||||
mRotatingShield->setDelete(true);
|
mRotatingShield->setDelete(true);
|
||||||
Vector2f offset = mCharacter->getDirection() * mCharacter->getRadius();
|
Vector2f offset = mCharacter->getDirectionVector() * mCharacter->getRadius();
|
||||||
mRotatingShield = std::shared_ptr<RotatingShield>(
|
mRotatingShield = std::shared_ptr<RotatingShield>(
|
||||||
new RotatingShield(mCharacter->getPosition() + offset));
|
new RotatingShield(mCharacter->getPosition() + offset));
|
||||||
mCharacter->mWorld.insert(mRotatingShield);
|
mCharacter->mWorld.insert(mRotatingShield);
|
||||||
|
|
|
@ -181,7 +181,7 @@ Weapon::setHolder(Character& holder) {
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
Weapon::insertProjectile(float angle) {
|
Weapon::insertProjectile(float angle) {
|
||||||
Vector2f offset(mHolder->getDirection() * mHolder->getRadius());
|
Vector2f offset(mHolder->getDirectionVector() * mHolder->getRadius());
|
||||||
|
|
||||||
float spread = (mHolder->getSpeed() == Vector2f())
|
float spread = (mHolder->getSpeed() == Vector2f())
|
||||||
? mSpread
|
? mSpread
|
||||||
|
@ -189,7 +189,7 @@ Weapon::insertProjectile(float angle) {
|
||||||
std::uniform_real_distribution<float> distribution(- spread, spread);
|
std::uniform_real_distribution<float> distribution(- spread, spread);
|
||||||
angle += distribution(mGenerator) + 90.0f;
|
angle += distribution(mGenerator) + 90.0f;
|
||||||
|
|
||||||
Vector2f direction(thor::rotatedVector(mHolder->getDirection(), angle));
|
Vector2f direction(thor::rotatedVector(mHolder->getDirectionVector(), angle));
|
||||||
|
|
||||||
std::shared_ptr<Sprite> projectile(new Bullet(mHolder->getPosition() + offset,
|
std::shared_ptr<Sprite> projectile(new Bullet(mHolder->getPosition() + offset,
|
||||||
*mHolder, direction, mProjectile, mProjectileSpeed,
|
*mHolder, direction, mProjectile, mProjectileSpeed,
|
||||||
|
|
18
src/util/Angles.cpp
Normal file
18
src/util/Angles.cpp
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
/*
|
||||||
|
* Angles.cpp
|
||||||
|
*
|
||||||
|
* Created on: 12.09.2013
|
||||||
|
* Author: felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Angles.h"
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
float radianToDegree(float radian) {
|
||||||
|
return radian * 180 / M_PI;
|
||||||
|
}
|
||||||
|
|
||||||
|
float degreeToRadian(float degree) {
|
||||||
|
return degree * M_PI / 180;
|
||||||
|
}
|
15
src/util/Angles.h
Normal file
15
src/util/Angles.h
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
/*
|
||||||
|
* Angles.h
|
||||||
|
*
|
||||||
|
* Created on: 12.09.2013
|
||||||
|
* Author: felix
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ANGLES_H_
|
||||||
|
#define ANGLES_H_
|
||||||
|
|
||||||
|
float radianToDegree(float radian);
|
||||||
|
|
||||||
|
float degreeToRadian(float degree);
|
||||||
|
|
||||||
|
#endif /* ANGLES_H_ */
|
|
@ -10,6 +10,8 @@
|
||||||
|
|
||||||
#include <SFML/System.hpp>
|
#include <SFML/System.hpp>
|
||||||
|
|
||||||
|
#include <LTBL/Constructs/Vec2f.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Vector class with comparison operator. All other operators are inherited
|
* Vector class with comparison operator. All other operators are inherited
|
||||||
* from sf::Vector2.
|
* from sf::Vector2.
|
||||||
|
@ -17,6 +19,9 @@
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class Vector2 : public sf::Vector2<T> {
|
class Vector2 : public sf::Vector2<T> {
|
||||||
public:
|
public:
|
||||||
|
/// Needed for conversion to Vec2f.
|
||||||
|
static int SCREEN_HEIGHT;
|
||||||
|
|
||||||
Vector2() : sf::Vector2<T>() {};
|
Vector2() : sf::Vector2<T>() {};
|
||||||
Vector2(T x, T y) : sf::Vector2<T>(x, y) {};
|
Vector2(T x, T y) : sf::Vector2<T>(x, y) {};
|
||||||
/**
|
/**
|
||||||
|
@ -26,8 +31,15 @@ public:
|
||||||
template <typename U>
|
template <typename U>
|
||||||
Vector2(const sf::Vector2<U>& vector) : sf::Vector2<T>(vector) {};
|
Vector2(const sf::Vector2<U>& vector) : sf::Vector2<T>(vector) {};
|
||||||
|
|
||||||
|
Vec2f
|
||||||
|
toVec2f() {
|
||||||
|
return Vec2f(sf::Vector2f::x, SCREEN_HEIGHT - sf::Vector2f::y);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
int Vector2<T>::SCREEN_HEIGHT = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Comparison operator meant for containers like std::set.
|
* Comparison operator meant for containers like std::set.
|
||||||
*
|
*
|
||||||
|
|
Reference in a new issue