From 9f3bf608e9b300d7f5c85acf591c7e3c2a0d4f43 Mon Sep 17 00:00:00 2001 From: Frederico Linhares Date: Mon, 23 May 2022 10:38:55 -0300 Subject: feat Subdivide collision detection * src/rect.c (cg_cRect_align_vertically, cg_cRect_align_horizontally): Collision detection consists of two different algorithms that detect if two boxes are aligned vertically and horizontally. Now those two algorithms can be used separately. --- src/rect.c | 48 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/src/rect.c b/src/rect.c index 206ab45..52c9dd4 100644 --- a/src/rect.c +++ b/src/rect.c @@ -27,6 +27,18 @@ cg_free_rect(mrb_state *mrb, void* obj) const struct mrb_data_type cg_rect_type = { "CG_Rect", cg_free_rect }; +static inline SDL_bool +align_vertically(int a_x, int a_width, int b_x, int b_width) +{ + return a_x <= b_x + b_width && a_x + a_width >= b_x; +} + +static inline SDL_bool +align_horizontally(int a_y, int a_height, int b_y, int b_height) +{ + return a_y <= b_y + b_height && a_y + a_height >= b_y; +} + static mrb_value cg_cRect_initialize(mrb_state *mrb, mrb_value self) { @@ -163,6 +175,30 @@ cg_cRect_draw_fill(mrb_state *mrb, mrb_value self) return self; } +static mrb_value +cg_cRect_align_vertically(mrb_state *mrb, mrb_value self) +{ + struct cg_rect *ptr, *that; + + mrb_get_args(mrb, "d", &that, &cg_rect_type); + ptr = (struct cg_rect *)DATA_PTR(self); + + return mrb_bool_value( + align_vertically(ptr->rect.x, ptr->rect.w, that->rect.x, that->rect.w)); +} + +static mrb_value +cg_cRect_align_horizontally(mrb_state *mrb, mrb_value self) +{ + struct cg_rect *ptr, *that; + + mrb_get_args(mrb, "d", &that, &cg_rect_type); + ptr = (struct cg_rect *)DATA_PTR(self); + + return mrb_bool_value( + align_horizontally(ptr->rect.y, ptr->rect.h, that->rect.y, that->rect.h)); +} + static mrb_value cg_cRect_collide(mrb_state *mrb, mrb_value self) { @@ -172,10 +208,8 @@ cg_cRect_collide(mrb_state *mrb, mrb_value self) ptr = (struct cg_rect *)DATA_PTR(self); return mrb_bool_value( - ptr->rect.x <= that->rect.x + that->rect.w && - ptr->rect.x + ptr->rect.w >= that->rect.x && - ptr->rect.y <= that->rect.y + that->rect.h && - ptr->rect.y + ptr->rect.h >= that->rect.y); + align_vertically(ptr->rect.x, ptr->rect.w, that->rect.x, that->rect.w) && + align_horizontally(ptr->rect.y, ptr->rect.h, that->rect.y, that->rect.h)); } void @@ -204,6 +238,12 @@ cg_rect_init(mrb_state *mrb) mrb, cg_cRect, "draw_lines", cg_cRect_draw_lines, MRB_ARGS_NONE()); mrb_define_method( mrb, cg_cRect, "draw_fill", cg_cRect_draw_fill, MRB_ARGS_NONE()); + mrb_define_method( + mrb, cg_cRect, "align_vertically?", cg_cRect_align_vertically, + MRB_ARGS_REQ(1)); + mrb_define_method( + mrb, cg_cRect, "align_horizontally?", cg_cRect_align_vertically, + MRB_ARGS_REQ(1)); mrb_define_method( mrb, cg_cRect, "collide?", cg_cRect_collide, MRB_ARGS_REQ(1)); } -- cgit v1.2.3