Add fireball particles, add max lifespan to fireball

This commit is contained in:
2024-02-10 11:39:01 +01:00
parent 1c6fab51c6
commit 1487d67a3b
5 changed files with 57 additions and 38 deletions

View File

@@ -174,11 +174,13 @@ ecs_entity_t placeBuilding(Game *game, BuildingType type,
ecs_set(ECS, building, AttachedEntity, {mage}); ecs_set(ECS, building, AttachedEntity, {mage});
ecs_set(ECS, building, Tower, { ecs_set(ECS, building, Tower, {
.range = 46.0f, .range = 46.0f,
.minDamage = 40.0f, .projMinDamage = 40.0f,
.maxDamage = 80.0f, .projMaxDamage = 80.0f,
.projectileSpeed = 100.0f, .projMinLifespan = 2.6f,
.projectileRadius = 4.0f, .projMaxLifespan = 3.2f,
.projectileDamageCount = 3, .projSpeed = 100.0f,
.projRadius = 4.0f,
.projDamageCount = 3,
.fireCooldown = 1.2f, .fireCooldown = 1.2f,
.fireElapsed = 0.0f, .fireElapsed = 0.0f,
}); });

View File

@@ -96,6 +96,26 @@ typedef struct ParticleEmitter {
} ParticleEmitter; } ParticleEmitter;
extern ECS_COMPONENT_DECLARE(ParticleEmitter); extern ECS_COMPONENT_DECLARE(ParticleEmitter);
static ParticleEmitter GET_FIREBALL_EMITTER() {
return (ParticleEmitter) {
.emitterLifetime = 2.0f,
.data.minOffset = { -2.0f, -2.0f },
.data.maxOffset = { 2.0f, 2.0f },
.data.emmitRate = 1.2f,
.data.emmitVariance = 1.0f,
.data.emmitVarianceMin = 0.0f,
.data.emmitVarianceMax = 1.0f,
.data.startColor = { 210, 0, 0, 210 },
.data.endColor = { 110, 10, 10, 110 },
.data.minLifetime = 1.0f,
.data.maxLifetime = 2.2f,
.data.minStartSize = 4.0f,
.data.maxStartSize = 6.0f,
.data.tileID = getParticleTypeTile(PARTICLE_CIRCLE),
.data.blend = BLEND_ADDITIVE
};
}
typedef struct Particle { typedef struct Particle {
Vector2 pos; Vector2 pos;
f32 rotation; f32 rotation;
@@ -278,11 +298,13 @@ extern ECS_COMPONENT_DECLARE(Unit);
typedef struct Tower { typedef struct Tower {
f32 range; f32 range;
f32 minDamage; f32 projMinDamage;
f32 maxDamage; f32 projMaxDamage;
f32 projectileSpeed; f32 projMinLifespan;
f32 projectileRadius; f32 projMaxLifespan;
i32 projectileDamageCount; f32 projSpeed;
f32 projRadius;
i32 projDamageCount;
f32 fireCooldown; f32 fireCooldown;
f32 fireElapsed; f32 fireElapsed;
} Tower; } Tower;

View File

@@ -570,23 +570,9 @@ static void renderGame(Game *game, float dt) {
InputState *input = ecs_singleton_get_mut(ECS, InputState); InputState *input = ecs_singleton_get_mut(ECS, InputState);
if (IsKeyReleased(KEY_SPACE)) { if (IsKeyReleased(KEY_SPACE)) {
ParticleEmitter emitter = { ParticleEmitter emitter = GET_FIREBALL_EMITTER();
.emitterLifetime = 2.0f, emitter.pos = input->mouseWorld;
.targetParticles = ecs_id(ParticleLayer1), emitter.targetParticles = ecs_id(ParticleLayer1);
.data.emmitRate = 1.2f,
.data.emmitVariance = 1.0f,
.data.emmitVarianceMin = 0.0f,
.data.emmitVarianceMax = 1.0f,
.pos = input->mouseWorld,
.data.startColor = { 210, 0, 0, 210 },
.data.endColor = { 110, 10, 10, 110 },
.data.minLifetime = 1.0f,
.data.maxLifetime = 2.2f,
.data.minStartSize = 4.0f,
.data.maxStartSize = 6.0f,
.data.tileID = getParticleTypeTile(PARTICLE_CIRCLE),
.data.blend = BLEND_ADDITIVE
};
ecs_entity_t e = entityCreateEmpty(); ecs_entity_t e = entityCreateEmpty();
ecs_set_ptr(ECS, e, ParticleEmitter, &emitter); ecs_set_ptr(ECS, e, ParticleEmitter, &emitter);

View File

@@ -58,11 +58,13 @@ void updateParticleEmitter(ecs_iter_t *it) {
ecs_entity_t entity = it->entities[i]; ecs_entity_t entity = it->entities[i];
if (ecs_has(ECS, entity, EmitterAttachment)) { if (ecs_has(ECS, entity, EmitterAttachment)) {
EmitterAttachment attachment = *ecs_get(ECS, entity, EmitterAttachment); EmitterAttachment attachment = *ecs_get(ECS, entity, EmitterAttachment);
if (ecs_is_alive(ECS, attachment.baseEntity)) { if (!ecs_is_alive(ECS, attachment.baseEntity)) {
Vector2 pos = *ecs_get(ECS, entity, Position); ecs_delete(ECS, attachment.baseEntity);
pos = Vector2Add(pos, attachment.offset); continue;
emitter[i].pos = pos;
} }
Vector2 pos = *ecs_get(ECS, attachment.baseEntity, Position);
pos = Vector2Add(pos, attachment.offset);
emitter[i].pos = pos;
} }
const struct ParticleEmitterData data = emitter[i].data; const struct ParticleEmitterData data = emitter[i].data;

View File

@@ -376,19 +376,29 @@ void updateTower(ecs_iter_t *it) {
Vector2 dir = Vector2Subtract(targetPos, center); Vector2 dir = Vector2Subtract(targetPos, center);
dir = Vector2Normalize(dir); dir = Vector2Normalize(dir);
dir = Vector2Scale(dir, tower[i].projectileSpeed); dir = Vector2Scale(dir, tower[i].projSpeed);
ecs_entity_t proj = entityCreateEmpty(); ecs_entity_t proj = entityCreateEmpty();
ecs_set(ECS, proj, Position, { center.x, center.y }); ecs_set(ECS, proj, Position, { center.x, center.y });
ecs_set(ECS, proj, Velocity, { dir.x, dir.y }); ecs_set(ECS, proj, Velocity, { dir.x, dir.y });
ecs_set(ECS, proj, Projectile, { ecs_set(ECS, proj, Projectile, {
.damage = randFloatRange(tower[i].minDamage, tower[i].maxDamage), .damage = randFloatRange(tower[i].projMinDamage, tower[i].projMaxDamage),
.target = targetPos, .target = targetPos,
.radius = tower[i].projectileRadius, .radius = tower[i].projRadius,
.damageCount = tower[i].projectileDamageCount .damageCount = tower[i].projDamageCount
}); });
ecs_set(ECS, proj, Owner, { owner[i].player }); ecs_set(ECS, proj, Owner, { owner[i].player });
f32 lifespan = randFloatRange(tower[i].projMinLifespan, tower[i].projMaxLifespan);
ecs_set(ECS, proj, DelayDelete, { .time = lifespan });
ecs_entity_t projEmitter = entityCreateEmpty();
ParticleEmitter emitter = GET_FIREBALL_EMITTER();
emitter.targetParticles = ecs_id(ParticleLayer1);
emitter.pos = center;
ecs_set_ptr(ECS, projEmitter, ParticleEmitter, &emitter);
ecs_set(ECS, projEmitter, EmitterAttachment, { .baseEntity = proj });
tower[i].fireElapsed = 0.0f; tower[i].fireElapsed = 0.0f;
} }
@@ -453,9 +463,6 @@ void updateProjectile(ecs_iter_t *it) {
continue; continue;
} }
DrawRectangleV((Vector2) {bounds.x, bounds.y}, (Vector2) {bounds.width, bounds.height},
RED);
pos[i] = Vector2Add(pos[i], Vector2Scale(vel[i], dt)); pos[i] = Vector2Add(pos[i], Vector2Scale(vel[i], dt));
if (pos[i].x < 0.0f || pos[i].y < 0.0f || if (pos[i].x < 0.0f || pos[i].y < 0.0f ||
pos[i].x >= game->map.width * game->map.tileWidth || pos[i].x >= game->map.width * game->map.tileWidth ||