Textbox is working now
This commit is contained in:
parent
c69fe1738c
commit
1a1038522c
23
app.c
23
app.c
@ -8,6 +8,8 @@
|
|||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "render_bundle.h"
|
#include "render_bundle.h"
|
||||||
|
#include "render_component.h"
|
||||||
|
#include "mapper_misc.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
@ -58,6 +60,27 @@ App *app_NewApp() {
|
|||||||
hit3->hitbox->fixed = true;
|
hit3->hitbox->fixed = true;
|
||||||
entity_Commit(app->entity, hit3);
|
entity_Commit(app->entity, hit3);
|
||||||
|
|
||||||
|
Entity *text1 = entity_Create(app->entity, "text_plate_large_1");
|
||||||
|
ADD_COMPONENT(text1, position);
|
||||||
|
text1->position->position = vec2(600, 550);
|
||||||
|
text1->render = render_NewComponent(app, "info_plate");
|
||||||
|
misc_InstantiateTextbox(app, text1, "So long lives this,\nAnd this gives life to thee.", misc_TextboxUpright(110, 110), -220);
|
||||||
|
entity_Commit(app->entity, text1);
|
||||||
|
|
||||||
|
Entity *text2 = entity_Create(app->entity, "text_plate_1");
|
||||||
|
ADD_COMPONENT(text2, position);
|
||||||
|
text2->position->position = vec2(250, 200);
|
||||||
|
text2->render = render_NewComponent(app, "info_plate_small_1");
|
||||||
|
misc_InstantiateTextbox(app, text2, "Press Space to jump.\nYou can jump again midair.", misc_TextboxUpright(70, 70), -180);
|
||||||
|
entity_Commit(app->entity, text2);
|
||||||
|
|
||||||
|
Entity *text3 = entity_Create(app->entity, "text_plate_2");
|
||||||
|
ADD_COMPONENT(text3, position);
|
||||||
|
text3->position->position = vec2(750, 200);
|
||||||
|
text3->render = render_NewComponent(app, "info_plate_small_2");
|
||||||
|
misc_InstantiateTextbox(app, text3, "Press ; to dash.\nYou can only dash one time midair.", misc_TextboxUpright(70, 70), -180);
|
||||||
|
entity_Commit(app->entity, text3);
|
||||||
|
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "physics.h"
|
#include "physics.h"
|
||||||
#include "easyx.h"
|
#include "easyx.h"
|
||||||
#include "render_bundle.h"
|
#include "render_bundle.h"
|
||||||
|
#include "render_component.h"
|
||||||
#include "util/tree.h"
|
#include "util/tree.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "render_util.h"
|
#include "render_util.h"
|
||||||
@ -63,14 +64,38 @@ void app_Render(App *app) {
|
|||||||
render_FillCircleW(app, vec2(200, 100), 20);
|
render_FillCircleW(app, vec2(200, 100), 20);
|
||||||
|
|
||||||
|
|
||||||
render_DrawBundleW(app, render_FindBundle("info_plate"), vec2(600, 550));
|
// render_DrawBundleW(app, render_FindBundle("info_plate"), vec2(600, 550));
|
||||||
render_DrawBundleW(app, render_FindBundle("info_plate_small_1"), vec2(250, 200));
|
render_DrawBundleW(app, render_FindBundle("info_plate_small_1"), vec2(250, 200));
|
||||||
render_DrawBundleW(app, render_FindBundle("info_plate_small_2"), vec2(750, 200));
|
render_DrawBundleW(app, render_FindBundle("info_plate_small_2"), vec2(750, 200));
|
||||||
|
|
||||||
|
// Draw entities
|
||||||
|
for (tree_Node *i = tree_FirstNode(app->entity->entities);
|
||||||
|
i != NULL;
|
||||||
|
i = tree_Node_Next(i)) {
|
||||||
|
Entity *e = (Entity *)i->data;
|
||||||
|
if (e->render) {
|
||||||
|
Component_Render *r = e->render;
|
||||||
|
|
||||||
|
// Calculate global position as offset
|
||||||
|
Vec2 pos = {.x = 0.0, .y = 0.0};
|
||||||
|
if (e->position)
|
||||||
|
pos = e->position->position;
|
||||||
|
// Has bundle
|
||||||
|
if (r->bundle)
|
||||||
|
render_DrawBundleW(app, r->bundle, pos);
|
||||||
|
// Has custom rendering
|
||||||
|
if (r->custom)
|
||||||
|
r->custom(app, e, camera_TransformVec2(app->camera, pos), r->custom_data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Draw particles
|
// Draw particles
|
||||||
setfillcolor(RGB(255, 255, 255));
|
setfillcolor(RGB(255, 255, 255));
|
||||||
setbkcolor(RGB(0, 0, 0));
|
setbkcolor(RGB(0, 0, 0));
|
||||||
particle_Render(app->particle);
|
particle_Render(app->particle);
|
||||||
|
|
||||||
|
|
||||||
|
settextcolor(RGB(255, 255, 255));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "mapper_misc.h"
|
#include "mapper_misc.h"
|
||||||
#include "app.h"
|
#include "app.h"
|
||||||
#include "entity.h"
|
#include "entity.h"
|
||||||
|
#include "physics.h"
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
#include "util/assert.h"
|
#include "util/assert.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -30,7 +31,8 @@ void misc_thinker_HazardRespawn(App *app, Entity *e, Duration deltaTime) {
|
|||||||
}
|
}
|
||||||
if (app->player->player == NULL) // No player
|
if (app->player->player == NULL) // No player
|
||||||
return;
|
return;
|
||||||
Component_Player *p = app->player->player;
|
Component_Player *p = app->player->player;
|
||||||
|
Box2 playerbox = physics_HitboxAbsolute(p->super->hitbox);
|
||||||
|
|
||||||
Box2 worldbox; // Offset if position component exists
|
Box2 worldbox; // Offset if position component exists
|
||||||
Vec2 worldspawn;
|
Vec2 worldspawn;
|
||||||
@ -42,7 +44,7 @@ void misc_thinker_HazardRespawn(App *app, Entity *e, Duration deltaTime) {
|
|||||||
worldspawn = e->misc->respawn->respawn_pos;
|
worldspawn = e->misc->respawn->respawn_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (box2_Contains(worldbox, p->super->position->position))
|
if (box2_Intersects(worldbox, playerbox, NULL))
|
||||||
p->hazardRespawn = worldspawn;
|
p->hazardRespawn = worldspawn;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,13 +58,14 @@ void misc_thinker_Textbox(App *app, Entity *e, Duration deltaTime) {
|
|||||||
t->progress = fmaxf(0.0f, t->progress - duration_Seconds(deltaTime) * MISC_TEXTBOX_FADEIN_SPEED);
|
t->progress = fmaxf(0.0f, t->progress - duration_Seconds(deltaTime) * MISC_TEXTBOX_FADEIN_SPEED);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Component_Player *p = app->player->player;
|
Component_Player *p = app->player->player;
|
||||||
|
Box2 playerbox = physics_HitboxAbsolute(p->super->hitbox);
|
||||||
|
|
||||||
Box2 worldbox; // Offset if position component exists
|
Box2 worldbox; // Offset if position component exists
|
||||||
ASSERT(e->position && "Textboxes must have a position component");
|
ASSERT(e->position && "Textboxes must have a position component");
|
||||||
worldbox = box2_Offset(t->trigger_box, e->position->position);
|
worldbox = box2_Offset(t->trigger_box, e->position->position);
|
||||||
|
|
||||||
if (box2_Contains(worldbox, p->super->position->position))
|
if (box2_Intersects(worldbox, playerbox, NULL))
|
||||||
// Fade in
|
// Fade in
|
||||||
t->progress = fminf(1.0f, t->progress + duration_Seconds(deltaTime) * MISC_TEXTBOX_FADEIN_SPEED);
|
t->progress = fminf(1.0f, t->progress + duration_Seconds(deltaTime) * MISC_TEXTBOX_FADEIN_SPEED);
|
||||||
else
|
else
|
||||||
@ -73,8 +76,8 @@ void misc_thinker_Textbox(App *app, Entity *e, Duration deltaTime) {
|
|||||||
|
|
||||||
// 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 yet");
|
ASSERT(e->misc == NULL && "Instantiate must be called with e.misc not set");
|
||||||
ASSERT(e->render == NULL && "Instantiate must be called with e.render not set yet");
|
ASSERT((e->render == NULL || e->render->custom == NULL) && "Instantiate for Textbox must be called with e.render.custom not set");
|
||||||
e->misc = zero_malloc(sizeof(Component_Misc));
|
e->misc = zero_malloc(sizeof(Component_Misc));
|
||||||
e->misc->textbox = zero_malloc(sizeof(misc_Textbox));
|
e->misc->textbox = zero_malloc(sizeof(misc_Textbox));
|
||||||
|
|
||||||
@ -82,6 +85,20 @@ void misc_InstantiateTextbox(App *app, Entity *e, const char *text, Box2 trigger
|
|||||||
e->misc->textbox->trigger_box = trigger_box;
|
e->misc->textbox->trigger_box = trigger_box;
|
||||||
e->misc->textbox->offset = offset;
|
e->misc->textbox->offset = offset;
|
||||||
|
|
||||||
e->render = render_NewComponentFunc(app, &misc_render_Textbox, NULL);
|
if (!e->render)
|
||||||
|
e->render = render_NewComponentFunc(app, &misc_render_Textbox, NULL);
|
||||||
|
else
|
||||||
|
e->render->custom = &misc_render_Textbox;
|
||||||
e->thinker = &misc_thinker_Textbox;
|
e->thinker = &misc_thinker_Textbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void misc_InstantiateHazardRespawn(App *app, Entity *e, Box2 trigger_box, Vec2 respawn_pos) {
|
||||||
|
ASSERT(e->misc == NULL && "Instantiate must be called with e.misc not set");
|
||||||
|
e->misc = zero_malloc(sizeof(Component_Misc));
|
||||||
|
e->misc->respawn = zero_malloc(sizeof(misc_HazardRespawn));
|
||||||
|
|
||||||
|
e->misc->respawn->respawn_pos = respawn_pos;
|
||||||
|
e->misc->respawn->trigger_box = trigger_box;
|
||||||
|
|
||||||
|
e->thinker = &misc_thinker_HazardRespawn;
|
||||||
|
}
|
||||||
|
@ -11,7 +11,7 @@ typedef struct _App App;
|
|||||||
typedef struct _Entity Entity;
|
typedef struct _Entity Entity;
|
||||||
|
|
||||||
|
|
||||||
#define MISC_TEXTBOX_FADEIN_SPEED 5.0 // Fades in/out in 1/5 seconds
|
#define MISC_TEXTBOX_FADEIN_SPEED 6.0 // Fades in/out in 1/6 seconds
|
||||||
|
|
||||||
// A textbox that shows itself when the player is close
|
// A textbox that shows itself when the player is close
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -55,6 +55,19 @@ void misc_DeleteComponent(Component_Misc *misc);
|
|||||||
// Creates misc + render components & sets the thinker.
|
// Creates misc + render components & sets the thinker.
|
||||||
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);
|
||||||
|
|
||||||
|
// Inserts the components for a hazard respawn area.
|
||||||
|
// Creates misc & sets the thinker.
|
||||||
|
void misc_InstantiateHazardRespawn(App *app, Entity *e, Box2 trigger_box, Vec2 respawn_pos);
|
||||||
|
|
||||||
|
|
||||||
|
static inline Box2 misc_TextboxUpright(double width, double height) {
|
||||||
|
Box2 b = {
|
||||||
|
.lefttop = {
|
||||||
|
.x = -width / 2.0,
|
||||||
|
.y = -height},
|
||||||
|
.size = {.x = width, .y = height}};
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,7 @@ extern "C" void misc_render_Textbox(App *app, Entity *e, Vec2 entity_screen_pos,
|
|||||||
rect.top = (LONG)round(entity_screen_pos.y) + t->offset + 40;
|
rect.top = (LONG)round(entity_screen_pos.y) + t->offset + 40;
|
||||||
|
|
||||||
// Convert & draw
|
// Convert & draw
|
||||||
|
// https://docs.easyx.cn/zh-cn/drawtext
|
||||||
convert_text(t->text);
|
convert_text(t->text);
|
||||||
drawtext((LPCTSTR)vector_Data(tbuf), &rect, DT_CENTER | DT_NOCLIP);
|
drawtext((LPCTSTR)vector_Data(tbuf), &rect, DT_CENTER | DT_NOCLIP);
|
||||||
}
|
}
|
||||||
|
9
types.h
9
types.h
@ -55,6 +55,15 @@ typedef struct {
|
|||||||
Vec2 size;
|
Vec2 size;
|
||||||
} Box2;
|
} Box2;
|
||||||
|
|
||||||
|
static inline Box2 box2(double x, double y, double width, double height) {
|
||||||
|
Box2 b;
|
||||||
|
b.lefttop.x = x;
|
||||||
|
b.lefttop.y = y;
|
||||||
|
b.size.x = width;
|
||||||
|
b.size.y = height;
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Intersection test.
|
// Intersection test.
|
||||||
bool box2_Intersects(const Box2 x, const Box2 y, Box2 *out_intersection);
|
bool box2_Intersects(const Box2 x, const Box2 y, Box2 *out_intersection);
|
||||||
|
Loading…
Reference in New Issue
Block a user