Add Floaty text particles
This commit is contained in:
@@ -8,6 +8,7 @@ ECS_COMPONENT_DECLARE(Resource);
|
|||||||
|
|
||||||
ECS_COMPONENT_DECLARE(Owner);
|
ECS_COMPONENT_DECLARE(Owner);
|
||||||
|
|
||||||
|
ECS_COMPONENT_DECLARE(FloatyTextParticle);
|
||||||
ECS_COMPONENT_DECLARE(EmitterAttachment);
|
ECS_COMPONENT_DECLARE(EmitterAttachment);
|
||||||
ECS_COMPONENT_DECLARE(ParticleEmitter);
|
ECS_COMPONENT_DECLARE(ParticleEmitter);
|
||||||
ECS_COMPONENT_DECLARE(ParticleLayer0);
|
ECS_COMPONENT_DECLARE(ParticleLayer0);
|
||||||
@@ -57,6 +58,7 @@ void initComponentIDs(ecs_world_t *ecs) {
|
|||||||
|
|
||||||
ECS_COMPONENT_DEFINE(ecs, Owner);
|
ECS_COMPONENT_DEFINE(ecs, Owner);
|
||||||
|
|
||||||
|
ECS_COMPONENT_DEFINE(ecs, FloatyTextParticle);
|
||||||
ECS_COMPONENT_DEFINE(ecs, EmitterAttachment);
|
ECS_COMPONENT_DEFINE(ecs, EmitterAttachment);
|
||||||
ECS_COMPONENT_DEFINE(ecs, ParticleEmitter);
|
ECS_COMPONENT_DEFINE(ecs, ParticleEmitter);
|
||||||
ECS_COMPONENT_DEFINE(ecs, ParticleLayer0);
|
ECS_COMPONENT_DEFINE(ecs, ParticleLayer0);
|
||||||
|
|||||||
@@ -41,6 +41,18 @@ extern ECS_COMPONENT_DECLARE(Owner);
|
|||||||
* Particle components
|
* Particle components
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
|
|
||||||
|
typedef struct FloatyTextParticle {
|
||||||
|
Vector2 pos;
|
||||||
|
Vector2 speed;
|
||||||
|
Color color;
|
||||||
|
Color targetColor;
|
||||||
|
char text[12];
|
||||||
|
f32 txtSize;
|
||||||
|
f32 duration;
|
||||||
|
f32 elapsed;
|
||||||
|
} FloatyTextParticle;
|
||||||
|
extern ECS_COMPONENT_DECLARE(FloatyTextParticle);
|
||||||
|
|
||||||
typedef struct EmitterAttachment {
|
typedef struct EmitterAttachment {
|
||||||
ecs_entity_t baseEntity;
|
ecs_entity_t baseEntity;
|
||||||
Vector2 offset;
|
Vector2 offset;
|
||||||
@@ -185,7 +197,10 @@ extern ECS_COMPONENT_DECLARE(Easing);
|
|||||||
/**********************************************************
|
/**********************************************************
|
||||||
* Event components
|
* Event components
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
|
typedef Rectangle HitBox;
|
||||||
|
|
||||||
typedef struct DamageEvent {
|
typedef struct DamageEvent {
|
||||||
|
HitBox hitbox;
|
||||||
f32 amount;
|
f32 amount;
|
||||||
} DamageEvent;
|
} DamageEvent;
|
||||||
|
|
||||||
@@ -202,7 +217,6 @@ typedef struct DamageEvent {
|
|||||||
* Gameplay components
|
* Gameplay components
|
||||||
*********************************************************/
|
*********************************************************/
|
||||||
|
|
||||||
typedef Rectangle HitBox;
|
|
||||||
extern ECS_COMPONENT_DECLARE(HitBox);
|
extern ECS_COMPONENT_DECLARE(HitBox);
|
||||||
|
|
||||||
extern ECS_COMPONENT_DECLARE(BzBTState);
|
extern ECS_COMPONENT_DECLARE(BzBTState);
|
||||||
|
|||||||
@@ -6,6 +6,49 @@
|
|||||||
#include <raymath.h>
|
#include <raymath.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static inline int lerpInt(int start, int end, f32 alpha)
|
||||||
|
{
|
||||||
|
float result = start + alpha * (end - start);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
static inline Color lerpColor(Color start, Color end, f32 alpha) {
|
||||||
|
return (Color) {
|
||||||
|
.r = lerpInt(start.r, end.r, alpha),
|
||||||
|
.g = lerpInt(start.g, end.g, alpha),
|
||||||
|
.b = lerpInt(start.b, end.b, alpha),
|
||||||
|
.a = lerpInt(start.a, end.a, alpha),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderFloatyTextParticle(ecs_iter_t *it) {
|
||||||
|
Game *game = ecs_singleton_get_mut(ECS, Game);
|
||||||
|
FloatyTextParticle *floaty = ecs_field(it, FloatyTextParticle, 1);
|
||||||
|
f32 dt = GetFrameTime();
|
||||||
|
|
||||||
|
for (i32 i = 0; i < it->count; i++) {
|
||||||
|
ecs_entity_t entity = it->entities[i];
|
||||||
|
|
||||||
|
f32 alpha = floaty[i].elapsed / floaty[i].duration;
|
||||||
|
Color color = lerpColor(floaty[i].color, floaty[i].targetColor, alpha);
|
||||||
|
Font font = game->font;
|
||||||
|
// Shadow
|
||||||
|
Vector2 shadowPos = floaty[i].pos;
|
||||||
|
shadowPos.x += 0.4f;
|
||||||
|
shadowPos.y += 0.4f;
|
||||||
|
Color shadowColor = DARKGRAY;
|
||||||
|
shadowColor.a = color.a;
|
||||||
|
DrawTextEx(font, floaty[i].text, shadowPos, floaty[i].txtSize, 1.0f, shadowColor);
|
||||||
|
DrawTextEx(font, floaty[i].text, floaty[i].pos, floaty[i].txtSize, 1.0f, color);
|
||||||
|
|
||||||
|
// pos += speed * dt
|
||||||
|
floaty[i].pos = Vector2Add(floaty[i].pos, Vector2Scale(floaty[i].speed, dt));
|
||||||
|
|
||||||
|
floaty[i].elapsed += dt;
|
||||||
|
if (floaty[i].elapsed >= floaty[i].duration)
|
||||||
|
ecs_delete(ECS, entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void updateParticleEmitter(ecs_iter_t *it) {
|
void updateParticleEmitter(ecs_iter_t *it) {
|
||||||
ParticleEmitter *emitter = ecs_field(it, ParticleEmitter, 1);
|
ParticleEmitter *emitter = ecs_field(it, ParticleEmitter, 1);
|
||||||
f32 dt = GetFrameTime();
|
f32 dt = GetFrameTime();
|
||||||
@@ -29,12 +72,6 @@ void updateParticleEmitter(ecs_iter_t *it) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int lerpInt(int start, int end, int amount)
|
|
||||||
{
|
|
||||||
float result = start + amount*(end - start);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
bool updateParticle(const Texture2D tex, Particle *particle, f32 dt) {
|
bool updateParticle(const Texture2D tex, Particle *particle, f32 dt) {
|
||||||
f32 alpha = particle->elapsed / particle->lifetime;
|
f32 alpha = particle->elapsed / particle->lifetime;
|
||||||
|
|
||||||
@@ -43,12 +80,7 @@ bool updateParticle(const Texture2D tex, Particle *particle, f32 dt) {
|
|||||||
f32 rot = Lerp(particle->startRotSpeed, particle->endRotSpeed, alpha);
|
f32 rot = Lerp(particle->startRotSpeed, particle->endRotSpeed, alpha);
|
||||||
Color startC = particle->startColor;
|
Color startC = particle->startColor;
|
||||||
Color endC = particle->endColor;
|
Color endC = particle->endColor;
|
||||||
Color color = {
|
Color color = lerpColor(startC, endC, alpha);
|
||||||
.r = lerpInt(startC.r, endC.r, alpha),
|
|
||||||
.g = lerpInt(startC.g, endC.g, alpha),
|
|
||||||
.b = lerpInt(startC.b, endC.b, alpha),
|
|
||||||
.a = lerpInt(startC.a, endC.a, alpha)
|
|
||||||
};
|
|
||||||
|
|
||||||
BeginBlendMode(particle->blend);
|
BeginBlendMode(particle->blend);
|
||||||
f32 hSize = size * 0.5f;
|
f32 hSize = size * 0.5f;
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ void entityUpdate(ecs_iter_t *it) {
|
|||||||
dealDmg *= multiplier;
|
dealDmg *= multiplier;
|
||||||
|
|
||||||
damageEvent(other, (DamageEvent) {
|
damageEvent(other, (DamageEvent) {
|
||||||
|
.hitbox = otherBounds,
|
||||||
.amount = dealDmg
|
.amount = dealDmg
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
|
#include <stdio.h>
|
||||||
#include "systems.h"
|
#include "systems.h"
|
||||||
|
|
||||||
#include "../game_state.h"
|
#include "../game_state.h"
|
||||||
#include "../sounds.h"
|
#include "../sounds.h"
|
||||||
|
#include "../utils.h"
|
||||||
|
#include "../entity_factory.h"
|
||||||
|
|
||||||
void damageEvent(ecs_entity_t entity, DamageEvent event) {
|
void damageEvent(ecs_entity_t entity, DamageEvent event) {
|
||||||
BZ_ASSERT(ecs_has(ECS, entity, Health));
|
BZ_ASSERT(ecs_has(ECS, entity, Health));
|
||||||
@@ -9,6 +12,24 @@ void damageEvent(ecs_entity_t entity, DamageEvent event) {
|
|||||||
Health *health = ecs_get_mut(ECS, entity, Health);
|
Health *health = ecs_get_mut(ECS, entity, Health);
|
||||||
health->hp -= event.amount;
|
health->hp -= event.amount;
|
||||||
|
|
||||||
|
Vector2 pos = {
|
||||||
|
event.hitbox.x + event.hitbox.width * 0.5f + randFloatRange(-2, 2),
|
||||||
|
event.hitbox.y + randFloatRange(2, 4)
|
||||||
|
};
|
||||||
|
|
||||||
|
FloatyTextParticle floatyText = {
|
||||||
|
.pos = pos,
|
||||||
|
.speed = { randFloatRange(-12, 12), -randFloatRange(26, 32) },
|
||||||
|
.color = {255, 0, 0, 255},
|
||||||
|
.targetColor = {255, 0, 0, GetRandomValue(60, 120)},
|
||||||
|
.txtSize = 6.5f,
|
||||||
|
.duration = randFloatRange(0.3, 0.68f),
|
||||||
|
.elapsed = 0
|
||||||
|
};
|
||||||
|
snprintf(floatyText.text, sizeof(floatyText.text), "-%.1f", event.amount);
|
||||||
|
ecs_entity_t floaty = entityCreateEmpty();
|
||||||
|
ecs_set_ptr(ECS, floaty, FloatyTextParticle, &floatyText);
|
||||||
|
|
||||||
bool hasAnimation = ecs_has(ECS, entity, Animation);
|
bool hasAnimation = ecs_has(ECS, entity, Animation);
|
||||||
if (hasAnimation && health->hp > 0) {
|
if (hasAnimation && health->hp > 0) {
|
||||||
// Still alive, just play hurt anim
|
// Still alive, just play hurt anim
|
||||||
|
|||||||
@@ -127,6 +127,8 @@ void setupSystems() {
|
|||||||
ECS_SYSTEM(ECS, updateEasingSystem, EcsOnUpdate, Easing, Position, HitBox, Rotation);
|
ECS_SYSTEM(ECS, updateEasingSystem, EcsOnUpdate, Easing, Position, HitBox, Rotation);
|
||||||
|
|
||||||
ECS_SYSTEM(ECS, renderHealthBar, EcsOnUpdate, Position, HitBox, Health);
|
ECS_SYSTEM(ECS, renderHealthBar, EcsOnUpdate, Position, HitBox, Health);
|
||||||
|
ECS_SYSTEM(ECS, renderFloatyTextParticle, EcsOnUpdate, FloatyTextParticle);
|
||||||
|
|
||||||
ECS_SYSTEM(ECS, renderDebugPath, EcsOnUpdate, Path);
|
ECS_SYSTEM(ECS, renderDebugPath, EcsOnUpdate, Path);
|
||||||
|
|
||||||
ECS_SYSTEM(ECS, renderColliders, EcsOnUpdate, Position, HitBox);
|
ECS_SYSTEM(ECS, renderColliders, EcsOnUpdate, Position, HitBox);
|
||||||
|
|||||||
@@ -37,6 +37,12 @@ void setAIBehaviour(ecs_entity_t entity, const BzBTNode *root,
|
|||||||
* Animation Systems
|
* Animation Systems
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 0: Game (singleton for Font)
|
||||||
|
* 1: FloatyTextParticle
|
||||||
|
*/
|
||||||
|
void renderFloatyTextParticle(ecs_iter_t *it);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 1: ParticleEmitter
|
* 1: ParticleEmitter
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user