diff --git a/App.c b/App.c index ce77f56..3c63934 100644 --- a/App.c +++ b/App.c @@ -4,7 +4,20 @@ #include "Input.h" #include "Physics_Component.h" #include "Player_Component.h" +#include "Types.h" #include +#include + + +static void _app_onHit(Entity *me, Entity *other, Vec2 triedDelta, void *data) { + fprintf( + stderr, + "[_app_onHit] Entity \"%s\" hit by \"%s\", delta: [%.2lf, %.2lf]\n", + me->name, + other->name, + triedDelta.x, + triedDelta.y); +} App *app_NewApp() { @@ -17,6 +30,33 @@ App *app_NewApp() { app->wantQuit = false; + + Entity *player = entity_Create(app->entity, "player"); + ADD_COMPONENT(player, player, zero_malloc(sizeof(Component_Player))); + ADD_COMPONENT(player, position, zero_malloc(sizeof(Component_Position))); + player->position->position = vec2(500, 500); + player->position->velocity = vec2(0, 0); + ADD_COMPONENT(player, hitbox, zero_malloc(sizeof(Component_Hitbox))); + player->hitbox->box.lefttop = vec2(-20, -80); + player->hitbox->box.size = vec2(40, 80); + entity_Commit(app->entity, player); + + Entity *hit1 = entity_Create(app->entity, "hit1"); + ADD_COMPONENT(hit1, hitbox, zero_malloc(sizeof(Component_Hitbox))); + hit1->hitbox->box.lefttop = vec2(200, 200); + hit1->hitbox->box.size = vec2(100, 400); + hit1->hitbox->fixed = true; + hit1->hitbox->onHit = &_app_onHit; + entity_Commit(app->entity, hit1); + + Entity *hit2 = entity_Create(app->entity, "hit2"); + ADD_COMPONENT(hit2, hitbox, zero_malloc(sizeof(Component_Hitbox))); + hit2->hitbox->box.lefttop = vec2(700, 200); + hit2->hitbox->box.size = vec2(100, 400); + hit2->hitbox->fixed = true; + hit2->hitbox->onHit = &_app_onHit; + entity_Commit(app->entity, hit2); + return app; } diff --git a/App.h b/App.h index 2e28933..fd62536 100644 --- a/App.h +++ b/App.h @@ -24,7 +24,7 @@ App *app_NewApp(); void app_DeleteApp(App *app); void app_Advance(App *app, Duration deltaTime); -void app_Render(); +void app_Render(App *app); #ifdef __cplusplus diff --git a/App_Render.cpp b/App_Render.cpp index d9af69e..123a004 100644 --- a/App_Render.cpp +++ b/App_Render.cpp @@ -1,11 +1,33 @@ #include "App.h" +#include "Physics_Component.h" +#include "easyx.h" +#include "util/tree.h" +#include #include extern "C" { -void app_Render() { +void app_Render(App *app) { + 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 = 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)); + } + } } } diff --git a/Entity.c b/Entity.c index a9b69e1..054aa19 100644 --- a/Entity.c +++ b/Entity.c @@ -64,6 +64,11 @@ Entity *entity_Create(System_Entity *sys, const char *name) { return e; } +void entity_Commit(System_Entity *sys, Entity *e) { + physics_AddEntity(sys->super->physics, e); + player_AddEntity(sys->super->player, e); +} + static inline void _entity_Delete(System_Entity *sys, uintptr_t id) { tree_Node *node = tree_FindNode(sys->entities, id); diff --git a/Entity.h b/Entity.h index e34f0ad..56a4d83 100644 --- a/Entity.h +++ b/Entity.h @@ -30,6 +30,12 @@ typedef struct _Entity { void *thinkerData; // Data managed by the Thinker, if exists. } Entity; +#define ADD_COMPONENT(entity, component, value) \ + do { \ + entity->component = value; \ + entity->component->super = entity; \ + } while (false) + typedef struct _App App; @@ -46,7 +52,10 @@ System_Entity *entity_NewSystem(App *super); void entity_DeleteSystem(System_Entity *sys); Entity *entity_Create(System_Entity *sys, const char *name); -void entity_Delete(System_Entity *sys, uintptr_t id); +// After the Entity from Create is assigned its components, +// it should be commited into the system via this function. +void entity_Commit(System_Entity *sys, Entity *e); +void entity_Delete(System_Entity *sys, uintptr_t id); void entity_Advance(System_Entity *sys, Duration deltaTime); diff --git a/Main.cpp b/Main.cpp index 70b1a57..efa666d 100644 --- a/Main.cpp +++ b/Main.cpp @@ -25,7 +25,10 @@ int main() { app_Advance(app, time_Reset(&lastUpdate)); - app_Render(); + BeginBatchDraw(); + cleardevice(); + app_Render(app); + EndBatchDraw(); Duration toSleep = {.microseconds = 1000000 / 30 - time_Reset(&lastFrame).microseconds}; duration_Sleep(toSleep); diff --git a/Physics_Component.c b/Physics_Component.c index 149802f..920c8f0 100644 --- a/Physics_Component.c +++ b/Physics_Component.c @@ -44,7 +44,8 @@ void physics_AddEntity(System_Physics *sys, Entity *e) { if (e->position) memcpy(tree_Insert(sys->pos, e->id, NULL), &e->position, sizeof(uintptr_t)); if (e->hitbox) { - ASSERT(!e->hitbox->fixed && !e->position && "Entity has non-Fixed Hitbox but no position"); + if (!e->hitbox->fixed) + ASSERT(e->position && "Entity has non-Fixed Hitbox but no position"); memcpy(tree_Insert(sys->hit, e->id, NULL), &e->hitbox, sizeof(uintptr_t)); } } @@ -85,11 +86,17 @@ static inline void _physics_AdvanceEntity(System_Physics *sys, Entity *e, Durati } +static double gravity = 30; + void physics_Advance(System_Physics *sys, Duration deltaTime) { for (tree_Node *i = tree_FirstNode(sys->pos); i != NULL; i = tree_Node_Next(i)) { Component_Position *pos = *((Component_Position **)i->data); + + // if (pos->super->hitbox && !pos->super->hitbox->fixed) + // pos->velocity.y += gravity * duration_Seconds(deltaTime); + _physics_AdvanceEntity(sys, pos->super, deltaTime); } } diff --git a/Physics_Move.c b/Physics_Move.c index 2913399..f1a88d7 100644 --- a/Physics_Move.c +++ b/Physics_Move.c @@ -42,6 +42,7 @@ void _physics_MoveX(System_Physics *sys, Entity *e, Duration deltaTime) { double maxdelta = tohit.lefttop.x - mybox.lefttop.x + tohit.size.x; delta = maxdelta + EPS; } + e->position->velocity.x = 0; } if (dabs(delta) < EPS) @@ -77,6 +78,7 @@ void _physics_MoveY(System_Physics *sys, Entity *e, Duration deltaTime) { double maxdelta = tohit.lefttop.y - mybox.lefttop.y + tohit.size.y; delta = maxdelta + EPS; } + e->position->velocity.y = 0; } if (dabs(delta) < EPS) diff --git a/Player_Component.c b/Player_Component.c index 77e347a..fde7b2e 100644 --- a/Player_Component.c +++ b/Player_Component.c @@ -45,7 +45,7 @@ void player_DeleteEntity(System_Player *sys, uintptr_t id) { } -static double walkSpeed = 2.0, jumpSpeed = 5.0; +static double walkSpeed = 200.0, jumpSpeed = 500.0; static int airjumpCount = 1; void player_Advance(System_Player *sys, Duration deltaTime) { @@ -69,7 +69,7 @@ void player_Advance(System_Player *sys, Duration deltaTime) { // Jump if (sys->super->input->keys[input_Key_Jump] == JustPressed) { if (sys->player->onGround || sys->player->jumpCount < airjumpCount) - sys->player->super->position->velocity.x = jumpSpeed; + sys->player->super->position->velocity.y = -jumpSpeed; if (!sys->player->onGround) // Took the second clause, airjumped sys->player->jumpCount++; } diff --git a/Types.h b/Types.h index b0a8bb3..b701c8a 100644 --- a/Types.h +++ b/Types.h @@ -2,12 +2,21 @@ #include #include +#include +#include #ifdef __cplusplus extern "C" { #endif +static inline void *zero_malloc(size_t size) { + void *d = malloc(size); + memset(d, 0, size); + return d; +} + + // A 2d vector of double. typedef struct { double x, y;