Compare commits
18 Commits
402d6f658e
...
0d4089d9ce
Author | SHA1 | Date |
---|---|---|
|
0d4089d9ce | |
|
41e4b34869 | |
|
1094e13c0a | |
|
54acd365d4 | |
|
2bda67e917 | |
|
42c4572066 | |
|
754d380221 | |
|
0fb1fe27de | |
|
204329d2aa | |
|
6bcccf7412 | |
|
c76ceba9bf | |
|
0a3f56f730 | |
|
0a6e7b4ddc | |
|
55ba03f2d6 | |
|
3961366ac4 | |
|
6f3f391d8a | |
|
fec9ac268d | |
|
a2c061c5e8 |
|
@ -32,6 +32,7 @@ int main(void)
|
|||
Font* fnt = get_font(&assets, "testfont");
|
||||
|
||||
int current_frame = 0;
|
||||
int elapsed = 0;
|
||||
while(!WindowShouldClose())
|
||||
{
|
||||
if (IsKeyReleased(KEY_C))
|
||||
|
@ -49,12 +50,12 @@ int main(void)
|
|||
EndDrawing();
|
||||
|
||||
// Update the animated Sprite
|
||||
spr2->elapsed++;
|
||||
if (spr2->elapsed == spr2->speed)
|
||||
elapsed++;
|
||||
if (elapsed == spr2->speed)
|
||||
{
|
||||
current_frame++;
|
||||
current_frame %= spr2->frame_count;
|
||||
spr2->elapsed = 0;
|
||||
elapsed = 0;
|
||||
}
|
||||
}
|
||||
term_assets(&assets);
|
||||
|
|
23
engine/EC.h
23
engine/EC.h
|
@ -45,13 +45,12 @@ typedef struct _CBBox_t {
|
|||
typedef struct _CTransform_t {
|
||||
Vector2 prev_position;
|
||||
Vector2 prev_velocity;
|
||||
Vector2 position;
|
||||
Vector2 velocity;
|
||||
Vector2 accel;
|
||||
Vector2 fric_coeff;
|
||||
Vector2 shape_factor;
|
||||
int8_t grav_delay;
|
||||
int8_t grav_timer;
|
||||
float grav_delay;
|
||||
float grav_timer;
|
||||
MovementMode_t movement_mode;
|
||||
bool active;
|
||||
} CTransform_t;
|
||||
|
@ -130,16 +129,15 @@ typedef struct _CHurtbox_t {
|
|||
} CHurtbox_t;
|
||||
|
||||
typedef struct _CLifeTimer_t {
|
||||
uint8_t timer;
|
||||
uint8_t life_time;
|
||||
float life_time;
|
||||
} CLifeTimer_t;
|
||||
|
||||
typedef struct _CAirTimer_t {
|
||||
float max_ftimer;
|
||||
float curr_ftimer;
|
||||
float decay_rate;
|
||||
uint8_t max_count;
|
||||
uint8_t curr_count;
|
||||
uint16_t max_ftimer;
|
||||
uint16_t curr_ftimer;
|
||||
uint16_t decay_rate;
|
||||
} CAirTimer_t;
|
||||
|
||||
typedef struct _BFSTile {
|
||||
|
@ -178,6 +176,7 @@ typedef struct _CWaterRunner {
|
|||
uint8_t movement_delay;
|
||||
int8_t movement_speed;
|
||||
int16_t counter;
|
||||
float fractional;
|
||||
}CWaterRunner_t;
|
||||
|
||||
// Credits to bedroomcoders.co.uk for this
|
||||
|
@ -187,7 +186,6 @@ typedef struct Sprite {
|
|||
Vector2 origin;
|
||||
Vector2 anchor;
|
||||
int frame_count;
|
||||
int elapsed;
|
||||
int speed;
|
||||
char* name;
|
||||
} Sprite_t;
|
||||
|
@ -207,6 +205,12 @@ typedef struct _CSprite_t {
|
|||
bool flip_y;
|
||||
bool pause;
|
||||
int current_frame;
|
||||
float fractional;
|
||||
float rotation; // Degree
|
||||
float rotation_speed; // Degree / s
|
||||
int elapsed;
|
||||
Vector2 offset;
|
||||
Color colour;
|
||||
} CSprite_t;
|
||||
|
||||
typedef struct _CMoveable_t {
|
||||
|
@ -233,6 +237,7 @@ static inline void set_bbox(CBBox_t* p_bbox, unsigned int x, unsigned int y)
|
|||
|
||||
struct Entity {
|
||||
Vector2 spawn_pos;
|
||||
Vector2 position;
|
||||
unsigned long m_id;
|
||||
unsigned int m_tag;
|
||||
unsigned long components[N_COMPONENTS];
|
||||
|
|
|
@ -18,5 +18,8 @@ typedef enum ActionType
|
|||
ACTION_PREVLEVEL,
|
||||
ACTION_TOGGLE_GRID,
|
||||
ACTION_SET_SPAWNPOINT,
|
||||
ACTION_TOGGLE_TIMESLOW,
|
||||
ACTION_SPAWN_TILE,
|
||||
ACTION_REMOVE_TILE,
|
||||
}ActionType_t;
|
||||
#endif // __ACTIONS_H
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include "zstd.h"
|
||||
#include <stdio.h>
|
||||
|
||||
uint8_t n_loaded[6] = {0};
|
||||
uint8_t n_loaded[N_ASSETS_TYPE] = {0};
|
||||
|
||||
// Hard limit number of
|
||||
typedef struct TextureData
|
||||
|
@ -70,7 +70,7 @@ static void unload_level_pack(LevelPack_t pack)
|
|||
// Maybe need a circular buffer??
|
||||
Texture2D* add_texture(Assets_t* assets, const char* name, const char* path)
|
||||
{
|
||||
uint8_t tex_idx = n_loaded[0];
|
||||
uint8_t tex_idx = n_loaded[AST_TEXTURE];
|
||||
assert(tex_idx < MAX_TEXTURES);
|
||||
Texture2D tex = LoadTexture(path);
|
||||
if (tex.width == 0 || tex.height == 0) return NULL;
|
||||
|
@ -78,13 +78,13 @@ Texture2D* add_texture(Assets_t* assets, const char* name, const char* path)
|
|||
textures[tex_idx].texture = tex;
|
||||
strncpy(textures[tex_idx].name, name, MAX_NAME_LEN);
|
||||
sc_map_put_s64(&assets->m_textures, textures[tex_idx].name, tex_idx);
|
||||
n_loaded[0]++;
|
||||
n_loaded[AST_TEXTURE]++;
|
||||
return &textures[tex_idx].texture;
|
||||
}
|
||||
|
||||
Texture2D* add_texture_rres(Assets_t* assets, const char* name, const char* filename, const RresFileInfo_t* rres_file)
|
||||
{
|
||||
uint8_t tex_idx = n_loaded[0];
|
||||
uint8_t tex_idx = n_loaded[AST_TEXTURE];
|
||||
assert(tex_idx < MAX_TEXTURES);
|
||||
|
||||
int res_id = rresGetResourceId(rres_file->dir, filename);
|
||||
|
@ -102,7 +102,7 @@ Texture2D* add_texture_rres(Assets_t* assets, const char* name, const char* file
|
|||
textures[tex_idx].texture = tex;
|
||||
strncpy(textures[tex_idx].name, name, MAX_NAME_LEN);
|
||||
sc_map_put_s64(&assets->m_textures, textures[tex_idx].name, tex_idx);
|
||||
n_loaded[0]++;
|
||||
n_loaded[AST_TEXTURE]++;
|
||||
out_tex = &textures[tex_idx].texture;
|
||||
}
|
||||
rresUnloadResourceChunk(chunk);
|
||||
|
@ -111,7 +111,7 @@ Texture2D* add_texture_rres(Assets_t* assets, const char* name, const char* file
|
|||
|
||||
Sound* add_sound_rres(Assets_t* assets, const char* name, const char* filename, const RresFileInfo_t* rres_file)
|
||||
{
|
||||
uint8_t snd_idx = n_loaded[2];
|
||||
uint8_t snd_idx = n_loaded[AST_SOUND];
|
||||
assert(snd_idx < MAX_SOUNDS);
|
||||
|
||||
int res_id = rresGetResourceId(rres_file->dir, filename);
|
||||
|
@ -128,55 +128,69 @@ Sound* add_sound_rres(Assets_t* assets, const char* name, const char* filename,
|
|||
sfx[snd_idx].sound = snd;
|
||||
strncpy(sfx[snd_idx].name, name, MAX_NAME_LEN);
|
||||
sc_map_put_s64(&assets->m_sounds, sfx[snd_idx].name, snd_idx);
|
||||
n_loaded[2]++;
|
||||
n_loaded[AST_SOUND]++;
|
||||
out_snd = &sfx[snd_idx].sound;
|
||||
}
|
||||
rresUnloadResourceChunk(chunk);
|
||||
return out_snd;
|
||||
}
|
||||
|
||||
Texture2D* add_texture_from_img(Assets_t* assets, const char* name, Image img)
|
||||
{
|
||||
uint8_t tex_idx = n_loaded[AST_TEXTURE];
|
||||
assert(tex_idx < MAX_TEXTURES);
|
||||
Texture2D tex = LoadTextureFromImage(img);
|
||||
if (tex.width == 0 || tex.height == 0) return NULL;
|
||||
|
||||
textures[tex_idx].texture = tex;
|
||||
strncpy(textures[tex_idx].name, name, MAX_NAME_LEN);
|
||||
sc_map_put_s64(&assets->m_textures, textures[tex_idx].name, tex_idx);
|
||||
n_loaded[AST_TEXTURE]++;
|
||||
return &textures[tex_idx].texture;
|
||||
}
|
||||
|
||||
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[AST_SPRITE];
|
||||
assert(spr_idx < MAX_SPRITES);
|
||||
memset(sprites + spr_idx, 0, sizeof(SpriteData_t));
|
||||
sprites[spr_idx].sprite.texture = texture;
|
||||
strncpy(sprites[spr_idx].name, name, MAX_NAME_LEN);
|
||||
sc_map_put_s64(&assets->m_sprites, sprites[spr_idx].name, spr_idx);
|
||||
n_loaded[1]++;
|
||||
n_loaded[AST_SPRITE]++;
|
||||
return &sprites[spr_idx].sprite;
|
||||
}
|
||||
|
||||
Sound* add_sound(Assets_t* assets, const char* name, const char* path)
|
||||
{
|
||||
uint8_t snd_idx = n_loaded[2];
|
||||
uint8_t snd_idx = n_loaded[AST_SOUND];
|
||||
assert(snd_idx < MAX_SOUNDS);
|
||||
sfx[snd_idx].sound = LoadSound(path);
|
||||
strncpy(sfx[snd_idx].name, name, MAX_NAME_LEN);
|
||||
sc_map_put_s64(&assets->m_sounds, sfx[snd_idx].name, snd_idx);
|
||||
n_loaded[2]++;
|
||||
n_loaded[AST_SOUND]++;
|
||||
return &sfx[snd_idx].sound;
|
||||
}
|
||||
|
||||
Font* add_font(Assets_t* assets, const char* name, const char* path)
|
||||
{
|
||||
uint8_t fnt_idx = n_loaded[3];
|
||||
uint8_t fnt_idx = n_loaded[AST_FONT];
|
||||
assert(fnt_idx < MAX_FONTS);
|
||||
fonts[fnt_idx].font = LoadFont(path);
|
||||
strncpy(fonts[fnt_idx].name, name, MAX_NAME_LEN);
|
||||
sc_map_put_s64(&assets->m_fonts, fonts[fnt_idx].name, fnt_idx);
|
||||
n_loaded[3]++;
|
||||
n_loaded[AST_FONT]++;
|
||||
return &fonts[fnt_idx].font;
|
||||
}
|
||||
|
||||
EmitterConfig_t* add_emitter_conf(Assets_t* assets, const char* name)
|
||||
{
|
||||
uint8_t emitter_idx = n_loaded[5];
|
||||
uint8_t emitter_idx = n_loaded[AST_EMITTER_CONF];
|
||||
assert(emitter_idx < MAX_EMITTER_CONF);
|
||||
memset(emitter_confs + emitter_idx, 0, sizeof(EmitterConfData_t));
|
||||
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]++;
|
||||
n_loaded[AST_EMITTER_CONF]++;
|
||||
return &emitter_confs[emitter_idx].conf;
|
||||
}
|
||||
|
||||
|
@ -185,7 +199,7 @@ LevelPack_t* add_level_pack(Assets_t* assets, const char* name, const char* path
|
|||
FILE* file = fopen(path, "rb");
|
||||
if (file == NULL) return NULL;
|
||||
|
||||
LevelPackData_t* pack_info = levelpacks + n_loaded[4];
|
||||
LevelPackData_t* pack_info = levelpacks + n_loaded[AST_LEVELPACK];
|
||||
fread(&pack_info->pack.n_levels, sizeof(uint32_t), 1, file);
|
||||
pack_info->pack.levels = calloc(pack_info->pack.n_levels, sizeof(LevelMap_t));
|
||||
|
||||
|
@ -201,10 +215,10 @@ LevelPack_t* add_level_pack(Assets_t* assets, const char* name, const char* path
|
|||
}
|
||||
|
||||
fclose(file);
|
||||
uint8_t pack_idx = n_loaded[4];
|
||||
uint8_t pack_idx = n_loaded[AST_LEVELPACK];
|
||||
strncpy(pack_info->name, name, MAX_NAME_LEN);
|
||||
sc_map_put_s64(&assets->m_levelpacks, levelpacks[pack_idx].name, pack_idx);
|
||||
n_loaded[4]++;
|
||||
n_loaded[AST_LEVELPACK]++;
|
||||
|
||||
return &levelpacks[pack_idx].pack;
|
||||
}
|
||||
|
@ -212,7 +226,7 @@ LevelPack_t* add_level_pack(Assets_t* assets, const char* name, const char* path
|
|||
|
||||
static LevelPack_t* add_level_pack_zst(Assets_t* assets, const char* name, const uint8_t* zst_buffer, uint32_t len)
|
||||
{
|
||||
LevelPackData_t* pack_info = levelpacks + n_loaded[4];
|
||||
LevelPackData_t* pack_info = levelpacks + n_loaded[AST_LEVELPACK];
|
||||
size_t read = 0;
|
||||
|
||||
ZSTD_inBuffer input = { level_decompressor.in_buffer, read, 0 };
|
||||
|
@ -350,10 +364,10 @@ load_end:
|
|||
}
|
||||
|
||||
pack_info->pack.n_levels = lvls;
|
||||
uint8_t pack_idx = n_loaded[4];
|
||||
uint8_t pack_idx = n_loaded[AST_LEVELPACK];
|
||||
strncpy(pack_info->name, name, MAX_NAME_LEN);
|
||||
sc_map_put_s64(&assets->m_levelpacks, levelpacks[pack_idx].name, pack_idx);
|
||||
n_loaded[4]++;
|
||||
n_loaded[AST_LEVELPACK]++;
|
||||
|
||||
return &levelpacks[pack_idx].pack;
|
||||
}
|
||||
|
@ -415,19 +429,19 @@ void init_assets(Assets_t* assets)
|
|||
|
||||
void free_all_assets(Assets_t* assets)
|
||||
{
|
||||
for (uint8_t i = 0; i < n_loaded[0]; ++i)
|
||||
for (uint8_t i = 0; i < n_loaded[AST_TEXTURE]; ++i)
|
||||
{
|
||||
UnloadTexture(textures[i].texture);
|
||||
}
|
||||
for (uint8_t i = 0; i < n_loaded[2]; ++i)
|
||||
for (uint8_t i = 0; i < n_loaded[AST_SOUND]; ++i)
|
||||
{
|
||||
UnloadSound(sfx[i].sound);
|
||||
}
|
||||
for (uint8_t i = 0; i < n_loaded[3]; ++i)
|
||||
for (uint8_t i = 0; i < n_loaded[AST_FONT]; ++i)
|
||||
{
|
||||
UnloadFont(fonts[i].font);
|
||||
}
|
||||
for (uint8_t i = 0; i < n_loaded[4]; ++i)
|
||||
for (uint8_t i = 0; i < n_loaded[AST_LEVELPACK]; ++i)
|
||||
{
|
||||
unload_level_pack(levelpacks[i].pack);
|
||||
}
|
||||
|
@ -516,24 +530,36 @@ LevelPack_t* get_level_pack(Assets_t* assets, const char* name)
|
|||
|
||||
void draw_sprite(Sprite_t* spr, int frame_num, Vector2 pos, float rotation, bool flip_x)
|
||||
{
|
||||
draw_sprite_pro(
|
||||
spr, frame_num, pos, rotation, flip_x ? 1: 0,
|
||||
(Vector2){1, 1}, WHITE
|
||||
);
|
||||
}
|
||||
|
||||
void draw_sprite_pro(Sprite_t* spr, int frame_num, Vector2 pos, float rotation, uint8_t flip, Vector2 scale, Color colour)
|
||||
{
|
||||
if (frame_num >= spr->frame_count) frame_num = spr->frame_count - 1;
|
||||
if (frame_num < 0) frame_num = 0;
|
||||
Rectangle rec = {
|
||||
spr->origin.x + spr->frame_size.x * frame_num,
|
||||
spr->origin.y,
|
||||
spr->frame_size.x * (flip_x ? -1:1),
|
||||
spr->frame_size.y
|
||||
spr->frame_size.x * ((flip & 1) ? -1 : 1),
|
||||
spr->frame_size.y * ((flip & 2) ? -1 : 1),
|
||||
};
|
||||
//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
|
||||
.x = pos.x,
|
||||
.y = pos.y,
|
||||
.width = spr->frame_size.x * scale.x,
|
||||
.height = spr->frame_size.y * scale.y
|
||||
};
|
||||
Vector2 anchor = spr->anchor;
|
||||
anchor.x *= scale.x;
|
||||
anchor.y *= scale.y;
|
||||
DrawTexturePro(
|
||||
*spr->texture,
|
||||
rec,
|
||||
dest,
|
||||
spr->anchor,
|
||||
rotation, WHITE
|
||||
anchor,
|
||||
rotation, colour
|
||||
);
|
||||
}
|
||||
|
|
|
@ -5,6 +5,17 @@
|
|||
#include "raylib.h"
|
||||
#include "rres.h"
|
||||
#include "particle_sys.h"
|
||||
#define N_ASSETS_TYPE 6
|
||||
typedef enum AssetType
|
||||
{
|
||||
AST_TEXTURE = 0,
|
||||
AST_SPRITE,
|
||||
AST_SOUND,
|
||||
AST_FONT,
|
||||
AST_LEVELPACK,
|
||||
AST_EMITTER_CONF,
|
||||
}AssetType_t;
|
||||
|
||||
|
||||
typedef struct Assets
|
||||
{
|
||||
|
@ -49,6 +60,7 @@ void free_all_assets(Assets_t* assets);
|
|||
void term_assets(Assets_t* assets);
|
||||
|
||||
Texture2D* add_texture(Assets_t* assets, const char* name, const char* path);
|
||||
Texture2D* add_texture_from_img(Assets_t* assets, const char* name, Image img);
|
||||
Sound* add_sound(Assets_t * assets, const char* name, const char* path);
|
||||
Font* add_font(Assets_t* assets, const char* name, const char* path);
|
||||
LevelPack_t* add_level_pack(Assets_t* assets, const char* name, const char* path);
|
||||
|
@ -70,6 +82,7 @@ Font* get_font(Assets_t* assets, const char* name);
|
|||
LevelPack_t* get_level_pack(Assets_t* assets, const char* name);
|
||||
|
||||
void draw_sprite(Sprite_t* spr, int frame_num, Vector2 pos, float rotation, bool flip_x);
|
||||
void draw_sprite_pro(Sprite_t* spr, int frame_num, Vector2 pos, float rotation, uint8_t flip, Vector2 scale, Color colour);
|
||||
|
||||
typedef struct SFX
|
||||
{
|
||||
|
|
|
@ -65,9 +65,8 @@ uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, bool check
|
|||
{
|
||||
if (ent->p_ent->m_id == p_other_ent->m_id) continue;
|
||||
if (!ent->p_ent->m_alive) continue;
|
||||
CTransform_t *p_ctransform = get_component(p_other_ent, CTRANSFORM_COMP_T);
|
||||
CBBox_t *p_bbox = get_component(p_other_ent, CBBOX_COMP_T);
|
||||
if (p_bbox == NULL || p_ctransform == NULL) continue;
|
||||
if (p_bbox == NULL) continue;
|
||||
//if (p_bbox->solid && !p_bbox->fragile)
|
||||
if (p_bbox->solid)
|
||||
{
|
||||
|
@ -75,7 +74,7 @@ uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, bool check
|
|||
find_AABB_overlap(
|
||||
(Vector2){ent->bbox.x, ent->bbox.y},
|
||||
(Vector2){ent->bbox.width, ent->bbox.height},
|
||||
p_ctransform->position, p_bbox->size, &overlap
|
||||
p_other_ent->position, p_bbox->size, &overlap
|
||||
)
|
||||
)
|
||||
{
|
||||
|
@ -134,14 +133,13 @@ uint8_t check_collision_line(const CollideEntity_t* ent, TileGrid_t* grid, bool
|
|||
{
|
||||
if (ent->p_ent->m_id == p_other_ent->m_id) continue;
|
||||
if (!ent->p_ent->m_alive) continue;
|
||||
CTransform_t *p_ctransform = get_component(p_other_ent, CTRANSFORM_COMP_T);
|
||||
CBBox_t *p_bbox = get_component(p_other_ent, CBBOX_COMP_T);
|
||||
if (p_bbox == NULL || p_ctransform == NULL) continue;
|
||||
if (p_bbox == NULL) continue;
|
||||
if (p_bbox->solid)
|
||||
{
|
||||
Rectangle box = {
|
||||
.x = p_ctransform->position.x,
|
||||
.y = p_ctransform->position.y,
|
||||
.x = p_other_ent->position.x,
|
||||
.y = p_other_ent->position.y,
|
||||
.width = p_bbox->size.x,
|
||||
.height = p_bbox->size.y,
|
||||
};
|
||||
|
@ -157,27 +155,26 @@ uint8_t check_collision_line(const CollideEntity_t* ent, TileGrid_t* grid, bool
|
|||
}
|
||||
|
||||
// TODO: This should be a point collision check, not an AABB check
|
||||
uint8_t check_collision_offset(Entity_t* p_ent, Vector2 pos, Vector2 bbox_sz, TileGrid_t* grid, Vector2 offset)
|
||||
uint8_t check_collision_at(Entity_t* p_ent, Vector2 pos, Vector2 bbox_sz, TileGrid_t* grid)
|
||||
{
|
||||
Vector2 new_pos = Vector2Add(pos, offset);
|
||||
CollideEntity_t ent = {
|
||||
.p_ent = p_ent,
|
||||
.bbox = (Rectangle){new_pos.x, new_pos.y, bbox_sz.x, bbox_sz.y},
|
||||
.bbox = (Rectangle){pos.x, pos.y, bbox_sz.x, bbox_sz.y},
|
||||
.prev_bbox = (Rectangle){pos.x, pos.y, bbox_sz.x, bbox_sz.y},
|
||||
.area = (TileArea_t){
|
||||
.tile_x1 = (new_pos.x) / grid->tile_size,
|
||||
.tile_y1 = (new_pos.y) / grid->tile_size,
|
||||
.tile_x2 = (new_pos.x + bbox_sz.x - 1) / grid->tile_size,
|
||||
.tile_y2 = (new_pos.y + bbox_sz.y - 1) / grid->tile_size
|
||||
.tile_x1 = (pos.x) / grid->tile_size,
|
||||
.tile_y1 = (pos.y) / grid->tile_size,
|
||||
.tile_x2 = (pos.x + bbox_sz.x - 1) / grid->tile_size,
|
||||
.tile_y2 = (pos.y + bbox_sz.y - 1) / grid->tile_size
|
||||
}
|
||||
};
|
||||
|
||||
return check_collision(&ent, grid, false);
|
||||
}
|
||||
|
||||
bool check_on_ground(Entity_t* p_ent, Vector2 pos, Vector2 prev_pos, Vector2 bbox_sz, TileGrid_t* grid)
|
||||
bool check_on_ground(Entity_t* p_ent, Vector2 prev_pos, Vector2 bbox_sz, TileGrid_t* grid)
|
||||
{
|
||||
Vector2 new_pos = Vector2Add(pos, (Vector2){0, 1});
|
||||
Vector2 new_pos = Vector2Add(p_ent->position, (Vector2){0, 1});
|
||||
CollideEntity_t ent = {
|
||||
.p_ent = p_ent,
|
||||
.bbox = (Rectangle){new_pos.x, new_pos.y + bbox_sz.y, bbox_sz.x, 1},
|
||||
|
@ -195,12 +192,13 @@ bool check_on_ground(Entity_t* p_ent, Vector2 pos, Vector2 prev_pos, Vector2 bbo
|
|||
|
||||
uint8_t check_bbox_edges(
|
||||
TileGrid_t* tilemap,
|
||||
Entity_t* p_ent, Vector2 pos, Vector2 bbox,
|
||||
Entity_t* p_ent, Vector2 bbox,
|
||||
bool ignore_fragile
|
||||
)
|
||||
{
|
||||
uint8_t detected = 0;
|
||||
|
||||
Vector2 pos = p_ent->position;
|
||||
// Too lazy to adjust the tile area to check, so just make a big one
|
||||
CollideEntity_t ent =
|
||||
{
|
||||
|
|
|
@ -59,7 +59,7 @@ typedef struct CollideEntity {
|
|||
void remove_entity_from_tilemap(EntityManager_t *p_manager, TileGrid_t* tilemap, Entity_t* p_ent);
|
||||
uint8_t check_collision(const CollideEntity_t* ent, TileGrid_t* grid, bool check_oneway);
|
||||
uint8_t check_collision_line(const CollideEntity_t* ent, TileGrid_t* grid, bool check_oneway);
|
||||
uint8_t check_collision_offset(Entity_t* p_ent, Vector2 pos, Vector2 bbox_sz, TileGrid_t* grid, Vector2 offset);
|
||||
bool check_on_ground(Entity_t* p_ent, Vector2 pos, Vector2 prev_pos, Vector2 bbox_sz, TileGrid_t* grid);
|
||||
uint8_t check_bbox_edges(TileGrid_t* tilemap, Entity_t* p_ent, Vector2 pos, Vector2 bbox, bool ignore_fragile);
|
||||
uint8_t check_collision_at(Entity_t* p_ent, Vector2 pos, Vector2 bbox_sz, TileGrid_t* grid);
|
||||
bool check_on_ground(Entity_t* p_ent, Vector2 prev_pos, Vector2 bbox_sz, TileGrid_t* grid);
|
||||
uint8_t check_bbox_edges(TileGrid_t* tilemap, Entity_t* p_ent, Vector2 bbox, bool ignore_fragile);
|
||||
#endif // __COLLISION_FUNCS_H
|
||||
|
|
|
@ -21,6 +21,9 @@ void deinit_engine(GameEngine_t* engine)
|
|||
|
||||
void process_inputs(GameEngine_t* engine, Scene_t* scene)
|
||||
{
|
||||
Vector2 raw_mouse_pos = GetMousePosition();
|
||||
scene->mouse_pos = raw_mouse_pos;
|
||||
|
||||
unsigned int sz = sc_queue_size(&engine->key_buffer);
|
||||
// Process any existing pressed key
|
||||
for (size_t i = 0; i < sz; i++)
|
||||
|
@ -48,6 +51,33 @@ void process_inputs(GameEngine_t* engine, Scene_t* scene)
|
|||
do_action(scene, action, true);
|
||||
sc_queue_add_last(&engine->key_buffer, button);
|
||||
}
|
||||
|
||||
|
||||
// Mouse button handling
|
||||
ActionType_t action = sc_map_get_64(&scene->action_map, MOUSE_BUTTON_RIGHT);
|
||||
if (sc_map_found(&scene->action_map))
|
||||
{
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_RIGHT))
|
||||
{
|
||||
do_action(scene, action, true);
|
||||
}
|
||||
else if (IsMouseButtonReleased(MOUSE_BUTTON_RIGHT))
|
||||
{
|
||||
do_action(scene, action, false);
|
||||
}
|
||||
}
|
||||
action = sc_map_get_64(&scene->action_map, MOUSE_BUTTON_LEFT);
|
||||
if (sc_map_found(&scene->action_map))
|
||||
{
|
||||
if (IsMouseButtonDown(MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
do_action(scene, action, true);
|
||||
}
|
||||
else if (IsMouseButtonReleased(MOUSE_BUTTON_LEFT))
|
||||
{
|
||||
do_action(scene, action, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void change_scene(GameEngine_t* engine, unsigned int idx)
|
||||
|
@ -68,30 +98,52 @@ bool load_sfx(GameEngine_t* engine, const char* snd_name, uint32_t tag_idx)
|
|||
return true;
|
||||
}
|
||||
|
||||
void play_sfx(GameEngine_t* engine, unsigned int tag_idx)
|
||||
void play_sfx_pitched(GameEngine_t* engine, unsigned int tag_idx, float pitch)
|
||||
{
|
||||
if (tag_idx >= engine->sfx_list.n_sfx) return;
|
||||
SFX_t* sfx = engine->sfx_list.sfx + tag_idx;
|
||||
if (sfx->plays == 0 && sfx->snd != NULL)
|
||||
if (sfx->snd != NULL)
|
||||
{
|
||||
PlaySound(*sfx->snd);
|
||||
sfx->plays++;
|
||||
engine->sfx_list.sfx_queue[engine->sfx_list.played_sfx++] = tag_idx;
|
||||
SetSoundPitch(*sfx->snd, pitch);
|
||||
//if (sfx->snd != NULL)
|
||||
{
|
||||
PlaySound(*sfx->snd);
|
||||
sfx->plays++;
|
||||
}
|
||||
//SetSoundPitch(*sfx->snd, 0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void play_sfx(GameEngine_t* engine, unsigned int tag_idx)
|
||||
{
|
||||
play_sfx_pitched(engine, tag_idx, 0.0f);
|
||||
}
|
||||
|
||||
void stop_sfx(GameEngine_t* engine, unsigned int tag_idx)
|
||||
{
|
||||
if (tag_idx >= engine->sfx_list.n_sfx) return;
|
||||
SFX_t* sfx = engine->sfx_list.sfx + tag_idx;
|
||||
if (sfx->snd != NULL && IsSoundPlaying(*sfx->snd))
|
||||
{
|
||||
StopSound(*sfx->snd);
|
||||
//sfx->plays--;
|
||||
}
|
||||
}
|
||||
|
||||
void update_sfx_list(GameEngine_t* engine)
|
||||
{
|
||||
for (uint32_t i = 0; i< engine->sfx_list.played_sfx; ++i)
|
||||
for (uint32_t i = 0; i< engine->sfx_list.n_sfx; ++i)
|
||||
{
|
||||
uint32_t tag_idx = engine->sfx_list.sfx_queue[i];
|
||||
engine->sfx_list.sfx[tag_idx].plays = 0;
|
||||
if (!IsSoundPlaying(*engine->sfx_list.sfx->snd))
|
||||
{
|
||||
engine->sfx_list.sfx[i].plays = 0;
|
||||
}
|
||||
}
|
||||
engine->sfx_list.played_sfx = 0;
|
||||
}
|
||||
|
||||
//void init_scene(Scene_t* scene, SceneType_t scene_type, system_func_t render_func, action_func_t action_func)
|
||||
void init_scene(Scene_t* scene, system_func_t render_func, action_func_t action_func)
|
||||
void init_scene(Scene_t* scene, render_func_t render_func, action_func_t action_func)
|
||||
{
|
||||
sc_map_init_64(&scene->action_map, 32, 0);
|
||||
sc_array_init(&scene->systems);
|
||||
|
@ -102,6 +154,7 @@ void init_scene(Scene_t* scene, system_func_t render_func, action_func_t action_
|
|||
scene->render_function = render_func;
|
||||
scene->action_function = action_func;
|
||||
scene->state = SCENE_ENDED;
|
||||
scene->time_scale = 1.0f;
|
||||
}
|
||||
|
||||
void free_scene(Scene_t* scene)
|
||||
|
@ -112,21 +165,23 @@ void free_scene(Scene_t* scene)
|
|||
deinit_particle_system(&scene->part_sys);
|
||||
}
|
||||
|
||||
inline void update_scene(Scene_t* scene)
|
||||
inline void update_scene(Scene_t* scene, float delta_time)
|
||||
{
|
||||
scene->delta_time = delta_time * scene->time_scale;
|
||||
system_func_t sys;
|
||||
sc_array_foreach(&scene->systems, sys)
|
||||
{
|
||||
sys(scene);
|
||||
}
|
||||
update_particle_system(&scene->part_sys);
|
||||
update_particle_system(&scene->part_sys, scene->delta_time);
|
||||
}
|
||||
|
||||
inline void render_scene(Scene_t* scene)
|
||||
{
|
||||
BeginDrawing();
|
||||
scene->render_function(scene);
|
||||
EndDrawing();
|
||||
if (scene->render_function != NULL)
|
||||
{
|
||||
scene->render_function(scene);
|
||||
}
|
||||
}
|
||||
|
||||
inline void do_action(Scene_t* scene, ActionType_t action, bool pressed)
|
||||
|
|
|
@ -37,6 +37,7 @@ typedef enum SceneState {
|
|||
SCENE_ENDED,
|
||||
}SceneState_t;
|
||||
|
||||
typedef void(*render_func_t)(Scene_t*);
|
||||
typedef void(*system_func_t)(Scene_t*);
|
||||
typedef void(*action_func_t)(Scene_t*, ActionType_t, bool);
|
||||
sc_array_def(system_func_t, systems);
|
||||
|
@ -44,9 +45,12 @@ sc_array_def(system_func_t, systems);
|
|||
struct Scene {
|
||||
struct sc_map_64 action_map; // key -> actions
|
||||
struct sc_array_systems systems;
|
||||
system_func_t render_function;
|
||||
render_func_t render_function;
|
||||
action_func_t action_function;
|
||||
EntityManager_t ent_manager;
|
||||
float delta_time;
|
||||
float time_scale;
|
||||
Vector2 mouse_pos;
|
||||
//SceneType_t scene_type;
|
||||
SceneState_t state;
|
||||
ParticleSystem_t part_sys;
|
||||
|
@ -60,15 +64,16 @@ void process_inputs(GameEngine_t* engine, Scene_t* scene);
|
|||
void change_scene(GameEngine_t* engine, unsigned int idx);
|
||||
bool load_sfx(GameEngine_t* engine, const char* snd_name, uint32_t tag_idx);
|
||||
void play_sfx(GameEngine_t* engine, unsigned int tag_idx);
|
||||
void play_sfx_pitched(GameEngine_t* engine, unsigned int tag_idx, float pitch);
|
||||
void update_sfx_list(GameEngine_t* engine);
|
||||
|
||||
// Inline functions, for convenience
|
||||
extern void update_scene(Scene_t* scene);
|
||||
extern void update_scene(Scene_t* scene, float delta_time);
|
||||
extern void render_scene(Scene_t* scene);
|
||||
extern void do_action(Scene_t* scene, ActionType_t action, bool pressed);
|
||||
|
||||
//void init_scene(Scene_t* scene, SceneType_t scene_type, system_func_t render_func, action_func_t action_func);
|
||||
void init_scene(Scene_t* scene, system_func_t render_func, action_func_t action_func);
|
||||
void init_scene(Scene_t* scene, render_func_t render_func, action_func_t action_func);
|
||||
void free_scene(Scene_t* scene);
|
||||
|
||||
#endif // __ENGINE_H
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef _ENGINE_CONF_H
|
||||
#define _ENGINE_CONF_H
|
||||
|
||||
#define MAX_ENTITIES 2048
|
||||
#define MAX_TEXTURES 16
|
||||
#define MAX_SPRITES 64
|
||||
#define MAX_SOUNDS 32
|
||||
|
@ -11,12 +12,12 @@
|
|||
#define N_SFX 32
|
||||
#define MAX_EMITTER_CONF 8
|
||||
//#define MAX_PARTICLE_EMITTER 8
|
||||
#define MAX_ACTIVE_PARTICLE_EMITTER 128
|
||||
#define MAX_PARTICLES 32
|
||||
#define MAX_ACTIVE_PARTICLE_EMITTER 512
|
||||
#define MAX_PARTICLES 64
|
||||
|
||||
#define MAX_TILE_TYPES 16
|
||||
|
||||
#define N_TAGS 10
|
||||
#define N_COMPONENTS 15
|
||||
#define MAX_COMP_POOL_SIZE 4096
|
||||
#define N_COMPONENTS 20
|
||||
#define MAX_COMP_POOL_SIZE MAX_ENTITIES
|
||||
#endif // _ENGINE_CONF_H
|
||||
|
|
|
@ -230,3 +230,8 @@ void print_mempool_stats(char* buffer)
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t get_num_of_free_entities(void)
|
||||
{
|
||||
return ent_mempool.free_list.count;
|
||||
}
|
||||
|
|
|
@ -13,4 +13,5 @@ void* get_component_wtih_id(ComponentEnum_t comp_type, unsigned long idx);
|
|||
void free_component_to_mempool(ComponentEnum_t comp_type, unsigned long idx);
|
||||
|
||||
void print_mempool_stats(char* buffer);
|
||||
uint32_t get_num_of_free_entities(void);
|
||||
#endif //__MEMPOOL_H
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "particle_sys.h"
|
||||
#include "assets.h"
|
||||
#include "raymath.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
void init_particle_system(ParticleSystem_t* system)
|
||||
{
|
||||
|
@ -30,9 +30,9 @@ static inline float generate_randrange(float lo, float hi)
|
|||
|
||||
static inline void spawn_particle(ParticleEmitter_t* emitter, uint32_t idx)
|
||||
{
|
||||
uint32_t lifetime = (emitter->config->particle_lifetime[1] - emitter->config->particle_lifetime[0]);
|
||||
float lifetime = (emitter->config->particle_lifetime[1] - emitter->config->particle_lifetime[0]);
|
||||
emitter->particles[idx].timer = emitter->config->particle_lifetime[0];
|
||||
emitter->particles[idx].timer += rand() % lifetime;
|
||||
emitter->particles[idx].timer += lifetime * rand()/ (float)RAND_MAX;
|
||||
emitter->particles[idx].alive = true;
|
||||
|
||||
float angle = generate_randrange(emitter->config->launch_range[0], emitter->config->launch_range[1]);
|
||||
|
@ -92,7 +92,7 @@ void play_emitter_handle(ParticleSystem_t* system, uint16_t handle)
|
|||
{
|
||||
// TODO: deal with stream type
|
||||
//spawn_particle(emitter, 0);
|
||||
uint32_t incr = 0;
|
||||
float incr = 0;
|
||||
for (uint32_t i = 0; i < emitter->n_particles; ++i)
|
||||
{
|
||||
emitter->particles[i].timer = incr;
|
||||
|
@ -151,7 +151,7 @@ EmitterHandle play_particle_emitter(ParticleSystem_t* system, const ParticleEmit
|
|||
return idx;
|
||||
}
|
||||
|
||||
void update_particle_system(ParticleSystem_t* system)
|
||||
void update_particle_system(ParticleSystem_t* system, float delta_time)
|
||||
{
|
||||
uint32_t emitter_idx = system->emitter_list[0].next;
|
||||
uint32_t prev_idx = 0;
|
||||
|
@ -163,7 +163,7 @@ void update_particle_system(ParticleSystem_t* system)
|
|||
|
||||
if (emitter->emitter_update_func != NULL && emitter->active)
|
||||
{
|
||||
emitter->active = emitter->emitter_update_func(emitter);
|
||||
emitter->active = emitter->emitter_update_func(emitter, delta_time);
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < emitter->n_particles; ++i)
|
||||
|
@ -175,13 +175,13 @@ void update_particle_system(ParticleSystem_t* system)
|
|||
{
|
||||
if (emitter->update_func != NULL)
|
||||
{
|
||||
emitter->update_func(emitter->particles + i, emitter->user_data);
|
||||
emitter->update_func(emitter->particles + i, emitter->user_data, delta_time);
|
||||
}
|
||||
|
||||
}
|
||||
// Lifetime update
|
||||
if (emitter->particles[i].timer > 0) emitter->particles[i].timer--;
|
||||
if (emitter->particles[i].timer == 0)
|
||||
|
||||
emitter->particles[i].timer -= delta_time;
|
||||
if (emitter->particles[i].timer <= 0.0f)
|
||||
{
|
||||
if (emitter->particles[i].spawned)
|
||||
{
|
||||
|
@ -222,6 +222,10 @@ void update_particle_system(ParticleSystem_t* system)
|
|||
{
|
||||
emitter->finished = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (emitter->finished)
|
||||
{
|
||||
system->emitter_list[prev_idx].next = system->emitter_list[emitter_idx].next;
|
||||
system->emitter_list[emitter_idx].next = 0;
|
||||
system->emitter_list[emitter_idx].playing = false;
|
||||
|
|
|
@ -22,15 +22,15 @@ typedef struct Particle
|
|||
float rotation;
|
||||
float angular_vel;
|
||||
float size;
|
||||
uint32_t timer;
|
||||
float timer;
|
||||
bool alive;
|
||||
bool spawned;
|
||||
}Particle_t;
|
||||
|
||||
typedef struct ParticleEmitter ParticleEmitter_t;
|
||||
|
||||
typedef void (*particle_update_func_t)(Particle_t* part, void* user_data);
|
||||
typedef bool (*emitter_check_func_t)(const ParticleEmitter_t* emitter);
|
||||
typedef void (*particle_update_func_t)(Particle_t* part, void* user_data, float delta_time);
|
||||
typedef bool (*emitter_check_func_t)(const ParticleEmitter_t* emitter, float delta_time);
|
||||
|
||||
typedef struct EmitterConfig
|
||||
{
|
||||
|
@ -38,8 +38,8 @@ typedef struct EmitterConfig
|
|||
float speed_range[2];
|
||||
float angle_range[2];
|
||||
float rotation_range[2];
|
||||
uint32_t particle_lifetime[2];
|
||||
uint32_t initial_spawn_delay;
|
||||
float particle_lifetime[2];
|
||||
float initial_spawn_delay;
|
||||
PartEmitterType_t type;
|
||||
bool one_shot;
|
||||
}EmitterConfig_t;
|
||||
|
@ -51,7 +51,7 @@ struct ParticleEmitter
|
|||
Vector2 position;
|
||||
Particle_t particles[MAX_PARTICLES];
|
||||
uint32_t n_particles;
|
||||
uint32_t timer;
|
||||
float timer;
|
||||
bool finished;
|
||||
bool active;
|
||||
void* user_data;
|
||||
|
@ -88,7 +88,7 @@ void update_emitter_handle_position(ParticleSystem_t* system, EmitterHandle hand
|
|||
void unload_emitter_handle(ParticleSystem_t* system, EmitterHandle handle);
|
||||
bool is_emitter_handle_alive(ParticleSystem_t* system, EmitterHandle handle);
|
||||
|
||||
void update_particle_system(ParticleSystem_t* system);
|
||||
void update_particle_system(ParticleSystem_t* system, float delta_time);
|
||||
void draw_particle_system(ParticleSystem_t* system);
|
||||
void deinit_particle_system(ParticleSystem_t* system);
|
||||
#endif // _PARTICLE_SYSTEM_H
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "assets_loader.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
|
||||
Scene_t* scenes[1];
|
||||
static GameEngine_t engine =
|
||||
|
@ -39,10 +40,14 @@ int main(void)
|
|||
scenes[0] = &scene.scene;
|
||||
change_scene(&engine, 0);
|
||||
|
||||
const float DT = 1.0f/60.0f;
|
||||
while(true)
|
||||
{
|
||||
float frame_time = GetFrameTime();
|
||||
float delta_time = fminf(frame_time, DT);
|
||||
|
||||
process_inputs(&engine, &scene.scene);
|
||||
update_scene(&scene.scene);
|
||||
update_scene(&scene.scene, delta_time);
|
||||
update_entity_manager(&scene.scene.ent_manager);
|
||||
// This is needed to advance time delta
|
||||
render_scene(&scene.scene);
|
||||
|
|
8
main.c
8
main.c
|
@ -4,6 +4,7 @@
|
|||
#include "ent_impl.h"
|
||||
#include "mempool.h"
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#define N_SCENES 4
|
||||
|
||||
Scene_t *scenes[N_SCENES];
|
||||
|
@ -79,6 +80,7 @@ int main(void)
|
|||
scenes[2] = &sandbox_scene.scene;
|
||||
change_scene(&engine, 0);
|
||||
|
||||
const float DT = 1.0f/60.0f;
|
||||
while (!WindowShouldClose())
|
||||
{
|
||||
// This entire key processing relies on the assumption that a pressed key will
|
||||
|
@ -92,7 +94,11 @@ int main(void)
|
|||
|
||||
process_inputs(&engine, curr_scene);
|
||||
|
||||
update_scene(curr_scene);
|
||||
|
||||
float frame_time = GetFrameTime();
|
||||
float delta_time = fminf(frame_time, DT);
|
||||
|
||||
update_scene(curr_scene, delta_time);
|
||||
update_entity_manager(&curr_scene->ent_manager);
|
||||
// This is needed to advance time delta
|
||||
render_scene(curr_scene);
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
#include "scene_impl.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
|
||||
// Maintain own queue to handle key presses
|
||||
struct sc_queue_32 key_buffer;
|
||||
|
||||
const float DT = 1.0f/60.0f;
|
||||
int main(void)
|
||||
{
|
||||
sc_queue_init(&key_buffer);
|
||||
|
@ -48,7 +50,9 @@ int main(void)
|
|||
sc_queue_add_last(&key_buffer, button);
|
||||
}
|
||||
|
||||
update_scene(&scene.scene);
|
||||
float frame_time = GetFrameTime();
|
||||
float delta_time = fminf(frame_time, DT);
|
||||
update_scene(&scene.scene, delta_time);
|
||||
update_entity_manager(&scene.scene.ent_manager);
|
||||
// This is needed to advance time delta
|
||||
BeginDrawing();
|
||||
|
|
|
@ -6,11 +6,9 @@
|
|||
#include "constants.h"
|
||||
static const Vector2 GRAVITY = {0, GRAV_ACCEL};
|
||||
|
||||
void simple_particle_system_update(Particle_t* part, void* user_data)
|
||||
void simple_particle_system_update(Particle_t* part, void* user_data, float delta_time)
|
||||
{
|
||||
(void)user_data;
|
||||
|
||||
float delta_time = DELTA_T; // TODO: Will need to think about delta time handling
|
||||
part->rotation += part->angular_vel;
|
||||
|
||||
part->velocity =
|
||||
|
@ -46,7 +44,7 @@ void simple_particle_system_update(Particle_t* part, void* user_data)
|
|||
}
|
||||
}
|
||||
|
||||
static bool check_mouse_click(const ParticleEmitter_t* emitter)
|
||||
static bool check_mouse_click(const ParticleEmitter_t* emitter, float delta_time)
|
||||
{
|
||||
return IsMouseButtonDown(MOUSE_RIGHT_BUTTON);
|
||||
}
|
||||
|
@ -65,11 +63,13 @@ int main(void)
|
|||
.origin = (Vector2){0, 0},
|
||||
.anchor = (Vector2){tex.width / 2, tex.height / 2},
|
||||
.frame_count = 0,
|
||||
.elapsed = 0,
|
||||
.speed = 0,
|
||||
.name = "test_spr"
|
||||
};
|
||||
|
||||
const float DT = 1.0f/60.0f;
|
||||
float delta_time = 0.0f;
|
||||
|
||||
EmitterConfig_t conf ={
|
||||
.one_shot = true,
|
||||
.launch_range = {0, 360},
|
||||
|
@ -86,6 +86,7 @@ int main(void)
|
|||
.update_func = &simple_particle_system_update,
|
||||
.emitter_update_func = NULL,
|
||||
.spr = (tex.width == 0) ? NULL : &spr,
|
||||
.user_data = &delta_time,
|
||||
};
|
||||
|
||||
EmitterConfig_t conf2 ={
|
||||
|
@ -106,6 +107,7 @@ int main(void)
|
|||
.update_func = &simple_particle_system_update,
|
||||
.emitter_update_func = &check_mouse_click,
|
||||
.spr = (tex.width == 0) ? NULL : &spr,
|
||||
.user_data = NULL,
|
||||
};
|
||||
|
||||
bool key_press = false;
|
||||
|
@ -114,6 +116,8 @@ int main(void)
|
|||
EmitterHandle han = 0;
|
||||
while(!WindowShouldClose())
|
||||
{
|
||||
float frame_time = GetFrameTime();
|
||||
delta_time = fminf(frame_time, DT);
|
||||
Vector2 mouse_pos = GetMousePosition();
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
|
@ -145,7 +149,7 @@ int main(void)
|
|||
han = 0;
|
||||
}
|
||||
|
||||
update_particle_system(&part_sys);
|
||||
update_particle_system(&part_sys, delta_time);
|
||||
sprintf(text_buffer, "free: %u", get_number_of_free_emitter(&part_sys));
|
||||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
|
|
2
run.sh
2
run.sh
|
@ -1,3 +1,3 @@
|
|||
#!/bin/sh
|
||||
|
||||
LSAN_OPTIONS=suppressions=./lsan_supp.txt ./build/$1
|
||||
./build.sh && LSAN_OPTIONS=suppressions=./lsan_supp.txt ./build/$1
|
||||
|
|
12
scene_test.c
12
scene_test.c
|
@ -3,6 +3,7 @@
|
|||
#include "assets_loader.h"
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
|
@ -10,6 +11,7 @@
|
|||
return true; // Just preventDefault everything lol
|
||||
}
|
||||
#endif
|
||||
const float DT = 1.0f/60.0f;
|
||||
|
||||
Scene_t* scenes[1];
|
||||
static GameEngine_t engine =
|
||||
|
@ -26,7 +28,9 @@ void update_loop(void)
|
|||
Scene_t* scene = engine.scenes[engine.curr_scene];
|
||||
process_inputs(&engine, scene);
|
||||
|
||||
update_scene(scene);
|
||||
float frame_time = GetFrameTime();
|
||||
float delta_time = fminf(frame_time, DT);
|
||||
update_scene(scene, delta_time);
|
||||
update_entity_manager(&scene->ent_manager);
|
||||
// This is needed to advance time delta
|
||||
render_scene(scene);
|
||||
|
@ -75,6 +79,7 @@ int main(void)
|
|||
emscripten_set_main_loop(update_loop, 0, 1);
|
||||
#else
|
||||
puts("Regular main loop");
|
||||
const float DT = 1.0f/60.0f;
|
||||
while(true)
|
||||
{
|
||||
|
||||
|
@ -82,7 +87,10 @@ int main(void)
|
|||
// appear in the polling of raylib
|
||||
process_inputs(&engine, &scene.scene);
|
||||
|
||||
update_scene(&scene.scene);
|
||||
float frame_time = GetFrameTime();
|
||||
float delta_time = fminf(frame_time, DT);
|
||||
|
||||
update_scene(&scene.scene, delta_time);
|
||||
update_entity_manager(&scene.scene.ent_manager);
|
||||
// This is needed to advance time delta
|
||||
render_scene(&scene.scene);
|
||||
|
|
|
@ -41,7 +41,7 @@ static bool parse_emitter_info(char* emitter_info_str, EmitterConfig_t* conf)
|
|||
char emitter_type;
|
||||
uint8_t one_shot;
|
||||
int data_count = sscanf(
|
||||
emitter_info_str, "%c,%f-%f,%f-%f,%f-%f,%f-%f,%u-%u,%u,%c",
|
||||
emitter_info_str, "%c,%f-%f,%f-%f,%f-%f,%f-%f,%f-%f,%f,%c",
|
||||
&emitter_type,
|
||||
conf->launch_range, conf->launch_range + 1,
|
||||
conf->speed_range, conf->speed_range + 1,
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
#define MOVE_ACCEL 1300
|
||||
|
||||
#ifndef TILE16_SIZE
|
||||
#define PLAYER_WIDTH 30
|
||||
#define PLAYER_WIDTH 28
|
||||
#define PLAYER_HEIGHT 42
|
||||
#define PLAYER_C_WIDTH 30
|
||||
#define PLAYER_C_WIDTH 28
|
||||
#define PLAYER_C_HEIGHT 26
|
||||
#else
|
||||
#define PLAYER_WIDTH 14
|
||||
|
|
|
@ -92,6 +92,7 @@ static void level_scene_render_func(Scene_t* scene)
|
|||
draw_rec.y = 0;
|
||||
draw_rec.height *= -1;
|
||||
static char buffer[512];
|
||||
BeginDrawing();
|
||||
ClearBackground(LIGHTGRAY);
|
||||
DrawTextureRec(
|
||||
data->game_viewport.texture,
|
||||
|
@ -123,6 +124,9 @@ static void level_scene_render_func(Scene_t* scene)
|
|||
draw_pos.y += SELECTION_TILE_SIZE + 5;
|
||||
sprintf(buffer, "Crate %s on spawn", crate_activation? "active" : "inactive");
|
||||
DrawText(buffer, draw_pos.x, draw_pos.y, 20, BLACK);
|
||||
draw_pos.y += SELECTION_TILE_SIZE + 5;
|
||||
sprintf(buffer, "Time scale: %.2f", scene->time_scale);
|
||||
DrawText(buffer, draw_pos.x, draw_pos.y, 20, BLACK);
|
||||
|
||||
// For DEBUG
|
||||
const int gui_x = data->game_rec.x + data->game_rec.width + 10;
|
||||
|
@ -136,7 +140,7 @@ static void level_scene_render_func(Scene_t* scene)
|
|||
CPlayerState_t* p_pstate = get_component(p_ent, CPLAYERSTATE_T);
|
||||
CMovementState_t* p_mstate = get_component(p_ent, CMOVEMENTSTATE_T);
|
||||
|
||||
sprintf(buffer, "Pos: %.3f\n %.3f", p_ct->position.x, p_ct->position.y);
|
||||
sprintf(buffer, "Pos: %.3f\n %.3f", p_ent->position.x, p_ent->position.y);
|
||||
DrawText(buffer, gui_x, gui_y, 12, BLACK);
|
||||
sprintf(buffer, "Vel: %.3f\n %.3f", p_ct->velocity.x, p_ct->velocity.y);
|
||||
DrawText(buffer, gui_x + 80, gui_y, 12, BLACK);
|
||||
|
@ -184,6 +188,7 @@ static void level_scene_render_func(Scene_t* scene)
|
|||
gui_y += 300;
|
||||
sprintf(buffer, "Chests: %u / %u", data->coins.current, data->coins.total);
|
||||
DrawText(buffer, gui_x, gui_y, 24, BLACK);
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
static void render_editor_game_scene(Scene_t* scene)
|
||||
|
@ -290,7 +295,6 @@ static void render_editor_game_scene(Scene_t* scene)
|
|||
char buffer[64] = {0};
|
||||
sc_map_foreach_value(&scene->ent_manager.entities, p_ent)
|
||||
{
|
||||
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
|
||||
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
|
||||
|
||||
// Draw the spawn point
|
||||
|
@ -303,10 +307,10 @@ static void render_editor_game_scene(Scene_t* scene)
|
|||
Vector2 box_size = {0};
|
||||
if (p_bbox != NULL) box_size = p_bbox->size;
|
||||
if (
|
||||
p_ct->position.x + box_size.x < min.x * tilemap.tile_size
|
||||
|| p_ct->position.x > max.x * tilemap.tile_size
|
||||
|| p_ct->position.y + box_size.y < min.y * tilemap.tile_size
|
||||
|| p_ct->position.y > max.y * tilemap.tile_size
|
||||
p_ent->position.x + box_size.x < min.x * tilemap.tile_size
|
||||
|| p_ent->position.x > max.x * tilemap.tile_size
|
||||
|| p_ent->position.y + box_size.y < min.y * tilemap.tile_size
|
||||
|| p_ent->position.y > max.y * tilemap.tile_size
|
||||
) continue;
|
||||
|
||||
Color colour;
|
||||
|
@ -336,11 +340,11 @@ static void render_editor_game_scene(Scene_t* scene)
|
|||
{
|
||||
if (p_ent->m_tag == BOULDER_ENT_TAG)
|
||||
{
|
||||
DrawCircleV(Vector2Add(p_ct->position, p_bbox->half_size), p_bbox->half_size.x, colour);
|
||||
DrawCircleV(Vector2Add(p_ent->position, p_bbox->half_size), p_bbox->half_size.x, colour);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawRectangle(p_ct->position.x, p_ct->position.y, p_bbox->size.x, p_bbox->size.y, colour);
|
||||
DrawRectangle(p_ent->position.x, p_ent->position.y, p_bbox->size.x, p_bbox->size.y, colour);
|
||||
}
|
||||
|
||||
if (p_ent->m_tag == CRATES_ENT_TAG)
|
||||
|
@ -352,42 +356,42 @@ static void render_editor_game_scene(Scene_t* scene)
|
|||
{
|
||||
case CONTAINER_LEFT_ARROW:
|
||||
DrawLine(
|
||||
p_ct->position.x,
|
||||
p_ct->position.y + p_bbox->half_size.y,
|
||||
p_ct->position.x + p_bbox->half_size.x,
|
||||
p_ct->position.y + p_bbox->half_size.y,
|
||||
p_ent->position.x,
|
||||
p_ent->position.y + p_bbox->half_size.y,
|
||||
p_ent->position.x + p_bbox->half_size.x,
|
||||
p_ent->position.y + p_bbox->half_size.y,
|
||||
BLACK
|
||||
);
|
||||
break;
|
||||
case CONTAINER_RIGHT_ARROW:
|
||||
DrawLine(
|
||||
p_ct->position.x + p_bbox->half_size.x,
|
||||
p_ct->position.y + p_bbox->half_size.y,
|
||||
p_ct->position.x + p_bbox->size.x,
|
||||
p_ct->position.y + p_bbox->half_size.y,
|
||||
p_ent->position.x + p_bbox->half_size.x,
|
||||
p_ent->position.y + p_bbox->half_size.y,
|
||||
p_ent->position.x + p_bbox->size.x,
|
||||
p_ent->position.y + p_bbox->half_size.y,
|
||||
BLACK
|
||||
);
|
||||
break;
|
||||
case CONTAINER_UP_ARROW:
|
||||
DrawLine(
|
||||
p_ct->position.x + p_bbox->half_size.x,
|
||||
p_ct->position.y,
|
||||
p_ct->position.x + p_bbox->half_size.x,
|
||||
p_ct->position.y + p_bbox->half_size.y,
|
||||
p_ent->position.x + p_bbox->half_size.x,
|
||||
p_ent->position.y,
|
||||
p_ent->position.x + p_bbox->half_size.x,
|
||||
p_ent->position.y + p_bbox->half_size.y,
|
||||
BLACK
|
||||
);
|
||||
break;
|
||||
case CONTAINER_DOWN_ARROW:
|
||||
DrawLine(
|
||||
p_ct->position.x + p_bbox->half_size.x,
|
||||
p_ct->position.y + p_bbox->half_size.y,
|
||||
p_ct->position.x + p_bbox->half_size.x,
|
||||
p_ct->position.y + p_bbox->size.y,
|
||||
p_ent->position.x + p_bbox->half_size.x,
|
||||
p_ent->position.y + p_bbox->half_size.y,
|
||||
p_ent->position.x + p_bbox->half_size.x,
|
||||
p_ent->position.y + p_bbox->size.y,
|
||||
BLACK
|
||||
);
|
||||
break;
|
||||
case CONTAINER_BOMB:
|
||||
DrawCircleV(Vector2Add(p_ct->position, p_bbox->half_size), p_bbox->half_size.x, BLACK);
|
||||
DrawCircleV(Vector2Add(p_ent->position, p_bbox->half_size), p_bbox->half_size.x, BLACK);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -403,8 +407,8 @@ static void render_editor_game_scene(Scene_t* scene)
|
|||
for (uint8_t i = 0;i < p_hitbox->n_boxes; ++i)
|
||||
{
|
||||
Rectangle rec = {
|
||||
.x = p_ct->position.x + p_hitbox->boxes[i].x,
|
||||
.y = p_ct->position.y + p_hitbox->boxes[i].y,
|
||||
.x = p_ent->position.x + p_hitbox->boxes[i].x,
|
||||
.y = p_ent->position.y + p_hitbox->boxes[i].y,
|
||||
.width = p_hitbox->boxes[i].width,
|
||||
.height = p_hitbox->boxes[i].height,
|
||||
};
|
||||
|
@ -414,8 +418,8 @@ static void render_editor_game_scene(Scene_t* scene)
|
|||
if (p_hurtbox != NULL)
|
||||
{
|
||||
Rectangle rec = {
|
||||
.x = p_ct->position.x + p_hurtbox->offset.x,
|
||||
.y = p_ct->position.y + p_hurtbox->offset.y,
|
||||
.x = p_ent->position.x + p_hurtbox->offset.x,
|
||||
.y = p_ent->position.y + p_hurtbox->offset.y,
|
||||
.width = p_hurtbox->size.x,
|
||||
.height = p_hurtbox->size.y,
|
||||
};
|
||||
|
@ -427,7 +431,7 @@ static void render_editor_game_scene(Scene_t* scene)
|
|||
const SpriteRenderInfo_t spr = p_cspr->sprites[p_cspr->current_idx];
|
||||
if (spr.sprite != NULL)
|
||||
{
|
||||
Vector2 pos = Vector2Add(p_ct->position, spr.offset);
|
||||
Vector2 pos = Vector2Add(p_ent->position, spr.offset);
|
||||
draw_sprite(spr.sprite, p_cspr->current_frame, pos, 0.0f, p_cspr->flip_x);
|
||||
}
|
||||
}
|
||||
|
@ -435,8 +439,7 @@ static void render_editor_game_scene(Scene_t* scene)
|
|||
|
||||
sc_map_foreach_value(&scene->ent_manager.entities_map[LEVEL_END_TAG], p_ent)
|
||||
{
|
||||
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
|
||||
DrawCircleV(p_ct->position, tilemap.tile_size >> 1, (data->coins.current < data->coins.total)? RED : GREEN);
|
||||
DrawCircleV(p_ent->position, tilemap.tile_size >> 1, (data->coins.current < data->coins.total)? RED : GREEN);
|
||||
}
|
||||
|
||||
draw_particle_system(&scene->part_sys);
|
||||
|
@ -518,9 +521,10 @@ static void spawn_chest(Scene_t* scene, unsigned int tile_idx)
|
|||
Entity_t* p_crate = create_chest(&scene->ent_manager);
|
||||
if (p_crate == NULL) return;
|
||||
|
||||
p_crate->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
|
||||
p_crate->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
|
||||
|
||||
CTransform_t* p_ctransform = get_component(p_crate, CTRANSFORM_COMP_T);
|
||||
p_ctransform->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
|
||||
p_ctransform->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
|
||||
p_ctransform->active = true;
|
||||
}
|
||||
|
||||
|
@ -529,10 +533,10 @@ static void spawn_crate(Scene_t* scene, unsigned int tile_idx, bool metal, Conta
|
|||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||
Entity_t* p_crate = create_crate(&scene->ent_manager, metal, item);
|
||||
if (p_crate == NULL) return;
|
||||
p_crate->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
|
||||
p_crate->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
|
||||
|
||||
CTransform_t* p_ctransform = get_component(p_crate, CTRANSFORM_COMP_T);
|
||||
p_ctransform->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
|
||||
p_ctransform->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
|
||||
p_ctransform->active = active;
|
||||
}
|
||||
|
||||
|
@ -542,21 +546,18 @@ static void spawn_boulder(Scene_t* scene, unsigned int tile_idx)
|
|||
Entity_t* p_boulder = create_boulder(&scene->ent_manager);
|
||||
if (p_boulder == NULL) return;
|
||||
|
||||
CTransform_t* p_ctransform = get_component(p_boulder, CTRANSFORM_COMP_T);
|
||||
p_ctransform->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
|
||||
p_ctransform->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
|
||||
p_boulder->position.x = (tile_idx % data->tilemap.width) * TILE_SIZE;
|
||||
p_boulder->position.y = (tile_idx / data->tilemap.width) * TILE_SIZE;
|
||||
}
|
||||
|
||||
static void toggle_block_system(Scene_t* scene)
|
||||
static void toggle_block_system(Scene_t* scene, ActionType_t action, bool pressed)
|
||||
{
|
||||
// TODO: This system is not good as the interface between raw input and actions is broken
|
||||
static unsigned int last_tile_idx = MAX_N_TILES;
|
||||
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||
TileGrid_t tilemap = data->tilemap;
|
||||
Vector2 raw_mouse_pos = {GetMouseX(), GetMouseY()};
|
||||
raw_mouse_pos = Vector2Subtract(raw_mouse_pos, (Vector2){data->game_rec.x, data->game_rec.y});
|
||||
Vector2 raw_mouse_pos = Vector2Subtract(scene->mouse_pos, (Vector2){data->game_rec.x, data->game_rec.y});
|
||||
|
||||
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
|
||||
if (action == ACTION_SPAWN_TILE && !pressed)
|
||||
{
|
||||
last_tile_idx = MAX_N_TILES;
|
||||
}
|
||||
|
@ -571,7 +572,7 @@ static void toggle_block_system(Scene_t* scene)
|
|||
if (tile_idx >= (tilemap.n_tiles - tilemap.width)) return;
|
||||
if (tile_idx == last_tile_idx) return;
|
||||
|
||||
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
||||
if (action == ACTION_SPAWN_TILE && pressed)
|
||||
{
|
||||
enum EntitySpawnSelection sel = (enum EntitySpawnSelection)current_spawn_selection;
|
||||
TileType_t new_type = EMPTY_TILE;
|
||||
|
@ -642,9 +643,8 @@ static void toggle_block_system(Scene_t* scene)
|
|||
Entity_t* p_ent = create_water_runner(&scene->ent_manager, DEFAULT_MAP_WIDTH, DEFAULT_MAP_HEIGHT, tile_idx);
|
||||
if (p_ent != NULL)
|
||||
{
|
||||
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
|
||||
p_ct->position.x = (tile_idx % tilemap.width) * tilemap.tile_size;
|
||||
p_ct->position.y = (tile_idx / tilemap.width) * tilemap.tile_size;
|
||||
p_ent->position.x = (tile_idx % tilemap.width) * tilemap.tile_size;
|
||||
p_ent->position.y = (tile_idx / tilemap.width) * tilemap.tile_size;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -653,9 +653,8 @@ static void toggle_block_system(Scene_t* scene)
|
|||
Entity_t* p_ent = create_level_end(&scene->ent_manager);
|
||||
if (p_ent != NULL)
|
||||
{
|
||||
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
|
||||
p_ct->position.x = (tile_idx % tilemap.width) * tilemap.tile_size + (tilemap.tile_size >> 1);
|
||||
p_ct->position.y = (tile_idx / tilemap.width) * tilemap.tile_size + (tilemap.tile_size >> 1);;
|
||||
p_ent->position.x = (tile_idx % tilemap.width) * tilemap.tile_size + (tilemap.tile_size >> 1);
|
||||
p_ent->position.y = (tile_idx / tilemap.width) * tilemap.tile_size + (tilemap.tile_size >> 1);;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -675,7 +674,7 @@ static void toggle_block_system(Scene_t* scene)
|
|||
p_crunner->state = BFS_RESET;
|
||||
}
|
||||
}
|
||||
else if (IsMouseButtonDown(MOUSE_RIGHT_BUTTON))
|
||||
else if (action == ACTION_REMOVE_TILE && pressed)
|
||||
{
|
||||
change_a_tile(&tilemap, tile_idx, EMPTY_TILE);
|
||||
tilemap.tiles[tile_idx].water_level = 0;
|
||||
|
@ -728,7 +727,7 @@ static void toggle_block_system(Scene_t* scene)
|
|||
&& raw_mouse_pos.y < SELECTION_REGION_HEIGHT
|
||||
)
|
||||
{
|
||||
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON))
|
||||
if (action == ACTION_SPAWN_TILE && !pressed)
|
||||
{
|
||||
current_spawn_selection = ((int)raw_mouse_pos.x / SELECTION_TILE_SIZE);
|
||||
}
|
||||
|
@ -965,11 +964,25 @@ static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
|
|||
}
|
||||
break;
|
||||
case ACTION_SET_SPAWNPOINT:
|
||||
{
|
||||
CTransform_t* p_ct = get_component(p_player, CTRANSFORM_COMP_T);
|
||||
p_player->spawn_pos = p_ct->position;
|
||||
}
|
||||
p_player->spawn_pos = p_player->position;
|
||||
break;
|
||||
case ACTION_TOGGLE_TIMESLOW:
|
||||
if (!pressed)
|
||||
{
|
||||
if (scene->time_scale < 1.0f)
|
||||
{
|
||||
scene->time_scale = 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
scene->time_scale = 0.25f;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ACTION_SPAWN_TILE:
|
||||
case ACTION_REMOVE_TILE:
|
||||
toggle_block_system(scene, action, pressed);
|
||||
update_entity_manager(&scene->ent_manager);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1214,7 +1227,6 @@ void init_sandbox_scene(LevelScene_t* scene)
|
|||
sc_array_add(&scene->scene.systems, &update_water_runner_system);
|
||||
sc_array_add(&scene->scene.systems, &player_respawn_system);
|
||||
sc_array_add(&scene->scene.systems, &level_end_detection_system);
|
||||
sc_array_add(&scene->scene.systems, &toggle_block_system);
|
||||
sc_array_add(&scene->scene.systems, &render_editor_game_scene);
|
||||
|
||||
// This avoid graphical glitch, not essential
|
||||
|
@ -1238,6 +1250,9 @@ void init_sandbox_scene(LevelScene_t* scene)
|
|||
sc_map_put_64(&scene->scene.action_map, KEY_R, ACTION_RESTART);
|
||||
sc_map_put_64(&scene->scene.action_map, KEY_B, ACTION_TOGGLE_GRID);
|
||||
sc_map_put_64(&scene->scene.action_map, KEY_V, ACTION_SET_SPAWNPOINT);
|
||||
sc_map_put_64(&scene->scene.action_map, KEY_U, ACTION_TOGGLE_TIMESLOW);
|
||||
sc_map_put_64(&scene->scene.action_map, MOUSE_LEFT_BUTTON, ACTION_SPAWN_TILE);
|
||||
sc_map_put_64(&scene->scene.action_map, MOUSE_RIGHT_BUTTON, ACTION_REMOVE_TILE);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ static void level_scene_render_func(Scene_t* scene)
|
|||
draw_rec.height *= -1;
|
||||
|
||||
static char buffer[512];
|
||||
BeginDrawing();
|
||||
ClearBackground(LIGHTGRAY);
|
||||
DrawTextureRec(
|
||||
data->game_viewport.texture,
|
||||
|
@ -50,6 +51,7 @@ static void level_scene_render_func(Scene_t* scene)
|
|||
|
||||
print_mempool_stats(buffer);
|
||||
DrawText(buffer, gui_x, 350, 12, BLACK);
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
|
||||
|
@ -202,17 +204,16 @@ static void render_regular_game_scene(Scene_t* scene)
|
|||
|
||||
sc_map_foreach_value(&scene->ent_manager.entities, p_ent)
|
||||
{
|
||||
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
|
||||
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
|
||||
|
||||
// Entity culling
|
||||
Vector2 box_size = {0};
|
||||
if (p_bbox != NULL) box_size = p_bbox->size;
|
||||
if (
|
||||
p_ct->position.x + box_size.x < min.x * tilemap.tile_size
|
||||
|| p_ct->position.x > max.x * tilemap.tile_size
|
||||
|| p_ct->position.y + box_size.y < min.y * tilemap.tile_size
|
||||
|| p_ct->position.y > max.y * tilemap.tile_size
|
||||
p_ent->position.x + box_size.x < min.x * tilemap.tile_size
|
||||
|| p_ent->position.x > max.x * tilemap.tile_size
|
||||
|| p_ent->position.y + box_size.y < min.y * tilemap.tile_size
|
||||
|| p_ent->position.y > max.y * tilemap.tile_size
|
||||
) continue;
|
||||
|
||||
// Render Sprite only
|
||||
|
@ -222,7 +223,7 @@ static void render_regular_game_scene(Scene_t* scene)
|
|||
const SpriteRenderInfo_t spr = p_cspr->sprites[p_cspr->current_idx];
|
||||
if (spr.sprite != NULL)
|
||||
{
|
||||
Vector2 pos = Vector2Add(p_ct->position, spr.offset);
|
||||
Vector2 pos = Vector2Add(p_ent->position, spr.offset);
|
||||
draw_sprite(spr.sprite, p_cspr->current_frame, pos, 0.0f, p_cspr->flip_x);
|
||||
}
|
||||
continue;
|
||||
|
@ -250,11 +251,11 @@ static void render_regular_game_scene(Scene_t* scene)
|
|||
{
|
||||
if (p_ent->m_tag == BOULDER_ENT_TAG)
|
||||
{
|
||||
DrawCircleV(Vector2Add(p_ct->position, p_bbox->half_size), p_bbox->half_size.x, colour);
|
||||
DrawCircleV(Vector2Add(p_ent->position, p_bbox->half_size), p_bbox->half_size.x, colour);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawRectangle(p_ct->position.x, p_ct->position.y, p_bbox->size.x, p_bbox->size.y, colour);
|
||||
DrawRectangle(p_ent->position.x, p_ent->position.y, p_bbox->size.x, p_bbox->size.y, colour);
|
||||
}
|
||||
|
||||
if (p_ent->m_tag == CRATES_ENT_TAG)
|
||||
|
@ -266,42 +267,42 @@ static void render_regular_game_scene(Scene_t* scene)
|
|||
{
|
||||
case CONTAINER_LEFT_ARROW:
|
||||
DrawLine(
|
||||
p_ct->position.x,
|
||||
p_ct->position.y + p_bbox->half_size.y,
|
||||
p_ct->position.x + p_bbox->half_size.x,
|
||||
p_ct->position.y + p_bbox->half_size.y,
|
||||
p_ent->position.x,
|
||||
p_ent->position.y + p_bbox->half_size.y,
|
||||
p_ent->position.x + p_bbox->half_size.x,
|
||||
p_ent->position.y + p_bbox->half_size.y,
|
||||
BLACK
|
||||
);
|
||||
break;
|
||||
case CONTAINER_RIGHT_ARROW:
|
||||
DrawLine(
|
||||
p_ct->position.x + p_bbox->half_size.x,
|
||||
p_ct->position.y + p_bbox->half_size.y,
|
||||
p_ct->position.x + p_bbox->size.x,
|
||||
p_ct->position.y + p_bbox->half_size.y,
|
||||
p_ent->position.x + p_bbox->half_size.x,
|
||||
p_ent->position.y + p_bbox->half_size.y,
|
||||
p_ent->position.x + p_bbox->size.x,
|
||||
p_ent->position.y + p_bbox->half_size.y,
|
||||
BLACK
|
||||
);
|
||||
break;
|
||||
case CONTAINER_UP_ARROW:
|
||||
DrawLine(
|
||||
p_ct->position.x + p_bbox->half_size.x,
|
||||
p_ct->position.y,
|
||||
p_ct->position.x + p_bbox->half_size.x,
|
||||
p_ct->position.y + p_bbox->half_size.y,
|
||||
p_ent->position.x + p_bbox->half_size.x,
|
||||
p_ent->position.y,
|
||||
p_ent->position.x + p_bbox->half_size.x,
|
||||
p_ent->position.y + p_bbox->half_size.y,
|
||||
BLACK
|
||||
);
|
||||
break;
|
||||
case CONTAINER_DOWN_ARROW:
|
||||
DrawLine(
|
||||
p_ct->position.x + p_bbox->half_size.x,
|
||||
p_ct->position.y + p_bbox->half_size.y,
|
||||
p_ct->position.x + p_bbox->half_size.x,
|
||||
p_ct->position.y + p_bbox->size.y,
|
||||
p_ent->position.x + p_bbox->half_size.x,
|
||||
p_ent->position.y + p_bbox->half_size.y,
|
||||
p_ent->position.x + p_bbox->half_size.x,
|
||||
p_ent->position.y + p_bbox->size.y,
|
||||
BLACK
|
||||
);
|
||||
break;
|
||||
case CONTAINER_BOMB:
|
||||
DrawCircleV(Vector2Add(p_ct->position, p_bbox->half_size), p_bbox->half_size.x, BLACK);
|
||||
DrawCircleV(Vector2Add(p_ent->position, p_bbox->half_size), p_bbox->half_size.x, BLACK);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -44,7 +44,7 @@ Entity_t* create_crate(EntityManager_t* ent_manager, bool metal, ContainerItem_t
|
|||
p_bbox->fragile = false;
|
||||
|
||||
CTransform_t* p_ctransform = add_component(p_crate, CTRANSFORM_COMP_T);
|
||||
p_ctransform->grav_delay = 7;
|
||||
p_ctransform->grav_delay = 0.20f;
|
||||
p_ctransform->shape_factor = metal ? (Vector2){0.7,0.7} : (Vector2){0.8,0.8} ;
|
||||
add_component(p_crate, CMOVEMENTSTATE_T);
|
||||
|
||||
|
@ -87,7 +87,7 @@ Entity_t* create_boulder(EntityManager_t* ent_manager)
|
|||
p_bbox->fragile = false;
|
||||
|
||||
CTransform_t* p_ctransform = add_component(p_boulder, CTRANSFORM_COMP_T);
|
||||
p_ctransform->grav_delay = 5;
|
||||
p_ctransform->grav_delay = 1.0f/12;
|
||||
p_ctransform->active = true;
|
||||
p_ctransform->shape_factor = (Vector2){0.6, 0.6};
|
||||
CMovementState_t* p_move = add_component(p_boulder, CMOVEMENTSTATE_T);
|
||||
|
@ -95,7 +95,7 @@ Entity_t* create_boulder(EntityManager_t* ent_manager)
|
|||
|
||||
add_component(p_boulder, CTILECOORD_COMP_T);
|
||||
CMoveable_t* p_cmove = add_component(p_boulder, CMOVEABLE_T);
|
||||
p_cmove->move_speed = 8;
|
||||
p_cmove->move_speed = 480;
|
||||
CHurtbox_t* p_hurtbox = add_component(p_boulder, CHURTBOX_T);
|
||||
p_hurtbox->size = p_bbox->size;
|
||||
p_hurtbox->def = 2;
|
||||
|
@ -159,6 +159,17 @@ Entity_t* create_bomb(EntityManager_t* ent_manager, Vector2 launch_dir)
|
|||
Entity_t* p_bomb = add_entity(ent_manager, DESTRUCTABLE_ENT_TAG);
|
||||
if (p_bomb == NULL) return NULL;
|
||||
|
||||
p_bomb->position.x += (TILE_SIZE - 25) / 2;
|
||||
p_bomb->position.y += (TILE_SIZE - 25) / 2;
|
||||
if (launch_dir.x > 0)
|
||||
{
|
||||
p_bomb->position.x += TILE_SIZE/ 2;
|
||||
}
|
||||
else if (launch_dir.x < 0)
|
||||
{
|
||||
p_bomb->position.x -= TILE_SIZE / 2;
|
||||
}
|
||||
|
||||
add_component(p_bomb, CTILECOORD_COMP_T);
|
||||
add_component(p_bomb, CMOVEMENTSTATE_T);
|
||||
CHitBoxes_t* p_hitbox = add_component(p_bomb, CHITBOXES_T);
|
||||
|
@ -179,19 +190,9 @@ Entity_t* create_bomb(EntityManager_t* ent_manager, Vector2 launch_dir)
|
|||
p_ctransform->active = true;
|
||||
p_ctransform->shape_factor = (Vector2){0.1, 0.1};
|
||||
p_ctransform->movement_mode = REGULAR_MOVEMENT;
|
||||
p_ctransform->position.x += (TILE_SIZE - 25) / 2;
|
||||
p_ctransform->position.y += (TILE_SIZE - 25) / 2;
|
||||
|
||||
p_ctransform->velocity = Vector2Scale(Vector2Normalize(launch_dir), 500);
|
||||
|
||||
if (launch_dir.x > 0)
|
||||
{
|
||||
p_ctransform->position.x += TILE_SIZE/ 2;
|
||||
}
|
||||
else if (launch_dir.x < 0)
|
||||
{
|
||||
p_ctransform->position.x -= TILE_SIZE / 2;
|
||||
}
|
||||
return p_bomb;
|
||||
}
|
||||
|
||||
|
@ -200,6 +201,8 @@ Entity_t* create_explosion(EntityManager_t* ent_manager)
|
|||
Entity_t* p_explosion = add_entity(ent_manager, DESTRUCTABLE_ENT_TAG);
|
||||
if (p_explosion == NULL) return NULL;
|
||||
|
||||
p_explosion->position.x -= 16;
|
||||
p_explosion->position.y -= 16;
|
||||
add_component(p_explosion, CTILECOORD_COMP_T);
|
||||
CHitBoxes_t* p_hitbox = add_component(p_explosion, CHITBOXES_T);
|
||||
p_hitbox->n_boxes = 1;
|
||||
|
@ -209,8 +212,6 @@ Entity_t* create_explosion(EntityManager_t* ent_manager)
|
|||
CTransform_t* p_ctransform = add_component(p_explosion, CTRANSFORM_COMP_T);
|
||||
p_ctransform->movement_mode = KINEMATIC_MOVEMENT;
|
||||
p_ctransform->active = true;
|
||||
p_ctransform->position.x -= 16;
|
||||
p_ctransform->position.y -= 16;
|
||||
p_hitbox->boxes[0] = (Rectangle){0, 0, TILE_SIZE + 32, TILE_SIZE + 32};
|
||||
|
||||
CSprite_t* p_cspr = add_component(p_explosion, CSPRITE_T);
|
||||
|
@ -218,7 +219,7 @@ Entity_t* create_explosion(EntityManager_t* ent_manager)
|
|||
p_cspr->current_idx = 17;
|
||||
|
||||
CLifeTimer_t* p_clifetimer = add_component(p_explosion, CLIFETIMER_T);
|
||||
p_clifetimer->life_time = 3;
|
||||
p_clifetimer->life_time = 0.05f;
|
||||
return p_explosion;
|
||||
}
|
||||
|
||||
|
@ -233,7 +234,7 @@ Entity_t* create_chest(EntityManager_t* ent_manager)
|
|||
p_bbox->fragile = true;
|
||||
|
||||
CTransform_t* p_ctransform = add_component(p_chest, CTRANSFORM_COMP_T);
|
||||
p_ctransform->grav_delay = 7;
|
||||
p_ctransform->grav_delay = 0.3f;
|
||||
p_ctransform->shape_factor = (Vector2){0.7,0.7};
|
||||
add_component(p_chest, CMOVEMENTSTATE_T);
|
||||
add_component(p_chest, CTILECOORD_COMP_T);
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
static void menu_scene_render_func(Scene_t* scene)
|
||||
{
|
||||
MenuSceneData_t* data = &(CONTAINER_OF(scene, MenuScene_t, scene)->data);
|
||||
ClearBackground(RAYWHITE);
|
||||
DrawText("This is a game", 25, 220, 12, BLACK);
|
||||
UI_button(data->buttons, "Start");
|
||||
UI_button(data->buttons + 1, "Sandbox");
|
||||
UI_button(data->buttons + 2, "Continue");
|
||||
UI_button(data->buttons + 3, "Exit");
|
||||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
DrawText("This is a game", 25, 220, 12, BLACK);
|
||||
UI_button(data->buttons, "Start");
|
||||
UI_button(data->buttons + 1, "Sandbox");
|
||||
UI_button(data->buttons + 2, "Continue");
|
||||
UI_button(data->buttons + 3, "Exit");
|
||||
EndDrawing();
|
||||
}
|
||||
|
||||
static void exec_component_function(Scene_t* scene, int sel)
|
||||
|
|
|
@ -98,8 +98,8 @@ Entity_t* create_player(EntityManager_t* ent_manager)
|
|||
CAirTimer_t* p_air = add_component(p_ent, CAIRTIMER_T);
|
||||
p_air->max_count = 10;
|
||||
p_air->curr_count = 10;
|
||||
p_air->max_ftimer = 300;
|
||||
p_air->decay_rate = 5;
|
||||
p_air->max_ftimer = 1.0f;
|
||||
p_air->decay_rate = 1.0f;
|
||||
|
||||
CSprite_t* p_cspr = add_component(p_ent, CSPRITE_T);
|
||||
p_cspr->sprites = player_sprite_map;
|
||||
|
|
|
@ -105,9 +105,8 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
|
|||
}
|
||||
|
||||
Entity_t* ent = create_crate(&scene->scene.ent_manager, tmp_idx > 5, item);
|
||||
CTransform_t* p_ct = get_component(ent, CTRANSFORM_COMP_T);
|
||||
p_ct->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
|
||||
p_ct->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
|
||||
ent->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
|
||||
ent->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -129,9 +128,8 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
|
|||
case 20:
|
||||
{
|
||||
Entity_t* ent = create_boulder(&scene->scene.ent_manager);
|
||||
CTransform_t* p_ct = get_component(ent, CTRANSFORM_COMP_T);
|
||||
p_ct->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
|
||||
p_ct->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
|
||||
ent->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
|
||||
ent->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
|
||||
}
|
||||
break;
|
||||
case 21:
|
||||
|
@ -142,10 +140,9 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
|
|||
case 22:
|
||||
{
|
||||
Entity_t* ent = create_player(&scene->scene.ent_manager);
|
||||
CTransform_t* p_ct = get_component(ent, CTRANSFORM_COMP_T);
|
||||
p_ct->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
|
||||
p_ct->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
|
||||
ent->spawn_pos = p_ct->position;
|
||||
ent->position.x = (i % scene->data.tilemap.width) * scene->data.tilemap.tile_size;
|
||||
ent->position.y = (i / scene->data.tilemap.width) * scene->data.tilemap.tile_size;
|
||||
ent->spawn_pos = ent->position;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -223,9 +223,8 @@ void update_water_runner_system(Scene_t* scene)
|
|||
while (move_left)
|
||||
{
|
||||
p_crunner->current_tile = p_crunner->bfs_tilemap.tilemap[p_crunner->current_tile].to;
|
||||
CTransform_t* p_ct = get_component(ent, CTRANSFORM_COMP_T);
|
||||
p_ct->position.x = (p_crunner->current_tile % tilemap.width) * tilemap.tile_size;
|
||||
p_ct->position.y = (p_crunner->current_tile / tilemap.width) * tilemap.tile_size;
|
||||
ent->position.x = (p_crunner->current_tile % tilemap.width) * tilemap.tile_size;
|
||||
ent->position.y = (p_crunner->current_tile / tilemap.width) * tilemap.tile_size;
|
||||
|
||||
Tile_t* tile = tilemap.tiles + p_crunner->current_tile;
|
||||
tile->wet = true;
|
||||
|
@ -290,6 +289,11 @@ void update_water_runner_system(Scene_t* scene)
|
|||
break;
|
||||
case SCANLINE_FILL:
|
||||
{
|
||||
const float FILL_RATE = 1.0f/24;
|
||||
p_crunner->fractional += scene->delta_time;
|
||||
if (p_crunner->fractional < FILL_RATE) break;
|
||||
|
||||
p_crunner->fractional -= FILL_RATE;
|
||||
// Unsigned usage here is okay
|
||||
unsigned int start_tile =
|
||||
(p_crunner->current_tile / p_crunner->bfs_tilemap.width) * p_crunner->bfs_tilemap.width;
|
||||
|
|
12
water_test.c
12
water_test.c
|
@ -108,7 +108,7 @@ static void level_scene_render_func(Scene_t* scene)
|
|||
const SpriteRenderInfo_t spr = p_cspr->sprites[p_cspr->current_idx];
|
||||
if (spr.sprite != NULL)
|
||||
{
|
||||
Vector2 pos = Vector2Add(p_ct->position, spr.offset);
|
||||
Vector2 pos = Vector2Add(p_ent->position, spr.offset);
|
||||
draw_sprite(spr.sprite, p_cspr->current_frame, pos, 0.0f, p_cspr->flip_x);
|
||||
}
|
||||
}
|
||||
|
@ -318,8 +318,8 @@ static void toggle_block_system(Scene_t* scene)
|
|||
if (p_ent == NULL) return;
|
||||
|
||||
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
|
||||
p_ct->position.x = (tile_idx % tilemap.width) * tilemap.tile_size;
|
||||
p_ct->position.y = (tile_idx / tilemap.width) * tilemap.tile_size;
|
||||
p_ent->position.x = (tile_idx % tilemap.width) * tilemap.tile_size;
|
||||
p_ent->position.y = (tile_idx / tilemap.width) * tilemap.tile_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -451,10 +451,14 @@ int main(void)
|
|||
sc_map_put_64(&scene.scene.action_map, KEY_P, ACTION_METAL_TOGGLE);
|
||||
|
||||
|
||||
const float DT = 1.0f/60.0f;
|
||||
while(true)
|
||||
{
|
||||
float frame_time = GetFrameTime();
|
||||
float delta_time = fminf(frame_time, DT);
|
||||
|
||||
process_inputs(&engine, &scene.scene);
|
||||
update_scene(&scene.scene);
|
||||
update_scene(&scene.scene, delta_time);
|
||||
update_entity_manager(&scene.scene.ent_manager);
|
||||
// This is needed to advance time delta
|
||||
render_scene(&scene.scene);
|
||||
|
|
Loading…
Reference in New Issue