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/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}))

View file

@ -50,6 +50,7 @@ TRunnerScreen::TRunnerScreen(std::weak_ptr<ScreenStack> 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,6 +289,7 @@ post_check_click:
SURFACE_UNIT_HEIGHT);
}
{
std::vector<decltype(electricityEffects.size())> to_remove;
for (decltype(electricityEffects.size()) idx = 0;
idx < electricityEffects.size(); ++idx) {
@ -298,6 +304,24 @@ post_check_click:
}
electricityEffects.pop_back();
}
}
{
std::vector<decltype(sparkEffects.size())> 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();
}
}
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);

View file

@ -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<ElectricityEffect> electricityEffects;
std::vector<SparkEffect> sparkEffects;
unsigned int idx_hit;
std::optional<unsigned int> controlled_walker_idx;
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/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})))