Compare commits
5 Commits
dc0fcc381c
...
a8b62f5aec
Author | SHA1 | Date |
---|---|---|
|
a8b62f5aec | |
|
43aa821c18 | |
|
7939b8753e | |
|
ad421d724a | |
|
b01edded42 |
|
@ -43,8 +43,8 @@ int main(void)
|
||||||
DrawTextEx(*fnt, "Press C to play a sound", (Vector2){64, 64}, 24, 1, RED);
|
DrawTextEx(*fnt, "Press C to play a sound", (Vector2){64, 64}, 24, 1, RED);
|
||||||
|
|
||||||
// Draw the static Sprite and animated Sprite
|
// Draw the static Sprite and animated Sprite
|
||||||
draw_sprite(spr, (Vector2){64,128}, false);
|
draw_sprite(spr, (Vector2){64,128}, 0.0f, false);
|
||||||
draw_sprite(spr2, (Vector2){64,180}, true);
|
draw_sprite(spr2, (Vector2){64,180}, 0.0f, true);
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
|
|
||||||
// Update the animated Sprite
|
// Update the animated Sprite
|
||||||
|
|
|
@ -183,6 +183,7 @@ typedef struct Sprite {
|
||||||
Texture2D* texture;
|
Texture2D* texture;
|
||||||
Vector2 frame_size;
|
Vector2 frame_size;
|
||||||
Vector2 origin;
|
Vector2 origin;
|
||||||
|
Vector2 anchor;
|
||||||
int frame_count;
|
int frame_count;
|
||||||
int current_frame;
|
int current_frame;
|
||||||
int elapsed;
|
int elapsed;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include "zstd.h"
|
#include "zstd.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
uint8_t n_loaded[5] = {0};
|
uint8_t n_loaded[6] = {0};
|
||||||
|
|
||||||
// Hard limit number of
|
// Hard limit number of
|
||||||
typedef struct TextureData
|
typedef struct TextureData
|
||||||
|
@ -36,12 +36,18 @@ typedef struct LevelPackData
|
||||||
LevelPack_t pack;
|
LevelPack_t pack;
|
||||||
char name[MAX_NAME_LEN];
|
char name[MAX_NAME_LEN];
|
||||||
}LevelPackData_t;
|
}LevelPackData_t;
|
||||||
|
typedef struct EmitterConfData
|
||||||
|
{
|
||||||
|
EmitterConfig_t conf;
|
||||||
|
char name[MAX_NAME_LEN];
|
||||||
|
}EmitterConfData_t;
|
||||||
|
|
||||||
static TextureData_t textures[MAX_TEXTURES];
|
static TextureData_t textures[MAX_TEXTURES];
|
||||||
static FontData_t fonts[MAX_FONTS];
|
static FontData_t fonts[MAX_FONTS];
|
||||||
static SoundData_t sfx[MAX_SOUNDS];
|
static SoundData_t sfx[MAX_SOUNDS];
|
||||||
static SpriteData_t sprites[MAX_SPRITES];
|
static SpriteData_t sprites[MAX_SPRITES];
|
||||||
static LevelPackData_t levelpacks[MAX_LEVEL_PACK];
|
static LevelPackData_t levelpacks[MAX_LEVEL_PACK];
|
||||||
|
static EmitterConfData_t emitter_confs[MAX_EMITTER_CONF];
|
||||||
|
|
||||||
#define DECOMPRESSOR_INBUF_LEN 4096
|
#define DECOMPRESSOR_INBUF_LEN 4096
|
||||||
#define DECOMPRESSOR_OUTBUF_LEN 4096
|
#define DECOMPRESSOR_OUTBUF_LEN 4096
|
||||||
|
@ -106,7 +112,7 @@ Sprite_t* add_sprite(Assets_t* assets, const char* name, Texture2D* texture)
|
||||||
{
|
{
|
||||||
uint8_t spr_idx = n_loaded[1];
|
uint8_t spr_idx = n_loaded[1];
|
||||||
assert(spr_idx < MAX_SPRITES);
|
assert(spr_idx < MAX_SPRITES);
|
||||||
memset(sprites + spr_idx, 0, sizeof(Sprite_t));
|
memset(sprites + spr_idx, 0, sizeof(SpriteData_t));
|
||||||
sprites[spr_idx].sprite.texture = texture;
|
sprites[spr_idx].sprite.texture = texture;
|
||||||
strncpy(sprites[spr_idx].name, name, MAX_NAME_LEN);
|
strncpy(sprites[spr_idx].name, name, MAX_NAME_LEN);
|
||||||
sc_map_put_s64(&assets->m_sprites, sprites[spr_idx].name, spr_idx);
|
sc_map_put_s64(&assets->m_sprites, sprites[spr_idx].name, spr_idx);
|
||||||
|
@ -136,6 +142,18 @@ Font* add_font(Assets_t* assets, const char* name, const char* path)
|
||||||
return &fonts[fnt_idx].font;
|
return &fonts[fnt_idx].font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EmitterConfig_t* add_emitter_conf(Assets_t* assets, const char* name, Sprite_t* sprite)
|
||||||
|
{
|
||||||
|
uint8_t emitter_idx = n_loaded[5];
|
||||||
|
assert(emitter_idx < MAX_EMITTER_CONF);
|
||||||
|
memset(emitter_confs + emitter_idx, 0, sizeof(EmitterConfData_t));
|
||||||
|
emitter_confs[emitter_idx].conf.spr = sprite;
|
||||||
|
strncpy(emitter_confs[emitter_idx].name, name, MAX_NAME_LEN);
|
||||||
|
sc_map_put_s64(&assets->m_emitter_confs, emitter_confs[emitter_idx].name, emitter_idx);
|
||||||
|
n_loaded[5]++;
|
||||||
|
return &emitter_confs[emitter_idx].conf;
|
||||||
|
}
|
||||||
|
|
||||||
LevelPack_t* add_level_pack(Assets_t* assets, const char* name, const char* path)
|
LevelPack_t* add_level_pack(Assets_t* assets, const char* name, const char* path)
|
||||||
{
|
{
|
||||||
FILE* file = fopen(path, "rb");
|
FILE* file = fopen(path, "rb");
|
||||||
|
@ -165,6 +183,7 @@ LevelPack_t* add_level_pack(Assets_t* assets, const char* name, const char* path
|
||||||
return &levelpacks[pack_idx].pack;
|
return &levelpacks[pack_idx].pack;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static LevelPack_t* add_level_pack_zst(Assets_t* assets, const char* name, FILE* file)
|
static LevelPack_t* add_level_pack_zst(Assets_t* assets, const char* name, FILE* file)
|
||||||
{
|
{
|
||||||
LevelPackData_t* pack_info = levelpacks + n_loaded[4];
|
LevelPackData_t* pack_info = levelpacks + n_loaded[4];
|
||||||
|
@ -338,6 +357,7 @@ void init_assets(Assets_t* assets)
|
||||||
sc_map_init_s64(&assets->m_textures, MAX_TEXTURES, 0);
|
sc_map_init_s64(&assets->m_textures, MAX_TEXTURES, 0);
|
||||||
sc_map_init_s64(&assets->m_sounds, MAX_SOUNDS, 0);
|
sc_map_init_s64(&assets->m_sounds, MAX_SOUNDS, 0);
|
||||||
sc_map_init_s64(&assets->m_levelpacks, MAX_LEVEL_PACK, 0);
|
sc_map_init_s64(&assets->m_levelpacks, MAX_LEVEL_PACK, 0);
|
||||||
|
sc_map_init_s64(&assets->m_emitter_confs, MAX_EMITTER_CONF, 0);
|
||||||
level_decompressor.ctx = ZSTD_createDCtx();
|
level_decompressor.ctx = ZSTD_createDCtx();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -365,6 +385,7 @@ void free_all_assets(Assets_t* assets)
|
||||||
sc_map_clear_s64(&assets->m_sounds);
|
sc_map_clear_s64(&assets->m_sounds);
|
||||||
sc_map_clear_s64(&assets->m_sprites);
|
sc_map_clear_s64(&assets->m_sprites);
|
||||||
sc_map_clear_s64(&assets->m_levelpacks);
|
sc_map_clear_s64(&assets->m_levelpacks);
|
||||||
|
sc_map_clear_s64(&assets->m_emitter_confs);
|
||||||
memset(n_loaded, 0, sizeof(n_loaded));
|
memset(n_loaded, 0, sizeof(n_loaded));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,6 +397,7 @@ void term_assets(Assets_t* assets)
|
||||||
sc_map_term_s64(&assets->m_sounds);
|
sc_map_term_s64(&assets->m_sounds);
|
||||||
sc_map_term_s64(&assets->m_sprites);
|
sc_map_term_s64(&assets->m_sprites);
|
||||||
sc_map_term_s64(&assets->m_levelpacks);
|
sc_map_term_s64(&assets->m_levelpacks);
|
||||||
|
sc_map_term_s64(&assets->m_emitter_confs);
|
||||||
ZSTD_freeDCtx(level_decompressor.ctx);
|
ZSTD_freeDCtx(level_decompressor.ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -399,6 +421,17 @@ Sprite_t* get_sprite(Assets_t* assets, const char* name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
EmitterConfig_t* get_emitter_conf(Assets_t* assets, const char* name)
|
||||||
|
{
|
||||||
|
uint8_t emitter_idx = sc_map_get_s64(&assets->m_emitter_confs, name);
|
||||||
|
if (sc_map_found(&assets->m_emitter_confs))
|
||||||
|
{
|
||||||
|
return &emitter_confs[emitter_idx].conf;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Sound* get_sound(Assets_t* assets, const char* name)
|
Sound* get_sound(Assets_t* assets, const char* name)
|
||||||
{
|
{
|
||||||
uint8_t snd_idx = sc_map_get_s64(&assets->m_sounds, name);
|
uint8_t snd_idx = sc_map_get_s64(&assets->m_sounds, name);
|
||||||
|
@ -429,7 +462,7 @@ LevelPack_t* get_level_pack(Assets_t* assets, const char* name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void draw_sprite(Sprite_t* spr, Vector2 pos, bool flip_x)
|
void draw_sprite(Sprite_t* spr, Vector2 pos, float rotation, bool flip_x)
|
||||||
{
|
{
|
||||||
Rectangle rec = {
|
Rectangle rec = {
|
||||||
spr->origin.x + spr->frame_size.x * spr->current_frame,
|
spr->origin.x + spr->frame_size.x * spr->current_frame,
|
||||||
|
@ -437,5 +470,18 @@ void draw_sprite(Sprite_t* spr, Vector2 pos, bool flip_x)
|
||||||
spr->frame_size.x * (flip_x ? -1:1),
|
spr->frame_size.x * (flip_x ? -1:1),
|
||||||
spr->frame_size.y
|
spr->frame_size.y
|
||||||
};
|
};
|
||||||
DrawTextureRec(*spr->texture, rec, pos, WHITE);
|
//DrawTextureRec(*spr->texture, rec, pos, WHITE);
|
||||||
|
Rectangle dest = {
|
||||||
|
.x = pos.x - spr->anchor.x,
|
||||||
|
.y = pos.y - spr->anchor.y,
|
||||||
|
.width = spr->frame_size.x,
|
||||||
|
.height = spr->frame_size.y
|
||||||
|
};
|
||||||
|
DrawTexturePro(
|
||||||
|
*spr->texture,
|
||||||
|
rec,
|
||||||
|
dest,
|
||||||
|
spr->anchor,
|
||||||
|
rotation, WHITE
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "EC.h"
|
#include "EC.h"
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
#include "rres.h"
|
#include "rres.h"
|
||||||
|
#include "particle_sys.h"
|
||||||
|
|
||||||
typedef struct Assets
|
typedef struct Assets
|
||||||
{
|
{
|
||||||
|
@ -12,6 +13,7 @@ typedef struct Assets
|
||||||
struct sc_map_s64 m_fonts;
|
struct sc_map_s64 m_fonts;
|
||||||
struct sc_map_s64 m_sprites;
|
struct sc_map_s64 m_sprites;
|
||||||
struct sc_map_s64 m_levelpacks;
|
struct sc_map_s64 m_levelpacks;
|
||||||
|
struct sc_map_s64 m_emitter_confs;
|
||||||
}Assets_t;
|
}Assets_t;
|
||||||
|
|
||||||
typedef struct LevelTileInfo
|
typedef struct LevelTileInfo
|
||||||
|
@ -57,14 +59,16 @@ Texture2D* add_texture_rres(Assets_t* assets, const char* name, const char* file
|
||||||
LevelPack_t* add_level_pack_rres(Assets_t* assets, const char* name, const char* filename, const RresFileInfo_t* rres_file);
|
LevelPack_t* add_level_pack_rres(Assets_t* assets, const char* name, const char* filename, const RresFileInfo_t* rres_file);
|
||||||
|
|
||||||
Sprite_t* add_sprite(Assets_t* assets, const char* name, Texture2D* texture);
|
Sprite_t* add_sprite(Assets_t* assets, const char* name, Texture2D* texture);
|
||||||
|
EmitterConfig_t* add_emitter_conf(Assets_t* assets, const char* name, Sprite_t* sprite);
|
||||||
|
|
||||||
Texture2D* get_texture(Assets_t* assets, const char* name);
|
Texture2D* get_texture(Assets_t* assets, const char* name);
|
||||||
Sprite_t* get_sprite(Assets_t* assets, const char* name);
|
Sprite_t* get_sprite(Assets_t* assets, const char* name);
|
||||||
|
EmitterConfig_t* get_emitter_conf(Assets_t* assets, const char* name);
|
||||||
Sound* get_sound(Assets_t* assets, const char* name);
|
Sound* get_sound(Assets_t* assets, const char* name);
|
||||||
Font* get_font(Assets_t* assets, const char* name);
|
Font* get_font(Assets_t* assets, const char* name);
|
||||||
LevelPack_t* get_level_pack(Assets_t* assets, const char* name);
|
LevelPack_t* get_level_pack(Assets_t* assets, const char* name);
|
||||||
|
|
||||||
void draw_sprite(Sprite_t* spr, Vector2 pos, bool flip_x);
|
void draw_sprite(Sprite_t* spr, Vector2 pos, float rotation, bool flip_x);
|
||||||
|
|
||||||
typedef struct SFX
|
typedef struct SFX
|
||||||
{
|
{
|
||||||
|
|
|
@ -94,6 +94,7 @@ void init_scene(Scene_t* scene, system_func_t render_func, action_func_t action_
|
||||||
sc_map_init_64(&scene->action_map, 32, 0);
|
sc_map_init_64(&scene->action_map, 32, 0);
|
||||||
sc_array_init(&scene->systems);
|
sc_array_init(&scene->systems);
|
||||||
init_entity_manager(&scene->ent_manager);
|
init_entity_manager(&scene->ent_manager);
|
||||||
|
init_particle_system(&scene->part_sys);
|
||||||
|
|
||||||
//scene->scene_type = scene_type;
|
//scene->scene_type = scene_type;
|
||||||
scene->render_function = render_func;
|
scene->render_function = render_func;
|
||||||
|
@ -106,6 +107,7 @@ void free_scene(Scene_t* scene)
|
||||||
sc_map_term_64(&scene->action_map);
|
sc_map_term_64(&scene->action_map);
|
||||||
sc_array_term(&scene->systems);
|
sc_array_term(&scene->systems);
|
||||||
free_entity_manager(&scene->ent_manager);
|
free_entity_manager(&scene->ent_manager);
|
||||||
|
deinit_particle_system(&scene->part_sys);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void update_scene(Scene_t* scene)
|
inline void update_scene(Scene_t* scene)
|
||||||
|
@ -115,6 +117,7 @@ inline void update_scene(Scene_t* scene)
|
||||||
{
|
{
|
||||||
sys(scene);
|
sys(scene);
|
||||||
}
|
}
|
||||||
|
update_particle_system(&scene->part_sys);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void render_scene(Scene_t* scene)
|
inline void render_scene(Scene_t* scene)
|
||||||
|
|
|
@ -22,7 +22,6 @@ typedef struct GameEngine {
|
||||||
unsigned int curr_scene;
|
unsigned int curr_scene;
|
||||||
Assets_t assets;
|
Assets_t assets;
|
||||||
SFXList_t sfx_list;
|
SFXList_t sfx_list;
|
||||||
ParticleSystem_t part_sys;
|
|
||||||
// Maintain own queue to handle key presses
|
// Maintain own queue to handle key presses
|
||||||
struct sc_queue_32 key_buffer;
|
struct sc_queue_32 key_buffer;
|
||||||
} GameEngine_t;
|
} GameEngine_t;
|
||||||
|
@ -50,6 +49,7 @@ struct Scene {
|
||||||
EntityManager_t ent_manager;
|
EntityManager_t ent_manager;
|
||||||
//SceneType_t scene_type;
|
//SceneType_t scene_type;
|
||||||
SceneState_t state;
|
SceneState_t state;
|
||||||
|
ParticleSystem_t part_sys;
|
||||||
GameEngine_t *engine;
|
GameEngine_t *engine;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,9 @@
|
||||||
#define MAX_NAME_LEN 32
|
#define MAX_NAME_LEN 32
|
||||||
#define MAX_LEVEL_PACK 4
|
#define MAX_LEVEL_PACK 4
|
||||||
#define N_SFX 18
|
#define N_SFX 18
|
||||||
#define MAX_PARTICLE_CONF 8
|
#define MAX_EMITTER_CONF 8
|
||||||
#define MAX_PARTICLE_EMITTER 16
|
//#define MAX_PARTICLE_EMITTER 8
|
||||||
|
#define MAX_ACTIVE_PARTICLE_EMITTER 32
|
||||||
#define MAX_PARTICLES 10
|
#define MAX_PARTICLES 10
|
||||||
|
|
||||||
#define MAX_TILE_TYPES 16
|
#define MAX_TILE_TYPES 16
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "particle_sys.h"
|
#include "particle_sys.h"
|
||||||
|
#include "assets.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
@ -10,14 +11,16 @@ void init_particle_system(ParticleSystem_t* system)
|
||||||
{
|
{
|
||||||
memset(system, 0, sizeof(ParticleSystem_t));
|
memset(system, 0, sizeof(ParticleSystem_t));
|
||||||
sc_queue_init(&system->free_list);
|
sc_queue_init(&system->free_list);
|
||||||
for ( uint32_t i = 1; i <= MAX_PARTICLE_EMITTER; ++i)
|
for ( uint32_t i = 1; i <= MAX_ACTIVE_PARTICLE_EMITTER; ++i)
|
||||||
{
|
{
|
||||||
sc_queue_add_last(&system->free_list, i);
|
sc_queue_add_last(&system->free_list, i);
|
||||||
}
|
}
|
||||||
system->tail_idx = 0;
|
system->tail_idx = 0;
|
||||||
}
|
}
|
||||||
void add_particle_emitter(ParticleSystem_t* system, const ParticleEmitter_t* in_emitter)
|
void play_particle_emitter(ParticleSystem_t* system, const ParticleEmitter_t* in_emitter)
|
||||||
{
|
{
|
||||||
|
if (in_emitter == NULL) return;
|
||||||
|
|
||||||
if (sc_queue_empty(&system->free_list)) return;
|
if (sc_queue_empty(&system->free_list)) return;
|
||||||
uint32_t idx = sc_queue_del_first(&system->free_list);
|
uint32_t idx = sc_queue_del_first(&system->free_list);
|
||||||
system->emitter_list[system->tail_idx].next = idx;
|
system->emitter_list[system->tail_idx].next = idx;
|
||||||
|
@ -33,24 +36,23 @@ void add_particle_emitter(ParticleSystem_t* system, const ParticleEmitter_t* in_
|
||||||
// Generate particles based on type
|
// Generate particles based on type
|
||||||
for (uint32_t i = 0; i < emitter->n_particles; ++i)
|
for (uint32_t i = 0; i < emitter->n_particles; ++i)
|
||||||
{
|
{
|
||||||
uint32_t lifetime = (emitter->config.particle_lifetime[1] - emitter->config.particle_lifetime[0]);
|
uint32_t lifetime = (emitter->config->particle_lifetime[1] - emitter->config->particle_lifetime[0]);
|
||||||
emitter->particles[i].timer = emitter->config.particle_lifetime[0];
|
emitter->particles[i].timer = emitter->config->particle_lifetime[0];
|
||||||
emitter->particles[i].timer += rand() % lifetime;
|
emitter->particles[i].timer += rand() % lifetime;
|
||||||
emitter->particles[i].alive = true;
|
emitter->particles[i].alive = true;
|
||||||
|
|
||||||
float angle = emitter->config.launch_range[1] - emitter->config.launch_range[0];
|
float angle = emitter->config->launch_range[1] - emitter->config->launch_range[0];
|
||||||
angle *= (float)rand() / (float)RAND_MAX;
|
angle *= (float)rand() / (float)RAND_MAX;
|
||||||
angle += emitter->config.launch_range[0];
|
angle += emitter->config->launch_range[0];
|
||||||
if(angle > 360) angle -= 360;
|
if(angle > 360) angle -= 360;
|
||||||
if(angle < -360) angle += 360;
|
if(angle < -360) angle += 360;
|
||||||
angle *= PI / 180;
|
|
||||||
|
|
||||||
float speed = emitter->config.speed_range[1] - emitter->config.speed_range[0];
|
float speed = emitter->config->speed_range[1] - emitter->config->speed_range[0];
|
||||||
speed *= (float)rand() / (float)RAND_MAX;
|
speed *= (float)rand() / (float)RAND_MAX;
|
||||||
speed += emitter->config.speed_range[0];
|
speed += emitter->config->speed_range[0];
|
||||||
|
|
||||||
emitter->particles[i].velocity.x = speed * cos(angle);
|
emitter->particles[i].velocity.x = speed * cos(angle * PI / 180);
|
||||||
emitter->particles[i].velocity.y = speed * sin(angle);
|
emitter->particles[i].velocity.y = speed * sin(angle * PI / 180);
|
||||||
emitter->particles[i].position = emitter->position;
|
emitter->particles[i].position = emitter->position;
|
||||||
emitter->particles[i].rotation = angle;
|
emitter->particles[i].rotation = angle;
|
||||||
emitter->particles[i].angular_vel = -10 + 20 * (float)rand() / (float)RAND_MAX;
|
emitter->particles[i].angular_vel = -10 + 20 * (float)rand() / (float)RAND_MAX;
|
||||||
|
@ -72,9 +74,9 @@ void update_particle_system(ParticleSystem_t* system)
|
||||||
{
|
{
|
||||||
if (emitter->particles[i].alive)
|
if (emitter->particles[i].alive)
|
||||||
{
|
{
|
||||||
if (emitter->config.update_func != NULL)
|
if (emitter->update_func != NULL)
|
||||||
{
|
{
|
||||||
emitter->config.update_func(emitter->particles + i, emitter->config.user_data);
|
emitter->update_func(emitter->particles + i, emitter->user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lifetime update
|
// Lifetime update
|
||||||
|
@ -119,7 +121,7 @@ void draw_particle_system(ParticleSystem_t* system)
|
||||||
{
|
{
|
||||||
if (part->alive)
|
if (part->alive)
|
||||||
{
|
{
|
||||||
if (emitter->tex == NULL || emitter->tex->width == 0)
|
if (emitter->config->spr == NULL)
|
||||||
{
|
{
|
||||||
Rectangle rect = {
|
Rectangle rect = {
|
||||||
.x = part->position.x,
|
.x = part->position.x,
|
||||||
|
@ -135,21 +137,7 @@ void draw_particle_system(ParticleSystem_t* system)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Rectangle source = {
|
draw_sprite(emitter->config->spr, part->position, part->rotation, false);
|
||||||
0.0f, 0.0f,
|
|
||||||
(float)emitter->tex->width, (float)emitter->tex->height
|
|
||||||
};
|
|
||||||
|
|
||||||
Rectangle dest = {
|
|
||||||
part->position.x, part->position.y,
|
|
||||||
(float)emitter->tex->width, (float)emitter->tex->height
|
|
||||||
};
|
|
||||||
Vector2 origin = { (float)emitter->tex->width / 2, (float)emitter->tex->height / 2 };
|
|
||||||
DrawTexturePro(
|
|
||||||
*emitter->tex,
|
|
||||||
source, dest, origin,
|
|
||||||
part->rotation, WHITE
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
#include "engine_conf.h"
|
#include "engine_conf.h"
|
||||||
#include "sc_queue.h"
|
#include "sc_queue.h"
|
||||||
|
#include "EC.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
@ -31,21 +32,21 @@ typedef struct EmitterConfig
|
||||||
float speed_range[2];
|
float speed_range[2];
|
||||||
uint32_t particle_lifetime[2];
|
uint32_t particle_lifetime[2];
|
||||||
PartEmitterType_t type;
|
PartEmitterType_t type;
|
||||||
void* user_data;
|
Sprite_t* spr;
|
||||||
particle_update_func_t update_func;
|
bool one_shot;
|
||||||
}EmitterConfig_t;
|
}EmitterConfig_t;
|
||||||
|
|
||||||
typedef struct ParticleEmitter
|
typedef struct ParticleEmitter
|
||||||
{
|
{
|
||||||
EmitterConfig_t config;
|
const EmitterConfig_t* config;
|
||||||
Vector2 position;
|
Vector2 position;
|
||||||
Particle_t particles[MAX_PARTICLES];
|
Particle_t particles[MAX_PARTICLES];
|
||||||
uint32_t n_particles;
|
uint32_t n_particles;
|
||||||
Texture2D* tex;
|
|
||||||
uint32_t timer;
|
uint32_t timer;
|
||||||
bool one_shot;
|
|
||||||
bool finished;
|
bool finished;
|
||||||
bool active;
|
bool active;
|
||||||
|
void* user_data;
|
||||||
|
particle_update_func_t update_func;
|
||||||
}ParticleEmitter_t;
|
}ParticleEmitter_t;
|
||||||
|
|
||||||
typedef struct IndexList
|
typedef struct IndexList
|
||||||
|
@ -55,8 +56,8 @@ typedef struct IndexList
|
||||||
|
|
||||||
typedef struct ParticleSystem
|
typedef struct ParticleSystem
|
||||||
{
|
{
|
||||||
ParticleEmitter_t emitters[MAX_PARTICLE_EMITTER + 1];
|
ParticleEmitter_t emitters[MAX_ACTIVE_PARTICLE_EMITTER + 1];
|
||||||
IndexList_t emitter_list[MAX_PARTICLE_EMITTER + 1];
|
IndexList_t emitter_list[MAX_ACTIVE_PARTICLE_EMITTER + 1];
|
||||||
struct sc_queue_64 free_list;
|
struct sc_queue_64 free_list;
|
||||||
uint32_t tail_idx;
|
uint32_t tail_idx;
|
||||||
uint32_t n_configs;
|
uint32_t n_configs;
|
||||||
|
@ -64,7 +65,7 @@ typedef struct ParticleSystem
|
||||||
}ParticleSystem_t;
|
}ParticleSystem_t;
|
||||||
|
|
||||||
void init_particle_system(ParticleSystem_t* system);
|
void init_particle_system(ParticleSystem_t* system);
|
||||||
void add_particle_emitter(ParticleSystem_t* system, const ParticleEmitter_t* in_emitter);
|
void play_particle_emitter(ParticleSystem_t* system, const ParticleEmitter_t* in_emitter);
|
||||||
void update_particle_system(ParticleSystem_t* system);
|
void update_particle_system(ParticleSystem_t* system);
|
||||||
void draw_particle_system(ParticleSystem_t* system);
|
void draw_particle_system(ParticleSystem_t* system);
|
||||||
void deinit_particle_system(ParticleSystem_t* system);
|
void deinit_particle_system(ParticleSystem_t* system);
|
||||||
|
|
|
@ -52,19 +52,30 @@ int main(void)
|
||||||
|
|
||||||
init_particle_system(&part_sys);
|
init_particle_system(&part_sys);
|
||||||
Texture2D tex = LoadTexture("res/bomb.png");
|
Texture2D tex = LoadTexture("res/bomb.png");
|
||||||
|
Sprite_t spr = {
|
||||||
|
.texture = &tex,
|
||||||
|
.frame_size = (Vector2){tex.width, tex.height},
|
||||||
|
.origin = (Vector2){0, 0},
|
||||||
|
.anchor = (Vector2){tex.width / 2, tex.height / 2},
|
||||||
|
.frame_count = 0,
|
||||||
|
.current_frame = 0,
|
||||||
|
.elapsed = 0,
|
||||||
|
.speed = 0,
|
||||||
|
.name = "test_spr"
|
||||||
|
};
|
||||||
|
|
||||||
EmitterConfig_t conf ={
|
EmitterConfig_t conf ={
|
||||||
|
.one_shot = true,
|
||||||
.launch_range = {0, 360},
|
.launch_range = {0, 360},
|
||||||
.speed_range = {400, 2000},
|
.speed_range = {400, 2000},
|
||||||
.particle_lifetime = {30, 110},
|
.particle_lifetime = {30, 110},
|
||||||
.update_func = &simple_particle_system_update
|
.spr = (tex.width == 0) ? NULL : &spr,
|
||||||
};
|
};
|
||||||
|
|
||||||
ParticleEmitter_t emitter = {
|
ParticleEmitter_t emitter = {
|
||||||
.config = conf,
|
.config = &conf,
|
||||||
.n_particles = MAX_PARTICLES,
|
.n_particles = MAX_PARTICLES,
|
||||||
.one_shot = true,
|
.update_func = &simple_particle_system_update
|
||||||
.tex = &tex,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool key_press = false;
|
bool key_press = false;
|
||||||
|
@ -77,7 +88,7 @@ int main(void)
|
||||||
else if (key_press && IsMouseButtonReleased(MOUSE_BUTTON_LEFT))
|
else if (key_press && IsMouseButtonReleased(MOUSE_BUTTON_LEFT))
|
||||||
{
|
{
|
||||||
emitter.position = GetMousePosition();
|
emitter.position = GetMousePosition();
|
||||||
add_particle_emitter(&part_sys, &emitter);
|
play_particle_emitter(&part_sys, &emitter);
|
||||||
key_press = false;
|
key_press = false;
|
||||||
}
|
}
|
||||||
update_particle_system(&part_sys);
|
update_particle_system(&part_sys);
|
||||||
|
|
13
scene_test.c
13
scene_test.c
|
@ -14,7 +14,7 @@ static GameEngine_t engine =
|
||||||
.max_scenes = 1,
|
.max_scenes = 1,
|
||||||
.curr_scene = 0,
|
.curr_scene = 0,
|
||||||
.assets = {0},
|
.assets = {0},
|
||||||
.sfx_list = {0}
|
.sfx_list = {0},
|
||||||
};
|
};
|
||||||
|
|
||||||
void update_loop(void)
|
void update_loop(void)
|
||||||
|
@ -35,7 +35,6 @@ int main(void)
|
||||||
InitAudioDevice();
|
InitAudioDevice();
|
||||||
init_engine(&engine);
|
init_engine(&engine);
|
||||||
|
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
load_from_infofile("res/assets.info.raw", &engine.assets);
|
load_from_infofile("res/assets.info.raw", &engine.assets);
|
||||||
init_player_creation("res/player_spr.info", &engine.assets);
|
init_player_creation("res/player_spr.info", &engine.assets);
|
||||||
|
@ -56,6 +55,7 @@ int main(void)
|
||||||
load_sfx(&engine, "snd_bland", BOULDER_LAND_SFX);
|
load_sfx(&engine, "snd_bland", BOULDER_LAND_SFX);
|
||||||
load_sfx(&engine, "snd_bubble", BUBBLE_SFX);
|
load_sfx(&engine, "snd_bubble", BUBBLE_SFX);
|
||||||
|
|
||||||
|
|
||||||
LevelScene_t scene;
|
LevelScene_t scene;
|
||||||
scene.scene.engine = &engine;
|
scene.scene.engine = &engine;
|
||||||
init_sandbox_scene(&scene);
|
init_sandbox_scene(&scene);
|
||||||
|
@ -68,6 +68,15 @@ int main(void)
|
||||||
scenes[0] = &scene.scene;
|
scenes[0] = &scene.scene;
|
||||||
change_scene(&engine, 0);
|
change_scene(&engine, 0);
|
||||||
|
|
||||||
|
EmitterConfig_t* conf = add_emitter_conf(&engine.assets, "pe_wood", get_sprite(&engine.assets, "bomb"));
|
||||||
|
conf->launch_range[0] = 240;
|
||||||
|
conf->launch_range[1] = 300;
|
||||||
|
conf->one_shot = true;
|
||||||
|
conf->speed_range[0] = 200;
|
||||||
|
conf->speed_range[1] = 300;
|
||||||
|
conf->particle_lifetime[0] = 30;
|
||||||
|
conf->particle_lifetime[1] = 110;
|
||||||
|
|
||||||
#if defined(PLATFORM_WEB)
|
#if defined(PLATFORM_WEB)
|
||||||
puts("Setting emscripten main loop");
|
puts("Setting emscripten main loop");
|
||||||
emscripten_set_main_loop(update_loop, 0, 1);
|
emscripten_set_main_loop(update_loop, 0, 1);
|
||||||
|
|
|
@ -225,7 +225,7 @@ static void render_editor_game_scene(Scene_t* scene)
|
||||||
uint8_t tile_sprite_idx = tilemap.tiles[i].tile_type + tilemap.tiles[i].rotation;
|
uint8_t tile_sprite_idx = tilemap.tiles[i].tile_type + tilemap.tiles[i].rotation;
|
||||||
if (data->tile_sprites[tile_sprite_idx] != NULL)
|
if (data->tile_sprites[tile_sprite_idx] != NULL)
|
||||||
{
|
{
|
||||||
draw_sprite(data->tile_sprites[tile_sprite_idx], (Vector2){x,y}, false);
|
draw_sprite(data->tile_sprites[tile_sprite_idx], (Vector2){x,y}, 0.0f, false);
|
||||||
}
|
}
|
||||||
else if (tilemap.tiles[i].tile_type == SOLID_TILE)
|
else if (tilemap.tiles[i].tile_type == SOLID_TILE)
|
||||||
{
|
{
|
||||||
|
@ -429,7 +429,7 @@ static void render_editor_game_scene(Scene_t* scene)
|
||||||
if (spr.sprite != NULL)
|
if (spr.sprite != NULL)
|
||||||
{
|
{
|
||||||
Vector2 pos = Vector2Add(p_ct->position, spr.offset);
|
Vector2 pos = Vector2Add(p_ct->position, spr.offset);
|
||||||
draw_sprite(spr.sprite, pos, p_cspr->flip_x);
|
draw_sprite(spr.sprite, pos, 0.0f, p_cspr->flip_x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -448,6 +448,9 @@ static void render_editor_game_scene(Scene_t* scene)
|
||||||
unsigned int y = ((p_runner->current_tile) / tilemap.width) * tilemap.tile_size;
|
unsigned int y = ((p_runner->current_tile) / tilemap.width) * tilemap.tile_size;
|
||||||
DrawCircle(x+16, y+16, 8, ColorAlpha(BLUE, 0.6));
|
DrawCircle(x+16, y+16, 8, ColorAlpha(BLUE, 0.6));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
draw_particle_system(&scene->part_sys);
|
||||||
|
|
||||||
for (int tile_y = min.y; tile_y < max.y; tile_y++)
|
for (int tile_y = min.y; tile_y < max.y; tile_y++)
|
||||||
{
|
{
|
||||||
for (int tile_x = min.x; tile_x < max.x; tile_x++)
|
for (int tile_x = min.x; tile_x < max.x; tile_x++)
|
||||||
|
|
|
@ -131,7 +131,7 @@ static void render_regular_game_scene(Scene_t* scene)
|
||||||
|
|
||||||
if (data->tile_sprites[tilemap.tiles[i].tile_type] != NULL)
|
if (data->tile_sprites[tilemap.tiles[i].tile_type] != NULL)
|
||||||
{
|
{
|
||||||
draw_sprite(data->tile_sprites[tilemap.tiles[i].tile_type], (Vector2){x,y}, false);
|
draw_sprite(data->tile_sprites[tilemap.tiles[i].tile_type], (Vector2){x,y}, 0.0f, false);
|
||||||
}
|
}
|
||||||
else if (tilemap.tiles[i].tile_type == SOLID_TILE)
|
else if (tilemap.tiles[i].tile_type == SOLID_TILE)
|
||||||
{
|
{
|
||||||
|
@ -223,7 +223,7 @@ static void render_regular_game_scene(Scene_t* scene)
|
||||||
if (spr.sprite != NULL)
|
if (spr.sprite != NULL)
|
||||||
{
|
{
|
||||||
Vector2 pos = Vector2Add(p_ct->position, spr.offset);
|
Vector2 pos = Vector2Add(p_ct->position, spr.offset);
|
||||||
draw_sprite(spr.sprite, pos, p_cspr->flip_x);
|
draw_sprite(spr.sprite, pos, 0.0f, p_cspr->flip_x);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -319,6 +319,7 @@ static void render_regular_game_scene(Scene_t* scene)
|
||||||
unsigned int y = ((p_runner->current_tile) / tilemap.width) * tilemap.tile_size;
|
unsigned int y = ((p_runner->current_tile) / tilemap.width) * tilemap.tile_size;
|
||||||
DrawCircle(x+16, y+16, 8, ColorAlpha(BLUE, 0.6));
|
DrawCircle(x+16, y+16, 8, ColorAlpha(BLUE, 0.6));
|
||||||
}
|
}
|
||||||
|
draw_particle_system(&scene->part_sys);
|
||||||
|
|
||||||
// Draw Border
|
// Draw Border
|
||||||
DrawLine(0, 0, 0, tilemap.height * tilemap.tile_size, BLACK);
|
DrawLine(0, 0, 0, tilemap.height * tilemap.tile_size, BLACK);
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
#include "game_systems.h"
|
#include "game_systems.h"
|
||||||
|
#include "particle_sys.h"
|
||||||
#include "ent_impl.h"
|
#include "ent_impl.h"
|
||||||
#include "AABB.h"
|
#include "AABB.h"
|
||||||
#include "EC.h"
|
#include "EC.h"
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void simple_particle_system_update(Particle_t* part, void* user_data);
|
||||||
|
|
||||||
static const Vector2 GRAVITY = {0, GRAV_ACCEL};
|
static const Vector2 GRAVITY = {0, GRAV_ACCEL};
|
||||||
static const Vector2 UPTHRUST = {0, -GRAV_ACCEL * 1.1};
|
static const Vector2 UPTHRUST = {0, -GRAV_ACCEL * 1.1};
|
||||||
typedef enum AnchorPoint {
|
typedef enum AnchorPoint {
|
||||||
|
@ -1627,6 +1630,19 @@ void container_destroy_system(Scene_t* scene)
|
||||||
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
|
Entity_t* p_ent = get_entity(&scene->ent_manager, ent_idx);
|
||||||
if (!p_ent->m_alive)
|
if (!p_ent->m_alive)
|
||||||
{
|
{
|
||||||
|
if (p_ent->m_tag == CRATES_ENT_TAG)
|
||||||
|
{
|
||||||
|
const CTransform_t* p_ctransform = get_component(p_ent, CTRANSFORM_COMP_T);
|
||||||
|
//const CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
|
||||||
|
ParticleEmitter_t emitter = {
|
||||||
|
.config = get_emitter_conf(&scene->engine->assets, "pe_wood"),
|
||||||
|
.position = p_ctransform->position,
|
||||||
|
.n_particles = 3,
|
||||||
|
.user_data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data),
|
||||||
|
.update_func = &simple_particle_system_update,
|
||||||
|
};
|
||||||
|
play_particle_emitter(&scene->part_sys, &emitter);
|
||||||
|
}
|
||||||
|
|
||||||
Entity_t* dmg_src = NULL;
|
Entity_t* dmg_src = NULL;
|
||||||
CHurtbox_t* p_hurtbox = get_component(p_ent, CHURTBOX_T);
|
CHurtbox_t* p_hurtbox = get_component(p_ent, CHURTBOX_T);
|
||||||
|
@ -1927,3 +1943,45 @@ void level_end_detection_system(Scene_t* scene)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void simple_particle_system_update(Particle_t* part, void* user_data)
|
||||||
|
{
|
||||||
|
LevelSceneData_t* lvl_data = (LevelSceneData_t*)user_data;
|
||||||
|
TileGrid_t tilemap = lvl_data->tilemap;
|
||||||
|
|
||||||
|
float delta_time = DELTA_T; // TODO: Will need to think about delta time handling
|
||||||
|
part->velocity =
|
||||||
|
Vector2Add(
|
||||||
|
part->velocity,
|
||||||
|
Vector2Scale(GRAVITY, delta_time)
|
||||||
|
);
|
||||||
|
|
||||||
|
float mag = Vector2Length(part->velocity);
|
||||||
|
part->velocity = Vector2Scale(
|
||||||
|
Vector2Normalize(part->velocity),
|
||||||
|
(mag > PLAYER_MAX_SPEED)? PLAYER_MAX_SPEED:mag
|
||||||
|
);
|
||||||
|
// 3 dp precision
|
||||||
|
if (fabs(part->velocity.x) < 1e-3) part->velocity.x = 0;
|
||||||
|
if (fabs(part->velocity.y) < 1e-3) part->velocity.y = 0;
|
||||||
|
|
||||||
|
part->position = Vector2Add(
|
||||||
|
part->position,
|
||||||
|
Vector2Scale(part->velocity, delta_time)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Level boundary collision
|
||||||
|
unsigned int level_width = tilemap.width * TILE_SIZE;
|
||||||
|
unsigned int level_height = tilemap.height * TILE_SIZE;
|
||||||
|
{
|
||||||
|
|
||||||
|
if(
|
||||||
|
part->position.x < 0 || part->position.x + part->size > level_width
|
||||||
|
|| part->position.y < 0 || part->position.y + part->size > level_height
|
||||||
|
)
|
||||||
|
{
|
||||||
|
part->timer = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "raymath.h"
|
#include "raymath.h"
|
||||||
|
|
||||||
static SpriteRenderInfo_t item_sprite_map[18] = {0};
|
static SpriteRenderInfo_t item_sprite_map[19] = {0};
|
||||||
|
|
||||||
bool init_item_creation(Assets_t* assets)
|
bool init_item_creation(Assets_t* assets)
|
||||||
{
|
{
|
||||||
|
@ -27,6 +27,7 @@ bool init_item_creation(Assets_t* assets)
|
||||||
item_sprite_map[16].sprite = get_sprite(assets, "m_b_crate");
|
item_sprite_map[16].sprite = get_sprite(assets, "m_b_crate");
|
||||||
item_sprite_map[17].sprite = get_sprite(assets, "explode");
|
item_sprite_map[17].sprite = get_sprite(assets, "explode");
|
||||||
item_sprite_map[17].offset = (Vector2){-12, -12};
|
item_sprite_map[17].offset = (Vector2){-12, -12};
|
||||||
|
item_sprite_map[18].sprite = get_sprite(assets, "chest");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +224,11 @@ Entity_t* create_chest(EntityManager_t* ent_manager, Assets_t* assets)
|
||||||
p_hurtbox->def = 4;
|
p_hurtbox->def = 4;
|
||||||
p_hurtbox->damage_src = -1;
|
p_hurtbox->damage_src = -1;
|
||||||
|
|
||||||
|
CSprite_t* p_cspr = add_component(p_chest, CSPRITE_T);
|
||||||
|
p_cspr->sprites = item_sprite_map;
|
||||||
|
p_cspr->current_idx = 18;
|
||||||
|
|
||||||
|
|
||||||
return p_chest;
|
return p_chest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -109,7 +109,7 @@ static void level_scene_render_func(Scene_t* scene)
|
||||||
if (spr.sprite != NULL)
|
if (spr.sprite != NULL)
|
||||||
{
|
{
|
||||||
Vector2 pos = Vector2Add(p_ct->position, spr.offset);
|
Vector2 pos = Vector2Add(p_ct->position, spr.offset);
|
||||||
draw_sprite(spr.sprite, pos, p_cspr->flip_x);
|
draw_sprite(spr.sprite, pos, 0.0f, p_cspr->flip_x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue