diff --git a/app.h b/app.h index 9727ed9..c6b7124 100644 --- a/app.h +++ b/app.h @@ -24,7 +24,7 @@ typedef struct _App { char *switch_level; uint32_t clear_color; - bool wantQuit; + bool wantQuit, debugOn; } App; App *app_NewApp(); diff --git a/app_file.c b/app_file.c index e427469..9b1fad4 100644 --- a/app_file.c +++ b/app_file.c @@ -103,8 +103,8 @@ static void _app_LevelCommand(App *app, char *cmd) { e->position->position = vec; e->position->velocity = vec2(0, 0); ADD_COMPONENT(e, hitbox); - e->hitbox->box.lefttop = vec2(-20, -80); - e->hitbox->box.size = vec2(40, 80); + e->hitbox->box.lefttop = vec2(-20, -50); + e->hitbox->box.size = vec2(40, 50); entity_Commit(app->entity, e); } diff --git a/app_render.cpp b/app_render.cpp index 4de2969..2dd4991 100644 --- a/app_render.cpp +++ b/app_render.cpp @@ -24,69 +24,10 @@ extern "C" { void app_Render(App *app) { render_SetModes(render_ModeDefault, time_Now()); + setbkcolor(app->clear_color); + cleardevice(); - for (tree_Node *i = tree_FirstNode(app->entity->entities); - i != NULL; - i = tree_Node_Next(i)) { - Entity *e = (Entity *)(i->data); - if (e->hitbox) { - if (e->hitbox->fixed) - setlinecolor(RGB(0, 255, 0)); - else - setlinecolor(RGB(255, 255, 0)); - - Box2 box = camera_TransformBox2(app->camera, physics_HitboxAbsolute(e->hitbox)); - rectangle( - (int)round(box.lefttop.x), - (int)round(box.lefttop.y), - (int)round(box.lefttop.x + box.size.x), - (int)round(box.lefttop.y + box.size.y)); - } - if (e->misc) { - if (e->misc->textbox) - setlinecolor(RGB(0, 0, 255)); - if (e->misc->respawn_pos) { - setlinecolor(RGB(255, 0, 255)); - Vec2 pos; - if (e->position) - pos = camera_TransformVec2(app->camera, vec2_Add(*e->misc->respawn_pos, e->position->position)); - else - pos = camera_TransformVec2(app->camera, *e->misc->respawn_pos); - line((int)round(pos.x + 12), (int)round(pos.y), (int)round(pos.x - 12), (int)round(pos.y)); - line((int)round(pos.x), (int)round(pos.y + 12), (int)round(pos.x), (int)round(pos.y - 12)); - } - if (e->misc->trigger_flags & misc_Hazard) - setlinecolor(RGB(255, 0, 0)); - if (e->misc->trigger_flags & misc_CameraFocus) - setlinecolor(RGB(0, 255, 255)); - if (e->misc->change_level) - setlinecolor(RGB(255, 255, 0)); - Box2 box; - if (e->position) - box = camera_TransformBox2(app->camera, box2_Offset(e->misc->trigger, e->position->position)); - else - box = camera_TransformBox2(app->camera, e->misc->trigger); - rectangle( - (int)round(box.lefttop.x), - (int)round(box.lefttop.y), - (int)round(box.lefttop.x + box.size.x), - (int)round(box.lefttop.y + box.size.y)); - } - } - if (app->player->player) { - setlinecolor(RGB(255, 0, 255)); - Vec2 respawn = camera_TransformVec2(app->camera, app->player->player->hazardRespawn); - circle((int)round(respawn.x), (int)round(respawn.y), 6); - } - - - setfillcolor(RGB(255, 255, 255)); - setbkcolor(RGB(0, 0, 0)); - render_SetModes(render_ModeRotate, since); - render_FillCircleW(app, vec2(200, 100), 20); - - - // Draw entities + // Draw fill boxes first for (tree_Node *i = tree_FirstNode(app->entity->entities); i != NULL; i = tree_Node_Next(i)) { @@ -102,12 +43,89 @@ void app_Render(App *app) { if (r->fillbox.size.x > EPS) { Box2 cam = camera_TransformBox2(app->camera, r->fillbox); setfillcolor(r->fillcolor); - fillrectangle( + solidrectangle( (int)round(cam.lefttop.x), (int)round(cam.lefttop.y), (int)round(cam.lefttop.x + cam.size.x), (int)round(cam.lefttop.y + cam.size.y)); } + } + } + + + // Debug boxes + if (app->debugOn) { + for (tree_Node *i = tree_FirstNode(app->entity->entities); + i != NULL; + i = tree_Node_Next(i)) { + Entity *e = (Entity *)(i->data); + if (e->hitbox) { + if (e->hitbox->fixed) + setlinecolor(RGB(0, 255, 0)); + else + setlinecolor(RGB(255, 255, 0)); + + Box2 box = camera_TransformBox2(app->camera, physics_HitboxAbsolute(e->hitbox)); + rectangle( + (int)round(box.lefttop.x), + (int)round(box.lefttop.y), + (int)round(box.lefttop.x + box.size.x), + (int)round(box.lefttop.y + box.size.y)); + } + if (e->misc) { + if (e->misc->textbox) + setlinecolor(RGB(0, 0, 255)); + if (e->misc->respawn_pos) { + setlinecolor(RGB(255, 0, 255)); + Vec2 pos; + if (e->position) + pos = camera_TransformVec2(app->camera, vec2_Add(*e->misc->respawn_pos, e->position->position)); + else + pos = camera_TransformVec2(app->camera, *e->misc->respawn_pos); + line((int)round(pos.x + 12), (int)round(pos.y), (int)round(pos.x - 12), (int)round(pos.y)); + line((int)round(pos.x), (int)round(pos.y + 12), (int)round(pos.x), (int)round(pos.y - 12)); + } + if (e->misc->trigger_flags & misc_Hazard) + setlinecolor(RGB(255, 0, 0)); + if (e->misc->trigger_flags & misc_CameraFocus) + setlinecolor(RGB(0, 255, 255)); + if (e->misc->change_level) + setlinecolor(RGB(255, 255, 0)); + Box2 box; + if (e->position) + box = camera_TransformBox2(app->camera, box2_Offset(e->misc->trigger, e->position->position)); + else + box = camera_TransformBox2(app->camera, e->misc->trigger); + rectangle( + (int)round(box.lefttop.x), + (int)round(box.lefttop.y), + (int)round(box.lefttop.x + box.size.x), + (int)round(box.lefttop.y + box.size.y)); + } + } + if (app->player->player) { + setlinecolor(RGB(255, 0, 255)); + Vec2 respawn = camera_TransformVec2(app->camera, app->player->player->hazardRespawn); + circle((int)round(respawn.x), (int)round(respawn.y), 6); + } + } + + + setfillcolor(RGB(255, 255, 255)); + setbkcolor(RGB(0, 0, 0)); + + // 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); @@ -117,6 +135,14 @@ void app_Render(App *app) { } } + // Draw player + if (app->player->player) { + setfillcolor(0xffffff); + setlinecolor(0); + Vec2 screen = camera_TransformVec2(app->camera, vec2_Add(box2_Center(app->player->player->super->hitbox->box), app->player->player->super->position->position)); + fillcircle((int)round(screen.x), (int)round(screen.y), (int)round(app->player->player->super->hitbox->box.size.y / 2.0)); + } + // Draw particles setfillcolor(RGB(255, 255, 255)); diff --git a/bundles.txt b/bundles.txt index 7951b98..b15226f 100644 --- a/bundles.txt +++ b/bundles.txt @@ -1,6 +1,6 @@ BUNDLE info_plate PRIM POLY -FG 255 255 255 +FG 210 210 210 BG 0 0 0 P 5.000000 -131.000000 P 64.000000 -94.000000 @@ -34,7 +34,7 @@ ENDBUNDLE BUNDLE info_plate_small_1 PRIM POLY -FG 255 255 255 +FG 210 210 210 BG 0 0 0 P 9.000000 -83.000000 P 39.000000 -57.000000 @@ -66,7 +66,7 @@ ENDBUNDLE BUNDLE info_plate_small_2 PRIM POLY -FG 255 255 255 +FG 210 210 210 BG 0 0 0 P 7.000000 -79.000000 P 45.000000 -63.000000 @@ -100,7 +100,7 @@ ENDBUNDLE BUNDLE spike PRIM POLY -FG 255 255 255 +FG 210 210 210 BG 0 0 0 P 0.000000 -50.000000 P 15.000000 0.000000 diff --git a/intro.txt b/intro.txt index c2e51f3..b63704d 100644 --- a/intro.txt +++ b/intro.txt @@ -1,18 +1,27 @@ CUTOFF 1000 +BACKGROUND 90 90 90 HITBOX -245 250 1427 44 PLAYER 600 250 -HITBOX -176 -408 78 798 -TEXTBOX 905 65 182 189 info_plate Welcome!\nPress\sSpace\sto\sjump.\nYou\scan\sjump\sagain\smidair. +HITBOX -200 -270 100 600 +TEXTBOX 905 65 182 189 info_plate Welcome!\sPress\sSpace\sto\sjump.\nYou\scan\sjump\sagain\smidair. HAZARD_RESPAWN 1051 29 123 237 1097 250 HITBOX 1114 250 68 524 -HAZARD 1128 600 424 89 +HAZARD 1181 600 300 89 HITBOX 1480 250 318 519 HITBOX 2903 -325 108 1226 HITBOX 2309 392 454 503 TEXTBOX 1566 120 123 134 info_plate_small_1 Press\s';'\sto\sdash,\son\sground\sor\smidair.\nYou\scan\sonly\sdash\s1\stime\smidair. -HAZARD 1758 733 600 103 +HAZARD 1797 733 513 103 HAZARD_RESPAWN 1492 23 297 242 1706 250 -LEVEL_TRANSITION 2624 853 371 76 level1.txt +LEVEL_TRANSITION 2762 1000 142 76 level1.txt 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 CAMERA_FOCUS 1050 -70 1400 1000 +FILL 40 40 40 -1178 250 2359 1500 +FILL 40 40 40 1480 250 318 1500 +FILL 40 40 40 2309 392 454 1500 +FILL 40 40 40 2903 -1000 1000 3000 +FILL 40 40 40 -2500 -270 2400 1000 +FILL 0 0 0 1181 600 300 1000 +FILL 0 0 0 1797 733 513 1000 +FILL 255 255 255 2762 1000 142 1000 diff --git a/main.cpp b/main.cpp index e08960b..c2ba271 100644 --- a/main.cpp +++ b/main.cpp @@ -26,7 +26,8 @@ int main() { #else // MSVC settextstyle(TEXTHEIGHT, 0, L"Courier New"); #endif - vector_Vector *debugText = vector_Create(1); + vector_Vector *debugText = vector_Create(1); + bool debugPressed = false; App *app = app_NewApp(); while (!app->wantQuit) { @@ -42,14 +43,23 @@ int main() { app_Advance(app, time_Reset(&lastUpdate)); BeginBatchDraw(); - cleardevice(); app_Render(app); - app_DebugText(app, debugText); - render_DrawText(10, 10, (const char *)vector_Data(debugText)); + if (app->debugOn) { + app_DebugText(app, debugText); + render_DrawText(10, 10, (const char *)vector_Data(debugText)); + } EndBatchDraw(); + // Check debug button status + if ((GetAsyncKeyState(VK_F3) & 0x8000) != 0) { + if (!debugPressed) + app->debugOn = !app->debugOn; + debugPressed = true; + } else + debugPressed = false; + Duration toSleep = {.microseconds = 1000000 / 200 - time_Reset(&lastFrame).microseconds}; duration_Sleep(toSleep); diff --git a/mapper_misc_render.cpp b/mapper_misc_render.cpp index ff631b2..ebc3153 100644 --- a/mapper_misc_render.cpp +++ b/mapper_misc_render.cpp @@ -53,16 +53,25 @@ extern "C" void misc_render_Textbox(App *app, Entity *e, Vec2 entity_screen_pos, int rgb = (int)round(fminf(t->progress, 1.0f) * 255.0); settextcolor(RGB(rgb, rgb, rgb)); + // Fade the background from App background to Black + int r = app->clear_color & 0xff; + int g = (app->clear_color & 0xff00) >> 8; + int b = (app->clear_color & 0xff0000) >> 16; + setbkcolor(RGB((int)roundf(r * (1.0f - t->progress)), (int)roundf(g * (1.0f - t->progress)), (int)roundf(b * (1.0f - t->progress)))); + + // Compute the bounding rect RECT rect; ASSERT(e->position && "Textboxes must have a position component"); rect.left = (LONG)round(entity_screen_pos.x) - 20; rect.right = (LONG)round(entity_screen_pos.x) + 20; - rect.top = (LONG)round(entity_screen_pos.y) + t->offset; - rect.top = (LONG)round(entity_screen_pos.y) + t->offset + 40; + rect.top = (LONG)round(entity_screen_pos.y) + t->offset * 0.8; // Convert & draw // https://docs.easyx.cn/zh-cn/drawtext convert_text(t->text); drawtext((LPCTSTR)vector_Data(tbuf), &rect, DT_CENTER | DT_NOCLIP); + + // Restore background to Black + setbkcolor(0); } diff --git a/player.c b/player.c index 63b6d50..9ce2257 100644 --- a/player.c +++ b/player.c @@ -72,19 +72,10 @@ void player_Advance(System_Player *sys, Duration deltaTime) { p->faceDirection = 1; // Face right by default // Particles - static Duration emitCooldown = {.microseconds = 150000}; + static Duration emitCooldown = {.microseconds = 80000}; static TimePoint lastEmit = {.microseconds = 0}; - if (time_Since(lastEmit).microseconds > emitCooldown.microseconds) { - lastEmit = time_Now(); - Vec2 to_pos = vec2_Add(p->super->position->position, vec2(0, -p->super->hitbox->box.size.y)); - particle_Emit( - sys->super->particle, - vec2_Add(vec2_Random(-20, 20, -10, 10), to_pos), - vec2(0, -100), 2, 6, 6, - duration_FromSeconds(0), &render_ModeInverse); - } - // Particles when dashing if (time_Since(p->lastDash).microseconds < dashLength.microseconds && dabs(p->super->position->velocity.x) > EPS) { + // When dashing static TimePoint lastDashEmit = {.microseconds = 0}; static Duration cooldown = {.microseconds = 4000}; if (time_Since(lastDashEmit).microseconds > cooldown.microseconds) { @@ -97,6 +88,23 @@ void player_Advance(System_Player *sys, Duration deltaTime) { 7, rand_DoubleRange(14, 20), rand_DoubleRange(32, 40), duration_FromSeconds(0), &render_ModeRotate); } + lastEmit = time_Now(); + lastEmit.microseconds -= 74000; + } else { + // When not dashing + if (time_Since(lastEmit).microseconds > emitCooldown.microseconds) { + lastEmit = time_Now(); + lastEmit.microseconds += duration_FromSeconds(0.05 * rand_Double01()).microseconds; + Vec2 to_pos = vec2_Add(p->super->position->position, vec2(0, -p->super->hitbox->box.size.y)); + particle_Emit( + sys->super->particle, + vec2_Add(vec2_Random(-10, 10, -10, 10), to_pos), + vec2_Add( + vec2(0, rand_DoubleRange(-200, -240)), + vec2_Scale(p->super->position->velocity, rand_DoubleRange(0.75, 1.0))), + 2, round(rand_DoubleRange(12, 16)), 20, + duration_FromSeconds(0), &render_ModeDefault); + } } diff --git a/render_util.h b/render_util.h index 62d437c..135ac4a 100644 --- a/render_util.h +++ b/render_util.h @@ -8,7 +8,7 @@ extern "C" { #endif -#define TEXTHEIGHT 18 +#define TEXTHEIGHT 24 // Draws text at the given on-screen position.