Add level transitions

This commit is contained in:
Edgaru089 2024-04-14 15:22:55 +08:00
parent 46d7d3c7c2
commit 17c5a96786
7 changed files with 64 additions and 10 deletions

View File

@ -68,7 +68,7 @@ static void _app_LevelCommand(App *app, char *cmd) {
c = TOKEN_DOUBLE; c = TOKEN_DOUBLE;
d = TOKEN_DOUBLE; d = TOKEN_DOUBLE;
Entity *e = entity_Create(app->entity, NULL); Entity *e = entity_Create(app->entity, cmd);
ADD_COMPONENT(e, hitbox); ADD_COMPONENT(e, hitbox);
e->hitbox->box = box2(a, b, c, d); e->hitbox->box = box2(a, b, c, d);
e->hitbox->fixed = true; e->hitbox->fixed = true;
@ -80,7 +80,7 @@ static void _app_LevelCommand(App *app, char *cmd) {
a = TOKEN_DOUBLE; a = TOKEN_DOUBLE;
b = TOKEN_DOUBLE; b = TOKEN_DOUBLE;
Entity *e = entity_Create(app->entity, NULL); Entity *e = entity_Create(app->entity, cmd);
ADD_COMPONENT(e, player); ADD_COMPONENT(e, player);
e->player->hazardRespawn = vec2(a, b); e->player->hazardRespawn = vec2(a, b);
ADD_COMPONENT(e, position); ADD_COMPONENT(e, position);
@ -101,7 +101,7 @@ static void _app_LevelCommand(App *app, char *cmd) {
e = TOKEN_DOUBLE; e = TOKEN_DOUBLE;
f = TOKEN_DOUBLE; f = TOKEN_DOUBLE;
Entity *en = entity_Create(app->entity, NULL); Entity *en = entity_Create(app->entity, cmd);
misc_InstantiateHazardRespawn(app, en, box2(a, b, c, d), vec2(e, f)); misc_InstantiateHazardRespawn(app, en, box2(a, b, c, d), vec2(e, f));
entity_Commit(app->entity, en); entity_Commit(app->entity, en);
} }
@ -113,7 +113,7 @@ static void _app_LevelCommand(App *app, char *cmd) {
c = TOKEN_DOUBLE; c = TOKEN_DOUBLE;
d = TOKEN_DOUBLE; d = TOKEN_DOUBLE;
Entity *e = entity_Create(app->entity, NULL); Entity *e = entity_Create(app->entity, cmd);
misc_InstantiateHazard(app, e, box2(a, b, c, d)); misc_InstantiateHazard(app, e, box2(a, b, c, d));
entity_Commit(app->entity, e); entity_Commit(app->entity, e);
} }
@ -125,7 +125,7 @@ static void _app_LevelCommand(App *app, char *cmd) {
c = TOKEN_DOUBLE; c = TOKEN_DOUBLE;
d = TOKEN_DOUBLE; d = TOKEN_DOUBLE;
Entity *e = entity_Create(app->entity, NULL); Entity *e = entity_Create(app->entity, cmd);
char *bundle = TOKEN; char *bundle = TOKEN;
if (bundle != NULL) if (bundle != NULL)
e->render = render_NewComponent(app, bundle); e->render = render_NewComponent(app, bundle);
@ -147,9 +147,17 @@ static void _app_LevelCommand(App *app, char *cmd) {
} }
CMD("LEVEL_TRANSITION") { CMD("LEVEL_TRANSITION") {
// TODO double a, b, c, d;
// Entity *e = entity_Create(app->entity, NULL); a = TOKEN_DOUBLE;
// entity_Commit(app->entity, e); b = TOKEN_DOUBLE;
c = TOKEN_DOUBLE;
d = TOKEN_DOUBLE;
char *next_level = TOKEN;
if (next_level) {
Entity *e = entity_Create(app->entity, cmd);
misc_InstantiateChangeLevel(app, e, box2(a, b, c, d), next_level);
entity_Commit(app->entity, e);
}
} }
CMD("CUTOFF") { CMD("CUTOFF") {
@ -166,6 +174,7 @@ void _app_SwitchLevel(App *app) {
WARN("called when switch_level is NULL", 0); WARN("called when switch_level is NULL", 0);
return; return;
} }
INFO("Switching level to %s", app->switch_level);
FILE *f = fopen(app->switch_level, "r"); FILE *f = fopen(app->switch_level, "r");
if (!f) { if (!f) {

View File

@ -56,6 +56,8 @@ void app_Render(App *app) {
} }
if (e->misc->trigger_flags & misc_Hazard) if (e->misc->trigger_flags & misc_Hazard)
setlinecolor(RGB(255, 0, 0)); setlinecolor(RGB(255, 0, 0));
if (e->misc->change_level)
setlinecolor(RGB(255, 255, 0));
Box2 box; Box2 box;
if (e->position) if (e->position)
box = camera_TransformBox2(app->camera, box2_Offset(e->misc->trigger, e->position->position)); box = camera_TransformBox2(app->camera, box2_Offset(e->misc->trigger, e->position->position));

View File

@ -4,6 +4,7 @@
#include "camera.h" #include "camera.h"
#include "mapper_misc.h" #include "mapper_misc.h"
#include "physics.h" #include "physics.h"
#include "render_component.h"
#include "util/assert.h" #include "util/assert.h"
#include "util/tree.h" #include "util/tree.h"
#include "util/vector.h" #include "util/vector.h"
@ -98,6 +99,7 @@ static inline void _entity_Delete(System_Entity *sys, uintptr_t id) {
player_DeleteEntity(sys->super->player, e->id); player_DeleteEntity(sys->super->player, e->id);
camera_DeleteEntity(sys->super->camera, e->id); camera_DeleteEntity(sys->super->camera, e->id);
_entity_FreeMembers(e); _entity_FreeMembers(e);
tree_Delete(sys->entities, node); tree_Delete(sys->entities, node);

4
level1.txt Normal file
View File

@ -0,0 +1,4 @@
CUTOFF 600
HITBOX 60 350 1134 65
TEXTBOX 541 191 178 166 info_plate_small_1 Work\sin\sProgress!!
PLAYER 565 350

View File

@ -18,6 +18,8 @@ void misc_DeleteComponent(Component_Misc *misc) {
} }
if (misc->respawn_pos) if (misc->respawn_pos)
free(misc->respawn_pos); free(misc->respawn_pos);
if (misc->change_level)
free(misc->change_level);
free(misc); free(misc);
} }
} }
@ -96,6 +98,22 @@ void misc_thinker_ToLive(App *app, Entity *e, Duration deltaTime) {
} }
} }
void misc_thinker_ChangeLevel(App *app, Entity *e, Duration deltaTime) {
if (!e->misc || !e->misc->change_level) {
WARN("called on an entity without misc or misc.change_level", 0);
e->thinker = NULL;
return;
}
if (app->player->player == NULL) // No player
return;
Component_Player *p = app->player->player;
Box2 playerbox = physics_HitboxAbsolute(p->super->hitbox);
Box2 worldbox = ABSOLUTE_BOX(e, e->misc->trigger);
if (box2_Intersects(worldbox, playerbox, NULL))
app_QueueLoadLevel(app, e->misc->change_level);
}
// Utility functions for creating misc entities // Utility functions for creating misc entities
void misc_InstantiateTextbox(App *app, Entity *e, const char *text, Box2 trigger_box, float offset) { void misc_InstantiateTextbox(App *app, Entity *e, const char *text, Box2 trigger_box, float offset) {
@ -140,3 +158,11 @@ void misc_InstantiateToLive(App *app, Entity *e, Duration duration, TimePoint si
e->thinker = &misc_thinker_ToLive; e->thinker = &misc_thinker_ToLive;
} }
void misc_InstantiateChangeLevel(App *app, Entity *e, Box2 trigger_box, const char *next_level) {
ASSERT(e->misc == NULL && "Instantiate must be called with e.misc not set");
e->misc = zero_malloc(sizeof(Component_Misc));
e->misc->trigger = trigger_box;
e->misc->change_level = copy_malloc(next_level);
e->thinker = &misc_thinker_ChangeLevel;
}

View File

@ -40,6 +40,10 @@ void misc_thinker_Hazard(App *app, Entity *e, Duration deltaTime);
// Kills itself after some time // Kills itself after some time
void misc_thinker_ToLive(App *app, Entity *e, Duration deltaTime); void misc_thinker_ToLive(App *app, Entity *e, Duration deltaTime);
// Thinker for level transition
void misc_thinker_ChangeLevel(App *app, Entity *e, Duration deltaTime);
typedef enum { typedef enum {
misc_Hazard = 1 << 0, // Hazard, harms the player on contact misc_Hazard = 1 << 0, // Hazard, harms the player on contact
} misc_TriggerFlags; } misc_TriggerFlags;
@ -51,7 +55,8 @@ typedef struct {
Box2 trigger; // Relative to Position if exists; absolute otherwise Box2 trigger; // Relative to Position if exists; absolute otherwise
misc_TriggerFlags trigger_flags; misc_TriggerFlags trigger_flags;
misc_Textbox *textbox; misc_Textbox *textbox;
Vec2 *respawn_pos; // Set hazard respawn trigger Vec2 *respawn_pos; // Set hazard respawn trigger
char *change_level; // Change level
TimePoint tolive; // Deletes itself after this time if it is not 0 TimePoint tolive; // Deletes itself after this time if it is not 0
} Component_Misc; } Component_Misc;
@ -80,6 +85,11 @@ void misc_InstantiateHazard(App *app, Entity *e, Box2 trigger_box);
void misc_InstantiateToLive(App *app, Entity *e, Duration duration, TimePoint since); void misc_InstantiateToLive(App *app, Entity *e, Duration duration, TimePoint since);
// Inserts components for change level
// Creates misc & the thinker.
void misc_InstantiateChangeLevel(App *app, Entity *e, Box2 trigger_box, const char *next_level);
static inline Box2 misc_TextboxUpright(double width, double height) { static inline Box2 misc_TextboxUpright(double width, double height) {
Box2 b = { Box2 b = {
.lefttop = { .lefttop = {

View File

@ -14,7 +14,8 @@ extern "C" {
#define SCREEN_WIDTH 1600 #define SCREEN_WIDTH 1600
#define SCREEN_HEIGHT 900 #define SCREEN_HEIGHT 900
#define WARN(fmt, ...) fprintf(stderr, "[WARN][%s] " fmt "\n", __func__, __VA_ARGS__) #define WARN(fmt, ...) fprintf(stderr, "[WARN][%s] " fmt "\n", __func__, ##__VA_ARGS__)
#define INFO(fmt, ...) fprintf(stderr, "[%s] " fmt "\n", __func__, ##__VA_ARGS__)
static inline void *zero_malloc(size_t size) { static inline void *zero_malloc(size_t size) {