From 11e7084586c23ba09b22f8bf54ca52ba078c98dc Mon Sep 17 00:00:00 2001 From: En Yi Date: Fri, 20 Mar 2020 20:11:06 +0800 Subject: [PATCH] Add target draw and collision --- include/header.h | 8 +++++++- main.c | 14 ++++++++++++-- obj/kinematics.c | 7 ------- obj/player.c | 2 ++ obj/target.c | 46 ++++++++++++++++++++++++++++++++++++++++++++-- utilities/math.c | 7 +++++++ 6 files changed, 72 insertions(+), 12 deletions(-) diff --git a/include/header.h b/include/header.h index 599ce59..9253c67 100644 --- a/include/header.h +++ b/include/header.h @@ -88,6 +88,11 @@ struct squishy_square Vector2 right_vertices[BEZIER_POINTS+1]; }; +struct target_obj +{ + double radius; + struct kinematic_obj kinematic; +}; // Object functions, kinematics.c struct kinematic_obj init_kinematic_obj(int width, int height); void move(struct kinematic_obj *obj, Vector2 acceleration); @@ -101,6 +106,7 @@ double mag(Vector2 vec); int sign(double val); Vector2 dir(Vector2 vec); void approach(double *val, double target, float f); +Vector2 center(Rectangle rect); // Linked list, linked_list.c void create_list(void); @@ -123,7 +129,7 @@ struct player_obj init_player_obj(); void player_input_check(struct player_obj *player); //Target stuff, target.c -struct kinematic_obj init_target(); +struct target_obj init_target(); //Debug stuff, debug.c void state_string(char *str, enum PLAYER_STATE state); diff --git a/main.c b/main.c index 9e64e1c..f4cf773 100644 --- a/main.c +++ b/main.c @@ -24,6 +24,7 @@ #include "header.h" struct kinematic_obj_node *kinematic_HEAD = NULL; +struct kinematic_obj_node *target_HEAD = NULL; int PLAYER_ACCEL = 1500; int JUMP_ACCEL = 15000; int JUMP_SPD = 350; @@ -60,8 +61,6 @@ int main() struct kinematic_obj tile6 = init_kinematic_obj(50, 300); struct kinematic_obj tile7 = init_kinematic_obj(50, 300); - struct kinematic_obj target = init_target(50, 300); - set_position(&player.kinematic, 400, 100); set_position(&tile, -50, 380); set_position(&tile2, 100, 280); @@ -81,6 +80,11 @@ int main() add_node(&tile6, &kinematic_HEAD); add_node(&tile7, &kinematic_HEAD); add_node(&player.kinematic, &kinematic_HEAD); + + + struct target_obj target = init_target(50, 300); + set_position(&target.kinematic, 150, 380); + add_node(&target.kinematic, &target_HEAD); SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -110,6 +114,11 @@ int main() DrawRectangleLinesEx(current->obj->rect, 1, BLACK); current = current->next; } + current = target_HEAD; + while(current){ + DrawCircle(current->obj->pos.x, current->obj->pos.y, current->obj->ori_width, BLACK); + current = current->next; + } DrawFPS(0,0); state_string(current_state, player.state); DrawText(current_state, 250, 0, 12, BLACK); @@ -127,6 +136,7 @@ int main() // De-Initialization //-------------------------------------------------------------------------------------- free_list(&kinematic_HEAD); + free_list(&target_HEAD); free_afterimages(&player); CloseWindow(); // Close window and OpenGL context //-------------------------------------------------------------------------------------- diff --git a/obj/kinematics.c b/obj/kinematics.c index 2f34f84..1725532 100644 --- a/obj/kinematics.c +++ b/obj/kinematics.c @@ -103,13 +103,6 @@ bool place_meeting(struct kinematic_obj *obj, Vector2 dir){ return false; } -Vector2 center(Rectangle rect){ - return (Vector2){ - .x = rect.x + rect.width/2, - .y = rect.y + rect.height/2 - }; -} - void adjust_hitbox(struct kinematic_obj *obj){ approach(&obj->dim_reduction[0], obj->set_dim_reduction[0], 0.2); approach(&obj->dim_reduction[1], obj->set_dim_reduction[1], 0.2); diff --git a/obj/player.c b/obj/player.c index 3bacef5..e54c85f 100644 --- a/obj/player.c +++ b/obj/player.c @@ -34,6 +34,8 @@ const unsigned int afterimage_frames = 10; static enum PLAYER_STATE state_buffer = IDLE; unsigned int PLAYER_SIZE = 30; +extern struct kinematic_obj_node *target_HEAD; + // The player FSM void player_input_check(struct player_obj *player){ Vector2 accel = (Vector2){ diff --git a/obj/target.c b/obj/target.c index 7e1d0be..3e75b29 100644 --- a/obj/target.c +++ b/obj/target.c @@ -1,5 +1,47 @@ #include "header.h" +#include +#include +// Target is circular, thus a kinematic obj has w=h +struct target_obj init_target(){ + return (struct target_obj){ + .radius = 12, + .kinematic = init_kinematic_obj(12, 12) + }; +} -struct kinematic_obj init_target(){ - return init_kinematic_obj(25, 25); +bool collide_target(struct kinematic_obj *obj, struct target_obj *target){ + /* The method is based off SAT + */ + Vector2 obj_center = center(obj->rect); + Vector2 target_center = center(target->kinematic.rect); + + float dist = Vector2Distance(obj_center, target_center); + + if (dist < target->radius) + return true; + + double max_dim = fmax(obj->rect.width, obj->rect.height); + if (dist > max_dim + target->radius) + return false; + + Vector2 n = Vector2Subtract(target_center, obj_center); + n = Vector2Normalize(n); + + Vector2 pos_check = obj->pos; + double obj_proj1 = Vector2DotProduct(pos_check, n); + pos_check.x += obj->rect.width; + double obj_proj2 = Vector2DotProduct(pos_check, n); + pos_check.y += obj->rect.height; + double obj_proj3 = Vector2DotProduct(pos_check, n); + pos_check.x -= obj->rect.width; + double obj_proj4 = Vector2DotProduct(pos_check, n); + + double min_proj = fmin(fmin(fmin(obj_proj1, obj_proj2), obj_proj3), obj_proj4); + double max_proj = fmax(fmax(fmax(obj_proj1, obj_proj2), obj_proj3), obj_proj4); + + double target_proj = Vector2DotProduct(target_center, n); + + if (!(max_proj < target_proj - target->radius) && !(min_proj > target_proj + target->radius)) + return true; + return false; } \ No newline at end of file diff --git a/utilities/math.c b/utilities/math.c index 2b12236..f94c76e 100644 --- a/utilities/math.c +++ b/utilities/math.c @@ -7,4 +7,11 @@ int sign(double val){ void approach(double *val, double target, float f){ *val += (target - *val) * f; +} + +Vector2 center(Rectangle rect){ + return (Vector2){ + .x = rect.x + rect.width/2, + .y = rect.y + rect.height/2 + }; } \ No newline at end of file