diff options
-rw-r--r-- | include/common.hpp | 4 | ||||
-rw-r--r-- | include/particle.hpp | 42 | ||||
-rw-r--r-- | include/texture.hpp | 1 | ||||
-rw-r--r-- | include/weather.hpp | 67 | ||||
-rw-r--r-- | include/world.hpp | 39 | ||||
-rw-r--r-- | main.cpp | 9 | ||||
-rw-r--r-- | src/engine.cpp | 7 | ||||
-rw-r--r-- | src/inventory.cpp | 9 | ||||
-rw-r--r-- | src/particle.cpp | 99 | ||||
-rw-r--r-- | src/texture.cpp | 6 | ||||
-rw-r--r-- | src/world.cpp | 77 | ||||
-rw-r--r-- | xml/!town.xml | 1 |
12 files changed, 258 insertions, 103 deletions
diff --git a/include/common.hpp b/include/common.hpp index 19af420..71039c7 100644 --- a/include/common.hpp +++ b/include/common.hpp @@ -91,11 +91,11 @@ struct vec2 { } template<typename T> - const vec2 operator+(const T &n) { + vec2 operator+(T n) const { return vec2 (x + n, y + n); } - const vec2 operator+(const vec2 &v) { + vec2 operator+(const vec2 &v) { return vec2 (x + v.x, y + v.y); } diff --git a/include/particle.hpp b/include/particle.hpp new file mode 100644 index 0000000..d9aa29f --- /dev/null +++ b/include/particle.hpp @@ -0,0 +1,42 @@ +#ifndef PARTICLE_HPP_ +#define PARTICLE_HPP_ + +#include <common.hpp> + +#include <list> + +#include <entityx/entityx.h> + +enum class ParticleType : char { + Drop, + Confetti +}; + +struct Particle { + vec2 location; + vec2 velocity; + ParticleType type; + int timeLeft; + + Particle(vec2 p, ParticleType t = ParticleType::Drop) + : location(p), type(t), timeLeft(3000) {} // TODO times +} __attribute__ ((packed)); + +class ParticleSystem : public entityx::System<ParticleSystem> { +private: + std::vector<Particle> parts; + bool max; + +public: + ParticleSystem(int count = 1024, bool m = false); + + void add(const vec2& pos, const ParticleType& type); + void addMultiple(const int& count, const ParticleType& type, std::function<vec2(void)> f); + + void render(void) const; + void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override; + + int getCount(void) const; +}; + +#endif // PARTICLE_HPP_ diff --git a/include/texture.hpp b/include/texture.hpp index e9082b3..878955e 100644 --- a/include/texture.hpp +++ b/include/texture.hpp @@ -91,6 +91,7 @@ namespace Colors { extern ColorTex white; /**< A solid white texture. */ extern ColorTex black; /**< A solid black texture. */ extern ColorTex red; /**< A solid red texture. */ + extern ColorTex blue; /**< A solid blue texture. */ /** * Creates the colors. diff --git a/include/weather.hpp b/include/weather.hpp new file mode 100644 index 0000000..f7b53f1 --- /dev/null +++ b/include/weather.hpp @@ -0,0 +1,67 @@ +#ifndef WEATHER_HPP_ +#define WEATHER_HPP_ + +#include <entityx/entityx.h> + +#include <common.hpp> +#include <particle.hpp> + +/** + * The weather type enum. + * This enum contains every type of weather currently implemented in the game. + * Weather is set by the world somewhere. + */ +enum class Weather : unsigned char { + Sunny = 0, /**< Sunny */ + Rainy, /**< Rain */ + Snowy, /**< Snow */ + count +}; + +constexpr const char *weatherStrings[] = { + "Sunny", + "Rainy", + "Snowy" +}; + +class WeatherSystem : public entityx::System<WeatherSystem> { +private: + Weather weather; + +public: + WeatherSystem(Weather w = Weather::Sunny) + : weather(w) {} + + void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override { + (void)en; + (void)ev; + (void)dt; + + static auto& partSystem = *game::engine.getSystem<ParticleSystem>(); + + switch (weather) { + case Weather::Sunny: + break; + case Weather::Rainy: + partSystem.add(vec2(offset.x - game::SCREEN_WIDTH / 2 + randGet() % game::SCREEN_WIDTH, + offset.y + game::SCREEN_HEIGHT / 2 + 100), + ParticleType::Drop); + break; // TODO + case Weather::Snowy: + break; // TODO + default: + break; + } + } + + inline void setWeather(const std::string& w) { + for (int i = 0; i < static_cast<int>(Weather::count); i++) { + if (w == weatherStrings[i]) { + weather = static_cast<Weather>(i); + return; + } + } + } +}; + +#endif // WEATHER_HPP_ diff --git a/include/world.hpp b/include/world.hpp index 8864d30..14c64d0 100644 --- a/include/world.hpp +++ b/include/world.hpp @@ -28,36 +28,16 @@ enum class WorldBGType : unsigned int { }; /** - * The weather type enum. - * This enum contains every type of weather currently implemented in the game. - * Weather is set by the world somewhere. - */ -enum class WorldWeather : unsigned char { - None = 0, /**< None (sunny) */ - Rain, /**< Rain */ - Snowy /**< Snow */ -}; - -/** - * Strings to represent each type of weather. - */ -constexpr const char* WorldWeatherString[3] = { - "None", - "Rainy", - "Snowy" -}; - -/** * The line structure. * This structure is used to store the world's ground, stored in vertical * lines. Dirt color and grass properties are also kept track of here. */ -typedef struct { +struct WorldData { bool grassUnpressed; /**< squishes grass if false */ float grassHeight[2]; /**< height of the two grass blades */ float groundHeight; /**< height of the 'line' */ unsigned char groundColor; /**< a value that affects the ground's color */ -} WorldData; +} __attribute__ ((packed)); /** * Defines how many game ticks it takes to go from day to night or vice versa. @@ -130,11 +110,6 @@ private: WorldData2 world; /** - * The current state of weather in the world. - */ - WorldWeather weather; - - /** * SDL's object for handling the background music. */ Mix_Music *bgmObj; @@ -176,22 +151,16 @@ public: inline float getWidth(void) const { return world.startX * -2.0f; } + float isAboveGround(const vec2& p) const; + void receive(const BGMToggleEvent &bte); void update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) override; void render(void); - inline const std::string getWeatherStr(void) const - { return WorldWeatherString[static_cast<int>(weather)]; } - - inline const WorldWeather& getWeatherId(void) const - { return weather; } - inline const std::string& getXMLFile(void) const { return currentXMLFile; } - void setWeather(const std::string &s); - void detect(entityx::TimeDelta dt); void goWorldLeft(Position& p); @@ -25,6 +25,7 @@ using namespace tinyxml2; #include <world.hpp> #include <render.hpp> #include <ui.hpp> +#include <particle.hpp> /** * The currently used folder to look for XML files in. @@ -311,6 +312,7 @@ void render() { // draw the world and player game::engine.getSystem<WorldSystem>()->render(); + game::engine.getSystem<ParticleSystem>()->render(); // draw the player's inventory //player->inv->draw(); @@ -327,9 +329,10 @@ void render() { if (ui::debug) { auto pos = game::engine.getSystem<PlayerSystem>()->getPosition(); ui::putText(offset.x - SCREEN_WIDTH2, (offset.y + SCREEN_HEIGHT2) - ui::fontSize, - "loc: %s\noffset: %s\nfps: %d\nticks: %d\nxml: %s", - pos.toString().c_str(), offset.toString().c_str(), fps, - game::time::getTickCount(), game::engine.getSystem<WorldSystem>()->getXMLFile().c_str()); + "loc: %s\noffset: %s\nfps: %d\nticks: %d\npcount: %d\nxml: %s", + pos.toString().c_str(), offset.toString().c_str(), fps, + game::time::getTickCount(), game::engine.getSystem<ParticleSystem>()->getCount(), + game::engine.getSystem<WorldSystem>()->getXMLFile().c_str()); } // draw the menu diff --git a/src/engine.cpp b/src/engine.cpp index 48e384d..aa0db73 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -8,6 +8,8 @@ #include <components.hpp> #include <player.hpp> #include <quest.hpp> +#include <particle.hpp> +#include <weather.hpp> Engine::Engine(void) : shouldRun(true), systems(game::entities, game::events) @@ -30,6 +32,9 @@ void Engine::init(void) { systems.add<MovementSystem>(); systems.add<DialogSystem>(); + systems.add<ParticleSystem>(); + systems.add<WeatherSystem>(); + systems.configure(); ui::initSounds(); @@ -57,6 +62,8 @@ void Engine::update(entityx::TimeDelta dt) systems.update<WorldSystem>(dt); systems.update<PlayerSystem>(dt); //systems.update<QuestSystem>(dt); // doesn't do anything + systems.update<WeatherSystem>(dt); + systems.update<ParticleSystem>(dt); } diff --git a/src/inventory.cpp b/src/inventory.cpp index fb999ea..480c803 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -27,16 +27,19 @@ void InventorySystem::update(entityx::EntityManager &en, entityx::EventManager & (void)ev; (void)dt; - vec2 start = vec2(offset.x, 100);// - game::SCREEN_WIDTH / 2 + 20, game::SCREEN_HEIGHT - 40); + // TODO TODO TODO TODO until we do something + return; + + //vec2 start = vec2(offset.x, 100);// - game::SCREEN_WIDTH / 2 + 20, game::SCREEN_HEIGHT - 40); //std::cout << start.x << ' ' << start.y << std::endl; - Render::textShader.use(); + /*Render::textShader.use(); glActiveTexture(GL_TEXTURE0); Colors::black.use(); Render::useShader(&Render::textShader); Render::drawRect(start, start + 20, -9.9f); - Render::textShader.unuse(); + Render::textShader.unuse();*/ } void InventorySystem::receive(const KeyDownEvent &kde) diff --git a/src/particle.cpp b/src/particle.cpp new file mode 100644 index 0000000..8090e2d --- /dev/null +++ b/src/particle.cpp @@ -0,0 +1,99 @@ +#include <particle.hpp> + +#include <engine.hpp> +#include <render.hpp> +#include <world.hpp> + +ParticleSystem::ParticleSystem(int count, bool m) + : max(m) +{ + parts.reserve(count); +} + +void ParticleSystem::add(const vec2& pos, const ParticleType& type) +{ + // TODO enforce max + //if (max && parts.size() >= std::end(parts)) + // return; + + parts.emplace_back(pos, type); +} + +void ParticleSystem::addMultiple(const int& count, const ParticleType& type, std::function<vec2(void)> f) +{ + int togo = count; + while (togo-- > 0) + parts.emplace_back(f(), type); +} + +void ParticleSystem::render(void) const +{ + static const GLfloat tex[12] = { + 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0 + }; + + Render::worldShader.use(); + Render::worldShader.enable(); + Colors::blue.use(); + + for (const auto& p : parts) { + GLfloat coord[18] = { + p.location.x, p.location.y, -1, + p.location.x, p.location.y + 5, -1, + p.location.x + 5, p.location.y + 5, -1, + p.location.x + 5, p.location.y + 5, -1, + p.location.x + 5, p.location.y, -1, + p.location.x, p.location.y, -1 + }; + + glVertexAttribPointer(Render::worldShader.coord, 3, GL_FLOAT, GL_FALSE, 0, coord); + glVertexAttribPointer(Render::worldShader.tex, 2, GL_FLOAT, GL_FALSE, 0, tex); + glDrawArrays(GL_TRIANGLES, 0, 6); + } + + Render::worldShader.disable(); + Render::worldShader.unuse(); +} + +void ParticleSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) +{ + (void)en; + (void)ev; + (void)dt; // TODO use for time to die + + auto& worldSystem = *game::engine.getSystem<WorldSystem>(); + + for (auto part = std::begin(parts); part != std::end(parts); part++) { + auto& p = *part; + + // update timers + p.timeLeft -= dt; + if (p.timeLeft <= 0) + parts.erase(part); + + // update movement + switch (p.type) { + case ParticleType::Drop: + if (p.velocity.y > -.5) + p.velocity.y -= 0.001f; + break; + case ParticleType::Confetti: + break; + } + + // really update movement + p.location.x += p.velocity.x * dt; + p.location.y += p.velocity.y * dt; + + // world collision + auto height = worldSystem.isAboveGround(p.location); + if (height != 0) + p.location.y = height + 5, p.velocity.y = randGet() % 10 / 40.0f; + } +} + +int ParticleSystem::getCount(void) const +{ + return parts.size(); +} + diff --git a/src/texture.cpp b/src/texture.cpp index 640b06e..da39ec0 100644 --- a/src/texture.cpp +++ b/src/texture.cpp @@ -8,11 +8,13 @@ namespace Colors ColorTex white; ColorTex black; ColorTex red; + ColorTex blue; void init(void) { white = ColorTex(Color(255, 255, 255)); - black = ColorTex(Color(0, 0, 0)); - red = ColorTex(Color(255, 0, 0)); + black = ColorTex(Color(0, 0, 0 )); + red = ColorTex(Color(255, 0, 0 )); + blue = ColorTex(Color(0, 0, 255)); } } diff --git a/src/world.cpp b/src/world.cpp index 08426a8..6f31a5b 100644 --- a/src/world.cpp +++ b/src/world.cpp @@ -21,6 +21,7 @@ using namespace std::literals::chrono_literals; #include <engine.hpp> #include <components.hpp> #include <player.hpp> +#include <weather.hpp> // local library headers #include <tinyxml2.h> @@ -74,12 +75,10 @@ const unsigned int GRASS_HEIGHT = HLINES(4); std::string currentXML; // pathnames of images for world themes -using StyleList = std::array<std::string, 9>; - +using StyleList = std::array<std::string, 8>; static const std::vector<StyleList> bgPaths = { { // Forest - "bg.png", // daytime background - "bgn.png", // nighttime background + "bg.png", // sky/background "bgFarMountain.png", // layer 1 (furthest) "forestTileFar.png", // layer 2 "forestTileBack.png", // layer 3 @@ -154,6 +153,15 @@ void WorldSystem::generate(int width) world.startX = HLINES(width * -0.5); } +float WorldSystem::isAboveGround(const vec2& p) const +{ + int line = std::clamp(static_cast<int>((p.x - world.startX) / game::HLINE), + 0, static_cast<int>(world.data.size())); + + const auto& gh = world.data[line].groundHeight; + return p.y >= gh ? 0 : gh; +} + static Color ambient; bool WorldSystem::save(void) @@ -279,7 +287,8 @@ void WorldSystem::load(const std::string& file) // weather tag else if (tagName == "weather") { - setWeather(wxml->GetText()); + game::engine.getSystem<WeatherSystem>()->setWeather(wxml->GetText()); + //setWeather(wxml->GetText()); } // link tags @@ -645,7 +654,7 @@ loadWorldFromXMLNoSave(std::string path) { }*/ WorldSystem::WorldSystem(void) - : weather(WorldWeather::None), bgmObj(nullptr) {} + : bgmObj(nullptr) {} WorldSystem::~WorldSystem(void) { @@ -668,10 +677,6 @@ void WorldSystem::render(void) // world width in pixels int width = HLINES(world.data.size()); - // used for alpha values of background textures - int alpha; - - static bool ambientUpdaterStarted = false; if (!ambientUpdaterStarted) { ambientUpdaterStarted = true; @@ -690,34 +695,12 @@ void WorldSystem::render(void) thAmbient.detach(); } - - switch (weather) { - case WorldWeather::Snowy: - alpha = 150; - break; - case WorldWeather::Rain: - alpha = 0; - break; - default: - alpha = 255 - worldShade * 4; - break; - } - // shade value for GLSL float shadeAmbient = std::max(0.0f, static_cast<float>(-worldShade) / 50 + 0.5f); // 0 to 1.5f if (shadeAmbient > 0.9f) shadeAmbient = 1; - // draw background images. - GLfloat tex_coord[] = { 0.0f, 1.0f, - 1.0f, 1.0f, - 1.0f, 0.0f, - - 1.0f, 0.0f, - 0.0f, 0.0f, - 0.0f, 1.0f,}; - // TODO scroll backdrop GLfloat bgOff = game::time::getTickCount() / static_cast<float>(DAY_CYCLE * 2); @@ -759,16 +742,6 @@ void WorldSystem::render(void) offset.x - backgroundOffset.x - 5, offset.y - backgroundOffset.y, 9.9f }; - GLfloat fron_tex_coord[] = { - offset.x - backgroundOffset.x - 5, offset.y + backgroundOffset.y, 9.8f, - offset.x + backgroundOffset.x + 5, offset.y + backgroundOffset.y, 9.8f, - offset.x + backgroundOffset.x + 5, offset.y - backgroundOffset.y, 9.8f, - - offset.x + backgroundOffset.x + 5, offset.y - backgroundOffset.y, 9.8f, - offset.x - backgroundOffset.x - 5, offset.y - backgroundOffset.y, 9.8f, - offset.x - backgroundOffset.x - 5, offset.y + backgroundOffset.y, 9.8f - }; - // rendering!! glActiveTexture(GL_TEXTURE0); @@ -789,10 +762,10 @@ void WorldSystem::render(void) makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions(0, back_tex_coord, scrolling_tex_coord, 6); - bgTex++; - glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.3 - static_cast<float>(alpha) / 255.0f); - - makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions(0, fron_tex_coord, tex_coord, 6); + // no more night bg + //bgTex++; + //glUniform4f(Render::worldShader.uniform[WU_tex_color], 1.0, 1.0, 1.0, 1.3 - static_cast<float>(alpha) / 255.0f); + //makeWorldDrawingSimplerEvenThoughAndyDoesntThinkWeCanMakeItIntoFunctions(0, fron_tex_coord, tex_coord, 6); // TODO make stars dynamic /*static GLuint starTex = Texture::loadTexture("assets/style/classic/bg/star.png"); @@ -1126,18 +1099,6 @@ void WorldSystem::receive(const BGMToggleEvent &bte) } } -void WorldSystem::setWeather(const std::string &s) -{ - for (unsigned int i = 3; i--;) { - if (WorldWeatherString[i] == s) { - weather = static_cast<WorldWeather>(i); - return; - } - } - - weather = WorldWeather::None; -} - void WorldSystem::update(entityx::EntityManager &en, entityx::EventManager &ev, entityx::TimeDelta dt) { (void)en; diff --git a/xml/!town.xml b/xml/!town.xml index d98e8c6..c197d8d 100644 --- a/xml/!town.xml +++ b/xml/!town.xml @@ -4,6 +4,7 @@ <World> <style background="0" bgm="assets/music/embark.wav" folder="assets/style/classic/"/> <generation width="320"/> + <weather>Rainy</weather> <time>6000</time> <link right="!town2.xml"/> <spawnx>-300</spawnx> |