From ad7d42155d90e69b9d7bc0f969d815c140f54989 Mon Sep 17 00:00:00 2001 From: Frank DeMarco Date: Sat, 12 Sep 2020 21:57:27 -0400 Subject: [PATCH] precise collision detection used Pixel object; fixed out of scope bug in collision detection --- demo/Demo.cpp | 18 +++++----- src/Sprite.cpp | 97 +++++++++++++++++++++++--------------------------- src/Sprite.hpp | 34 +++++++++--------- 3 files changed, 71 insertions(+), 78 deletions(-) diff --git a/demo/Demo.cpp b/demo/Demo.cpp index 3c1cd28..be4cdda 100644 --- a/demo/Demo.cpp +++ b/demo/Demo.cpp @@ -13,15 +13,15 @@ screen resolution, debug display, loading wheel animation, shadowed sprite, separate update and draw, sprite movement cage, multiple windows, multiple renderers, node children list, node animations list, copy constructor for all - base classes (esp. sprite, audio), private and public class members, pixel - class iterator, sprite movement history, input history, use seconds instead of - milliseconds, store a node's animations in list, frame object for sprite - class, inline short functions, add box2d to library, load in separate thread - and display progress, add anchor to box class, add comments to code, generate - documentation from comments, get resource function, automatically update - animations, add arguments list to animation call, queue multiple calls to - animation, print list of chunk and music decoders available, allow nodes that - aren't connected to root + base classes (esp. sprite, audio, pixels), private and public class members, + pixel class iterator, sprite movement history, input history, use seconds + instead of milliseconds, store a node's animations in list, frame object for + sprite class, inline short functions, add box2d to library, load in separate + thread and display progress, add anchor to box class, add comments to code, + generate documentation from comments, get resource function, automatically + update animations, add arguments list to animation call, queue multiple calls + to animation, print list of chunk and music decoders available, allow nodes + that aren't connected to root :) SWEATY HANDS :) OILY SNACKS :) AND BAD HYGIENE :) diff --git a/src/Sprite.cpp b/src/Sprite.cpp index 4117555..d33130e 100644 --- a/src/Sprite.cpp +++ b/src/Sprite.cpp @@ -308,87 +308,87 @@ const SDL_Color& Sprite::get_color_mod() const return color_mod; } -float Sprite::get_w() +float Sprite::get_w() const { return get_box().get_w(); } -float Sprite::get_h() +float Sprite::get_h() const { return get_box().get_h(); } -glm::vec2 Sprite::get_size() +glm::vec2 Sprite::get_size() const { return get_box().get_size(); } -float Sprite::get_top(int index) +float Sprite::get_top(int index) const { return get_box(index).get_top(); } -float Sprite::get_right(int index) +float Sprite::get_right(int index) const { return get_box(index).get_right(); } -float Sprite::get_bottom(int index) +float Sprite::get_bottom(int index) const { return get_box(index).get_bottom(); } -float Sprite::get_left(int index) +float Sprite::get_left(int index) const { return get_box(index).get_left(); } -float Sprite::get_center_x(int index) +float Sprite::get_center_x(int index) const { return get_box(index).get_center_x(); } -float Sprite::get_center_y(int index) +float Sprite::get_center_y(int index) const { return get_box(index).get_center_y(); } -glm::vec2 Sprite::get_nw(int index) +glm::vec2 Sprite::get_nw(int index) const { return get_box(index).get_nw(); } -glm::vec2 Sprite::get_north(int index) +glm::vec2 Sprite::get_north(int index) const { return get_box(index).get_north(); } -glm::vec2 Sprite::get_ne(int index) +glm::vec2 Sprite::get_ne(int index) const { return get_box(index).get_ne(); } -glm::vec2 Sprite::get_east(int index) +glm::vec2 Sprite::get_east(int index) const { return get_box(index).get_east(); } -glm::vec2 Sprite::get_se(int index) +glm::vec2 Sprite::get_se(int index) const { return get_box(index).get_se(); } -glm::vec2 Sprite::get_south(int index) +glm::vec2 Sprite::get_south(int index) const { return get_box(index).get_south(); } -glm::vec2 Sprite::get_sw(int index) +glm::vec2 Sprite::get_sw(int index) const { return get_box(index).get_sw(); } -glm::vec2 Sprite::get_west(int index) +glm::vec2 Sprite::get_west(int index) const { return get_box(index).get_west(); } @@ -588,6 +588,7 @@ bool Sprite::collide(const Segment& segment, glm::vec2& intersection, bool all) bool Sprite::collide(const Box& box, bool precise, Box* overlap, bool all, SDL_Texture* other_texture) const { + Box o; if (precise) { int texture_access; @@ -610,7 +611,6 @@ bool Sprite::collide(const Box& box, bool precise, Box* overlap, bool all, SDL_T } if (precise && overlap == nullptr) { - Box o; overlap = &o; } } @@ -621,29 +621,6 @@ bool Sprite::collide(const Box& box, bool precise, Box* overlap, bool all, SDL_T if (precise) { bool collision_detected = false; - int w = overlap->get_w(), h = overlap->get_h(); - Uint32 format = SDL_PIXELFORMAT_RGBA32; - int bytes_per_pixel = SDL_BYTESPERPIXEL(format); - int bytes_per_row = bytes_per_pixel * w; - int bytes_total = h * bytes_per_row; - SDL_Rect rect; - Uint8* other_region = nullptr; - if (other_texture != nullptr) - { - rect.x = overlap->get_left() - box.get_left(); - rect.y = overlap->get_top() - box.get_top(); - rect.w = w; - rect.h = h; - other_region = new Uint8[bytes_total]; - SDL_SetRenderTarget(const_cast(get_renderer()), other_texture); - SDL_RenderReadPixels( - const_cast(get_renderer()), &rect, format, other_region, bytes_per_row); - } - rect.x = overlap->get_left() - get_box(ii).get_left(); - rect.y = overlap->get_top() - get_box(ii).get_top(); - rect.w = w; - rect.h = h; - Uint8* region = new Uint8[bytes_total]; SDL_Texture* collision_check_frame; if (get_scale() == 1) { @@ -654,22 +631,38 @@ bool Sprite::collide(const Box& box, bool precise, Box* overlap, bool all, SDL_T collision_check_frame = sfw::duplicate_texture( const_cast(get_renderer()), get_current_frame(), get_box(ii).get_size()); } - SDL_SetRenderTarget(const_cast(get_renderer()), collision_check_frame); - SDL_RenderReadPixels( - const_cast(get_renderer()), &rect, format, region, bytes_per_row); - for (int byte_index = 3; byte_index < bytes_total; byte_index += 4) + Pixels region_pixels = Pixels( + const_cast(get_renderer()), collision_check_frame, overlap->stamp(-get_nw(ii))); + if (other_texture == nullptr) { - if (region[byte_index] > 0 && (other_texture == nullptr || other_region[byte_index] > 0)) + for (int x = 0; x < static_cast(overlap->get_w()); x++) { - collision_detected = true; - break; + for (int y = 0; y < static_cast(overlap->get_h()); y++) + { + if (region_pixels.get(x, y).a > 0) + { + collision_detected = true; + break; + } + } } } - delete[] region; - if (other_region != nullptr) + else { - delete[] other_region; - } + Pixels other_region_pixels = Pixels( + const_cast(get_renderer()), other_texture, overlap->stamp(-box.get_nw())); + for (int x = 0; x < static_cast(overlap->get_w()); x++) + { + for (int y = 0; y < static_cast(overlap->get_h()); y++) + { + if (region_pixels.get(x, y).a > 0 && other_region_pixels.get(x, y).a > 0) + { + collision_detected = true; + break; + } + } + } + } if (get_scale() != 1) { SDL_DestroyTexture(collision_check_frame); diff --git a/src/Sprite.hpp b/src/Sprite.hpp index 06eff3d..9d769d8 100644 --- a/src/Sprite.hpp +++ b/src/Sprite.hpp @@ -82,23 +82,23 @@ struct Sprite : Node Uint8 get_alpha_mod() const; void set_color_mod(const SDL_Color&); const SDL_Color& get_color_mod() const; - float get_w(); - float get_h(); - glm::vec2 get_size(); - float get_top(int = 0); - float get_right(int = 0); - float get_bottom(int = 0); - float get_left(int = 0); - float get_center_x(int = 0); - float get_center_y(int = 0); - glm::vec2 get_nw(int = 0); - glm::vec2 get_north(int = 0); - glm::vec2 get_ne(int = 0); - glm::vec2 get_east(int = 0); - glm::vec2 get_se(int = 0); - glm::vec2 get_south(int = 0); - glm::vec2 get_sw(int = 0); - glm::vec2 get_west(int = 0); + float get_w() const; + float get_h() const; + glm::vec2 get_size() const; + float get_top(int = 0) const; + float get_right(int = 0) const; + float get_bottom(int = 0) const; + float get_left(int = 0) const; + float get_center_x(int = 0) const; + float get_center_y(int = 0) const; + glm::vec2 get_nw(int = 0) const; + glm::vec2 get_north(int = 0) const; + glm::vec2 get_ne(int = 0) const; + glm::vec2 get_east(int = 0) const; + glm::vec2 get_se(int = 0) const; + glm::vec2 get_south(int = 0) const; + glm::vec2 get_sw(int = 0) const; + glm::vec2 get_west(int = 0) const; glm::vec2 get_center(int = 0) const; void set_top(float); void set_right(float);