Camera focus rectangle

This commit is contained in:
Edgaru089 2024-04-15 14:18:12 +08:00
parent b7944015f7
commit 697272fe06
6 changed files with 57 additions and 6 deletions

View File

@ -156,9 +156,21 @@ static void _app_LevelCommand(App *app, char *cmd) {
} }
} }
CMD("CAMERA_FOCUS") {
Box2 box = readbox2();
Entity *e = entity_Create(app->entity, cmd);
misc_InstantiateCameraFocus(app, e, box);
entity_Commit(app->entity, e);
}
CMD("CUTOFF") { CMD("CUTOFF") {
app->player->cutoff = TOKEN_DOUBLE; app->player->cutoff = TOKEN_DOUBLE;
} }
else {
WARN("unknown command \"%s\"", cmd);
}
} }

View File

@ -38,8 +38,8 @@ void camera_DeleteEntity(System_Camera *sys, uintptr_t id) {
void camera_Advance(System_Camera *sys, Duration deltaTime) { void camera_Advance(System_Camera *sys, Duration deltaTime) {
Vec2 tocenter; Vec2 tocenter;
if (sys->target.size.x > EPS) if (sys->target != NULL)
tocenter = box2_Center(sys->target); tocenter = box2_Center(*sys->target);
else if (sys->player) else if (sys->player)
tocenter = vec2_Add( tocenter = vec2_Add(
sys->player->super->position->position, sys->player->super->position->position,

View File

@ -15,9 +15,9 @@ typedef struct {
App *super; App *super;
Component_Player *player; Component_Player *player;
Box2 screen; // Screen box, e.g. 1280x720 origin (0,0) Box2 screen; // Screen box, e.g. 1280x720 origin (0,0)
Box2 cam, target; // Current & target camera Box2 cam, *target; // Current & target camera
double speed; // Fraction of distance between cam & target to be covered in 1 sec double speed; // Fraction of distance between cam & target to be covered in 1 sec
} System_Camera; } System_Camera;
System_Camera *camera_NewSystem(App *super); System_Camera *camera_NewSystem(App *super);

View File

@ -15,3 +15,4 @@ HAZARD_RESPAWN 1492 23 297 242 1706 250
LEVEL_TRANSITION 2624 853 371 76 level1.txt LEVEL_TRANSITION 2624 853 371 76 level1.txt
TEXTBOX 2577 264 137 132 info_plate_small_2 Jump\sdown\sto\sthe\snext\slevel.\nNow\scomplete\swith\slevel\stransitions! TEXTBOX 2577 264 137 132 info_plate_small_2 Jump\sdown\sto\sthe\snext\slevel.\nNow\scomplete\swith\slevel\stransitions!
HAZARD_RESPAWN 2315 41 107 368 2372 392 HAZARD_RESPAWN 2315 41 107 368 2372 392
CAMERA_FOCUS 1050 -70 1400 1000

View File

@ -115,6 +115,28 @@ void misc_thinker_ChangeLevel(App *app, Entity *e, Duration deltaTime) {
} }
void misc_thinker_CameraFocus(App *app, Entity *e, Duration deltaTime) {
if (!e->misc || !(e->misc->trigger_flags & misc_CameraFocus)) {
WARN("called on an entity without misc or misc.flags&misc_CameraFocus", 0);
e->thinker = NULL;
return;
}
if (app->player->player == NULL) // No player
return;
Component_Player *p = app->player->player;
Box2 worldbox = ABSOLUTE_BOX(e, e->misc->trigger);
if (box2_Contains(worldbox, p->super->position->position)) {
app->camera->target = &e->misc->trigger;
} else {
if (app->camera->target == &e->misc->trigger)
// Player just left this box
app->camera->target = NULL;
}
}
// 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) {
ASSERT(e->misc == NULL && "Instantiate must be called with e.misc not set"); ASSERT(e->misc == NULL && "Instantiate must be called with e.misc not set");
@ -166,3 +188,11 @@ void misc_InstantiateChangeLevel(App *app, Entity *e, Box2 trigger_box, const ch
e->misc->change_level = copy_malloc(next_level); e->misc->change_level = copy_malloc(next_level);
e->thinker = &misc_thinker_ChangeLevel; e->thinker = &misc_thinker_ChangeLevel;
} }
void misc_InstantiateCameraFocus(App *app, Entity *e, Box2 trigger_box) {
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->trigger_flags = misc_CameraFocus;
e->thinker = &misc_thinker_CameraFocus;
}

View File

@ -43,9 +43,13 @@ void misc_thinker_ToLive(App *app, Entity *e, Duration deltaTime);
// Thinker for level transition // Thinker for level transition
void misc_thinker_ChangeLevel(App *app, Entity *e, Duration deltaTime); void misc_thinker_ChangeLevel(App *app, Entity *e, Duration deltaTime);
// Thinker for camera focus
void misc_thinker_CameraFocus(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_CameraFocus = 1 << 1, // Camera focuses the center of the box when player's pos is in the box
} misc_TriggerFlags; } misc_TriggerFlags;
@ -89,6 +93,10 @@ void misc_InstantiateToLive(App *app, Entity *e, Duration duration, TimePoint si
// Creates misc & the thinker. // Creates misc & the thinker.
void misc_InstantiateChangeLevel(App *app, Entity *e, Box2 trigger_box, const char *next_level); void misc_InstantiateChangeLevel(App *app, Entity *e, Box2 trigger_box, const char *next_level);
// Inserts components for camera focus box
// Creates misc & thinker
void misc_InstantiateCameraFocus(App *app, Entity *e, Box2 trigger_box);
static inline Box2 misc_TextboxUpright(double width, double height) { static inline Box2 misc_TextboxUpright(double width, double height) {
Box2 b = { Box2 b = {