Rework electricity effect (again)
All checks were successful
Build and Publish WASM version of demo / Build-And-Deploy (push) Successful in 22s
All checks were successful
Build and Publish WASM version of demo / Build-And-Deploy (push) Successful in 22s
This commit is contained in:
parent
8e8a8b0684
commit
310fa33b01
4 changed files with 65 additions and 18 deletions
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
// standard library includes
|
// standard library includes
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
// third party includes
|
// third party includes
|
||||||
#include <raylib.h>
|
#include <raylib.h>
|
||||||
|
@ -13,39 +14,60 @@
|
||||||
|
|
||||||
ElectricityEffect::ElectricityEffect(Vector3 center, float radius,
|
ElectricityEffect::ElectricityEffect(Vector3 center, float radius,
|
||||||
int line_count, float lifetime)
|
int line_count, float lifetime)
|
||||||
: cylinders(), lifetime(lifetime), timer(0.0F) {
|
: cylinders(),
|
||||||
|
center(center),
|
||||||
|
radius(radius),
|
||||||
|
lifetime(lifetime),
|
||||||
|
timer(0.0F) {
|
||||||
cylinders.reserve(line_count);
|
cylinders.reserve(line_count);
|
||||||
|
|
||||||
|
const float line_max_length = radius * CYLINDER_LINE_MAX_LENGTH_RATIO;
|
||||||
|
|
||||||
// Generate cylinders.
|
// Generate cylinders.
|
||||||
std::queue<Vector3> positions;
|
std::queue<std::tuple<Vector3, int>> positions;
|
||||||
Vector3 next, dir;
|
std::tuple<Vector3, int> next;
|
||||||
for (unsigned int idx = 0; idx < CYLINDER_SPLIT_COUNT; ++idx) {
|
Vector3 next_pos, dir;
|
||||||
positions.push(center);
|
for (unsigned int idx = 0; idx < CYLINDER_SPLIT_COUNT && line_count > 0;
|
||||||
|
++idx, --line_count) {
|
||||||
|
cylinders.push_back(Cylinder{.next_idx = -1,
|
||||||
|
.point = center,
|
||||||
|
.mdir = Vector3Normalize(Vector3{
|
||||||
|
call_js_get_random() * 2.0F - 1.0F,
|
||||||
|
call_js_get_random() * 2.0F - 1.0F,
|
||||||
|
call_js_get_random() * 2.0F - 1.0F,
|
||||||
|
})});
|
||||||
|
positions.push({center, cylinders.size() - 1});
|
||||||
}
|
}
|
||||||
while (line_count-- > 0 && !positions.empty()) {
|
while (line_count-- > 0 && !positions.empty()) {
|
||||||
next = positions.front();
|
next = positions.front();
|
||||||
|
next_pos = std::get<Vector3>(next);
|
||||||
positions.pop();
|
positions.pop();
|
||||||
|
|
||||||
dir = Vector3Normalize(center - next);
|
dir = Vector3Normalize(center - next_pos);
|
||||||
dir = Vector3Normalize(Vector3{call_js_get_random() * 2.0F - 1.0F,
|
dir = Vector3Normalize(Vector3{call_js_get_random() * 2.0F - 1.0F,
|
||||||
call_js_get_random() * 2.0F - 1.0F,
|
call_js_get_random() * 2.0F - 1.0F,
|
||||||
call_js_get_random() * 2.0F - 1.0F} +
|
call_js_get_random() * 2.0F - 1.0F} +
|
||||||
dir);
|
dir);
|
||||||
|
|
||||||
auto coll = GetRayCollisionSphere(Ray{.position = next, .direction = dir},
|
auto coll = GetRayCollisionSphere(
|
||||||
center, radius);
|
Ray{.position = next_pos, .direction = dir}, center, radius);
|
||||||
|
|
||||||
if (coll.distance > CYLINDER_LINE_MAX_LENGTH) {
|
if (coll.distance > line_max_length) {
|
||||||
coll.point =
|
coll.point =
|
||||||
next + Vector3Normalize(coll.point - next) * CYLINDER_LINE_MAX_LENGTH;
|
next_pos + Vector3Normalize(coll.point - next_pos) * line_max_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
cylinders.push_back(Cylinder{.start = next, .end = coll.point});
|
cylinders.push_back(Cylinder{
|
||||||
|
.next_idx = std::get<int>(next),
|
||||||
|
.point = coll.point,
|
||||||
|
.mdir = Vector3Normalize(Vector3{call_js_get_random() * 2.0F - 1.0F,
|
||||||
|
call_js_get_random() * 2.0F - 1.0F,
|
||||||
|
call_js_get_random() * 2.0F - 1.0F})});
|
||||||
|
|
||||||
dir = Vector3Normalize(center - coll.point);
|
dir = Vector3Normalize(center - coll.point);
|
||||||
coll.point = coll.point + dir * (radius * CYLINDER_EDGE_OFFSET);
|
coll.point = coll.point + dir * (radius * CYLINDER_EDGE_OFFSET);
|
||||||
for (unsigned int idx = 0; idx < CYLINDER_SPLIT_COUNT; ++idx) {
|
for (unsigned int idx = 0; idx < CYLINDER_SPLIT_COUNT; ++idx) {
|
||||||
positions.push(coll.point);
|
positions.push({coll.point, cylinders.size() - 1});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +75,21 @@ ElectricityEffect::ElectricityEffect(Vector3 center, float radius,
|
||||||
bool ElectricityEffect::update(float dt) {
|
bool ElectricityEffect::update(float dt) {
|
||||||
timer += dt;
|
timer += dt;
|
||||||
|
|
||||||
|
for (auto &cylinder : cylinders) {
|
||||||
|
cylinder.point = cylinder.point + cylinder.mdir * (dt * CYLINDER_MOVE_RATE);
|
||||||
|
if (Vector3Distance(cylinder.point, center) > radius) {
|
||||||
|
cylinder.point =
|
||||||
|
cylinder.point - cylinder.mdir * (dt * CYLINDER_MOVE_RATE);
|
||||||
|
Vector3 to_center = center - cylinder.point;
|
||||||
|
Vector3 perpendicular = Vector3Normalize(Vector3Perpendicular(to_center));
|
||||||
|
cylinder.mdir = Vector3Normalize(
|
||||||
|
to_center + Vector3RotateByAxisAngle(perpendicular,
|
||||||
|
Vector3Normalize(to_center),
|
||||||
|
call_js_get_random() * PI * 2) *
|
||||||
|
(call_js_get_random() * radius));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return timer >= lifetime;
|
return timer >= lifetime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +97,10 @@ void ElectricityEffect::draw(Color color) {
|
||||||
float ratio = timer < lifetime ? (1.0F - timer / lifetime) : 0.0F;
|
float ratio = timer < lifetime ? (1.0F - timer / lifetime) : 0.0F;
|
||||||
|
|
||||||
for (const auto &cylinder : cylinders) {
|
for (const auto &cylinder : cylinders) {
|
||||||
DrawCylinderEx(cylinder.start, cylinder.end, CYLINDER_MAX_RADIUS * ratio,
|
if (cylinder.next_idx >= 0) {
|
||||||
CYLINDER_MAX_RADIUS * ratio, CYLINDER_SIDES, color);
|
DrawCylinderEx(cylinder.point, cylinders.at(cylinder.next_idx).point,
|
||||||
|
CYLINDER_MAX_RADIUS * ratio, CYLINDER_MAX_RADIUS * ratio,
|
||||||
|
CYLINDER_SIDES, color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,8 @@ constexpr int CYLINDER_SPLIT_COUNT = 3;
|
||||||
constexpr int CYLINDER_SIDES = 3;
|
constexpr int CYLINDER_SIDES = 3;
|
||||||
constexpr float CYLINDER_MAX_RADIUS = 0.03F;
|
constexpr float CYLINDER_MAX_RADIUS = 0.03F;
|
||||||
constexpr float CYLINDER_EDGE_OFFSET = 0.01F;
|
constexpr float CYLINDER_EDGE_OFFSET = 0.01F;
|
||||||
constexpr float CYLINDER_LINE_MAX_LENGTH = 1.5F;
|
constexpr float CYLINDER_LINE_MAX_LENGTH_RATIO = 0.85F;
|
||||||
|
constexpr float CYLINDER_MOVE_RATE = 0.05F;
|
||||||
|
|
||||||
class ElectricityEffect {
|
class ElectricityEffect {
|
||||||
public:
|
public:
|
||||||
|
@ -25,10 +26,13 @@ class ElectricityEffect {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Cylinder {
|
struct Cylinder {
|
||||||
Vector3 start, end;
|
int next_idx;
|
||||||
|
Vector3 point, mdir;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<Cylinder> cylinders;
|
std::vector<Cylinder> cylinders;
|
||||||
|
Vector3 center;
|
||||||
|
float radius;
|
||||||
float lifetime;
|
float lifetime;
|
||||||
float timer;
|
float timer;
|
||||||
};
|
};
|
||||||
|
|
|
@ -101,8 +101,9 @@ bool TRunnerScreen::update(float dt, bool is_resized) {
|
||||||
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(
|
electricityEffects.push_back(ElectricityEffect(
|
||||||
walkers[controlled_walker_idx.value()].get_body_pos(), 1.7F,
|
walkers[controlled_walker_idx.value()].get_body_pos(),
|
||||||
ELECTRICITY_EFFECT_LINE_COUNT, 1.0F));
|
ELECTRICITY_EFFECT_RADIUS, ELECTRICITY_EFFECT_LINE_COUNT,
|
||||||
|
ELECTRICITY_EFFECT_LIFETIME));
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
controlled_walker_idx.reset();
|
controlled_walker_idx.reset();
|
||||||
|
|
|
@ -30,6 +30,8 @@ constexpr float SURFACE_RESET_TIME_TRI_DRAW = 3.0F;
|
||||||
constexpr float SURFACE_RESET_Y_OFFSET = 40.0F;
|
constexpr float SURFACE_RESET_Y_OFFSET = 40.0F;
|
||||||
|
|
||||||
constexpr int ELECTRICITY_EFFECT_LINE_COUNT = 35;
|
constexpr int ELECTRICITY_EFFECT_LINE_COUNT = 35;
|
||||||
|
constexpr float ELECTRICITY_EFFECT_RADIUS = 2.0F;
|
||||||
|
constexpr float ELECTRICITY_EFFECT_LIFETIME = 3.0F;
|
||||||
|
|
||||||
class TRunnerScreen : public Screen {
|
class TRunnerScreen : public Screen {
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in a new issue