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,
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 :)

View File

@ -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<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;
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<SDL_Renderer*>(get_renderer()), get_current_frame(), get_box(ii).get_size());
}
SDL_SetRenderTarget(const_cast<SDL_Renderer*>(get_renderer()), collision_check_frame);
SDL_RenderReadPixels(
const_cast<SDL_Renderer*>(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<SDL_Renderer*>(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<int>(overlap->get_w()); x++)
{
collision_detected = true;
break;
for (int y = 0; y < static_cast<int>(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<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)
{
SDL_DestroyTexture(collision_check_frame);

View File

@ -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);