precise collision detection used Pixel object; fixed out of scope bug in collision detection

This commit is contained in:
Frank DeMarco 2020-09-12 21:57:27 -04:00
parent 72a36a1d57
commit ad7d42155d
3 changed files with 71 additions and 78 deletions

View File

@ -13,15 +13,15 @@
screen resolution, debug display, loading wheel animation, shadowed sprite, screen resolution, debug display, loading wheel animation, shadowed sprite,
separate update and draw, sprite movement cage, multiple windows, multiple separate update and draw, sprite movement cage, multiple windows, multiple
renderers, node children list, node animations list, copy constructor for all renderers, node children list, node animations list, copy constructor for all
base classes (esp. sprite, audio), private and public class members, pixel base classes (esp. sprite, audio, pixels), private and public class members,
class iterator, sprite movement history, input history, use seconds instead of pixel class iterator, sprite movement history, input history, use seconds
milliseconds, store a node's animations in list, frame object for sprite instead of milliseconds, store a node's animations in list, frame object for
class, inline short functions, add box2d to library, load in separate thread sprite class, inline short functions, add box2d to library, load in separate
and display progress, add anchor to box class, add comments to code, generate thread and display progress, add anchor to box class, add comments to code,
documentation from comments, get resource function, automatically update generate documentation from comments, get resource function, automatically
animations, add arguments list to animation call, queue multiple calls to update animations, add arguments list to animation call, queue multiple calls
animation, print list of chunk and music decoders available, allow nodes that to animation, print list of chunk and music decoders available, allow nodes
aren't connected to root that aren't connected to root
:) SWEATY HANDS :) OILY SNACKS :) AND BAD HYGIENE :) :) SWEATY HANDS :) OILY SNACKS :) AND BAD HYGIENE :)

View File

@ -308,87 +308,87 @@ const SDL_Color& Sprite::get_color_mod() const
return color_mod; return color_mod;
} }
float Sprite::get_w() float Sprite::get_w() const
{ {
return get_box().get_w(); return get_box().get_w();
} }
float Sprite::get_h() float Sprite::get_h() const
{ {
return get_box().get_h(); return get_box().get_h();
} }
glm::vec2 Sprite::get_size() glm::vec2 Sprite::get_size() const
{ {
return get_box().get_size(); return get_box().get_size();
} }
float Sprite::get_top(int index) float Sprite::get_top(int index) const
{ {
return get_box(index).get_top(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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(); 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 bool Sprite::collide(const Box& box, bool precise, Box* overlap, bool all, SDL_Texture* other_texture) const
{ {
Box o;
if (precise) if (precise)
{ {
int texture_access; 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) if (precise && overlap == nullptr)
{ {
Box o;
overlap = &o; overlap = &o;
} }
} }
@ -621,29 +621,6 @@ bool Sprite::collide(const Box& box, bool precise, Box* overlap, bool all, SDL_T
if (precise) if (precise)
{ {
bool collision_detected = false; 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<SDL_Renderer*>(get_renderer()), other_texture);
SDL_RenderReadPixels(
const_cast<SDL_Renderer*>(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; SDL_Texture* collision_check_frame;
if (get_scale() == 1) 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( collision_check_frame = sfw::duplicate_texture(
const_cast<SDL_Renderer*>(get_renderer()), get_current_frame(), get_box(ii).get_size()); const_cast<SDL_Renderer*>(get_renderer()), get_current_frame(), get_box(ii).get_size());
} }
SDL_SetRenderTarget(const_cast<SDL_Renderer*>(get_renderer()), collision_check_frame); Pixels region_pixels = Pixels(
SDL_RenderReadPixels( const_cast<SDL_Renderer*>(get_renderer()), collision_check_frame, overlap->stamp(-get_nw(ii)));
const_cast<SDL_Renderer*>(get_renderer()), &rect, format, region, bytes_per_row); if (other_texture == nullptr)
for (int byte_index = 3; byte_index < bytes_total; byte_index += 4)
{ {
if (region[byte_index] > 0 && (other_texture == nullptr || other_region[byte_index] > 0)) for (int x = 0; x < static_cast<int>(overlap->get_w()); x++)
{ {
collision_detected = true; for (int y = 0; y < static_cast<int>(overlap->get_h()); y++)
break; {
if (region_pixels.get(x, y).a > 0)
{
collision_detected = true;
break;
}
}
} }
} }
delete[] region; else
if (other_region != nullptr)
{ {
delete[] other_region; Pixels other_region_pixels = Pixels(
} const_cast<SDL_Renderer*>(get_renderer()), other_texture, overlap->stamp(-box.get_nw()));
for (int x = 0; x < static_cast<int>(overlap->get_w()); x++)
{
for (int y = 0; y < static_cast<int>(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) if (get_scale() != 1)
{ {
SDL_DestroyTexture(collision_check_frame); SDL_DestroyTexture(collision_check_frame);

View File

@ -82,23 +82,23 @@ struct Sprite : Node
Uint8 get_alpha_mod() const; Uint8 get_alpha_mod() const;
void set_color_mod(const SDL_Color&); void set_color_mod(const SDL_Color&);
const SDL_Color& get_color_mod() const; const SDL_Color& get_color_mod() const;
float get_w(); float get_w() const;
float get_h(); float get_h() const;
glm::vec2 get_size(); glm::vec2 get_size() const;
float get_top(int = 0); float get_top(int = 0) const;
float get_right(int = 0); float get_right(int = 0) const;
float get_bottom(int = 0); float get_bottom(int = 0) const;
float get_left(int = 0); float get_left(int = 0) const;
float get_center_x(int = 0); float get_center_x(int = 0) const;
float get_center_y(int = 0); float get_center_y(int = 0) const;
glm::vec2 get_nw(int = 0); glm::vec2 get_nw(int = 0) const;
glm::vec2 get_north(int = 0); glm::vec2 get_north(int = 0) const;
glm::vec2 get_ne(int = 0); glm::vec2 get_ne(int = 0) const;
glm::vec2 get_east(int = 0); glm::vec2 get_east(int = 0) const;
glm::vec2 get_se(int = 0); glm::vec2 get_se(int = 0) const;
glm::vec2 get_south(int = 0); glm::vec2 get_south(int = 0) const;
glm::vec2 get_sw(int = 0); glm::vec2 get_sw(int = 0) const;
glm::vec2 get_west(int = 0); glm::vec2 get_west(int = 0) const;
glm::vec2 get_center(int = 0) const; glm::vec2 get_center(int = 0) const;
void set_top(float); void set_top(float);
void set_right(float); void set_right(float);