Add particles!
This commit is contained in:
BIN
assets/game.png
BIN
assets/game.png
Binary file not shown.
|
Before Width: | Height: | Size: 440 KiB After Width: | Height: | Size: 441 KiB |
File diff suppressed because one or more lines are too long
@@ -8,6 +8,11 @@ ECS_COMPONENT_DECLARE(Resource);
|
|||||||
|
|
||||||
ECS_COMPONENT_DECLARE(Owner);
|
ECS_COMPONENT_DECLARE(Owner);
|
||||||
|
|
||||||
|
ECS_COMPONENT_DECLARE(EmitterAttachment);
|
||||||
|
ECS_COMPONENT_DECLARE(ParticleEmitter);
|
||||||
|
ECS_COMPONENT_DECLARE(ParticleLayer0);
|
||||||
|
ECS_COMPONENT_DECLARE(ParticleLayer1);
|
||||||
|
|
||||||
ECS_COMPONENT_DECLARE(SpatialGridID);
|
ECS_COMPONENT_DECLARE(SpatialGridID);
|
||||||
ECS_COMPONENT_DECLARE(Position);
|
ECS_COMPONENT_DECLARE(Position);
|
||||||
ECS_COMPONENT_DECLARE(Size);
|
ECS_COMPONENT_DECLARE(Size);
|
||||||
@@ -50,6 +55,11 @@ void initComponentIDs(ecs_world_t *ecs) {
|
|||||||
|
|
||||||
ECS_COMPONENT_DEFINE(ecs, Owner);
|
ECS_COMPONENT_DEFINE(ecs, Owner);
|
||||||
|
|
||||||
|
ECS_COMPONENT_DEFINE(ecs, EmitterAttachment);
|
||||||
|
ECS_COMPONENT_DEFINE(ecs, ParticleEmitter);
|
||||||
|
ECS_COMPONENT_DEFINE(ecs, ParticleLayer0);
|
||||||
|
ECS_COMPONENT_DEFINE(ecs, ParticleLayer1);
|
||||||
|
|
||||||
ECS_COMPONENT_DEFINE(ecs, SpatialGridID);
|
ECS_COMPONENT_DEFINE(ecs, SpatialGridID);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Position);
|
ECS_COMPONENT_DEFINE(ecs, Position);
|
||||||
ECS_COMPONENT_DEFINE(ecs, Size);
|
ECS_COMPONENT_DEFINE(ecs, Size);
|
||||||
|
|||||||
@@ -37,7 +37,69 @@ typedef struct Owner {
|
|||||||
} Owner;
|
} Owner;
|
||||||
extern ECS_COMPONENT_DECLARE(Owner);
|
extern ECS_COMPONENT_DECLARE(Owner);
|
||||||
|
|
||||||
|
/**********************************************************
|
||||||
|
* Particle components
|
||||||
|
*********************************************************/
|
||||||
|
|
||||||
|
typedef struct EmitterAttachment {
|
||||||
|
ecs_entity_t baseEntity;
|
||||||
|
Vector2 offset;
|
||||||
|
} EmitterAttachment;
|
||||||
|
extern ECS_COMPONENT_DECLARE(EmitterAttachment);
|
||||||
|
typedef struct ParticleEmitter {
|
||||||
|
f32 emitterElapsed;
|
||||||
|
f32 emitterLifetime;
|
||||||
|
Vector2 pos;
|
||||||
|
|
||||||
|
struct ParticleEmitterData {
|
||||||
|
// offset
|
||||||
|
Vector2 minOffset, maxOffset;
|
||||||
|
// startVel
|
||||||
|
Vector2 minStartVel, maxStartVel;
|
||||||
|
// endVel
|
||||||
|
Vector2 minEndVel, maxEndVel;
|
||||||
|
// startSize
|
||||||
|
f32 minStartSize, maxStartSize;
|
||||||
|
// endSize
|
||||||
|
f32 minEndSize, maxEndSize;
|
||||||
|
// startRotSpeed
|
||||||
|
f32 minStartRotSpeed, maxStartRotSpeed;
|
||||||
|
// endRotSpeed
|
||||||
|
f32 minEndRotSpeed, maxEndRotSpeed;
|
||||||
|
// startColor
|
||||||
|
Color minStartColor, maxStartColor;
|
||||||
|
// endColor
|
||||||
|
Color minEndColor, maxEndColor;
|
||||||
|
// lifetime
|
||||||
|
f32 minLifetime, maxLifetime;
|
||||||
|
|
||||||
|
BlendMode blend;
|
||||||
|
BzTileID tileID;
|
||||||
|
} data;
|
||||||
|
|
||||||
|
ecs_entity_t targetParticles; // ParticleLayer0 / ParticleLayer1
|
||||||
|
} ParticleEmitter;
|
||||||
|
extern ECS_COMPONENT_DECLARE(ParticleEmitter);
|
||||||
|
|
||||||
|
typedef struct Particle {
|
||||||
|
Vector2 pos;
|
||||||
|
f32 rotation;
|
||||||
|
const Vector2 startVel, endVel;
|
||||||
|
const f32 startSize, endSize;
|
||||||
|
const f32 startRotSpeed, endRotSpeed;
|
||||||
|
const Color startColor, endColor;
|
||||||
|
const BlendMode blend: 8;
|
||||||
|
const BzTileID tileID: 24;
|
||||||
|
const f32 lifetime;
|
||||||
|
f32 elapsed;
|
||||||
|
} Particle;
|
||||||
|
static_assert(sizeof(Particle) == 64, "");
|
||||||
|
|
||||||
|
// 2 Separate components (Before entity, After entity), so we don't need to sort
|
||||||
|
typedef Particle ParticleLayer0, ParticleLayer1;
|
||||||
|
|
||||||
|
extern ECS_COMPONENT_DECLARE(ParticleLayer0);
|
||||||
|
extern ECS_COMPONENT_DECLARE(ParticleLayer1);
|
||||||
|
|
||||||
/**********************************************************
|
/**********************************************************
|
||||||
* Movement components
|
* Movement components
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ typedef struct Game {
|
|||||||
f32 elapsed;
|
f32 elapsed;
|
||||||
|
|
||||||
ecs_query_t *drawQuery;
|
ecs_query_t *drawQuery;
|
||||||
|
ecs_query_t *particles0Query;
|
||||||
|
ecs_query_t *particles1Query;
|
||||||
} Game;
|
} Game;
|
||||||
|
|
||||||
extern ecs_world_t *ECS;
|
extern ecs_world_t *ECS;
|
||||||
|
|||||||
@@ -34,6 +34,45 @@ static OwnerType getOwnerType(BzTileID tile) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef enum ParticleType {
|
||||||
|
PARTICLE_NONE = -1,
|
||||||
|
PARTICLE_CIRCLE,
|
||||||
|
PARTICLE_SMALL_SQUARE,
|
||||||
|
PARTICLE_SQUARE,
|
||||||
|
PARTICLE_COUNT,
|
||||||
|
} ParticleType;
|
||||||
|
|
||||||
|
static BzTileID getParticleTypeTile(ParticleType type) {
|
||||||
|
switch (type) {
|
||||||
|
case PARTICLE_SQUARE: return 1559;
|
||||||
|
case PARTICLE_CIRCLE: return 1560;
|
||||||
|
case PARTICLE_SMALL_SQUARE: return 1561;
|
||||||
|
default: return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ParticleType getParticleType(BzTileID tile) {
|
||||||
|
switch (tile) {
|
||||||
|
case 1559:
|
||||||
|
return PARTICLE_SQUARE;
|
||||||
|
case 1560:
|
||||||
|
return PARTICLE_CIRCLE;
|
||||||
|
case 1561:
|
||||||
|
return PARTICLE_SMALL_SQUARE;
|
||||||
|
default:
|
||||||
|
return PARTICLE_COUNT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *getParticleTypeStr(ParticleType type) {
|
||||||
|
switch (type) {
|
||||||
|
case PARTICLE_SQUARE: return "square";
|
||||||
|
case PARTICLE_CIRCLE: return "circle";
|
||||||
|
case PARTICLE_SMALL_SQUARE: return "small_square";
|
||||||
|
default: return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typedef enum TerrainType {
|
typedef enum TerrainType {
|
||||||
TERRAIN_NONE = -1,
|
TERRAIN_NONE = -1,
|
||||||
TERRAIN_GOLD_ORE,
|
TERRAIN_GOLD_ORE,
|
||||||
|
|||||||
78
game/main.c
78
game/main.c
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "pathfinding.h"
|
#include "pathfinding.h"
|
||||||
#include "sounds.h"
|
#include "sounds.h"
|
||||||
|
#include "entity_factory.h"
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
const char *GAME_DATA_SAVE_PATH = "game_data.ini";
|
const char *GAME_DATA_SAVE_PATH = "game_data.ini";
|
||||||
@@ -192,6 +193,12 @@ bool init(void *userData) {
|
|||||||
{ ecs_id(TextureRegion) }
|
{ ecs_id(TextureRegion) }
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
game->particles0Query = ecs_query(ECS, {
|
||||||
|
.filter.terms = { { ecs_id(ParticleLayer0) } }
|
||||||
|
});
|
||||||
|
game->particles1Query = ecs_query(ECS, {
|
||||||
|
.filter.terms = { { ecs_id(ParticleLayer1) } }
|
||||||
|
});
|
||||||
|
|
||||||
{
|
{
|
||||||
ECS_COMPONENT_DEFINE(ECS, InputState);
|
ECS_COMPONENT_DEFINE(ECS, InputState);
|
||||||
@@ -354,6 +361,8 @@ void deinit(void *userData) {
|
|||||||
// Destroy queries
|
// Destroy queries
|
||||||
ecs_query_fini(input->queries.selected);
|
ecs_query_fini(input->queries.selected);
|
||||||
ecs_query_fini(game->drawQuery);
|
ecs_query_fini(game->drawQuery);
|
||||||
|
ecs_query_fini(game->particles0Query);
|
||||||
|
ecs_query_fini(game->particles1Query);
|
||||||
|
|
||||||
Game gameCopy = *game;
|
Game gameCopy = *game;
|
||||||
InputState inputCopy = *input;
|
InputState inputCopy = *input;
|
||||||
@@ -530,6 +539,22 @@ static void renderGame(Game *game, float dt) {
|
|||||||
DrawTexturePro(tex, draw.src, draw.dst, draw.origin, draw.rotation, c);
|
DrawTexturePro(tex, draw.src, draw.dst, draw.origin, draw.rotation, c);
|
||||||
}
|
}
|
||||||
bzTileMapClearCollisionLayer(&game->map, COLL_LAYER_TRANSPARENCY);
|
bzTileMapClearCollisionLayer(&game->map, COLL_LAYER_TRANSPARENCY);
|
||||||
|
|
||||||
|
// Draw particle layer 1
|
||||||
|
it = ecs_query_iter(ECS, game->particles1Query);
|
||||||
|
ecs_defer_begin(ECS);
|
||||||
|
while (ecs_iter_next(&it)) {
|
||||||
|
Particle *particle = ecs_field(&it, Particle, 1);
|
||||||
|
for (i32 i = 0; i < it.count; i++) {
|
||||||
|
DrawCircleV(particle[i].pos, 2.0f, RED);
|
||||||
|
if (updateParticle(tex, &particle[i], dt))
|
||||||
|
ecs_delete(ECS, it.entities[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ecs_defer_end(ECS);
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
Vector2 target = GetMousePosition();
|
Vector2 target = GetMousePosition();
|
||||||
target = GetScreenToWorld2D(target, game->camera);
|
target = GetScreenToWorld2D(target, game->camera);
|
||||||
static f32 elapsed = 0;
|
static f32 elapsed = 0;
|
||||||
@@ -543,7 +568,6 @@ static void renderGame(Game *game, float dt) {
|
|||||||
elapsed += dt * 2;
|
elapsed += dt * 2;
|
||||||
elapsed = Clamp(elapsed, 0, 1.0f);
|
elapsed = Clamp(elapsed, 0, 1.0f);
|
||||||
attack = false;
|
attack = false;
|
||||||
#if 0
|
|
||||||
if (worker && false) {
|
if (worker && false) {
|
||||||
Position *pos = ecs_get_mut(ECS, worker, Position);
|
Position *pos = ecs_get_mut(ECS, worker, Position);
|
||||||
DrawCircle(pos->x, pos->y, 2.0f, BLUE);
|
DrawCircle(pos->x, pos->y, 2.0f, BLUE);
|
||||||
@@ -709,6 +733,58 @@ void imguiRender(float dt, void *userData) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
igText("Input state: %s", inputState);
|
igText("Input state: %s", inputState);
|
||||||
|
if (igCollapsingHeader_TreeNodeFlags("ParticleEditor", 0)) {
|
||||||
|
static ParticleEmitter emitter = {0.0f};
|
||||||
|
emitter.data.tileID = getParticleTypeTile(PARTICLE_CIRCLE);
|
||||||
|
emitter.data.blend = BLEND_ADDITIVE;
|
||||||
|
struct ParticleEmitterData *data = &emitter.data;
|
||||||
|
igSliderFloat2("Pos", &emitter.pos.x, 0.0f, 1000.0f, "%.2f", 0);
|
||||||
|
igSliderFloat2("minOffset", &data->minOffset.x, -50.0f, 50.0f, "%.2f", 0);
|
||||||
|
igSliderFloat2("maxOffset", &data->maxOffset.x, -50.0f, 50.0f, "%.2f", 0);
|
||||||
|
|
||||||
|
igSliderFloat2("minStartVel", &data->minStartVel.x, -50.0f, 50.0f, "%.2f", 0);
|
||||||
|
igSliderFloat2("maxStartVel", &data->maxStartVel.x, -50.0f, 50.0f, "%.2f", 0);
|
||||||
|
|
||||||
|
igSliderFloat2("minEndVel", &data->minEndVel.x, -50.0f, 50.0f, "%.2f", 0);
|
||||||
|
igSliderFloat2("maxEndVel", &data->maxEndVel.x, -50.0f, 50.0f, "%.2f", 0);
|
||||||
|
|
||||||
|
igSliderFloat("minStartSize", &data->minStartSize, -50.0f, 50.0f, "%.2f", 0);
|
||||||
|
igSliderFloat("maxStartSize", &data->maxStartSize, -50.0f, 50.0f, "%.2f", 0);
|
||||||
|
|
||||||
|
igSliderFloat("minEndSize", &data->minEndSize, -50.0f, 50.0f, "%.2f", 0);
|
||||||
|
igSliderFloat("maxEndSize", &data->maxEndSize, -50.0f, 50.0f, "%.2f", 0);
|
||||||
|
|
||||||
|
igSliderFloat("minStartRotSpeed", &data->minStartRotSpeed, -50.0f, 50.0f, "%.2f", 0);
|
||||||
|
igSliderFloat("maxStartRotSpeed", &data->maxStartRotSpeed, -50.0f, 50.0f, "%.2f", 0);
|
||||||
|
|
||||||
|
igSliderFloat("minEndRotSpeed", &data->minEndRotSpeed, -50.0f, 50.0f, "%.2f", 0);
|
||||||
|
igSliderFloat("maxEndRotSpeed", &data->maxEndRotSpeed, -50.0f, 50.0f, "%.2f", 0);
|
||||||
|
|
||||||
|
#define igColor(label, color) \
|
||||||
|
do { \
|
||||||
|
\
|
||||||
|
float cols[4] = { color.r / 255.0f, color.g / 255.0f, \
|
||||||
|
color.b / 255.0f, color.a / 255.0f }; \
|
||||||
|
igColorEdit4(label, cols, 0); \
|
||||||
|
color.r = cols[0] * 255.0f; \
|
||||||
|
color.g = cols[1] * 255.0f; \
|
||||||
|
color.b = cols[2] * 255.0f; \
|
||||||
|
color.a = cols[3] * 255.0f; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
|
igColor("minStartColor", data->minStartColor);
|
||||||
|
igColor("maxStartColor", data->maxStartColor);
|
||||||
|
igColor("minEndColor", data->minEndColor);
|
||||||
|
igColor("maxEndColor", data->maxEndColor);
|
||||||
|
#undef igColor
|
||||||
|
|
||||||
|
igSliderFloat("minLifetime", &data->minLifetime, 0.0f, 6.0f, "%.2f", 0);
|
||||||
|
igSliderFloat("maxLifetime", &data->maxLifetime, 0.0f, 6.0f, "%.2f", 0);
|
||||||
|
Particle particle = spawnParticle(&emitter);
|
||||||
|
ecs_entity_t e = entityCreateEmpty();
|
||||||
|
ecs_set_ptr(ECS, e, ParticleLayer1, &particle);
|
||||||
|
}
|
||||||
if (igCollapsingHeader_TreeNodeFlags("Selection", 0)) {
|
if (igCollapsingHeader_TreeNodeFlags("Selection", 0)) {
|
||||||
switch (input->state) {
|
switch (input->state) {
|
||||||
case INPUT_SELECTED_UNITS:
|
case INPUT_SELECTED_UNITS:
|
||||||
|
|||||||
@@ -3,6 +3,109 @@
|
|||||||
#include "../game_state.h"
|
#include "../game_state.h"
|
||||||
|
|
||||||
#include <raymath.h>
|
#include <raymath.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void updateParticleEmitter(ecs_iter_t *it) {
|
||||||
|
ParticleEmitter *emitter = ecs_field(it, ParticleEmitter, 1);
|
||||||
|
f32 dt = GetFrameTime();
|
||||||
|
|
||||||
|
for (i32 i = 0; i < it->count; i++) {
|
||||||
|
ecs_entity_t entity = it->entities[i];
|
||||||
|
if (ecs_has(ECS, entity, EmitterAttachment)) {
|
||||||
|
EmitterAttachment attachment = *ecs_get(ECS, entity, EmitterAttachment);
|
||||||
|
if (!ecs_is_alive(ECS, attachment.baseEntity)) {
|
||||||
|
ecs_delete(ECS, entity);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Vector2 pos = *ecs_get(ECS, entity, Position);
|
||||||
|
pos = Vector2Add(pos, attachment.offset);
|
||||||
|
emitter->pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
emitter[i].emitterElapsed += dt;
|
||||||
|
if (emitter[i].emitterElapsed >= emitter[i].emitterLifetime)
|
||||||
|
ecs_delete(ECS, entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
f32 alpha = particle->elapsed / particle->lifetime;
|
||||||
|
|
||||||
|
Vector2 vel = Vector2Lerp(particle->startVel, particle->endVel, alpha);
|
||||||
|
f32 size = Lerp(particle->startSize, particle->endSize, alpha);
|
||||||
|
f32 rot = Lerp(particle->startRotSpeed, particle->endRotSpeed, alpha);
|
||||||
|
Color startC = particle->startColor;
|
||||||
|
Color endC = particle->endColor;
|
||||||
|
Color color = {
|
||||||
|
.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);
|
||||||
|
f32 hSize = size * 0.5f;
|
||||||
|
Vector2 center = particle->pos;
|
||||||
|
Rectangle src = getTextureRect(particle->tileID);
|
||||||
|
src.x += 0.1f;
|
||||||
|
src.y += 0.1f;
|
||||||
|
src.width -= 0.2f;
|
||||||
|
src.height -= 0.2f;
|
||||||
|
DrawTexturePro(tex, src, (Rectangle) {
|
||||||
|
center.x,
|
||||||
|
center.y,
|
||||||
|
size, size
|
||||||
|
}, (Vector2) {hSize, hSize}, rot, color);
|
||||||
|
//EndBlendMode();
|
||||||
|
|
||||||
|
particle->pos = Vector2Add(particle->pos, Vector2Scale(vel, dt));
|
||||||
|
particle->elapsed += dt;
|
||||||
|
return alpha >= 1.0f;
|
||||||
|
}
|
||||||
|
// https://stackoverflow.com/questions/13408990/how-to-generate-random-float-number-in-c
|
||||||
|
static inline f32 randFloatRange(f32 min, f32 max) {
|
||||||
|
float scale = rand() / (float) RAND_MAX; /* [0, 1.0] */
|
||||||
|
return min + scale * ( max - min ); /* [min, max] */
|
||||||
|
}
|
||||||
|
static inline Vector2 randVector2Range(Vector2 from, Vector2 to) {
|
||||||
|
return (Vector2) {
|
||||||
|
randFloatRange(from.x, to.x),
|
||||||
|
randFloatRange(from.y, to.y)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
static inline Color randColorRange(Color from, Color to) {
|
||||||
|
return (Color) {
|
||||||
|
.r = GetRandomValue(from.r, to.r),
|
||||||
|
.g = GetRandomValue(from.g, to.g),
|
||||||
|
.b = GetRandomValue(from.b, to.b),
|
||||||
|
.a = GetRandomValue(from.a, to.a),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
Particle spawnParticle(const ParticleEmitter *emitter) {
|
||||||
|
const struct ParticleEmitterData *data = &emitter->data;
|
||||||
|
return (Particle) {
|
||||||
|
.pos = Vector2Add(emitter->pos, randVector2Range(data->minOffset, data->maxOffset)),
|
||||||
|
.rotation = 0.0f,
|
||||||
|
.startVel = randVector2Range(data->minStartVel, data->maxStartVel),
|
||||||
|
.endVel = randVector2Range(data->minEndVel, data->maxEndVel),
|
||||||
|
.startSize = randFloatRange(data->minStartSize, data->maxStartSize),
|
||||||
|
.endSize = randFloatRange(data->minEndSize, data->maxEndSize),
|
||||||
|
.startRotSpeed = randFloatRange(data->minStartRotSpeed, data->maxStartRotSpeed),
|
||||||
|
.endRotSpeed = randFloatRange(data->minEndRotSpeed, data->maxEndRotSpeed),
|
||||||
|
.startColor = randColorRange(data->minStartColor, data->maxStartColor),
|
||||||
|
.endColor = randColorRange(data->minEndColor, data->maxEndColor),
|
||||||
|
.blend = data->blend,
|
||||||
|
.tileID = data->tileID,
|
||||||
|
.elapsed = 0.0f,
|
||||||
|
.lifetime = randFloatRange(data->minLifetime, data->maxLifetime),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
void updateAnimationState(ecs_iter_t *it) {
|
void updateAnimationState(ecs_iter_t *it) {
|
||||||
Animation *anim = ecs_field(it, Animation, 1);
|
Animation *anim = ecs_field(it, Animation, 1);
|
||||||
|
|||||||
@@ -32,6 +32,14 @@ void setAIBehaviour(ecs_entity_t entity, const BzBTNode *root,
|
|||||||
* Animation Systems
|
* Animation Systems
|
||||||
**********************************/
|
**********************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 1: ParticleEmitter
|
||||||
|
*/
|
||||||
|
void updateParticleEmitter(ecs_iter_t *it);
|
||||||
|
|
||||||
|
bool updateParticle(const Texture2D tex, Particle *particle, f32 dt);
|
||||||
|
|
||||||
|
Particle spawnParticle(const ParticleEmitter *emitter);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* 1: Animation
|
* 1: Animation
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 440 KiB After Width: | Height: | Size: 441 KiB |
@@ -2411,6 +2411,36 @@
|
|||||||
"value":""
|
"value":""
|
||||||
}]
|
}]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id":1559,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"particle",
|
||||||
|
"type":"string",
|
||||||
|
"value":""
|
||||||
|
}],
|
||||||
|
"type":"square"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":1560,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"particle",
|
||||||
|
"type":"string",
|
||||||
|
"value":""
|
||||||
|
}],
|
||||||
|
"type":"circle"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":1561,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"particle",
|
||||||
|
"type":"string",
|
||||||
|
"value":""
|
||||||
|
}],
|
||||||
|
"type":"small_square"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"animation":[
|
"animation":[
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1108,6 +1108,21 @@
|
|||||||
<property name="terrain" value=""/>
|
<property name="terrain" value=""/>
|
||||||
</properties>
|
</properties>
|
||||||
</tile>
|
</tile>
|
||||||
|
<tile id="1559" type="square">
|
||||||
|
<properties>
|
||||||
|
<property name="particle" value=""/>
|
||||||
|
</properties>
|
||||||
|
</tile>
|
||||||
|
<tile id="1560" type="circle">
|
||||||
|
<properties>
|
||||||
|
<property name="particle" value=""/>
|
||||||
|
</properties>
|
||||||
|
</tile>
|
||||||
|
<tile id="1561" type="small_square">
|
||||||
|
<properties>
|
||||||
|
<property name="particle" value=""/>
|
||||||
|
</properties>
|
||||||
|
</tile>
|
||||||
<tile id="1563" type="mage">
|
<tile id="1563" type="mage">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="animation" value="idle"/>
|
<property name="animation" value="idle"/>
|
||||||
|
|||||||
Binary file not shown.
@@ -41,6 +41,7 @@ building_tiles = extract_by_property(all_tiles, "building")
|
|||||||
entity_tiles = extract_by_property(all_tiles, "entity")
|
entity_tiles = extract_by_property(all_tiles, "entity")
|
||||||
item_tiles = extract_by_property(all_tiles, "item")
|
item_tiles = extract_by_property(all_tiles, "item")
|
||||||
ownership_tiles = extract_by_property(all_tiles, "ownership")
|
ownership_tiles = extract_by_property(all_tiles, "ownership")
|
||||||
|
particle_tiles = extract_by_property(all_tiles, "particle")
|
||||||
|
|
||||||
writer.header_guard_start()
|
writer.header_guard_start()
|
||||||
script_name = os.path.basename(__file__)
|
script_name = os.path.basename(__file__)
|
||||||
@@ -56,10 +57,16 @@ terrain_writer = EnumWriter(writer, terrain_tiles, "terrain")
|
|||||||
building_writer = EnumWriter(writer, building_tiles, "building")
|
building_writer = EnumWriter(writer, building_tiles, "building")
|
||||||
entity_writer = EnumWriter(writer, entity_tiles, "entity")
|
entity_writer = EnumWriter(writer, entity_tiles, "entity")
|
||||||
ownership_writer = EnumWriter(writer, ownership_tiles, "owner")
|
ownership_writer = EnumWriter(writer, ownership_tiles, "owner")
|
||||||
|
particle_write = EnumWriter(writer, particle_tiles, "particle")
|
||||||
|
|
||||||
ownership_writer.output_enum()
|
ownership_writer.output_enum()
|
||||||
ownership_writer.output_tile_to_enum("getOwnerType")
|
ownership_writer.output_tile_to_enum("getOwnerType")
|
||||||
|
|
||||||
|
particle_write.output_enum()
|
||||||
|
particle_write.output_enum_to_tile("getParticleTypeTile")
|
||||||
|
particle_write.output_tile_to_enum("getParticleType")
|
||||||
|
particle_write.output_enum_to_str("getParticleTypeStr")
|
||||||
|
|
||||||
terrain_writer.output_enum()
|
terrain_writer.output_enum()
|
||||||
terrain_writer.output_tile_has_anim("terrainHasAnimation")
|
terrain_writer.output_tile_has_anim("terrainHasAnimation")
|
||||||
terrain_writer.output_tile_anim_sequence("terrainGetAnimationSequence")
|
terrain_writer.output_tile_anim_sequence("terrainGetAnimationSequence")
|
||||||
|
|||||||
Reference in New Issue
Block a user