Compare commits
14 Commits
cb703877cb
...
eec62d4581
Author | SHA1 | Date |
---|---|---|
|
eec62d4581 | |
|
bba12b9b39 | |
|
e670af2519 | |
|
70d7fda22c | |
|
e0ea01a4de | |
|
ca392a0efd | |
|
f6f3214dc1 | |
|
9387189927 | |
|
8e9efc622d | |
|
5de188c503 | |
|
5dbe2cc4d0 | |
|
87c415d52c | |
|
62703c0317 | |
|
396551a572 |
|
@ -85,6 +85,19 @@ target_link_libraries(water_test
|
||||||
target_compile_options(water_test PRIVATE -fsanitize=address -gdwarf-4)
|
target_compile_options(water_test PRIVATE -fsanitize=address -gdwarf-4)
|
||||||
target_link_options(water_test PRIVATE -fsanitize=address -gdwarf-4)
|
target_link_options(water_test PRIVATE -fsanitize=address -gdwarf-4)
|
||||||
|
|
||||||
|
add_executable(level_load_test
|
||||||
|
level_load_test.c
|
||||||
|
)
|
||||||
|
target_include_directories(level_load_test
|
||||||
|
PRIVATE
|
||||||
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
|
)
|
||||||
|
target_link_libraries(level_load_test
|
||||||
|
${GAME_LIBS}
|
||||||
|
)
|
||||||
|
target_compile_options(level_load_test PRIVATE -fsanitize=address -gdwarf-4)
|
||||||
|
target_link_options(level_load_test PRIVATE -fsanitize=address -gdwarf-4)
|
||||||
|
|
||||||
add_executable(menu_test
|
add_executable(menu_test
|
||||||
menu_test.c
|
menu_test.c
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
#include "constants.h"
|
||||||
|
#include "mempool.h"
|
||||||
|
#include "raymath.h"
|
||||||
|
#include "scene_impl.h"
|
||||||
|
#include "ent_impl.h"
|
||||||
|
#include "water_flow.h"
|
||||||
|
#include "game_systems.h"
|
||||||
|
#include "assets_loader.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
// Maintain own queue to handle key presses
|
||||||
|
struct sc_queue_32 key_buffer;
|
||||||
|
|
||||||
|
Scene_t* scenes[1];
|
||||||
|
static GameEngine_t engine =
|
||||||
|
{
|
||||||
|
.scenes = scenes,
|
||||||
|
.max_scenes = 1,
|
||||||
|
.curr_scene = 0,
|
||||||
|
.assets = {0}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
sc_queue_init(&key_buffer);
|
||||||
|
InitWindow(1280, 640, "raylib");
|
||||||
|
SetTargetFPS(60);
|
||||||
|
init_memory_pools();
|
||||||
|
|
||||||
|
init_assets(&engine.assets);
|
||||||
|
load_from_infofile("res/test_assets.info", &engine.assets);
|
||||||
|
LevelPack_t* pack = get_level_pack(&engine.assets, "TestLevels");
|
||||||
|
assert(pack != NULL);
|
||||||
|
|
||||||
|
LevelScene_t scene;
|
||||||
|
scene.scene.engine = &engine;
|
||||||
|
scene.data.level_pack = pack;
|
||||||
|
scene.data.current_level = 0;
|
||||||
|
|
||||||
|
init_game_scene(&scene);
|
||||||
|
assert(load_level_tilemap(&scene, 0) == true);
|
||||||
|
|
||||||
|
scene.data.tile_sprites[ONEWAY_TILE] = get_sprite(&engine.assets, "tl_owp");
|
||||||
|
scene.data.tile_sprites[LADDER] = get_sprite(&engine.assets, "tl_ldr");
|
||||||
|
scenes[0] = &scene.scene;
|
||||||
|
change_scene(&engine, 0);
|
||||||
|
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
|
||||||
|
// This entire key processing relies on the assumption that a pressed key will
|
||||||
|
// appear in the polling of raylib
|
||||||
|
|
||||||
|
unsigned int sz = sc_queue_size(&key_buffer);
|
||||||
|
// Process any existing pressed key
|
||||||
|
for (size_t i = 0; i < sz; i++)
|
||||||
|
{
|
||||||
|
int button = sc_queue_del_first(&key_buffer);
|
||||||
|
ActionType_t action = sc_map_get_64(&scene.scene.action_map, button);
|
||||||
|
if (IsKeyReleased(button))
|
||||||
|
{
|
||||||
|
do_action(&scene.scene, action, false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
do_action(&scene.scene, action, true);
|
||||||
|
sc_queue_add_last(&key_buffer, button);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect new key presses
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
int button = GetKeyPressed();
|
||||||
|
if (button == 0) break;
|
||||||
|
ActionType_t action = sc_map_get_64(&scene.scene.action_map, button);
|
||||||
|
if (!sc_map_found(&scene.scene.action_map)) continue;
|
||||||
|
do_action(&scene.scene, action, true);
|
||||||
|
sc_queue_add_last(&key_buffer, button);
|
||||||
|
}
|
||||||
|
|
||||||
|
update_scene(&scene.scene);
|
||||||
|
update_entity_manager(&scene.scene.ent_manager);
|
||||||
|
// This is needed to advance time delta
|
||||||
|
render_scene(&scene.scene);
|
||||||
|
if (WindowShouldClose()) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int m_id;
|
||||||
|
Entity_t* ent;
|
||||||
|
sc_map_foreach(&scene.scene.ent_manager.entities_map[DYNMEM_ENT_TAG], m_id, ent)
|
||||||
|
{
|
||||||
|
free_water_runner(ent, &scene.scene.ent_manager);
|
||||||
|
}
|
||||||
|
free_scene(&scene.scene);
|
||||||
|
term_level_scene_data(&scene.data);
|
||||||
|
sc_queue_term(&key_buffer);
|
||||||
|
term_assets(&engine.assets);
|
||||||
|
CloseWindow();
|
||||||
|
}
|
45
main.c
45
main.c
|
@ -1,13 +1,15 @@
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
#include "assets_loader.h"
|
||||||
#include "scene_impl.h"
|
#include "scene_impl.h"
|
||||||
|
#include "ent_impl.h"
|
||||||
#include "mempool.h"
|
#include "mempool.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#define N_SCENES 3
|
#define N_SCENES 4
|
||||||
|
|
||||||
Scene_t *scenes[N_SCENES];
|
Scene_t *scenes[N_SCENES];
|
||||||
static GameEngine_t engine = {
|
static GameEngine_t engine = {
|
||||||
.scenes = scenes,
|
.scenes = scenes,
|
||||||
.max_scenes = 2,
|
.max_scenes = 3,
|
||||||
.curr_scene = 0,
|
.curr_scene = 0,
|
||||||
.assets = {0}
|
.assets = {0}
|
||||||
};
|
};
|
||||||
|
@ -15,20 +17,6 @@ static GameEngine_t engine = {
|
||||||
const int screenWidth = 1280;
|
const int screenWidth = 1280;
|
||||||
const int screenHeight = 640;
|
const int screenHeight = 640;
|
||||||
|
|
||||||
static void load_assets(void)
|
|
||||||
{
|
|
||||||
Texture2D* tex = add_texture(&engine.assets, "plr_tex", "res/test_tex.png");
|
|
||||||
Sprite_t* spr = add_sprite(&engine.assets, "plr_stand", tex);
|
|
||||||
spr->origin = (Vector2){0, 0};
|
|
||||||
spr->frame_size = (Vector2){32, 32};
|
|
||||||
|
|
||||||
spr = add_sprite(&engine.assets, "plr_run", tex);
|
|
||||||
spr->frame_count = 4;
|
|
||||||
spr->origin = (Vector2){0, 0};
|
|
||||||
spr->frame_size = (Vector2){32, 32};
|
|
||||||
spr->speed = 15;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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;
|
||||||
|
|
||||||
|
@ -42,22 +30,32 @@ int main(void)
|
||||||
init_memory_pools();
|
init_memory_pools();
|
||||||
|
|
||||||
init_assets(&engine.assets);
|
init_assets(&engine.assets);
|
||||||
load_assets();
|
load_from_infofile("res/assets.info", &engine.assets);
|
||||||
|
init_player_creation("res/player_spr.info", &engine.assets);
|
||||||
|
|
||||||
|
LevelScene_t sandbox_scene;
|
||||||
|
sandbox_scene.scene.engine = &engine;
|
||||||
|
init_sandbox_scene(&sandbox_scene);
|
||||||
|
|
||||||
LevelScene_t level_scene;
|
LevelScene_t level_scene;
|
||||||
level_scene.scene.engine = &engine;
|
level_scene.scene.engine = &engine;
|
||||||
init_level_scene(&level_scene);
|
init_game_scene(&level_scene);
|
||||||
|
LevelPack_t* pack = get_level_pack(&engine.assets, "TestLevels");
|
||||||
|
if (pack != NULL)
|
||||||
|
{
|
||||||
|
level_scene.data.level_pack = pack;
|
||||||
|
level_scene.data.current_level = 0;
|
||||||
|
load_level_tilemap(&level_scene, 0);
|
||||||
|
}
|
||||||
|
|
||||||
MenuScene_t menu_scene;
|
MenuScene_t menu_scene;
|
||||||
menu_scene.scene.engine = &engine;
|
menu_scene.scene.engine = &engine;
|
||||||
init_menu_scene(&menu_scene);
|
init_menu_scene(&menu_scene);
|
||||||
scenes[0] = &menu_scene.scene;
|
scenes[0] = &menu_scene.scene;
|
||||||
scenes[1] = &level_scene.scene;
|
scenes[1] = &level_scene.scene;
|
||||||
|
scenes[2] = &sandbox_scene.scene;
|
||||||
change_scene(&engine, 0);
|
change_scene(&engine, 0);
|
||||||
|
|
||||||
//Camera2D camera = { 0 };
|
|
||||||
//camera.offset = (Vector2){0,0};
|
|
||||||
//camera.rotation = 0.0f;
|
|
||||||
//camera.zoom = 1.0f;
|
|
||||||
while (!WindowShouldClose())
|
while (!WindowShouldClose())
|
||||||
{
|
{
|
||||||
// This entire key processing relies on the assumption that a pressed key will
|
// This entire key processing relies on the assumption that a pressed key will
|
||||||
|
@ -102,7 +100,8 @@ int main(void)
|
||||||
sc_queue_clear(&key_buffer);
|
sc_queue_clear(&key_buffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free_level_scene(&level_scene);
|
free_sandbox_scene(&sandbox_scene);
|
||||||
|
free_game_scene(&level_scene);
|
||||||
free_menu_scene(&menu_scene);
|
free_menu_scene(&menu_scene);
|
||||||
sc_queue_term(&key_buffer);
|
sc_queue_term(&key_buffer);
|
||||||
term_assets(&engine.assets);
|
term_assets(&engine.assets);
|
||||||
|
|
|
@ -1,2 +1,5 @@
|
||||||
*
|
*
|
||||||
!.gitignore
|
!.gitignore
|
||||||
|
!ldtk_repacker.py
|
||||||
|
!test_assets.info
|
||||||
|
!testLevels.lvldata
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
import sys
|
||||||
|
import argparse
|
||||||
|
import pprint
|
||||||
|
import json
|
||||||
|
import struct
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser()
|
||||||
|
parser.add_argument('filename')
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
print("Parsing", args.filename)
|
||||||
|
|
||||||
|
with open(args.filename, 'r') as f:
|
||||||
|
level_pack_data = json.load(f)
|
||||||
|
|
||||||
|
#pprint.pprint(level_pack_data)
|
||||||
|
ENUMIDS_TILETYPE_MAPPING = {
|
||||||
|
'Solid': 1,
|
||||||
|
'Water': 2
|
||||||
|
}
|
||||||
|
|
||||||
|
ENTID_MAPPING = {
|
||||||
|
'Player': 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# First go to tilesets and find Simple_tiles identifier, then find enumTags to identifier which tile type is what tileid
|
||||||
|
ids_tiletype_map = {}
|
||||||
|
tileset_defs = level_pack_data["defs"]["tilesets"]
|
||||||
|
|
||||||
|
for ts_def in tileset_defs:
|
||||||
|
if ts_def["identifier"] != "Simple_tiles":
|
||||||
|
continue
|
||||||
|
for tag in ts_def["enumTags"]:
|
||||||
|
ids_tiletype_map[tag["tileIds"][0]] = ENUMIDS_TILETYPE_MAPPING[tag["enumValueId"]]
|
||||||
|
|
||||||
|
if not ids_tiletype_map:
|
||||||
|
print("No tileset definition")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
pprint.pprint(ids_tiletype_map)
|
||||||
|
|
||||||
|
# Number of levels is the length of the levels
|
||||||
|
n_levels = len(level_pack_data["levels"])
|
||||||
|
print("Number of levels:", n_levels)
|
||||||
|
|
||||||
|
fileparts = args.filename.split('.')
|
||||||
|
if len(fileparts) == 1:
|
||||||
|
fileparts.append("lvldat")
|
||||||
|
else:
|
||||||
|
fileparts[-1] = "lvldata"
|
||||||
|
converted_filename = '.'.join(fileparts)
|
||||||
|
|
||||||
|
# Each level should be packed as: [width, 2 bytes][height, 2 bytes][tile_type,entity,water,padding 1,1,1,1 bytes][tile_type,entity,water,padding 1,1,1,1 bytes]...
|
||||||
|
with open(converted_filename, 'wb+') as out_file:
|
||||||
|
out_file.write(struct.pack("<I", n_levels))
|
||||||
|
# Then loop the levels. Read the layerIndstances
|
||||||
|
for level in level_pack_data["levels"]:
|
||||||
|
# Search for __identifier for the level layout
|
||||||
|
level_name = level["identifier"]
|
||||||
|
print("Parsing level", level_name)
|
||||||
|
|
||||||
|
|
||||||
|
level_layout = {}
|
||||||
|
entity_layout = {}
|
||||||
|
water_layout = {}
|
||||||
|
for layer in level['layerInstances']:
|
||||||
|
if layer["__identifier"] == "Tiles":
|
||||||
|
level_layout = layer
|
||||||
|
elif layer["__identifier"] == "Entities":
|
||||||
|
entity_layout = layer
|
||||||
|
elif layer["__identifier"] == "Water":
|
||||||
|
water_layout = layer
|
||||||
|
|
||||||
|
# Dimensions of each level is obtained via __cWid and __cHei. Get the __gridSize as well
|
||||||
|
width = level_layout["__cWid"]
|
||||||
|
height = level_layout["__cHei"]
|
||||||
|
print(f"Dim.: {width}x{height}")
|
||||||
|
# Create a W x H array of tile information
|
||||||
|
n_tiles = width * height
|
||||||
|
tiles_info = [[0,0,0] for _ in range(n_tiles)]
|
||||||
|
# Loop through gridTiles, get "d" as the index to fill the info
|
||||||
|
for tile in level_layout["gridTiles"]:
|
||||||
|
tiles_info[tile["d"][0]][0] = ids_tiletype_map[tile["t"]]
|
||||||
|
|
||||||
|
for i, water_level in enumerate(water_layout["intGridCsv"]):
|
||||||
|
tiles_info[i][2] = water_level
|
||||||
|
|
||||||
|
for ent in entity_layout["entityInstances"]:
|
||||||
|
if ent["__identifier"] in ENTID_MAPPING:
|
||||||
|
x,y = ent["__grid"]
|
||||||
|
tiles_info[y*width + x][1] = ENTID_MAPPING[ent["__identifier"]]
|
||||||
|
|
||||||
|
out_file.write(struct.pack("<32s2H", level_name.encode('utf-8'), width, height))
|
||||||
|
for tile in tiles_info:
|
||||||
|
out_file.write(struct.pack("<3Bx", *tile))
|
||||||
|
|
||||||
|
|
||||||
|
for y in range(height):
|
||||||
|
for x in range(width):
|
||||||
|
print(tiles_info[y*width + x], end=" ")
|
||||||
|
print()
|
||||||
|
|
Binary file not shown.
|
@ -0,0 +1,2 @@
|
||||||
|
-LevelPack
|
||||||
|
TestLevels: res/testLevels.lvldata
|
|
@ -31,7 +31,7 @@ int main(void)
|
||||||
|
|
||||||
LevelScene_t scene;
|
LevelScene_t scene;
|
||||||
scene.scene.engine = &engine;
|
scene.scene.engine = &engine;
|
||||||
init_level_scene(&scene);
|
init_sandbox_scene(&scene);
|
||||||
scene.data.tile_sprites[ONEWAY_TILE] = get_sprite(&engine.assets, "tl_owp");
|
scene.data.tile_sprites[ONEWAY_TILE] = get_sprite(&engine.assets, "tl_owp");
|
||||||
scene.data.tile_sprites[LADDER] = get_sprite(&engine.assets, "tl_ldr");
|
scene.data.tile_sprites[LADDER] = get_sprite(&engine.assets, "tl_ldr");
|
||||||
scenes[0] = &scene.scene;
|
scenes[0] = &scene.scene;
|
||||||
|
@ -78,7 +78,7 @@ int main(void)
|
||||||
render_scene(&scene.scene);
|
render_scene(&scene.scene);
|
||||||
if (WindowShouldClose()) break;
|
if (WindowShouldClose()) break;
|
||||||
}
|
}
|
||||||
free_level_scene(&scene);
|
free_sandbox_scene(&scene);
|
||||||
sc_queue_term(&key_buffer);
|
sc_queue_term(&key_buffer);
|
||||||
term_assets(&engine.assets);
|
term_assets(&engine.assets);
|
||||||
CloseWindow();
|
CloseWindow();
|
||||||
|
|
|
@ -6,7 +6,9 @@ add_library(lib_scenes STATIC
|
||||||
water_flow.c
|
water_flow.c
|
||||||
editor_scene.c
|
editor_scene.c
|
||||||
menu_scene.c
|
menu_scene.c
|
||||||
|
game_scene.c
|
||||||
game_systems.c
|
game_systems.c
|
||||||
|
scene_systems.c
|
||||||
)
|
)
|
||||||
target_include_directories(lib_scenes
|
target_include_directories(lib_scenes
|
||||||
PUBLIC
|
PUBLIC
|
||||||
|
|
|
@ -6,6 +6,7 @@ typedef enum AssetInfoType
|
||||||
{
|
{
|
||||||
TEXTURE_INFO,
|
TEXTURE_INFO,
|
||||||
SPRITE_INFO,
|
SPRITE_INFO,
|
||||||
|
LEVELPACK_INFO,
|
||||||
INVALID_INFO
|
INVALID_INFO
|
||||||
}AssetInfoType_t;
|
}AssetInfoType_t;
|
||||||
|
|
||||||
|
@ -64,6 +65,10 @@ bool load_from_infofile(const char* file, Assets_t* assets)
|
||||||
{
|
{
|
||||||
info_type = SPRITE_INFO;
|
info_type = SPRITE_INFO;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(tmp, "LevelPack") == 0)
|
||||||
|
{
|
||||||
|
info_type = LEVELPACK_INFO;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
info_type = INVALID_INFO;
|
info_type = INVALID_INFO;
|
||||||
|
@ -90,6 +95,16 @@ bool load_from_infofile(const char* file, Assets_t* assets)
|
||||||
//strcpy(tmp2, name);
|
//strcpy(tmp2, name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case LEVELPACK_INFO:
|
||||||
|
{
|
||||||
|
if (add_level_pack(assets, name, info_str) == NULL)
|
||||||
|
{
|
||||||
|
printf("Unable to add level pack at line %lu\n", line_num);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("Added level pack %s as %s\n", info_str, name);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SPRITE_INFO:
|
case SPRITE_INFO:
|
||||||
{
|
{
|
||||||
SpriteInfo_t spr_info = {0};
|
SpriteInfo_t spr_info = {0};
|
||||||
|
|
|
@ -40,4 +40,8 @@
|
||||||
|
|
||||||
#define MAX_WATER_LEVEL 4
|
#define MAX_WATER_LEVEL 4
|
||||||
#define WATER_BBOX_STEP (TILE_SIZE / MAX_WATER_LEVEL)
|
#define WATER_BBOX_STEP (TILE_SIZE / MAX_WATER_LEVEL)
|
||||||
|
|
||||||
|
#define MAX_LEVEL_NUM 50
|
||||||
|
#define MAX_N_TILES 4096
|
||||||
|
|
||||||
#endif // __CONSTANTS_H
|
#endif // __CONSTANTS_H
|
||||||
|
|
|
@ -8,7 +8,6 @@
|
||||||
#include "raymath.h"
|
#include "raymath.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define MAX_N_TILES 4096
|
|
||||||
static Tile_t all_tiles[MAX_N_TILES] = {0};
|
static Tile_t all_tiles[MAX_N_TILES] = {0};
|
||||||
|
|
||||||
enum EntitySpawnSelection {
|
enum EntitySpawnSelection {
|
||||||
|
@ -720,7 +719,7 @@ static void restart_editor_level(Scene_t* scene)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
|
static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
|
||||||
{
|
{
|
||||||
CPlayerState_t* p_playerstate;
|
CPlayerState_t* p_playerstate;
|
||||||
sc_map_foreach_value(&scene->ent_manager.component_map[CPLAYERSTATE_T], p_playerstate)
|
sc_map_foreach_value(&scene->ent_manager.component_map[CPLAYERSTATE_T], p_playerstate)
|
||||||
|
@ -777,12 +776,25 @@ void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_level_scene(LevelScene_t* scene)
|
void init_sandbox_scene(LevelScene_t* scene)
|
||||||
{
|
{
|
||||||
//init_scene(&scene->scene, LEVEL_SCENE, &level_scene_render_func, &level_do_action);
|
//init_scene(&scene->scene, LEVEL_SCENE, &level_scene_render_func, &level_do_action);
|
||||||
init_scene(&scene->scene, &level_scene_render_func, &level_do_action);
|
init_scene(&scene->scene, &level_scene_render_func, &level_do_action);
|
||||||
|
|
||||||
init_level_scene_data(&scene->data);
|
scene->data.tilemap.tiles = all_tiles;
|
||||||
|
init_level_scene_data(
|
||||||
|
&scene->data, MAX_N_TILES, all_tiles,
|
||||||
|
(Rectangle){25, 25, VIEWABLE_MAP_WIDTH*TILE_SIZE, VIEWABLE_MAP_HEIGHT*TILE_SIZE}
|
||||||
|
);
|
||||||
|
for (size_t i = 0; i < scene->data.tilemap.width; ++i)
|
||||||
|
{
|
||||||
|
unsigned int tile_idx = (scene->data.tilemap.height - 1) * scene->data.tilemap.width + i;
|
||||||
|
change_a_tile(&scene->data.tilemap, tile_idx, SOLID_TILE);
|
||||||
|
}
|
||||||
|
|
||||||
|
create_player(&scene->scene.ent_manager, &scene->scene.engine->assets);
|
||||||
|
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);
|
||||||
sc_array_add(&scene->scene.systems, &player_movement_input_system);
|
sc_array_add(&scene->scene.systems, &player_movement_input_system);
|
||||||
|
@ -825,43 +837,10 @@ void init_level_scene(LevelScene_t* scene)
|
||||||
sc_map_put_64(&scene->scene.action_map, KEY_Q, ACTION_EXIT);
|
sc_map_put_64(&scene->scene.action_map, KEY_Q, ACTION_EXIT);
|
||||||
sc_map_put_64(&scene->scene.action_map, KEY_R, ACTION_RESTART);
|
sc_map_put_64(&scene->scene.action_map, KEY_R, ACTION_RESTART);
|
||||||
|
|
||||||
scene->data.tilemap.width = DEFAULT_MAP_WIDTH;
|
|
||||||
scene->data.tilemap.height = DEFAULT_MAP_HEIGHT;
|
|
||||||
scene->data.tilemap.tile_size = TILE_SIZE;
|
|
||||||
scene->data.tilemap.n_tiles = scene->data.tilemap.width * scene->data.tilemap.height;
|
|
||||||
assert(scene->data.tilemap.n_tiles <= MAX_N_TILES);
|
|
||||||
scene->data.tilemap.tiles = all_tiles;
|
|
||||||
memset(scene->data.tile_sprites, 0, sizeof(scene->data.tile_sprites));
|
|
||||||
for (size_t i = 0; i < scene->data.tilemap.n_tiles;i++)
|
|
||||||
{
|
|
||||||
all_tiles[i].solid = NOT_SOLID;
|
|
||||||
all_tiles[i].tile_type = EMPTY_TILE;
|
|
||||||
all_tiles[i].moveable = true;
|
|
||||||
all_tiles[i].max_water_level = 4;
|
|
||||||
sc_map_init_64v(&all_tiles[i].entities_set, 16, 0);
|
|
||||||
all_tiles[i].size = (Vector2){TILE_SIZE, TILE_SIZE};
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < scene->data.tilemap.width; ++i)
|
|
||||||
{
|
|
||||||
unsigned int tile_idx = (scene->data.tilemap.height - 1) * scene->data.tilemap.width + i;
|
|
||||||
change_a_tile(&scene->data.tilemap, tile_idx, SOLID_TILE);
|
|
||||||
}
|
|
||||||
|
|
||||||
create_player(&scene->scene.ent_manager, &scene->scene.engine->assets);
|
|
||||||
update_entity_manager(&scene->scene.ent_manager);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_level_scene(LevelScene_t* scene)
|
void free_sandbox_scene(LevelScene_t* scene)
|
||||||
{
|
{
|
||||||
free_scene(&scene->scene);
|
free_scene(&scene->scene);
|
||||||
for (size_t i = 0; i < scene->data.tilemap.n_tiles;i++)
|
|
||||||
{
|
|
||||||
all_tiles[i].solid = 0;
|
|
||||||
sc_map_term_64v(&all_tiles[i].entities_set);
|
|
||||||
}
|
|
||||||
term_level_scene_data(&scene->data);
|
term_level_scene_data(&scene->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reload_level_scene(LevelScene_t* scene)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
|
@ -11,15 +11,15 @@ static CBBox_t bbox_buffer[MAX_COMP_POOL_SIZE];
|
||||||
static CTransform_t ctransform_buffer[MAX_COMP_POOL_SIZE];
|
static CTransform_t ctransform_buffer[MAX_COMP_POOL_SIZE];
|
||||||
static CTileCoord_t ctilecoord_buffer[MAX_COMP_POOL_SIZE];
|
static CTileCoord_t ctilecoord_buffer[MAX_COMP_POOL_SIZE];
|
||||||
static CMovementState_t cmstate_buffer[MAX_COMP_POOL_SIZE];
|
static CMovementState_t cmstate_buffer[MAX_COMP_POOL_SIZE];
|
||||||
static CJump_t cjump_buffer[1]; // Only player is expected to have this
|
static CJump_t cjump_buffer[8]; // Only player is expected to have this
|
||||||
static CPlayerState_t cplayerstate_buffer[1]; // Only player is expected to have this
|
static CPlayerState_t cplayerstate_buffer[8]; // Only player is expected to have this
|
||||||
static CContainer_t ccontainer_buffer[MAX_COMP_POOL_SIZE];
|
static CContainer_t ccontainer_buffer[MAX_COMP_POOL_SIZE];
|
||||||
static CHitBoxes_t chitboxes_buffer[MAX_COMP_POOL_SIZE];
|
static CHitBoxes_t chitboxes_buffer[MAX_COMP_POOL_SIZE];
|
||||||
static CHurtbox_t churtbox_buffer[MAX_COMP_POOL_SIZE];
|
static CHurtbox_t churtbox_buffer[MAX_COMP_POOL_SIZE];
|
||||||
static CSprite_t csprite_buffer[MAX_COMP_POOL_SIZE];
|
static CSprite_t csprite_buffer[MAX_COMP_POOL_SIZE];
|
||||||
static CMoveable_t cmoveable_buffer[MAX_COMP_POOL_SIZE];
|
static CMoveable_t cmoveable_buffer[MAX_COMP_POOL_SIZE];
|
||||||
static CLifeTimer_t clifetimer_buffer[MAX_COMP_POOL_SIZE];
|
static CLifeTimer_t clifetimer_buffer[MAX_COMP_POOL_SIZE];
|
||||||
static CWaterRunner_t cwaterrunner_buffer[4];
|
static CWaterRunner_t cwaterrunner_buffer[32];
|
||||||
|
|
||||||
typedef struct ULongCircBuffer {
|
typedef struct ULongCircBuffer {
|
||||||
unsigned long* buffer; // data buffer
|
unsigned long* buffer; // data buffer
|
||||||
|
@ -83,15 +83,15 @@ static MemPool_t comp_mempools[N_COMPONENTS] = {
|
||||||
{ctransform_buffer, MAX_COMP_POOL_SIZE, sizeof(CTransform_t), NULL, {0}},
|
{ctransform_buffer, MAX_COMP_POOL_SIZE, sizeof(CTransform_t), NULL, {0}},
|
||||||
{ctilecoord_buffer, MAX_COMP_POOL_SIZE, sizeof(CTileCoord_t), NULL, {0}},
|
{ctilecoord_buffer, MAX_COMP_POOL_SIZE, sizeof(CTileCoord_t), NULL, {0}},
|
||||||
{cmstate_buffer, MAX_COMP_POOL_SIZE, sizeof(CMovementState_t), NULL, {0}},
|
{cmstate_buffer, MAX_COMP_POOL_SIZE, sizeof(CMovementState_t), NULL, {0}},
|
||||||
{cjump_buffer, 1, sizeof(CJump_t), NULL, {0}},
|
{cjump_buffer, 8, sizeof(CJump_t), NULL, {0}},
|
||||||
{cplayerstate_buffer, 1, sizeof(CPlayerState_t), NULL, {0}},
|
{cplayerstate_buffer, 8, sizeof(CPlayerState_t), NULL, {0}},
|
||||||
{ccontainer_buffer, MAX_COMP_POOL_SIZE, sizeof(CContainer_t), NULL, {0}},
|
{ccontainer_buffer, MAX_COMP_POOL_SIZE, sizeof(CContainer_t), NULL, {0}},
|
||||||
{chitboxes_buffer, MAX_COMP_POOL_SIZE, sizeof(CHitBoxes_t), NULL, {0}},
|
{chitboxes_buffer, MAX_COMP_POOL_SIZE, sizeof(CHitBoxes_t), NULL, {0}},
|
||||||
{churtbox_buffer, MAX_COMP_POOL_SIZE, sizeof(CHurtbox_t), NULL, {0}},
|
{churtbox_buffer, MAX_COMP_POOL_SIZE, sizeof(CHurtbox_t), NULL, {0}},
|
||||||
{csprite_buffer, MAX_COMP_POOL_SIZE, sizeof(CSprite_t), NULL, {0}},
|
{csprite_buffer, MAX_COMP_POOL_SIZE, sizeof(CSprite_t), NULL, {0}},
|
||||||
{cmoveable_buffer, MAX_COMP_POOL_SIZE, sizeof(CMoveable_t), NULL, {0}},
|
{cmoveable_buffer, MAX_COMP_POOL_SIZE, sizeof(CMoveable_t), NULL, {0}},
|
||||||
{clifetimer_buffer, MAX_COMP_POOL_SIZE, sizeof(CLifeTimer_t), NULL, {0}},
|
{clifetimer_buffer, MAX_COMP_POOL_SIZE, sizeof(CLifeTimer_t), NULL, {0}},
|
||||||
{cwaterrunner_buffer, 4, sizeof(CWaterRunner_t), NULL, {0}},
|
{cwaterrunner_buffer, 32, sizeof(CWaterRunner_t), NULL, {0}},
|
||||||
};
|
};
|
||||||
static MemPool_t ent_mempool = {
|
static MemPool_t ent_mempool = {
|
||||||
.buffer = entity_buffer,
|
.buffer = entity_buffer,
|
||||||
|
|
|
@ -13,5 +13,7 @@ typedef enum ActionType
|
||||||
ACTION_CONFIRM,
|
ACTION_CONFIRM,
|
||||||
ACTION_EXIT,
|
ACTION_EXIT,
|
||||||
ACTION_RESTART,
|
ACTION_RESTART,
|
||||||
|
ACTION_NEXTLEVEL,
|
||||||
|
ACTION_PREVLEVEL,
|
||||||
}ActionType_t;
|
}ActionType_t;
|
||||||
#endif // __ACTIONS_H
|
#endif // __ACTIONS_H
|
||||||
|
|
|
@ -1,12 +1,16 @@
|
||||||
#include "assets.h"
|
#include "assets.h"
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#define MAX_TEXTURES 16
|
#define MAX_TEXTURES 16
|
||||||
#define MAX_SPRITES 16
|
#define MAX_SPRITES 64
|
||||||
#define MAX_SOUNDS 16
|
#define MAX_SOUNDS 16
|
||||||
#define MAX_FONTS 4
|
#define MAX_FONTS 4
|
||||||
|
#define MAX_N_TILES 4096
|
||||||
#define MAX_NAME_LEN 32
|
#define MAX_NAME_LEN 32
|
||||||
uint8_t free_idx[4] = {0};
|
#define MAX_LEVEL_PACK 4
|
||||||
|
uint8_t n_loaded[5] = {0};
|
||||||
|
|
||||||
// Hard limit number of
|
// Hard limit number of
|
||||||
typedef struct TextureData
|
typedef struct TextureData
|
||||||
|
@ -29,17 +33,31 @@ typedef struct SoundData
|
||||||
Sound sound;
|
Sound sound;
|
||||||
char name[MAX_NAME_LEN];
|
char name[MAX_NAME_LEN];
|
||||||
}SoundData_t;
|
}SoundData_t;
|
||||||
|
typedef struct LevelPackData
|
||||||
|
{
|
||||||
|
LevelPack_t pack;
|
||||||
|
char name[MAX_NAME_LEN];
|
||||||
|
}LevelPackData_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 void unload_level_pack(LevelPack_t pack)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < pack.n_levels; ++i)
|
||||||
|
{
|
||||||
|
free(pack.levels[i].tiles);
|
||||||
|
}
|
||||||
|
free(pack.levels);
|
||||||
|
}
|
||||||
|
|
||||||
// Maybe need a circular buffer??
|
// Maybe need a circular buffer??
|
||||||
Texture2D* add_texture(Assets_t* assets, const char* name, const char* path)
|
Texture2D* add_texture(Assets_t* assets, const char* name, const char* path)
|
||||||
{
|
{
|
||||||
uint8_t tex_idx = free_idx[0];
|
uint8_t tex_idx = n_loaded[0];
|
||||||
assert(tex_idx < MAX_TEXTURES);
|
assert(tex_idx < MAX_TEXTURES);
|
||||||
Texture2D tex = LoadTexture(path);
|
Texture2D tex = LoadTexture(path);
|
||||||
if (tex.width == 0 || tex.height == 0) return NULL;
|
if (tex.width == 0 || tex.height == 0) return NULL;
|
||||||
|
@ -47,59 +65,107 @@ Texture2D* add_texture(Assets_t* assets, const char* name, const char* path)
|
||||||
textures[tex_idx].texture = tex;
|
textures[tex_idx].texture = tex;
|
||||||
strncpy(textures[tex_idx].name, name, MAX_NAME_LEN);
|
strncpy(textures[tex_idx].name, name, MAX_NAME_LEN);
|
||||||
sc_map_put_s64(&assets->m_textures, textures[tex_idx].name, tex_idx);
|
sc_map_put_s64(&assets->m_textures, textures[tex_idx].name, tex_idx);
|
||||||
free_idx[0]++;
|
n_loaded[0]++;
|
||||||
return &textures[tex_idx].texture;
|
return &textures[tex_idx].texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sprite_t* add_sprite(Assets_t* assets, const char* name, Texture2D* texture)
|
Sprite_t* add_sprite(Assets_t* assets, const char* name, Texture2D* texture)
|
||||||
{
|
{
|
||||||
uint8_t spr_idx = free_idx[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(Sprite_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);
|
||||||
free_idx[1]++;
|
n_loaded[1]++;
|
||||||
return &sprites[spr_idx].sprite;
|
return &sprites[spr_idx].sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
Sound* add_sound(Assets_t* assets, const char* name, const char* path)
|
Sound* add_sound(Assets_t* assets, const char* name, const char* path)
|
||||||
{
|
{
|
||||||
uint8_t snd_idx = free_idx[2];
|
uint8_t snd_idx = n_loaded[2];
|
||||||
assert(snd_idx < MAX_SOUNDS);
|
assert(snd_idx < MAX_SOUNDS);
|
||||||
sfx[snd_idx].sound = LoadSound(path);
|
sfx[snd_idx].sound = LoadSound(path);
|
||||||
strncpy(sfx[snd_idx].name, name, MAX_NAME_LEN);
|
strncpy(sfx[snd_idx].name, name, MAX_NAME_LEN);
|
||||||
sc_map_put_s64(&assets->m_sounds, sfx[snd_idx].name, snd_idx);
|
sc_map_put_s64(&assets->m_sounds, sfx[snd_idx].name, snd_idx);
|
||||||
free_idx[2]++;
|
n_loaded[2]++;
|
||||||
return &sfx[snd_idx].sound;
|
return &sfx[snd_idx].sound;
|
||||||
}
|
}
|
||||||
|
|
||||||
Font* add_font(Assets_t* assets, const char* name, const char* path)
|
Font* add_font(Assets_t* assets, const char* name, const char* path)
|
||||||
{
|
{
|
||||||
uint8_t fnt_idx = free_idx[3];
|
uint8_t fnt_idx = n_loaded[3];
|
||||||
assert(fnt_idx < MAX_FONTS);
|
assert(fnt_idx < MAX_FONTS);
|
||||||
fonts[fnt_idx].font = LoadFont(path);
|
fonts[fnt_idx].font = LoadFont(path);
|
||||||
strncpy(fonts[fnt_idx].name, name, MAX_NAME_LEN);
|
strncpy(fonts[fnt_idx].name, name, MAX_NAME_LEN);
|
||||||
sc_map_put_s64(&assets->m_fonts, fonts[fnt_idx].name, fnt_idx);
|
sc_map_put_s64(&assets->m_fonts, fonts[fnt_idx].name, fnt_idx);
|
||||||
free_idx[3]++;
|
n_loaded[3]++;
|
||||||
return &fonts[fnt_idx].font;
|
return &fonts[fnt_idx].font;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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];
|
||||||
|
fread(&pack_info->pack.n_levels, sizeof(uint32_t), 1, file);
|
||||||
|
pack_info->pack.levels = calloc(pack_info->pack.n_levels, sizeof(LevelMap_t));
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < pack_info->pack.n_levels; ++i)
|
||||||
|
{
|
||||||
|
fread(pack_info->pack.levels[i].level_name, sizeof(char), 32, file);
|
||||||
|
fread(&pack_info->pack.levels[i].width, sizeof(uint16_t), 1, file);
|
||||||
|
fread(&pack_info->pack.levels[i].height, sizeof(uint16_t), 1, file);
|
||||||
|
uint32_t n_tiles = pack_info->pack.levels[i].width * pack_info->pack.levels[i].height;
|
||||||
|
|
||||||
|
pack_info->pack.levels[i].tiles = calloc(n_tiles, sizeof(LevelTileInfo_t));
|
||||||
|
fread(pack_info->pack.levels[i].tiles, 4, n_tiles, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(file);
|
||||||
|
uint8_t pack_idx = n_loaded[4];
|
||||||
|
strncpy(pack_info->name, name, MAX_NAME_LEN);
|
||||||
|
sc_map_put_s64(&assets->m_levelpacks, levelpacks[pack_idx].name, pack_idx);
|
||||||
|
n_loaded[4]++;
|
||||||
|
|
||||||
|
return &levelpacks[pack_idx].pack;
|
||||||
|
}
|
||||||
|
|
||||||
void init_assets(Assets_t* assets)
|
void init_assets(Assets_t* assets)
|
||||||
{
|
{
|
||||||
sc_map_init_s64(&assets->m_fonts, MAX_FONTS, 0);
|
sc_map_init_s64(&assets->m_fonts, MAX_FONTS, 0);
|
||||||
sc_map_init_s64(&assets->m_sprites, MAX_SPRITES, 0);
|
sc_map_init_s64(&assets->m_sprites, MAX_SPRITES, 0);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_all_assets(Assets_t* assets)
|
void free_all_assets(Assets_t* assets)
|
||||||
{
|
{
|
||||||
|
for (uint8_t i = 0; i < n_loaded[0]; ++i)
|
||||||
|
{
|
||||||
|
UnloadTexture(textures[i].texture);
|
||||||
|
}
|
||||||
|
for (uint8_t i = 0; i < n_loaded[2]; ++i)
|
||||||
|
{
|
||||||
|
UnloadSound(sfx[i].sound);
|
||||||
|
}
|
||||||
|
for (uint8_t i = 0; i < n_loaded[3]; ++i)
|
||||||
|
{
|
||||||
|
UnloadFont(fonts[i].font);
|
||||||
|
}
|
||||||
|
for (uint8_t i = 0; i < n_loaded[4]; ++i)
|
||||||
|
{
|
||||||
|
unload_level_pack(levelpacks[i].pack);
|
||||||
|
}
|
||||||
|
|
||||||
sc_map_clear_s64(&assets->m_textures);
|
sc_map_clear_s64(&assets->m_textures);
|
||||||
sc_map_clear_s64(&assets->m_fonts);
|
sc_map_clear_s64(&assets->m_fonts);
|
||||||
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);
|
||||||
memset(free_idx, 0, sizeof(free_idx));
|
sc_map_clear_s64(&assets->m_levelpacks);
|
||||||
|
memset(n_loaded, 0, sizeof(n_loaded));
|
||||||
}
|
}
|
||||||
|
|
||||||
void term_assets(Assets_t* assets)
|
void term_assets(Assets_t* assets)
|
||||||
|
@ -109,6 +175,7 @@ void term_assets(Assets_t* assets)
|
||||||
sc_map_term_s64(&assets->m_fonts);
|
sc_map_term_s64(&assets->m_fonts);
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture2D* get_texture(Assets_t* assets, const char* name)
|
Texture2D* get_texture(Assets_t* assets, const char* name)
|
||||||
|
@ -151,6 +218,16 @@ Font* get_font(Assets_t* assets, const char* name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LevelPack_t* get_level_pack(Assets_t* assets, const char* name)
|
||||||
|
{
|
||||||
|
uint8_t pack_idx = sc_map_get_s64(&assets->m_levelpacks, name);
|
||||||
|
if (sc_map_found(&assets->m_levelpacks))
|
||||||
|
{
|
||||||
|
return &levelpacks[pack_idx].pack;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void draw_sprite(Sprite_t* spr, Vector2 pos, bool flip_x)
|
void draw_sprite(Sprite_t* spr, Vector2 pos, bool flip_x)
|
||||||
{
|
{
|
||||||
Rectangle rec = {
|
Rectangle rec = {
|
||||||
|
|
|
@ -10,8 +10,30 @@ typedef struct Assets
|
||||||
struct sc_map_s64 m_sounds;
|
struct sc_map_s64 m_sounds;
|
||||||
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;
|
||||||
}Assets_t;
|
}Assets_t;
|
||||||
|
|
||||||
|
typedef struct LevelTileInfo
|
||||||
|
{
|
||||||
|
uint8_t tile_type;
|
||||||
|
uint8_t entity_to_spawn;
|
||||||
|
uint8_t water;
|
||||||
|
uint8_t dummy[1];
|
||||||
|
}LevelTileInfo_t;
|
||||||
|
|
||||||
|
typedef struct LevelMap
|
||||||
|
{
|
||||||
|
char level_name[32];
|
||||||
|
uint16_t width;
|
||||||
|
uint16_t height;
|
||||||
|
LevelTileInfo_t* tiles;
|
||||||
|
}LevelMap_t;
|
||||||
|
|
||||||
|
typedef struct LevelPack
|
||||||
|
{
|
||||||
|
uint32_t n_levels;
|
||||||
|
LevelMap_t* levels;
|
||||||
|
}LevelPack_t;
|
||||||
|
|
||||||
void init_assets(Assets_t* assets);
|
void init_assets(Assets_t* assets);
|
||||||
void free_all_assets(Assets_t* assets);
|
void free_all_assets(Assets_t* assets);
|
||||||
|
@ -21,12 +43,13 @@ Texture2D* add_texture(Assets_t* assets, const char* name, const char* path);
|
||||||
Sprite_t* add_sprite(Assets_t* assets, const char* name, Texture2D* texture);
|
Sprite_t* add_sprite(Assets_t* assets, const char* name, Texture2D* texture);
|
||||||
Sound* add_sound(Assets_t * assets, const char* name, const char* path);
|
Sound* add_sound(Assets_t * assets, const char* name, const char* path);
|
||||||
Font* add_font(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);
|
||||||
|
|
||||||
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);
|
||||||
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);
|
||||||
|
|
||||||
void draw_sprite(Sprite_t* spr, Vector2 pos, bool flip_x);
|
void draw_sprite(Sprite_t* spr, Vector2 pos, bool flip_x);
|
||||||
#endif // __ASSETS_H
|
#endif // __ASSETS_H
|
||||||
|
|
|
@ -28,6 +28,7 @@ typedef struct TileGrid
|
||||||
unsigned int width;
|
unsigned int width;
|
||||||
unsigned int height;
|
unsigned int height;
|
||||||
unsigned int n_tiles;
|
unsigned int n_tiles;
|
||||||
|
unsigned int max_tiles;
|
||||||
unsigned int tile_size;
|
unsigned int tile_size;
|
||||||
Tile_t* tiles;
|
Tile_t* tiles;
|
||||||
}TileGrid_t;
|
}TileGrid_t;
|
||||||
|
|
|
@ -0,0 +1,430 @@
|
||||||
|
#include "scene_impl.h"
|
||||||
|
#include "game_systems.h"
|
||||||
|
#include "water_flow.h"
|
||||||
|
#include "constants.h"
|
||||||
|
#include "ent_impl.h"
|
||||||
|
#include "mempool.h"
|
||||||
|
#include "raylib.h"
|
||||||
|
#include "raymath.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static Tile_t all_tiles[MAX_N_TILES] = {0};
|
||||||
|
|
||||||
|
static void level_scene_render_func(Scene_t* scene)
|
||||||
|
{
|
||||||
|
LevelSceneData_t* data = &(CONTAINER_OF(scene, LevelScene_t, scene)->data);
|
||||||
|
TileGrid_t tilemap = data->tilemap;
|
||||||
|
|
||||||
|
Entity_t* p_ent;
|
||||||
|
|
||||||
|
BeginTextureMode(data->game_viewport);
|
||||||
|
ClearBackground(WHITE);
|
||||||
|
BeginMode2D(data->cam);
|
||||||
|
for (size_t i = 0; i < tilemap.n_tiles; ++i)
|
||||||
|
{
|
||||||
|
char buffer[6] = {0};
|
||||||
|
int x = (i % tilemap.width) * TILE_SIZE;
|
||||||
|
int y = (i / tilemap.width) * TILE_SIZE;
|
||||||
|
sprintf(buffer, "%u", sc_map_size_64v(&tilemap.tiles[i].entities_set));
|
||||||
|
|
||||||
|
if (!tilemap.tiles[i].moveable)
|
||||||
|
{
|
||||||
|
// Draw water tile
|
||||||
|
Color water_colour = ColorAlpha(RED, 0.2);
|
||||||
|
DrawRectangle(x, y, TILE_SIZE, TILE_SIZE, water_colour);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->tile_sprites[tilemap.tiles[i].tile_type] != NULL)
|
||||||
|
{
|
||||||
|
draw_sprite(data->tile_sprites[tilemap.tiles[i].tile_type], (Vector2){x,y}, false);
|
||||||
|
}
|
||||||
|
else if (tilemap.tiles[i].tile_type == SOLID_TILE)
|
||||||
|
{
|
||||||
|
DrawRectangle(x, y, TILE_SIZE, TILE_SIZE, BLACK);
|
||||||
|
}
|
||||||
|
else if (tilemap.tiles[i].tile_type == ONEWAY_TILE)
|
||||||
|
{
|
||||||
|
DrawRectangle(x, y, TILE_SIZE, TILE_SIZE, MAROON);
|
||||||
|
}
|
||||||
|
else if (tilemap.tiles[i].tile_type == LADDER)
|
||||||
|
{
|
||||||
|
DrawRectangle(x, y, TILE_SIZE, TILE_SIZE, ORANGE);
|
||||||
|
}
|
||||||
|
else if (tilemap.tiles[i].tile_type == SPIKES)
|
||||||
|
{
|
||||||
|
DrawRectangle(
|
||||||
|
x + tilemap.tiles[i].offset.x, y + tilemap.tiles[i].offset.y,
|
||||||
|
tilemap.tiles[i].size.x, tilemap.tiles[i].size.y, RED
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (tilemap.tiles[i].wet)
|
||||||
|
{
|
||||||
|
#define SURFACE_THICKNESS 4
|
||||||
|
int up = i - tilemap.width;
|
||||||
|
int bot = i + tilemap.width;
|
||||||
|
int right = i + 1;
|
||||||
|
int left = i - 1;
|
||||||
|
int bot_line = y + TILE_SIZE - tilemap.tiles[i].water_level * WATER_BBOX_STEP - SURFACE_THICKNESS / 2;
|
||||||
|
if (up >= 0 && tilemap.tiles[up].wet)
|
||||||
|
{
|
||||||
|
DrawLineEx((Vector2){x + TILE_SIZE / 2, y}, (Vector2){x + TILE_SIZE / 2, y + TILE_SIZE - tilemap.tiles[i].water_level * WATER_BBOX_STEP}, SURFACE_THICKNESS, ColorAlpha(BLUE, 0.7));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (
|
||||||
|
bot <= tilemap.n_tiles
|
||||||
|
&& tilemap.tiles[i].water_level == 0
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (i % tilemap.width != 0 && tilemap.tiles[left].wet && (tilemap.tiles[bot].solid == SOLID || tilemap.tiles[bot-1].solid == SOLID))
|
||||||
|
{
|
||||||
|
DrawLineEx((Vector2){x, bot_line}, (Vector2){x + TILE_SIZE / 2, bot_line}, SURFACE_THICKNESS, ColorAlpha(BLUE, 0.7));
|
||||||
|
}
|
||||||
|
if (right % tilemap.width != 0 && tilemap.tiles[right].wet && (tilemap.tiles[bot].solid == SOLID || tilemap.tiles[bot+1].solid == SOLID))
|
||||||
|
{
|
||||||
|
DrawLineEx((Vector2){x + TILE_SIZE / 2, bot_line}, (Vector2){x + TILE_SIZE, bot_line}, SURFACE_THICKNESS, ColorAlpha(BLUE, 0.7));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw water tile
|
||||||
|
uint32_t water_height = tilemap.tiles[i].water_level * WATER_BBOX_STEP;
|
||||||
|
// Draw water tile
|
||||||
|
Color water_colour = ColorAlpha(BLUE, 0.5);
|
||||||
|
DrawRectangle(
|
||||||
|
x,
|
||||||
|
y + (TILE_SIZE - water_height),
|
||||||
|
TILE_SIZE,
|
||||||
|
water_height,
|
||||||
|
water_colour
|
||||||
|
);
|
||||||
|
if (tilemap.tiles[i].max_water_level < MAX_WATER_LEVEL)
|
||||||
|
{
|
||||||
|
DrawRectangleLinesEx((Rectangle){x, y, TILE_SIZE, TILE_SIZE}, 2.0, ColorAlpha(BLUE, 0.5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
Color colour;
|
||||||
|
switch(p_ent->m_tag)
|
||||||
|
{
|
||||||
|
case PLAYER_ENT_TAG:
|
||||||
|
colour = RED;
|
||||||
|
break;
|
||||||
|
case CRATES_ENT_TAG:
|
||||||
|
colour = p_bbox->fragile? BROWN : GRAY;
|
||||||
|
break;
|
||||||
|
case BOULDER_ENT_TAG:
|
||||||
|
colour = GRAY;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
colour = BLACK;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_bbox != NULL)
|
||||||
|
{
|
||||||
|
if (p_ent->m_tag == BOULDER_ENT_TAG)
|
||||||
|
{
|
||||||
|
DrawCircleV(Vector2Add(p_ct->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);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p_ent->m_tag == CRATES_ENT_TAG)
|
||||||
|
{
|
||||||
|
CContainer_t* p_container = get_component(p_ent, CCONTAINER_T);
|
||||||
|
if (p_container != NULL)
|
||||||
|
{
|
||||||
|
switch (p_container->item)
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
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,
|
||||||
|
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,
|
||||||
|
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,
|
||||||
|
BLACK
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case CONTAINER_BOMB:
|
||||||
|
DrawCircleV(Vector2Add(p_ct->position, p_bbox->half_size), p_bbox->half_size.x, BLACK);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CHurtbox_t* p_hurtbox = get_component(p_ent, CHURTBOX_T);
|
||||||
|
CHitBoxes_t* p_hitbox = get_component(p_ent, CHITBOXES_T);
|
||||||
|
if (p_hitbox != NULL)
|
||||||
|
{
|
||||||
|
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,
|
||||||
|
.width = p_hitbox->boxes[i].width,
|
||||||
|
.height = p_hitbox->boxes[i].height,
|
||||||
|
};
|
||||||
|
DrawRectangleLinesEx(rec, 1.5, ORANGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p_hurtbox != NULL)
|
||||||
|
{
|
||||||
|
Rectangle rec = {
|
||||||
|
.x = p_ct->position.x + p_hurtbox->offset.x,
|
||||||
|
.y = p_ct->position.y + p_hurtbox->offset.y,
|
||||||
|
.width = p_hurtbox->size.x,
|
||||||
|
.height = p_hurtbox->size.y,
|
||||||
|
};
|
||||||
|
DrawRectangleLinesEx(rec, 1.5, PURPLE);
|
||||||
|
}
|
||||||
|
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 = Vector2Add(p_ct->position, spr.offset);
|
||||||
|
draw_sprite(spr.sprite, pos, p_cspr->flip_x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sc_map_foreach_value(&scene->ent_manager.entities_map[DYNMEM_ENT_TAG], p_ent)
|
||||||
|
{
|
||||||
|
CWaterRunner_t* p_runner = get_component(p_ent, CWATERRUNNER_T);
|
||||||
|
|
||||||
|
unsigned int x = ((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));
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < tilemap.n_tiles; ++i)
|
||||||
|
{
|
||||||
|
int x = (i % tilemap.width) * TILE_SIZE;
|
||||||
|
int y = (i / tilemap.width) * TILE_SIZE;
|
||||||
|
sprintf(buffer, "%u", sc_map_size_64v(&tilemap.tiles[i].entities_set));
|
||||||
|
|
||||||
|
if (tilemap.tiles[i].solid > 0)
|
||||||
|
{
|
||||||
|
DrawText(buffer, x, y, 10, WHITE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Draw water tile
|
||||||
|
DrawText(buffer, x, y, 10, BLACK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw tile grid
|
||||||
|
for (size_t i = 0; i < tilemap.width; ++i)
|
||||||
|
{
|
||||||
|
int x = (i+1)*TILE_SIZE;
|
||||||
|
DrawLine(x, 0, x, tilemap.height * TILE_SIZE, BLACK);
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < tilemap.height;++i)
|
||||||
|
{
|
||||||
|
int y = (i+1)*TILE_SIZE;
|
||||||
|
DrawLine(0, y, tilemap.width * TILE_SIZE, y, BLACK);
|
||||||
|
}
|
||||||
|
EndMode2D();
|
||||||
|
EndTextureMode();
|
||||||
|
|
||||||
|
Rectangle draw_rec = data->game_rec;
|
||||||
|
draw_rec.x = 0;
|
||||||
|
draw_rec.y = 0;
|
||||||
|
draw_rec.height *= -1;
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(LIGHTGRAY);
|
||||||
|
DrawTextureRec(
|
||||||
|
data->game_viewport.texture,
|
||||||
|
draw_rec,
|
||||||
|
(Vector2){data->game_rec.x, data->game_rec.y},
|
||||||
|
WHITE
|
||||||
|
);
|
||||||
|
|
||||||
|
// For DEBUG
|
||||||
|
const int gui_x = data->game_rec.x + data->game_rec.width + 10;
|
||||||
|
sc_map_foreach_value(&scene->ent_manager.entities_map[PLAYER_ENT_TAG], p_ent)
|
||||||
|
{
|
||||||
|
CTransform_t* p_ct = get_component(p_ent, CTRANSFORM_COMP_T);
|
||||||
|
CJump_t* p_cjump = get_component(p_ent, CJUMP_COMP_T);
|
||||||
|
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);
|
||||||
|
DrawText(buffer, gui_x, 15, 12, BLACK);
|
||||||
|
sprintf(buffer, "Vel: %.3f\n %.3f", p_ct->velocity.x, p_ct->velocity.y);
|
||||||
|
DrawText(buffer, gui_x + 80, 15, 12, BLACK);
|
||||||
|
//sprintf(buffer, "Accel: %.3f\n %.3f", p_ct->accel.x, p_ct->accel.y);
|
||||||
|
//DrawText(buffer, tilemap.width * TILE_SIZE + 128, 60, 12, BLACK);
|
||||||
|
sprintf(buffer, "Jumps: %u", p_cjump->jumps);
|
||||||
|
DrawText(buffer, gui_x, 60, 12, BLACK);
|
||||||
|
sprintf(buffer, "Crouch: %u", p_pstate->is_crouch);
|
||||||
|
DrawText(buffer, gui_x, 90, 12, BLACK);
|
||||||
|
sprintf(buffer, "Water: %s", p_mstate->water_state & 1? "YES":"NO");
|
||||||
|
DrawText(buffer, gui_x, 120, 12, BLACK);
|
||||||
|
sprintf(buffer, "Ladder: %u", p_pstate->ladder_state);
|
||||||
|
DrawText(buffer, gui_x, 150, 12, BLACK);
|
||||||
|
}
|
||||||
|
//sprintf(buffer, "Spawn Entity: %s", get_spawn_selection_string(current_spawn_selection));
|
||||||
|
//DrawText(buffer, gui_x, 240, 12, BLACK);
|
||||||
|
sprintf(buffer, "Number of Entities: %u", sc_map_size_64v(&scene->ent_manager.entities));
|
||||||
|
DrawText(buffer, gui_x, 270, 12, BLACK);
|
||||||
|
sprintf(buffer, "FPS: %u", GetFPS());
|
||||||
|
DrawText(buffer, gui_x, 320, 12, BLACK);
|
||||||
|
|
||||||
|
static char mempool_stats[512];
|
||||||
|
print_mempool_stats(mempool_stats);
|
||||||
|
DrawText(mempool_stats, gui_x, 350, 12, BLACK);
|
||||||
|
EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void level_do_action(Scene_t* scene, ActionType_t action, bool pressed)
|
||||||
|
{
|
||||||
|
CPlayerState_t* p_playerstate;
|
||||||
|
sc_map_foreach_value(&scene->ent_manager.component_map[CPLAYERSTATE_T], p_playerstate)
|
||||||
|
{
|
||||||
|
switch(action)
|
||||||
|
{
|
||||||
|
case ACTION_UP:
|
||||||
|
p_playerstate->player_dir.y = (pressed)? -1 : 0;
|
||||||
|
break;
|
||||||
|
case ACTION_DOWN:
|
||||||
|
p_playerstate->player_dir.y = (pressed)? 1 : 0;
|
||||||
|
break;
|
||||||
|
case ACTION_LEFT:
|
||||||
|
p_playerstate->player_dir.x = (pressed)? -1 : 0;
|
||||||
|
break;
|
||||||
|
case ACTION_RIGHT:
|
||||||
|
p_playerstate->player_dir.x = (pressed)? 1 : 0;
|
||||||
|
break;
|
||||||
|
case ACTION_JUMP:
|
||||||
|
p_playerstate->jump_pressed = pressed;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!pressed)
|
||||||
|
{
|
||||||
|
switch (action)
|
||||||
|
{
|
||||||
|
case ACTION_RESTART:
|
||||||
|
reload_level_tilemap((LevelScene_t*)scene);
|
||||||
|
break;
|
||||||
|
case ACTION_NEXTLEVEL:
|
||||||
|
load_next_level_tilemap((LevelScene_t*)scene);
|
||||||
|
break;
|
||||||
|
case ACTION_PREVLEVEL:
|
||||||
|
load_prev_level_tilemap((LevelScene_t*)scene);
|
||||||
|
break;
|
||||||
|
case ACTION_EXIT:
|
||||||
|
if(scene->engine != NULL)
|
||||||
|
{
|
||||||
|
change_scene(scene->engine, 0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void init_game_scene(LevelScene_t* scene)
|
||||||
|
{
|
||||||
|
//init_scene(&scene->scene, LEVEL_SCENE, &level_scene_render_func, &level_do_action);
|
||||||
|
init_scene(&scene->scene, &level_scene_render_func, &level_do_action);
|
||||||
|
|
||||||
|
scene->data.tilemap.tiles = all_tiles;
|
||||||
|
init_level_scene_data(
|
||||||
|
&scene->data, MAX_N_TILES, all_tiles,
|
||||||
|
(Rectangle){25, 25, 32*TILE_SIZE, 18*TILE_SIZE}
|
||||||
|
);
|
||||||
|
|
||||||
|
create_player(&scene->scene.ent_manager, &scene->scene.engine->assets);
|
||||||
|
update_entity_manager(&scene->scene.ent_manager);
|
||||||
|
|
||||||
|
// insert level scene systems
|
||||||
|
sc_array_add(&scene->scene.systems, &update_tilemap_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &player_movement_input_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &player_bbox_update_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &player_pushing_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &friction_coefficient_update_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &global_external_forces_system);
|
||||||
|
|
||||||
|
sc_array_add(&scene->scene.systems, &moveable_update_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &movement_update_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &boulder_destroy_wooden_tile_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &update_tilemap_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &tile_collision_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &hitbox_update_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &player_crushing_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &spike_collision_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &state_transition_update_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &player_ground_air_transition_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &lifetimer_update_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &container_destroy_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &sprite_animation_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &camera_update_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &player_dir_reset_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &player_respawn_system);
|
||||||
|
sc_array_add(&scene->scene.systems, &update_water_runner_system);
|
||||||
|
|
||||||
|
// This avoid graphical glitch, not essential
|
||||||
|
//sc_array_add(&scene->scene.systems, &update_tilemap_system);
|
||||||
|
|
||||||
|
sc_map_put_64(&scene->scene.action_map, KEY_UP, ACTION_UP);
|
||||||
|
sc_map_put_64(&scene->scene.action_map, KEY_DOWN, ACTION_DOWN);
|
||||||
|
sc_map_put_64(&scene->scene.action_map, KEY_LEFT, ACTION_LEFT);
|
||||||
|
sc_map_put_64(&scene->scene.action_map, KEY_RIGHT, ACTION_RIGHT);
|
||||||
|
sc_map_put_64(&scene->scene.action_map, KEY_SPACE, ACTION_JUMP);
|
||||||
|
sc_map_put_64(&scene->scene.action_map, KEY_Q, ACTION_EXIT);
|
||||||
|
sc_map_put_64(&scene->scene.action_map, KEY_R, ACTION_RESTART);
|
||||||
|
sc_map_put_64(&scene->scene.action_map, KEY_RIGHT_BRACKET, ACTION_NEXTLEVEL);
|
||||||
|
sc_map_put_64(&scene->scene.action_map, KEY_LEFT_BRACKET, ACTION_PREVLEVEL);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void free_game_scene(LevelScene_t* scene)
|
||||||
|
{
|
||||||
|
free_scene(&scene->scene);
|
||||||
|
term_level_scene_data(&scene->data);
|
||||||
|
}
|
|
@ -26,103 +26,6 @@ static inline unsigned int get_tile_idx(int x, int y, unsigned int tilemap_width
|
||||||
return tile_y * tilemap_width + tile_x;
|
return tile_y * tilemap_width + tile_x;
|
||||||
}
|
}
|
||||||
|
|
||||||
void change_a_tile(TileGrid_t* tilemap, unsigned int tile_idx, TileType_t new_type)
|
|
||||||
{
|
|
||||||
TileType_t last_type = tilemap->tiles[tile_idx].tile_type;
|
|
||||||
tilemap->tiles[tile_idx].tile_type = new_type;
|
|
||||||
|
|
||||||
switch (new_type)
|
|
||||||
{
|
|
||||||
case EMPTY_TILE:
|
|
||||||
tilemap->tiles[tile_idx].solid = NOT_SOLID;
|
|
||||||
break;
|
|
||||||
case ONEWAY_TILE:
|
|
||||||
tilemap->tiles[tile_idx].solid = ONE_WAY;
|
|
||||||
break;
|
|
||||||
case LADDER:
|
|
||||||
{
|
|
||||||
int up_tile = tile_idx - tilemap->width;
|
|
||||||
if (up_tile > 0 && tilemap->tiles[up_tile].tile_type != LADDER)
|
|
||||||
{
|
|
||||||
tilemap->tiles[tile_idx].solid = ONE_WAY;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tilemap->tiles[tile_idx].solid = NOT_SOLID;
|
|
||||||
}
|
|
||||||
int down_tile = tile_idx + tilemap->width;
|
|
||||||
if (down_tile < tilemap->n_tiles && tilemap->tiles[down_tile].tile_type == LADDER)
|
|
||||||
{
|
|
||||||
tilemap->tiles[down_tile].solid = (tilemap->tiles[tile_idx].tile_type != LADDER)? ONE_WAY : NOT_SOLID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SPIKES:
|
|
||||||
tilemap->tiles[tile_idx].solid = NOT_SOLID;
|
|
||||||
break;
|
|
||||||
case SOLID_TILE:
|
|
||||||
tilemap->tiles[tile_idx].solid = SOLID;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (last_type == LADDER && new_type != LADDER)
|
|
||||||
{
|
|
||||||
int down_tile = tile_idx + tilemap->width;
|
|
||||||
if (down_tile < tilemap->n_tiles && tilemap->tiles[down_tile].tile_type == LADDER)
|
|
||||||
{
|
|
||||||
tilemap->tiles[down_tile].solid = ONE_WAY;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (new_type == SPIKES)
|
|
||||||
{
|
|
||||||
// Priority: Down, Up, Left, Right
|
|
||||||
if (tile_idx + tilemap->width < tilemap->n_tiles && tilemap->tiles[tile_idx + tilemap->width].tile_type == SOLID_TILE)
|
|
||||||
{
|
|
||||||
tilemap->tiles[tile_idx].offset = (Vector2){0,16};
|
|
||||||
tilemap->tiles[tile_idx].size = (Vector2){32,16};
|
|
||||||
}
|
|
||||||
else if (tile_idx - tilemap->width >= 0 && tilemap->tiles[tile_idx - tilemap->width].tile_type == SOLID_TILE)
|
|
||||||
{
|
|
||||||
tilemap->tiles[tile_idx].offset = (Vector2){0,0};
|
|
||||||
tilemap->tiles[tile_idx].size = (Vector2){32,16};
|
|
||||||
}
|
|
||||||
else if (tile_idx % tilemap->width != 0 && tilemap->tiles[tile_idx - 1].tile_type == SOLID_TILE)
|
|
||||||
{
|
|
||||||
tilemap->tiles[tile_idx].offset = (Vector2){0,0};
|
|
||||||
tilemap->tiles[tile_idx].size = (Vector2){16,32};
|
|
||||||
}
|
|
||||||
else if ((tile_idx + 1) % tilemap->width != 0 && tilemap->tiles[tile_idx + 1].tile_type == SOLID_TILE)
|
|
||||||
{
|
|
||||||
tilemap->tiles[tile_idx].offset = (Vector2){16,0};
|
|
||||||
tilemap->tiles[tile_idx].size = (Vector2){16,32};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tilemap->tiles[tile_idx].offset = (Vector2){0,16};
|
|
||||||
tilemap->tiles[tile_idx].size = (Vector2){32,16};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (new_type == ONEWAY_TILE)
|
|
||||||
{
|
|
||||||
tilemap->tiles[tile_idx].offset = (Vector2){0,0};
|
|
||||||
tilemap->tiles[tile_idx].size = (Vector2){32,10};
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tilemap->tiles[tile_idx].offset = (Vector2){0,0};
|
|
||||||
tilemap->tiles[tile_idx].size = (Vector2){32,32};
|
|
||||||
}
|
|
||||||
|
|
||||||
tilemap->tiles[tile_idx].moveable = (
|
|
||||||
tilemap->tiles[tile_idx].tile_type == EMPTY_TILE
|
|
||||||
|| tilemap->tiles[tile_idx].tile_type == SPIKES
|
|
||||||
);
|
|
||||||
tilemap->tiles[tile_idx].def = (tilemap->tiles[tile_idx].tile_type == SOLID_TILE) ? 5: 2;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------- Collision functions ------------------------------------
|
// ------------------------- Collision functions ------------------------------------
|
||||||
// Do not subtract one for the size for any collision check, just pass normally. The extra one is important for AABB test
|
// Do not subtract one for the size for any collision check, just pass normally. The extra one is important for AABB test
|
||||||
|
|
||||||
|
@ -1746,8 +1649,8 @@ void camera_update_system(Scene_t* scene)
|
||||||
}
|
}
|
||||||
Vector2 max = GetWorldToScreen2D(
|
Vector2 max = GetWorldToScreen2D(
|
||||||
(Vector2){
|
(Vector2){
|
||||||
lvl_scene->data.tilemap.width * TILE_SIZE,
|
fmax(lvl_scene->data.tilemap.width * TILE_SIZE, lvl_scene->data.game_rec.width),
|
||||||
lvl_scene->data.tilemap.height * TILE_SIZE
|
fmax(lvl_scene->data.tilemap.height * TILE_SIZE, lvl_scene->data.game_rec.height)
|
||||||
},
|
},
|
||||||
lvl_scene->data.cam
|
lvl_scene->data.cam
|
||||||
);
|
);
|
||||||
|
@ -1758,17 +1661,3 @@ void camera_update_system(Scene_t* scene)
|
||||||
if (min.x > 0) lvl_scene->data.cam.offset.x = width/2.0f - min.x;
|
if (min.x > 0) lvl_scene->data.cam.offset.x = width/2.0f - min.x;
|
||||||
if (min.y > 0) lvl_scene->data.cam.offset.y = height/2.0f - min.y;
|
if (min.y > 0) lvl_scene->data.cam.offset.y = height/2.0f - min.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_level_scene_data(LevelSceneData_t* data)
|
|
||||||
{
|
|
||||||
data->game_viewport = LoadRenderTexture(VIEWABLE_MAP_WIDTH*TILE_SIZE, VIEWABLE_MAP_HEIGHT*TILE_SIZE);
|
|
||||||
data->game_rec = (Rectangle){25, 25, VIEWABLE_MAP_WIDTH*TILE_SIZE, VIEWABLE_MAP_HEIGHT*TILE_SIZE};
|
|
||||||
data->cam = (Camera2D){0};
|
|
||||||
data->cam.rotation = 0.0f;
|
|
||||||
data->cam.zoom = 1.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
void term_level_scene_data(LevelSceneData_t* data)
|
|
||||||
{
|
|
||||||
UnloadRenderTexture(data->game_viewport); // Unload render texture
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#ifndef __GAME_SYSTEMS_H
|
#ifndef __GAME_SYSTEMS_H
|
||||||
#define __GAME_SYSTEMS_H
|
#define __GAME_SYSTEMS_H
|
||||||
#include "scene_impl.h"
|
#include "scene_impl.h"
|
||||||
void init_level_scene_data(LevelSceneData_t* data);
|
|
||||||
void term_level_scene_data(LevelSceneData_t* data);
|
|
||||||
|
|
||||||
void player_movement_input_system(Scene_t* scene);
|
void player_movement_input_system(Scene_t* scene);
|
||||||
void player_bbox_update_system(Scene_t* scene);
|
void player_bbox_update_system(Scene_t* scene);
|
||||||
|
@ -26,5 +24,4 @@ void player_respawn_system(Scene_t* scene);
|
||||||
void lifetimer_update_system(Scene_t* scene);
|
void lifetimer_update_system(Scene_t* scene);
|
||||||
void spike_collision_system(Scene_t* scene);
|
void spike_collision_system(Scene_t* scene);
|
||||||
|
|
||||||
void change_a_tile(TileGrid_t* tilemap, unsigned int tile_idx, TileType_t new_type);
|
|
||||||
#endif // __GAME_SYSTEMS_H
|
#endif // __GAME_SYSTEMS_H
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
#include "constants.h"
|
#include "constants.h"
|
||||||
#include "raymath.h"
|
#include "raymath.h"
|
||||||
|
|
||||||
static SpriteRenderInfo_t item_sprite_map[2] = {0};
|
static SpriteRenderInfo_t item_sprite_map[3] = {0};
|
||||||
|
|
||||||
bool init_item_creation(Assets_t* assets)
|
bool init_item_creation(Assets_t* assets)
|
||||||
{
|
{
|
||||||
item_sprite_map[0].sprite = get_sprite(assets, "w_crate");
|
item_sprite_map[0].sprite = get_sprite(assets, "w_crate");
|
||||||
item_sprite_map[1].sprite = get_sprite(assets, "m_crate");
|
item_sprite_map[1].sprite = get_sprite(assets, "m_crate");
|
||||||
|
item_sprite_map[2].sprite = get_sprite(assets, "arrow");
|
||||||
|
item_sprite_map[2].offset = (Vector2){-8, 4};
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,6 +87,9 @@ Entity_t* create_arrow(EntityManager_t* ent_manager, Assets_t* assets, uint8_t d
|
||||||
p_ctransform->movement_mode = KINEMATIC_MOVEMENT;
|
p_ctransform->movement_mode = KINEMATIC_MOVEMENT;
|
||||||
p_ctransform->active = true;
|
p_ctransform->active = true;
|
||||||
|
|
||||||
|
CSprite_t* p_cspr = add_component(p_arrow, CSPRITE_T);
|
||||||
|
p_cspr->sprites = item_sprite_map;
|
||||||
|
p_cspr->current_idx = 2;
|
||||||
//p_hitbox->boxes[0] = (Rectangle){TILE_SIZE - 5, TILE_SIZE / 2 - 5, 5, 5};
|
//p_hitbox->boxes[0] = (Rectangle){TILE_SIZE - 5, TILE_SIZE / 2 - 5, 5, 5};
|
||||||
switch(dir)
|
switch(dir)
|
||||||
{
|
{
|
||||||
|
|
|
@ -10,8 +10,9 @@ static void menu_scene_render_func(Scene_t* scene)
|
||||||
ClearBackground(RAYWHITE);
|
ClearBackground(RAYWHITE);
|
||||||
DrawText("This is a game", 25, 220, 12, BLACK);
|
DrawText("This is a game", 25, 220, 12, BLACK);
|
||||||
UI_button(data->buttons, "Start");
|
UI_button(data->buttons, "Start");
|
||||||
UI_button(data->buttons + 1, "Continue");
|
UI_button(data->buttons + 1, "Sandbox");
|
||||||
UI_button(data->buttons + 2, "Exit");
|
UI_button(data->buttons + 2, "Continue");
|
||||||
|
UI_button(data->buttons + 3, "Exit");
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +58,9 @@ static void menu_do_action(Scene_t* scene, ActionType_t action, bool pressed)
|
||||||
case 0:
|
case 0:
|
||||||
change_scene(scene->engine, 1);
|
change_scene(scene->engine, 1);
|
||||||
break;
|
break;
|
||||||
|
case 1:
|
||||||
|
change_scene(scene->engine, 2);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -128,7 +132,6 @@ void init_menu_scene(MenuScene_t* scene)
|
||||||
.state = STATE_NORMAL,
|
.state = STATE_NORMAL,
|
||||||
.alpha = 1.0
|
.alpha = 1.0
|
||||||
};
|
};
|
||||||
|
|
||||||
scene->data.buttons[1] = (UIComp_t) {
|
scene->data.buttons[1] = (UIComp_t) {
|
||||||
.bbox = {25,300,125,30},
|
.bbox = {25,300,125,30},
|
||||||
.state = STATE_NORMAL,
|
.state = STATE_NORMAL,
|
||||||
|
@ -139,7 +142,12 @@ void init_menu_scene(MenuScene_t* scene)
|
||||||
.state = STATE_NORMAL,
|
.state = STATE_NORMAL,
|
||||||
.alpha = 1.0
|
.alpha = 1.0
|
||||||
};
|
};
|
||||||
scene->data.max_comp = 3;
|
scene->data.buttons[3] = (UIComp_t) {
|
||||||
|
.bbox = {25,390,125,30},
|
||||||
|
.state = STATE_NORMAL,
|
||||||
|
.alpha = 1.0
|
||||||
|
};
|
||||||
|
scene->data.max_comp = 4;
|
||||||
scene->data.selected_comp = 0;
|
scene->data.selected_comp = 0;
|
||||||
scene->data.mode = KEYBOARD_MODE;
|
scene->data.mode = KEYBOARD_MODE;
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@ typedef struct LevelSceneData {
|
||||||
Rectangle game_rec;
|
Rectangle game_rec;
|
||||||
Camera2D cam;
|
Camera2D cam;
|
||||||
Sprite_t* tile_sprites[MAX_TILE_TYPES];
|
Sprite_t* tile_sprites[MAX_TILE_TYPES];
|
||||||
|
LevelPack_t* level_pack;
|
||||||
|
unsigned int current_level;
|
||||||
}LevelSceneData_t;
|
}LevelSceneData_t;
|
||||||
|
|
||||||
typedef struct LevelScene {
|
typedef struct LevelScene {
|
||||||
|
@ -32,9 +34,18 @@ typedef struct LevelScene {
|
||||||
LevelSceneData_t data;
|
LevelSceneData_t data;
|
||||||
}LevelScene_t;
|
}LevelScene_t;
|
||||||
|
|
||||||
void init_level_scene(LevelScene_t* scene);
|
void init_game_scene(LevelScene_t* scene);
|
||||||
void free_level_scene(LevelScene_t* scene);
|
void free_game_scene(LevelScene_t* scene);
|
||||||
void reload_level_scene(LevelScene_t* scene);
|
void init_sandbox_scene(LevelScene_t* scene);
|
||||||
|
void free_sandbox_scene(LevelScene_t* scene);
|
||||||
|
void init_level_scene_data(LevelSceneData_t* data, uint32_t max_tiles, Tile_t* tiles, Rectangle view_zone);
|
||||||
|
//void init_level_scene_data(LevelSceneData_t* data, uint32_t max_tiles, Tile_t* tiles);
|
||||||
|
void term_level_scene_data(LevelSceneData_t* data);
|
||||||
|
void reload_level_tilemap(LevelScene_t* scene);
|
||||||
|
void load_next_level_tilemap(LevelScene_t* scene);
|
||||||
|
void load_prev_level_tilemap(LevelScene_t* scene);
|
||||||
|
bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num);
|
||||||
|
void change_a_tile(TileGrid_t* tilemap, unsigned int tile_idx, TileType_t new_type);
|
||||||
|
|
||||||
typedef enum GuiMode {
|
typedef enum GuiMode {
|
||||||
KEYBOARD_MODE,
|
KEYBOARD_MODE,
|
||||||
|
@ -42,7 +53,7 @@ typedef enum GuiMode {
|
||||||
} GuiMode_t;
|
} GuiMode_t;
|
||||||
|
|
||||||
typedef struct MenuSceneData {
|
typedef struct MenuSceneData {
|
||||||
UIComp_t buttons[3];
|
UIComp_t buttons[4];
|
||||||
int selected_comp;
|
int selected_comp;
|
||||||
int max_comp;
|
int max_comp;
|
||||||
GuiMode_t mode;
|
GuiMode_t mode;
|
||||||
|
@ -55,4 +66,5 @@ typedef struct MenuScene {
|
||||||
|
|
||||||
void init_menu_scene(MenuScene_t* scene);
|
void init_menu_scene(MenuScene_t* scene);
|
||||||
void free_menu_scene(MenuScene_t* scene);
|
void free_menu_scene(MenuScene_t* scene);
|
||||||
|
|
||||||
#endif // __SCENE_IMPL_H
|
#endif // __SCENE_IMPL_H
|
||||||
|
|
|
@ -0,0 +1,220 @@
|
||||||
|
#include "scene_impl.h"
|
||||||
|
#include "ent_impl.h"
|
||||||
|
#include "constants.h"
|
||||||
|
|
||||||
|
void init_level_scene_data(LevelSceneData_t* data, uint32_t max_tiles, Tile_t* tiles, Rectangle view_zone)
|
||||||
|
//void init_level_scene_data(LevelSceneData_t* data, uint32_t max_tiles, Tile_t* tiles)
|
||||||
|
{
|
||||||
|
//data->game_viewport = LoadRenderTexture(VIEWABLE_MAP_WIDTH*TILE_SIZE, VIEWABLE_MAP_HEIGHT*TILE_SIZE);
|
||||||
|
//data->game_rec = (Rectangle){25, 25, VIEWABLE_MAP_WIDTH*TILE_SIZE, VIEWABLE_MAP_HEIGHT*TILE_SIZE};
|
||||||
|
data->game_viewport = LoadRenderTexture(view_zone.width, view_zone.height);
|
||||||
|
data->game_rec = view_zone;
|
||||||
|
data->cam = (Camera2D){0};
|
||||||
|
data->cam.rotation = 0.0f;
|
||||||
|
data->cam.zoom = 1.0f;
|
||||||
|
|
||||||
|
data->tilemap.max_tiles = max_tiles;
|
||||||
|
if (tiles != NULL)
|
||||||
|
{
|
||||||
|
data->tilemap.tiles = tiles;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
data->tilemap.tiles = calloc(max_tiles, sizeof(Tile_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
data->tilemap.width = DEFAULT_MAP_WIDTH;
|
||||||
|
data->tilemap.height = DEFAULT_MAP_HEIGHT;
|
||||||
|
data->tilemap.tile_size = TILE_SIZE;
|
||||||
|
data->tilemap.n_tiles = data->tilemap.width * data->tilemap.height;
|
||||||
|
memset(data->tile_sprites, 0, sizeof(data->tile_sprites));
|
||||||
|
for (size_t i = 0; i < max_tiles;i++)
|
||||||
|
{
|
||||||
|
data->tilemap.tiles[i].solid = NOT_SOLID;
|
||||||
|
data->tilemap.tiles[i].tile_type = EMPTY_TILE;
|
||||||
|
data->tilemap.tiles[i].moveable = true;
|
||||||
|
data->tilemap.tiles[i].max_water_level = 4;
|
||||||
|
sc_map_init_64v(&data->tilemap.tiles[i].entities_set, 16, 0);
|
||||||
|
data->tilemap.tiles[i].size = (Vector2){TILE_SIZE, TILE_SIZE};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void term_level_scene_data(LevelSceneData_t* data)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < data->tilemap.max_tiles;i++)
|
||||||
|
{
|
||||||
|
sc_map_term_64v(&data->tilemap.tiles[i].entities_set);
|
||||||
|
}
|
||||||
|
UnloadRenderTexture(data->game_viewport); // Unload render texture
|
||||||
|
}
|
||||||
|
|
||||||
|
bool load_level_tilemap(LevelScene_t* scene, unsigned int level_num)
|
||||||
|
{
|
||||||
|
if (level_num >= scene->data.level_pack->n_levels) return false;
|
||||||
|
|
||||||
|
LevelMap_t lvl_map = scene->data.level_pack->levels[level_num];
|
||||||
|
uint32_t n_tiles = lvl_map.width * lvl_map.height;
|
||||||
|
if (n_tiles > scene->data.tilemap.max_tiles) return false;
|
||||||
|
|
||||||
|
scene->data.current_level = level_num;
|
||||||
|
scene->data.tilemap.width = lvl_map.width;
|
||||||
|
scene->data.tilemap.height = lvl_map.height;
|
||||||
|
scene->data.tilemap.n_tiles = n_tiles;
|
||||||
|
|
||||||
|
clear_entity_manager(&scene->scene.ent_manager);
|
||||||
|
for (size_t i = 0; i < scene->data.tilemap.n_tiles;i++)
|
||||||
|
{
|
||||||
|
scene->data.tilemap.tiles[i].max_water_level = 4;
|
||||||
|
scene->data.tilemap.tiles[i].solid = NOT_SOLID;
|
||||||
|
scene->data.tilemap.tiles[i].tile_type = EMPTY_TILE;
|
||||||
|
scene->data.tilemap.tiles[i].moveable = true;
|
||||||
|
scene->data.tilemap.tiles[i].size = (Vector2){TILE_SIZE, TILE_SIZE};
|
||||||
|
sc_map_clear_64v(&scene->data.tilemap.tiles[i].entities_set);
|
||||||
|
|
||||||
|
switch (lvl_map.tiles[i].tile_type)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
change_a_tile(&scene->data.tilemap, i, SOLID_TILE);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
switch (lvl_map.tiles[i].entity_to_spawn)
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
Entity_t* ent = create_player(&scene->scene.ent_manager, &scene->scene.engine->assets);
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
scene->data.tilemap.tiles[i].water_level = lvl_map.tiles[i].water;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reload_level_tilemap(LevelScene_t* scene)
|
||||||
|
{
|
||||||
|
load_level_tilemap(scene, scene->data.current_level);
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_next_level_tilemap(LevelScene_t* scene)
|
||||||
|
{
|
||||||
|
unsigned int lvl = scene->data.current_level;
|
||||||
|
lvl++;
|
||||||
|
if (lvl < scene->data.level_pack->n_levels)
|
||||||
|
{
|
||||||
|
load_level_tilemap(scene, lvl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void load_prev_level_tilemap(LevelScene_t* scene)
|
||||||
|
{
|
||||||
|
unsigned int lvl = scene->data.current_level;
|
||||||
|
lvl--;
|
||||||
|
if (lvl >= 0)
|
||||||
|
{
|
||||||
|
load_level_tilemap(scene, lvl);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void change_a_tile(TileGrid_t* tilemap, unsigned int tile_idx, TileType_t new_type)
|
||||||
|
{
|
||||||
|
TileType_t last_type = tilemap->tiles[tile_idx].tile_type;
|
||||||
|
tilemap->tiles[tile_idx].tile_type = new_type;
|
||||||
|
|
||||||
|
switch (new_type)
|
||||||
|
{
|
||||||
|
case EMPTY_TILE:
|
||||||
|
tilemap->tiles[tile_idx].solid = NOT_SOLID;
|
||||||
|
break;
|
||||||
|
case ONEWAY_TILE:
|
||||||
|
tilemap->tiles[tile_idx].solid = ONE_WAY;
|
||||||
|
break;
|
||||||
|
case LADDER:
|
||||||
|
{
|
||||||
|
int up_tile = tile_idx - tilemap->width;
|
||||||
|
if (up_tile > 0 && tilemap->tiles[up_tile].tile_type != LADDER)
|
||||||
|
{
|
||||||
|
tilemap->tiles[tile_idx].solid = ONE_WAY;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tilemap->tiles[tile_idx].solid = NOT_SOLID;
|
||||||
|
}
|
||||||
|
int down_tile = tile_idx + tilemap->width;
|
||||||
|
if (down_tile < tilemap->n_tiles && tilemap->tiles[down_tile].tile_type == LADDER)
|
||||||
|
{
|
||||||
|
tilemap->tiles[down_tile].solid = (tilemap->tiles[tile_idx].tile_type != LADDER)? ONE_WAY : NOT_SOLID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SPIKES:
|
||||||
|
tilemap->tiles[tile_idx].solid = NOT_SOLID;
|
||||||
|
break;
|
||||||
|
case SOLID_TILE:
|
||||||
|
tilemap->tiles[tile_idx].solid = SOLID;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (last_type == LADDER && new_type != LADDER)
|
||||||
|
{
|
||||||
|
int down_tile = tile_idx + tilemap->width;
|
||||||
|
if (down_tile < tilemap->n_tiles && tilemap->tiles[down_tile].tile_type == LADDER)
|
||||||
|
{
|
||||||
|
tilemap->tiles[down_tile].solid = ONE_WAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_type == SPIKES)
|
||||||
|
{
|
||||||
|
// Priority: Down, Up, Left, Right
|
||||||
|
if (tile_idx + tilemap->width < tilemap->n_tiles && tilemap->tiles[tile_idx + tilemap->width].tile_type == SOLID_TILE)
|
||||||
|
{
|
||||||
|
tilemap->tiles[tile_idx].offset = (Vector2){0,16};
|
||||||
|
tilemap->tiles[tile_idx].size = (Vector2){32,16};
|
||||||
|
}
|
||||||
|
else if (tile_idx - tilemap->width >= 0 && tilemap->tiles[tile_idx - tilemap->width].tile_type == SOLID_TILE)
|
||||||
|
{
|
||||||
|
tilemap->tiles[tile_idx].offset = (Vector2){0,0};
|
||||||
|
tilemap->tiles[tile_idx].size = (Vector2){32,16};
|
||||||
|
}
|
||||||
|
else if (tile_idx % tilemap->width != 0 && tilemap->tiles[tile_idx - 1].tile_type == SOLID_TILE)
|
||||||
|
{
|
||||||
|
tilemap->tiles[tile_idx].offset = (Vector2){0,0};
|
||||||
|
tilemap->tiles[tile_idx].size = (Vector2){16,32};
|
||||||
|
}
|
||||||
|
else if ((tile_idx + 1) % tilemap->width != 0 && tilemap->tiles[tile_idx + 1].tile_type == SOLID_TILE)
|
||||||
|
{
|
||||||
|
tilemap->tiles[tile_idx].offset = (Vector2){16,0};
|
||||||
|
tilemap->tiles[tile_idx].size = (Vector2){16,32};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tilemap->tiles[tile_idx].offset = (Vector2){0,16};
|
||||||
|
tilemap->tiles[tile_idx].size = (Vector2){32,16};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (new_type == ONEWAY_TILE)
|
||||||
|
{
|
||||||
|
tilemap->tiles[tile_idx].offset = (Vector2){0,0};
|
||||||
|
tilemap->tiles[tile_idx].size = (Vector2){32,10};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tilemap->tiles[tile_idx].offset = (Vector2){0,0};
|
||||||
|
tilemap->tiles[tile_idx].size = (Vector2){32,32};
|
||||||
|
}
|
||||||
|
|
||||||
|
tilemap->tiles[tile_idx].moveable = (
|
||||||
|
tilemap->tiles[tile_idx].tile_type == EMPTY_TILE
|
||||||
|
|| tilemap->tiles[tile_idx].tile_type == SPIKES
|
||||||
|
);
|
||||||
|
tilemap->tiles[tile_idx].def = (tilemap->tiles[tile_idx].tile_type == SOLID_TILE) ? 5: 2;
|
||||||
|
|
||||||
|
}
|
31
water_test.c
31
water_test.c
|
@ -9,7 +9,6 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define MAX_N_TILES 4096
|
|
||||||
static Tile_t all_tiles[MAX_N_TILES] = {0};
|
static Tile_t all_tiles[MAX_N_TILES] = {0};
|
||||||
|
|
||||||
// Maintain own queue to handle key presses
|
// Maintain own queue to handle key presses
|
||||||
|
@ -193,7 +192,6 @@ static void level_scene_render_func(Scene_t* scene)
|
||||||
);
|
);
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
}
|
}
|
||||||
#define MAX_N_TILES 4096
|
|
||||||
|
|
||||||
static inline unsigned int get_tile_idx(int x, int y, const TileGrid_t* tilemap)
|
static inline unsigned int get_tile_idx(int x, int y, const TileGrid_t* tilemap)
|
||||||
{
|
{
|
||||||
|
@ -415,30 +413,16 @@ int main(void)
|
||||||
init_memory_pools();
|
init_memory_pools();
|
||||||
|
|
||||||
init_assets(&engine.assets);
|
init_assets(&engine.assets);
|
||||||
load_from_infofile("res/assets.info", &engine.assets);
|
|
||||||
init_player_creation("res/player_spr.info", &engine.assets);
|
|
||||||
|
|
||||||
LevelScene_t scene;
|
LevelScene_t scene;
|
||||||
scene.scene.engine = &engine;
|
scene.scene.engine = &engine;
|
||||||
init_scene(&scene.scene, &level_scene_render_func, &level_do_action);
|
init_scene(&scene.scene, &level_scene_render_func, &level_do_action);
|
||||||
init_level_scene_data(&scene.data);
|
init_level_scene_data(
|
||||||
|
&scene.data, MAX_N_TILES, all_tiles,
|
||||||
scene.data.tilemap.width = DEFAULT_MAP_WIDTH;
|
(Rectangle){25, 25, VIEWABLE_MAP_WIDTH*TILE_SIZE, VIEWABLE_MAP_HEIGHT*TILE_SIZE}
|
||||||
scene.data.tilemap.height = DEFAULT_MAP_HEIGHT;
|
);
|
||||||
scene.data.tilemap.tile_size = TILE_SIZE;
|
|
||||||
scene.data.tilemap.n_tiles = scene.data.tilemap.width * scene.data.tilemap.height;
|
|
||||||
assert(scene.data.tilemap.n_tiles <= MAX_N_TILES);
|
assert(scene.data.tilemap.n_tiles <= MAX_N_TILES);
|
||||||
scene.data.tilemap.tiles = all_tiles;
|
|
||||||
memset(scene.data.tile_sprites, 0, sizeof(scene.data.tile_sprites));
|
|
||||||
for (size_t i = 0; i < scene.data.tilemap.n_tiles;i++)
|
|
||||||
{
|
|
||||||
all_tiles[i].solid = NOT_SOLID;
|
|
||||||
all_tiles[i].tile_type = EMPTY_TILE;
|
|
||||||
all_tiles[i].moveable = true;
|
|
||||||
all_tiles[i].max_water_level = 4;
|
|
||||||
sc_map_init_64v(&all_tiles[i].entities_set, 16, 0);
|
|
||||||
all_tiles[i].size = (Vector2){TILE_SIZE, TILE_SIZE};
|
|
||||||
}
|
|
||||||
for (size_t i = 0; i < scene.data.tilemap.width; ++i)
|
for (size_t i = 0; i < scene.data.tilemap.width; ++i)
|
||||||
{
|
{
|
||||||
unsigned int tile_idx = (scene.data.tilemap.height - 1) * scene.data.tilemap.width + i;
|
unsigned int tile_idx = (scene.data.tilemap.height - 1) * scene.data.tilemap.width + i;
|
||||||
|
@ -519,11 +503,6 @@ int main(void)
|
||||||
free_water_runner(ent, &scene.scene.ent_manager);
|
free_water_runner(ent, &scene.scene.ent_manager);
|
||||||
}
|
}
|
||||||
free_scene(&scene.scene);
|
free_scene(&scene.scene);
|
||||||
for (size_t i = 0; i < scene.data.tilemap.n_tiles;i++)
|
|
||||||
{
|
|
||||||
all_tiles[i].solid = 0;
|
|
||||||
sc_map_term_64v(&all_tiles[i].entities_set);
|
|
||||||
}
|
|
||||||
term_level_scene_data(&scene.data);
|
term_level_scene_data(&scene.data);
|
||||||
sc_queue_term(&key_buffer);
|
sc_queue_term(&key_buffer);
|
||||||
term_assets(&engine.assets);
|
term_assets(&engine.assets);
|
||||||
|
|
Loading…
Reference in New Issue