Impl. SparkEffect
All checks were successful
Build and Publish WASM version of demo / Build-And-Deploy (push) Successful in 25s

SparkEffect is an additional effect that occurs when successfully
"hacking" a Walker.
This commit is contained in:
Stephen Seo 2023-08-25 13:07:38 +09:00
parent dd678f12ba
commit 12cddad260
6 changed files with 131 additions and 13 deletions

View file

@ -21,7 +21,8 @@ SOURCES = \
src/walker.cc \ src/walker.cc \
src/surface_triangle.cc \ src/surface_triangle.cc \
src/screen_walker_hack.cc \ src/screen_walker_hack.cc \
src/electricity_effect.cc src/electricity_effect.cc \
src/spark_effect.cc
HEADERS = \ HEADERS = \
src/game.h \ src/game.h \
@ -33,7 +34,8 @@ HEADERS = \
src/walker.h \ src/walker.h \
src/surface_triangle.h \ src/surface_triangle.h \
src/screen_walker_hack.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})) OBJECTS = $(addprefix ${OBJDIR}/,$(subst .cc,.cc.o,${SOURCES}))

View file

@ -50,6 +50,7 @@ TRunnerScreen::TRunnerScreen(std::weak_ptr<ScreenStack> stack)
mouse_hit{0.0F, 0.0F, 0.0F}, mouse_hit{0.0F, 0.0F, 0.0F},
surface_triangles(), surface_triangles(),
electricityEffects(), electricityEffects(),
sparkEffects(),
idx_hit(SURFACE_UNIT_WIDTH / 2 + idx_hit(SURFACE_UNIT_WIDTH / 2 +
(SURFACE_UNIT_HEIGHT / 2) * SURFACE_UNIT_WIDTH), (SURFACE_UNIT_HEIGHT / 2) * SURFACE_UNIT_WIDTH),
controlled_walker_idx(std::nullopt), 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_RADIUS, ELECTRICITY_EFFECT_LINE_COUNT,
ELECTRICITY_EFFECT_LIFETIME)); 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 { } else {
controlled_walker_idx.reset(); controlled_walker_idx.reset();
} }
@ -284,19 +289,38 @@ post_check_click:
SURFACE_UNIT_HEIGHT); SURFACE_UNIT_HEIGHT);
} }
std::vector<decltype(electricityEffects.size())> to_remove; {
for (decltype(electricityEffects.size()) idx = 0; std::vector<decltype(electricityEffects.size())> to_remove;
idx < electricityEffects.size(); ++idx) { for (decltype(electricityEffects.size()) idx = 0;
if (electricityEffects[idx].update(dt)) { idx < electricityEffects.size(); ++idx) {
to_remove.push_back(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) { std::vector<decltype(sparkEffects.size())> to_remove;
electricityEffects[*iter] = *electricityEffects.rbegin(); 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; return false;
@ -344,6 +368,10 @@ bool TRunnerScreen::draw(RenderTexture *render_texture) {
ee.draw(GREEN); ee.draw(GREEN);
} }
for (auto &se : sparkEffects) {
se.draw(GREEN);
}
// TODO DEBUG // TODO DEBUG
if (!controlled_walker_idx.has_value() && !flags.test(0)) { if (!controlled_walker_idx.has_value() && !flags.test(0)) {
DrawLine3D(Vector3{0.0F, 3.0F, 0.0F}, mouse_hit, BLACK); DrawLine3D(Vector3{0.0F, 3.0F, 0.0F}, mouse_hit, BLACK);

View file

@ -15,6 +15,7 @@
// local includes // local includes
#include "common_constants.h" #include "common_constants.h"
#include "electricity_effect.h" #include "electricity_effect.h"
#include "spark_effect.h"
#include "surface_triangle.h" #include "surface_triangle.h"
#include "walker.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_RADIUS = 2.0F;
constexpr float ELECTRICITY_EFFECT_LIFETIME = 3.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 { class TRunnerScreen : public Screen {
public: public:
struct SurfaceUnit { struct SurfaceUnit {
@ -88,6 +94,7 @@ class TRunnerScreen : public Screen {
SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT * 2> > SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT * 2> >
surface_triangles; surface_triangles;
std::vector<ElectricityEffect> electricityEffects; std::vector<ElectricityEffect> electricityEffects;
std::vector<SparkEffect> sparkEffects;
unsigned int idx_hit; unsigned int idx_hit;
std::optional<unsigned int> controlled_walker_idx; std::optional<unsigned int> controlled_walker_idx;
const int left_text_width; const int left_text_width;

43
src/spark_effect.cc Normal file
View file

@ -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);
}
}

36
src/spark_effect.h Normal file
View file

@ -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 <vector>
// third party includes
#include <raylib.h>
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<Spark> sparks;
float lifetime;
float timer;
};
#endif

View file

@ -18,7 +18,8 @@ SOURCES = \
../src/walker.cc \ ../src/walker.cc \
../src/surface_triangle.cc \ ../src/surface_triangle.cc \
../src/screen_walker_hack.cc \ ../src/screen_walker_hack.cc \
../src/electricity_effect.cc ../src/electricity_effect.cc \
../src/spark_effect.cc
HEADERS = \ HEADERS = \
../src/ems.h \ ../src/ems.h \
@ -30,7 +31,8 @@ HEADERS = \
../src/walker.h \ ../src/walker.h \
../src/surface_triangle.h \ ../src/surface_triangle.h \
../src/screen_walker_hack.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}))) OBJECTS = $(addprefix ${OBJDIR}/,$(subst ..,PREVDIR,$(subst .cc,.cc.o,${SOURCES})))