diff --git a/Makefile b/Makefile index ccafaa3..ea69839 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,8 @@ SOURCES = \ src/walker.cc \ src/surface_triangle.cc \ src/screen_walker_hack.cc \ - src/electricity_effect.cc + src/electricity_effect.cc \ + src/spark_effect.cc HEADERS = \ src/game.h \ @@ -33,7 +34,8 @@ HEADERS = \ src/walker.h \ src/surface_triangle.h \ src/screen_walker_hack.h \ - src/electricity_effect.h + src/electricity_effect.h \ + src/spark_effect.h OBJECTS = $(addprefix ${OBJDIR}/,$(subst .cc,.cc.o,${SOURCES})) diff --git a/src/screen_trunner.cc b/src/screen_trunner.cc index fea5b55..dd36e1a 100644 --- a/src/screen_trunner.cc +++ b/src/screen_trunner.cc @@ -50,6 +50,7 @@ TRunnerScreen::TRunnerScreen(std::weak_ptr stack) mouse_hit{0.0F, 0.0F, 0.0F}, surface_triangles(), electricityEffects(), + sparkEffects(), idx_hit(SURFACE_UNIT_WIDTH / 2 + (SURFACE_UNIT_HEIGHT / 2) * SURFACE_UNIT_WIDTH), controlled_walker_idx(std::nullopt), @@ -105,6 +106,10 @@ bool TRunnerScreen::update(float dt, bool is_resized) { ELECTRICITY_EFFECT_RADIUS, ELECTRICITY_EFFECT_LINE_COUNT, ELECTRICITY_EFFECT_LIFETIME)); + sparkEffects.push_back( + SparkEffect(SPARK_EFFECT_SPARK_COUNT, SPARK_EFFECT_LIFETIME, + walkers[controlled_walker_idx.value()].get_body_pos(), + SPARK_EFFECT_XZ_VARIANCE, SPARK_EFFECT_RADIUS)); } else { controlled_walker_idx.reset(); } @@ -284,19 +289,38 @@ post_check_click: SURFACE_UNIT_HEIGHT); } - std::vector to_remove; - for (decltype(electricityEffects.size()) idx = 0; - idx < electricityEffects.size(); ++idx) { - if (electricityEffects[idx].update(dt)) { - to_remove.push_back(idx); + { + std::vector to_remove; + for (decltype(electricityEffects.size()) idx = 0; + idx < electricityEffects.size(); ++idx) { + if (electricityEffects[idx].update(dt)) { + to_remove.push_back(idx); + } + } + + for (auto iter = to_remove.rbegin(); iter != to_remove.rend(); ++iter) { + if (*iter != electricityEffects.size() - 1) { + electricityEffects[*iter] = *electricityEffects.rbegin(); + } + electricityEffects.pop_back(); } } - for (auto iter = to_remove.rbegin(); iter != to_remove.rend(); ++iter) { - if (*iter != electricityEffects.size() - 1) { - electricityEffects[*iter] = *electricityEffects.rbegin(); + { + std::vector to_remove; + for (decltype(sparkEffects.size()) idx = 0; idx < sparkEffects.size(); + ++idx) { + if (sparkEffects[idx].update(dt)) { + to_remove.push_back(idx); + } + } + + for (auto iter = to_remove.rbegin(); iter != to_remove.rend(); ++iter) { + if (*iter != sparkEffects.size() - 1) { + sparkEffects[*iter] = *sparkEffects.rbegin(); + } + sparkEffects.pop_back(); } - electricityEffects.pop_back(); } return false; @@ -344,6 +368,10 @@ bool TRunnerScreen::draw(RenderTexture *render_texture) { ee.draw(GREEN); } + for (auto &se : sparkEffects) { + se.draw(GREEN); + } + // TODO DEBUG if (!controlled_walker_idx.has_value() && !flags.test(0)) { DrawLine3D(Vector3{0.0F, 3.0F, 0.0F}, mouse_hit, BLACK); diff --git a/src/screen_trunner.h b/src/screen_trunner.h index 966cf61..6ed211a 100644 --- a/src/screen_trunner.h +++ b/src/screen_trunner.h @@ -15,6 +15,7 @@ // local includes #include "common_constants.h" #include "electricity_effect.h" +#include "spark_effect.h" #include "surface_triangle.h" #include "walker.h" @@ -33,6 +34,11 @@ constexpr int ELECTRICITY_EFFECT_LINE_COUNT = 35; constexpr float ELECTRICITY_EFFECT_RADIUS = 2.0F; constexpr float ELECTRICITY_EFFECT_LIFETIME = 3.0F; +constexpr int SPARK_EFFECT_SPARK_COUNT = 30; +constexpr float SPARK_EFFECT_RADIUS = 2.0F; +constexpr float SPARK_EFFECT_XZ_VARIANCE = 0.5F; +constexpr float SPARK_EFFECT_LIFETIME = ELECTRICITY_EFFECT_LIFETIME; + class TRunnerScreen : public Screen { public: struct SurfaceUnit { @@ -88,6 +94,7 @@ class TRunnerScreen : public Screen { SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT * 2> > surface_triangles; std::vector electricityEffects; + std::vector sparkEffects; unsigned int idx_hit; std::optional controlled_walker_idx; const int left_text_width; diff --git a/src/spark_effect.cc b/src/spark_effect.cc new file mode 100644 index 0000000..79f0863 --- /dev/null +++ b/src/spark_effect.cc @@ -0,0 +1,43 @@ +#include "spark_effect.h" + +// local includes +#include "3d_helpers.h" +#include "ems.h" + +SparkEffect::SparkEffect(int count, float lifetime, Vector3 pos, + float pos_xz_variance, float radius) + : sparks(), lifetime(lifetime), timer(0.0F) { + Vector3 above_pos = pos; + above_pos.y += radius; + for (; count > 0; --count) { + sparks.push_back(Spark{ + .pos = pos + Vector3{call_js_get_random() * pos_xz_variance * 2 - + pos_xz_variance, + 0.0F, + call_js_get_random() * pos_xz_variance * 2 - + pos_xz_variance}, + .vel = + from_edge_to_sphere_random(above_pos, pos, radius) * + (SPARK_VEL_RATE + call_js_get_random() * SPARK_VEL_VARIANCE * 2.0F - + SPARK_VEL_VARIANCE)}); + } +} + +bool SparkEffect::update(float dt) { + timer += dt; + + for (auto &spark : sparks) { + spark.vel.y -= SPARK_ACC_RATE * dt; + spark.pos = spark.pos + spark.vel * dt; + } + + return timer > lifetime; +} + +void SparkEffect::draw(Color color) { + float ratio = timer < lifetime ? (1.0F - timer / lifetime) : 0.0F; + + for (const auto &spark : sparks) { + DrawSphere(spark.pos, SPARK_RADIUS * ratio, color); + } +} diff --git a/src/spark_effect.h b/src/spark_effect.h new file mode 100644 index 0000000..3746d69 --- /dev/null +++ b/src/spark_effect.h @@ -0,0 +1,36 @@ +#ifndef JUMPARTIFACT_DOT_COM_DEMO_0_SPARK_EFFECT_H_ +#define JUMPARTIFACT_DOT_COM_DEMO_0_SPARK_EFFECT_H_ + +// standard library includes +#include + +// third party includes +#include + +constexpr float SPARK_RADIUS = 0.03F; +constexpr float SPARK_VEL_RATE = 5.0F; +constexpr float SPARK_VEL_VARIANCE = 1.0F; +constexpr float SPARK_ACC_RATE = 10.0F; + +class SparkEffect { + public: + SparkEffect(int count, float lifetime, Vector3 pos, float pos_xz_variance, + float radius); + + /// Returns true if end of lifetime. + bool update(float dt); + + /// Assumes draw mode is active when called. + void draw(Color color); + + private: + struct Spark { + Vector3 pos, vel; + }; + + std::vector sparks; + float lifetime; + float timer; +}; + +#endif diff --git a/wasm_build/Makefile b/wasm_build/Makefile index aeb738e..0af63c6 100644 --- a/wasm_build/Makefile +++ b/wasm_build/Makefile @@ -18,7 +18,8 @@ SOURCES = \ ../src/walker.cc \ ../src/surface_triangle.cc \ ../src/screen_walker_hack.cc \ - ../src/electricity_effect.cc + ../src/electricity_effect.cc \ + ../src/spark_effect.cc HEADERS = \ ../src/ems.h \ @@ -30,7 +31,8 @@ HEADERS = \ ../src/walker.h \ ../src/surface_triangle.h \ ../src/screen_walker_hack.h \ - ../src/electricity_effect.h + ../src/electricity_effect.h \ + ../src/spark_effect.h OBJECTS = $(addprefix ${OBJDIR}/,$(subst ..,PREVDIR,$(subst .cc,.cc.o,${SOURCES})))