Add "electricity" effect when "hacking" a walker
All checks were successful
Build and Publish WASM version of demo / Build-And-Deploy (push) Successful in 23s
All checks were successful
Build and Publish WASM version of demo / Build-And-Deploy (push) Successful in 23s
This commit is contained in:
parent
b113f2ae23
commit
6a0c4d6f37
6 changed files with 159 additions and 5 deletions
8
Makefile
8
Makefile
|
@ -20,7 +20,8 @@ SOURCES = \
|
||||||
src/ems.cc \
|
src/ems.cc \
|
||||||
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
|
||||||
|
|
||||||
HEADERS = \
|
HEADERS = \
|
||||||
src/game.h \
|
src/game.h \
|
||||||
|
@ -30,8 +31,9 @@ HEADERS = \
|
||||||
src/3d_helpers.h \
|
src/3d_helpers.h \
|
||||||
src/ems.h \
|
src/ems.h \
|
||||||
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
|
||||||
|
|
||||||
OBJECTS = $(addprefix ${OBJDIR}/,$(subst .cc,.cc.o,${SOURCES}))
|
OBJECTS = $(addprefix ${OBJDIR}/,$(subst .cc,.cc.o,${SOURCES}))
|
||||||
|
|
||||||
|
|
86
src/electricity_effect.cc
Normal file
86
src/electricity_effect.cc
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
#include "electricity_effect.h"
|
||||||
|
|
||||||
|
// third party includes
|
||||||
|
#include <raylib.h>
|
||||||
|
#include <raymath.h>
|
||||||
|
|
||||||
|
// local includes
|
||||||
|
#include "3d_helpers.h"
|
||||||
|
#include "ems.h"
|
||||||
|
|
||||||
|
ElectricityEffect::ElectricityEffect(Vector3 center, float radius,
|
||||||
|
int line_count, float lifetime)
|
||||||
|
: cylinders(),
|
||||||
|
center(center),
|
||||||
|
cylinder_radius(CYLINDER_MAX_RADIUS),
|
||||||
|
lifetime(lifetime),
|
||||||
|
timer(0.0F) {
|
||||||
|
cylinders.reserve(line_count);
|
||||||
|
|
||||||
|
// Generate cylinders.
|
||||||
|
int sub_count = 0;
|
||||||
|
Vector3 dir, pos;
|
||||||
|
for (; line_count > 0; --line_count) {
|
||||||
|
if (sub_count == 0) {
|
||||||
|
dir.x = call_js_get_random() * 2.0F - 1.0F;
|
||||||
|
dir.y = call_js_get_random() * 2.0F - 1.0F;
|
||||||
|
dir.z = call_js_get_random() * 2.0F - 1.0F;
|
||||||
|
|
||||||
|
dir = Vector3Normalize(dir);
|
||||||
|
|
||||||
|
pos = center + dir * (radius * 0.7F);
|
||||||
|
|
||||||
|
dir.x = call_js_get_random() * 2.0F - 1.0F;
|
||||||
|
dir.y = call_js_get_random() * 2.0F - 1.0F;
|
||||||
|
dir.z = call_js_get_random() * 2.0F - 1.0F;
|
||||||
|
|
||||||
|
dir = Vector3Normalize(dir);
|
||||||
|
|
||||||
|
auto coll = GetRayCollisionSphere(
|
||||||
|
Ray{.position = center, .direction = dir}, center, radius);
|
||||||
|
|
||||||
|
cylinders.push_back(Cylinder{.start = pos, .end = coll.point});
|
||||||
|
|
||||||
|
pos = coll.point;
|
||||||
|
} else {
|
||||||
|
dir = Vector3Normalize(center - pos);
|
||||||
|
|
||||||
|
pos = pos + dir * (radius * CYLINDER_EDGE_OFFSET);
|
||||||
|
|
||||||
|
for (unsigned int idx = 0; idx < CYLINDER_SPLIT_COUNT; ++idx) {
|
||||||
|
dir.x = call_js_get_random() * 2.0F - 1.0F;
|
||||||
|
dir.y = call_js_get_random() * 2.0F - 1.0F;
|
||||||
|
dir.z = call_js_get_random() * 2.0F - 1.0F;
|
||||||
|
|
||||||
|
dir = Vector3Normalize(dir);
|
||||||
|
|
||||||
|
auto coll = GetRayCollisionSphere(
|
||||||
|
Ray{.position = pos, .direction = dir}, center, radius);
|
||||||
|
|
||||||
|
cylinders.push_back(Cylinder{.start = pos, .end = coll.point});
|
||||||
|
|
||||||
|
if (idx == CYLINDER_SPLIT_COUNT - 1) {
|
||||||
|
pos = coll.point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (++sub_count >= CYLINDER_SUB_COUNT_MAX) {
|
||||||
|
sub_count = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ElectricityEffect::update(float dt) {
|
||||||
|
timer += dt;
|
||||||
|
|
||||||
|
return timer >= lifetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElectricityEffect::draw(Color color) {
|
||||||
|
float ratio = timer < lifetime ? (1.0F - timer / lifetime) : 0.0F;
|
||||||
|
|
||||||
|
for (const auto &cylinder : cylinders) {
|
||||||
|
DrawCylinderEx(cylinder.start, cylinder.end, CYLINDER_MAX_RADIUS * ratio,
|
||||||
|
CYLINDER_MAX_RADIUS * ratio, 8, color);
|
||||||
|
}
|
||||||
|
}
|
38
src/electricity_effect.h
Normal file
38
src/electricity_effect.h
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
#ifndef JUMPARTIFACT_DOT_COM_DEMO_0_ELECTRICITY_EFFECT_H_
|
||||||
|
#define JUMPARTIFACT_DOT_COM_DEMO_0_ELECTRICITY_EFFECT_H_
|
||||||
|
|
||||||
|
// standard library includes
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
// third party includes
|
||||||
|
#include <raylib.h>
|
||||||
|
|
||||||
|
constexpr int CYLINDER_SUB_COUNT_MAX = 3;
|
||||||
|
constexpr int CYLINDER_SPLIT_COUNT = 3;
|
||||||
|
constexpr int CYLINDER_SIDES = 8;
|
||||||
|
constexpr float CYLINDER_MAX_RADIUS = 0.03F;
|
||||||
|
constexpr float CYLINDER_EDGE_OFFSET = 0.01F;
|
||||||
|
|
||||||
|
class ElectricityEffect {
|
||||||
|
public:
|
||||||
|
ElectricityEffect(Vector3 center, float radius, int line_count,
|
||||||
|
float lifetime);
|
||||||
|
|
||||||
|
/// Returns true if lifetime ended.
|
||||||
|
bool update(float dt);
|
||||||
|
/// Assumes draw mode is active.
|
||||||
|
void draw(Color color);
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Cylinder {
|
||||||
|
Vector3 start, end;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Cylinder> cylinders;
|
||||||
|
Vector3 center;
|
||||||
|
float cylinder_radius;
|
||||||
|
float lifetime;
|
||||||
|
float timer;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -49,6 +49,7 @@ TRunnerScreen::TRunnerScreen(std::weak_ptr<ScreenStack> stack)
|
||||||
camera_target{0.0F, 0.0F, 0.0F},
|
camera_target{0.0F, 0.0F, 0.0F},
|
||||||
mouse_hit{0.0F, 0.0F, 0.0F},
|
mouse_hit{0.0F, 0.0F, 0.0F},
|
||||||
surface_triangles(),
|
surface_triangles(),
|
||||||
|
electricityEffects(),
|
||||||
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),
|
||||||
|
@ -99,6 +100,10 @@ bool TRunnerScreen::update(float dt, bool is_resized) {
|
||||||
if (flags.test(1)) {
|
if (flags.test(1)) {
|
||||||
if (walker_hack_success && controlled_walker_idx.has_value()) {
|
if (walker_hack_success && controlled_walker_idx.has_value()) {
|
||||||
walkers[controlled_walker_idx.value()].set_player_controlled(true);
|
walkers[controlled_walker_idx.value()].set_player_controlled(true);
|
||||||
|
electricityEffects.push_back(ElectricityEffect(
|
||||||
|
walkers[controlled_walker_idx.value()].get_body_pos(), 1.7F, 15,
|
||||||
|
1.0F));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
controlled_walker_idx.reset();
|
controlled_walker_idx.reset();
|
||||||
}
|
}
|
||||||
|
@ -278,6 +283,21 @@ post_check_click:
|
||||||
SURFACE_UNIT_HEIGHT);
|
SURFACE_UNIT_HEIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<decltype(electricityEffects.size())> 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();
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -319,6 +339,10 @@ bool TRunnerScreen::draw(RenderTexture *render_texture) {
|
||||||
walker.draw(TEMP_cube_model);
|
walker.draw(TEMP_cube_model);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (auto &ee : electricityEffects) {
|
||||||
|
ee.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);
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
// local includes
|
// local includes
|
||||||
#include "common_constants.h"
|
#include "common_constants.h"
|
||||||
|
#include "electricity_effect.h"
|
||||||
#include "surface_triangle.h"
|
#include "surface_triangle.h"
|
||||||
#include "walker.h"
|
#include "walker.h"
|
||||||
|
|
||||||
|
@ -82,6 +83,7 @@ class TRunnerScreen : public Screen {
|
||||||
std::unique_ptr<std::array<SurfaceTriangle,
|
std::unique_ptr<std::array<SurfaceTriangle,
|
||||||
SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT * 2> >
|
SURFACE_UNIT_WIDTH * SURFACE_UNIT_HEIGHT * 2> >
|
||||||
surface_triangles;
|
surface_triangles;
|
||||||
|
std::vector<ElectricityEffect> electricityEffects;
|
||||||
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;
|
||||||
|
|
|
@ -17,7 +17,8 @@ SOURCES = \
|
||||||
../src/raymath.cc \
|
../src/raymath.cc \
|
||||||
../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
|
||||||
|
|
||||||
HEADERS = \
|
HEADERS = \
|
||||||
../src/ems.h \
|
../src/ems.h \
|
||||||
|
@ -28,7 +29,8 @@ HEADERS = \
|
||||||
../src/3d_helpers.h \
|
../src/3d_helpers.h \
|
||||||
../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
|
||||||
|
|
||||||
OBJECTS = $(addprefix ${OBJDIR}/,$(subst ..,PREVDIR,$(subst .cc,.cc.o,${SOURCES})))
|
OBJECTS = $(addprefix ${OBJDIR}/,$(subst ..,PREVDIR,$(subst .cc,.cc.o,${SOURCES})))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue