Compare commits

...

4 Commits

Author SHA1 Message Date
En Yi f4167c6270 Add chest count in main game 2024-08-20 16:38:07 +08:00
En Yi bae17e8a87 Add level ending in main game 2024-08-20 14:52:26 +08:00
En Yi f208964e7f Fix rendering for finishing the level 2024-08-20 14:03:59 +08:00
En Yi 2be80ea6bf Add sprites for player finishing the stage
Also add cave exit sprite

They are all placeholder for now.
2024-08-20 14:03:41 +08:00
10 changed files with 169 additions and 29 deletions

View File

@ -275,7 +275,7 @@ static LevelPack_t* add_level_pack_zst(Assets_t* assets, const char* name, const
for (lvls = 0; lvls < n_levels; ++lvls) for (lvls = 0; lvls < n_levels; ++lvls)
{ {
printf("Parsing level %u\n", lvls); printf("Parsing level %u\n", lvls);
output.size = 36; output.size = 38;
output.pos = 0; output.pos = 0;
do do
@ -310,6 +310,7 @@ static LevelPack_t* add_level_pack_zst(Assets_t* assets, const char* name, const
memcpy(pack_info->pack.levels[lvls].level_name, level_decompressor.out_buffer, 32); memcpy(pack_info->pack.levels[lvls].level_name, level_decompressor.out_buffer, 32);
memcpy(&pack_info->pack.levels[lvls].width, level_decompressor.out_buffer + 32, 2); memcpy(&pack_info->pack.levels[lvls].width, level_decompressor.out_buffer + 32, 2);
memcpy(&pack_info->pack.levels[lvls].height, level_decompressor.out_buffer + 34, 2); memcpy(&pack_info->pack.levels[lvls].height, level_decompressor.out_buffer + 34, 2);
memcpy(&pack_info->pack.levels[lvls].n_chests, level_decompressor.out_buffer + 36, 2);
pack_info->pack.levels[lvls].level_name[31] = '\0'; pack_info->pack.levels[lvls].level_name[31] = '\0';
printf("Level name: %s\n", pack_info->pack.levels[lvls].level_name); printf("Level name: %s\n", pack_info->pack.levels[lvls].level_name);
printf("WxH: %u %u\n", pack_info->pack.levels[lvls].width, pack_info->pack.levels[lvls].height); printf("WxH: %u %u\n", pack_info->pack.levels[lvls].width, pack_info->pack.levels[lvls].height);

View File

@ -58,6 +58,7 @@ typedef struct LevelMap
char level_name[32]; char level_name[32];
uint16_t width; uint16_t width;
uint16_t height; uint16_t height;
uint16_t n_chests;
LevelTileInfo_t* tiles; LevelTileInfo_t* tiles;
}LevelMap_t; }LevelMap_t;

View File

@ -38,6 +38,7 @@ ENUMIDS_TILETYPE_MAPPING = {
'Runner': 21, 'Runner': 21,
'Player': 22, 'Player': 22,
'Chest': 23, 'Chest': 23,
'Exit': 24,
} }
#ENTID_MAPPING = { #ENTID_MAPPING = {
@ -76,6 +77,7 @@ with open(converted_filename, 'wb+') as out_file:
out_file.write(struct.pack("<I", n_levels)) out_file.write(struct.pack("<I", n_levels))
# Then loop the levels. Read the layerIndstances # Then loop the levels. Read the layerIndstances
for level in level_pack_data["levels"]: for level in level_pack_data["levels"]:
n_chests : int = 0
# Search for __identifier for the level layout # Search for __identifier for the level layout
level_name = level["identifier"] level_name = level["identifier"]
print("Parsing level", level_name) print("Parsing level", level_name)
@ -103,6 +105,8 @@ with open(converted_filename, 'wb+') as out_file:
for i, tile in enumerate(level_layout["gridTiles"]): for i, tile in enumerate(level_layout["gridTiles"]):
try: try:
tiles_info[tile["d"][0]][0] = ids_tiletype_map[tile["t"]] tiles_info[tile["d"][0]][0] = ids_tiletype_map[tile["t"]]
if tiles_info[tile["d"][0]][0] == ENUMIDS_TILETYPE_MAPPING ["Chest"]:
n_chests += 1
except Exception as e: except Exception as e:
print("Error on tile", i, i % width, i // height) print("Error on tile", i, i % width, i // height)
print(e) print(e)
@ -116,7 +120,7 @@ with open(converted_filename, 'wb+') as out_file:
x,y = ent["__grid"] x,y = ent["__grid"]
tiles_info[y*width + x][0] = ENUMIDS_TILETYPE_MAPPING[ent["__identifier"]] tiles_info[y*width + x][0] = ENUMIDS_TILETYPE_MAPPING[ent["__identifier"]]
out_file.write(struct.pack("<32s2H", level_name.encode('utf-8'), width, height)) out_file.write(struct.pack("<32s3H", level_name.encode('utf-8'), width, height, n_chests))
for tile in tiles_info: for tile in tiles_info:
out_file.write(struct.pack("<3Bx", *tile)) out_file.write(struct.pack("<3Bx", *tile))

View File

@ -248,10 +248,38 @@ static void render_editor_game_scene(Scene_t* scene)
} }
} }
sc_map_foreach_value(&scene->ent_manager.entities_map[LEVEL_END_TAG], p_ent)
{
CSprite_t* p_cspr = get_component(p_ent, CSPRITE_T);
if (p_cspr != NULL)
{
const SpriteRenderInfo_t spr = p_cspr->sprites[p_cspr->current_idx];
if (spr.sprite != NULL)
{
Vector2 pos = p_ent->position;
pos = Vector2Subtract(
pos,
get_anchor_offset(spr.sprite->frame_size, spr.src_anchor, p_cspr->flip_x)
);
Vector2 offset = spr.offset;
if (p_cspr->flip_x) offset.x *= -1;
pos = Vector2Add(pos, offset);
draw_sprite(spr.sprite, (data->coins.current < data->coins.total) ? 0 : 1, pos, 0.0f, p_cspr->flip_x);
}
}
else
{
DrawCircleV(p_ent->position, tilemap.tile_size >> 1, (data->coins.current < data->coins.total)? RED : GREEN);
}
}
char buffer[64] = {0}; char buffer[64] = {0};
sc_map_foreach_value(&scene->ent_manager.entities, p_ent) sc_map_foreach_value(&scene->ent_manager.entities, p_ent)
{ {
if (p_ent->m_tag == LEVEL_END_TAG) continue;
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T); CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
// Entity culling // Entity culling
@ -393,11 +421,11 @@ static void render_editor_game_scene(Scene_t* scene)
pos, pos,
get_anchor_offset(p_bbox->size, spr.dest_anchor, p_cspr->flip_x) get_anchor_offset(p_bbox->size, spr.dest_anchor, p_cspr->flip_x)
); );
pos = Vector2Subtract(
pos,
get_anchor_offset(spr.sprite->frame_size, spr.src_anchor, p_cspr->flip_x)
);
} }
pos = Vector2Subtract(
pos,
get_anchor_offset(spr.sprite->frame_size, spr.src_anchor, p_cspr->flip_x)
);
Vector2 offset = spr.offset; Vector2 offset = spr.offset;
if (p_cspr->flip_x) offset.x *= -1; if (p_cspr->flip_x) offset.x *= -1;
@ -408,11 +436,6 @@ static void render_editor_game_scene(Scene_t* scene)
} }
} }
sc_map_foreach_value(&scene->ent_manager.entities_map[LEVEL_END_TAG], p_ent)
{
DrawCircleV(p_ent->position, tilemap.tile_size >> 1, (data->coins.current < data->coins.total)? RED : GREEN);
}
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++)
@ -1131,7 +1154,7 @@ static void at_level_complete(Scene_t* scene)
data->sm.fractional -= 1.0f; data->sm.fractional -= 1.0f;
data->sm.counter++; data->sm.counter++;
} }
if (data->sm.counter >= 3) if (data->sm.counter >= 1)
{ {
do_action(scene, ACTION_NEXTLEVEL, true); do_action(scene, ACTION_NEXTLEVEL, true);
at_level_dead(scene); at_level_dead(scene);
@ -1195,6 +1218,20 @@ void init_sandbox_scene(LevelScene_t* scene)
scene->data.game_rec scene->data.game_rec
); );
{
Entity_t* p_player = create_player(&scene->scene.ent_manager);
CSprite_t* p_cspr = get_component(p_player, CSPRITE_T);
p_cspr->flip_x = true;
p_player->position.x = 100;
p_player->position.y = (scene->data.tilemap.height - 2) * scene->data.tilemap.tile_size;
scene->data.player_spawn = p_player->position;
scene->data.camera.target_pos = p_player->position;
scene->data.camera.cam.target = p_player->position;
}
update_entity_manager(&scene->scene.ent_manager);
BeginTextureMode(scene->scene.layers.render_layers[SELECTION_LAYER].layer_tex); BeginTextureMode(scene->scene.layers.render_layers[SELECTION_LAYER].layer_tex);
ClearBackground(LIGHTGRAY); ClearBackground(LIGHTGRAY);
Vector2 draw_pos = {0, 0}; Vector2 draw_pos = {0, 0};
@ -1370,8 +1407,6 @@ void init_sandbox_scene(LevelScene_t* scene)
EndTextureMode(); EndTextureMode();
create_player(&scene->scene.ent_manager);
update_entity_manager(&scene->scene.ent_manager);
// insert level scene systems // insert level scene systems
sc_array_add(&scene->scene.systems, &update_tilemap_system); sc_array_add(&scene->scene.systems, &update_tilemap_system);

View File

@ -7,6 +7,7 @@ bool init_player_creation(const char* info_file, Assets_t* assets);
bool init_player_creation_rres(const char* rres_file, const char* file, Assets_t* assets); bool init_player_creation_rres(const char* rres_file, const char* file, Assets_t* assets);
Entity_t* create_player(EntityManager_t* ent_manager); Entity_t* create_player(EntityManager_t* ent_manager);
Entity_t* create_dead_player(EntityManager_t* ent_manager); Entity_t* create_dead_player(EntityManager_t* ent_manager);
Entity_t* create_player_finish(EntityManager_t* ent_manager);
bool init_item_creation(Assets_t* assets); bool init_item_creation(Assets_t* assets);

View File

@ -51,6 +51,8 @@ static void level_scene_render_func(Scene_t* scene)
print_mempool_stats(buffer); print_mempool_stats(buffer);
DrawText(buffer, gui_x, 150, 12, BLACK); DrawText(buffer, gui_x, 150, 12, BLACK);
sprintf(buffer, "Chests: %u / %u", data->coins.current, data->coins.total);
DrawText(buffer, gui_x, data->game_rec.y + data->game_rec.height, 24, BLACK);
EndTextureMode(); EndTextureMode();
} }
@ -174,8 +176,38 @@ static void render_regular_game_scene(Scene_t* scene)
} }
} }
sc_map_foreach_value(&scene->ent_manager.entities_map[LEVEL_END_TAG], p_ent)
{
// There is only a few exits, can may be get away without culling
CSprite_t* p_cspr = get_component(p_ent, CSPRITE_T);
if (p_cspr != NULL)
{
const SpriteRenderInfo_t spr = p_cspr->sprites[p_cspr->current_idx];
if (spr.sprite != NULL)
{
Vector2 pos = p_ent->position;
pos = Vector2Subtract(
pos,
get_anchor_offset(spr.sprite->frame_size, spr.src_anchor, p_cspr->flip_x)
);
Vector2 offset = spr.offset;
if (p_cspr->flip_x) offset.x *= -1;
pos = Vector2Add(pos, offset);
draw_sprite(spr.sprite, (data->coins.current < data->coins.total) ? 0 : 1, pos, 0.0f, p_cspr->flip_x);
}
}
else
{
DrawCircleV(p_ent->position, tilemap.tile_size >> 1, (data->coins.current < data->coins.total)? RED : GREEN);
}
}
sc_map_foreach_value(&scene->ent_manager.entities, p_ent) sc_map_foreach_value(&scene->ent_manager.entities, p_ent)
{ {
if (p_ent->m_tag == LEVEL_END_TAG) continue;
CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T); CBBox_t* p_bbox = get_component(p_ent, CBBOX_COMP_T);
// Entity culling // Entity culling
@ -202,11 +234,11 @@ static void render_regular_game_scene(Scene_t* scene)
pos, pos,
get_anchor_offset(p_bbox->size, spr.dest_anchor, p_cspr->flip_x) get_anchor_offset(p_bbox->size, spr.dest_anchor, p_cspr->flip_x)
); );
pos = Vector2Subtract(
pos,
get_anchor_offset(spr.sprite->frame_size, spr.src_anchor, p_cspr->flip_x)
);
} }
pos = Vector2Subtract(
pos,
get_anchor_offset(spr.sprite->frame_size, spr.src_anchor, p_cspr->flip_x)
);
Vector2 offset = spr.offset; Vector2 offset = spr.offset;
if (p_cspr->flip_x) offset.x *= -1; if (p_cspr->flip_x) offset.x *= -1;
@ -374,14 +406,14 @@ static void render_regular_game_scene(Scene_t* scene)
} }
sc_map_foreach_value(&scene->ent_manager.entities_map[DYNMEM_ENT_TAG], p_ent) //sc_map_foreach_value(&scene->ent_manager.entities_map[DYNMEM_ENT_TAG], p_ent)
{ //{
CWaterRunner_t* p_runner = get_component(p_ent, CWATERRUNNER_T); // CWaterRunner_t* p_runner = get_component(p_ent, CWATERRUNNER_T);
unsigned int x = ((p_runner->current_tile) % tilemap.width) * tilemap.tile_size; // unsigned int x = ((p_runner->current_tile) % tilemap.width) * tilemap.tile_size;
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_particle_system(&scene->part_sys);
// Draw water tile // Draw water tile
@ -425,8 +457,17 @@ static void at_level_start(Scene_t* scene)
static void at_level_complete(Scene_t* scene) static void at_level_complete(Scene_t* scene)
{ {
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data); LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
do_action(scene, ACTION_NEXTLEVEL, true); data->sm.fractional += scene->delta_time;
data->sm.state = LEVEL_STATE_STARTING; if (data->sm.fractional > 1.0f)
{
data->sm.fractional -= 1.0f;
data->sm.counter++;
}
if (data->sm.counter >= 1)
{
do_action(scene, ACTION_NEXTLEVEL, false);
data->sm.state = LEVEL_STATE_STARTING;
}
} }
void init_game_scene(LevelScene_t* scene) void init_game_scene(LevelScene_t* scene)

View File

@ -2017,6 +2017,16 @@ void level_end_detection_system(Scene_t* scene)
) )
) )
{ {
Entity_t* ent = create_player_finish(&scene->ent_manager);
if (ent != NULL)
{
ent->position = p_flag->position;
ent->position.y += tilemap.tile_size >> 1;
CSprite_t* p_cspr = get_component(p_other_ent, CSPRITE_T);
CSprite_t* new_cspr = get_component(ent, CSPRITE_T);
new_cspr->flip_x = p_cspr->flip_x;
}
destroy_entity(scene, &lvl_scene->data.tilemap, p_other_ent); destroy_entity(scene, &lvl_scene->data.tilemap, p_other_ent);
change_level_state(&lvl_scene->data, LEVEL_STATE_COMPLETE); change_level_state(&lvl_scene->data, LEVEL_STATE_COMPLETE);

View File

@ -2,7 +2,7 @@
#include "constants.h" #include "constants.h"
#include "raymath.h" #include "raymath.h"
static SpriteRenderInfo_t item_sprite_map[20] = {0}; static SpriteRenderInfo_t item_sprite_map[21] = {0};
bool init_item_creation(Assets_t* assets) bool init_item_creation(Assets_t* assets)
{ {
@ -29,6 +29,10 @@ bool init_item_creation(Assets_t* assets)
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"); item_sprite_map[18].sprite = get_sprite(assets, "chest");
item_sprite_map[19].sprite = get_sprite(assets, "boulder"); item_sprite_map[19].sprite = get_sprite(assets, "boulder");
item_sprite_map[20].sprite = get_sprite(assets, "exit");
item_sprite_map[20].src_anchor = AP_BOT_CENTER;
item_sprite_map[20].src_anchor = AP_BOT_CENTER;
item_sprite_map[20].offset = (Vector2){0, TILE_SIZE >> 1};
return true; return true;
} }
@ -256,6 +260,10 @@ Entity_t* create_level_end(EntityManager_t* ent_manager)
Entity_t* p_flag = add_entity(ent_manager, LEVEL_END_TAG); Entity_t* p_flag = add_entity(ent_manager, LEVEL_END_TAG);
if (p_flag == NULL) return NULL; if (p_flag == NULL) return NULL;
CSprite_t* p_cspr = add_component(p_flag, CSPRITE_T);
p_cspr->sprites = item_sprite_map;
p_cspr->current_idx = 20;
add_component(p_flag, CTILECOORD_COMP_T); add_component(p_flag, CTILECOORD_COMP_T);
return p_flag; return p_flag;
} }

View File

@ -4,7 +4,7 @@
#include <string.h> #include <string.h>
#include "raymath.h" #include "raymath.h"
#define N_PLAYER_SPRITES 11 #define N_PLAYER_SPRITES 12
enum PlayerSpriteEnum enum PlayerSpriteEnum
{ {
SPR_PLAYER_STAND = 0, SPR_PLAYER_STAND = 0,
@ -18,6 +18,7 @@ enum PlayerSpriteEnum
SPR_PLAYER_USWIM, SPR_PLAYER_USWIM,
SPR_PLAYER_DSWIM, SPR_PLAYER_DSWIM,
SPR_PLAYER_DEAD, SPR_PLAYER_DEAD,
SPR_PLAYER_ENTER,
}; };
static SpriteRenderInfo_t player_sprite_map[N_PLAYER_SPRITES] = {0}; static SpriteRenderInfo_t player_sprite_map[N_PLAYER_SPRITES] = {0};
@ -136,6 +137,32 @@ Entity_t* create_dead_player(EntityManager_t* ent_manager)
return p_ent; return p_ent;
} }
static unsigned int player_finish_transition_func(Entity_t* ent)
{
CSprite_t* p_spr = get_component(ent, CSPRITE_T);
// Due to index-from-0
if (p_spr->current_frame == p_spr->sprites[p_spr->current_idx].sprite->frame_count - 1)
{
p_spr->pause = true;
}
return p_spr->current_idx;
}
Entity_t* create_player_finish(EntityManager_t* ent_manager)
{
Entity_t* p_ent = add_entity(ent_manager, NO_ENT_TAG);
if (p_ent == NULL) return NULL;
CSprite_t* p_cspr = add_component(p_ent, CSPRITE_T);
p_cspr->sprites = player_sprite_map;
p_cspr->current_idx = SPR_PLAYER_ENTER;
p_cspr->transition_func = &player_finish_transition_func;
add_component(p_ent, CTILECOORD_COMP_T);
return p_ent;
}
static AnchorPoint_t parse_anchor_symbol(const char symbol[2]) static AnchorPoint_t parse_anchor_symbol(const char symbol[2])
{ {
if (symbol[0] == 't') if (symbol[0] == 't')

View File

@ -65,6 +65,8 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
scene->data.tilemap.width = lvl_map.width; scene->data.tilemap.width = lvl_map.width;
scene->data.tilemap.height = lvl_map.height; scene->data.tilemap.height = lvl_map.height;
scene->data.tilemap.n_tiles = n_tiles; scene->data.tilemap.n_tiles = n_tiles;
scene->data.coins.current = 0;
scene->data.coins.total = lvl_map.n_chests;
clear_entity_manager(&scene->scene.ent_manager); clear_entity_manager(&scene->scene.ent_manager);
@ -158,6 +160,16 @@ bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
p_ctransform->active = true; p_ctransform->active = true;
} }
break; break;
case 24:
{
Entity_t* ent = create_level_end(&scene->scene.ent_manager);
if (ent != NULL)
{
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 + (scene->data.tilemap.tile_size >> 1);
}
}
break;
default: default:
break; break;
} }