New collision detection
This commit is contained in:
@@ -1,47 +1,34 @@
|
||||
#include "sdlpp_circlecolider.hpp"
|
||||
#include "sdlpp_geometry.hpp"
|
||||
|
||||
namespace SDLPP {
|
||||
CircleColider::CircleColider( double x, double y, double rad )
|
||||
: CircleColider( {x, y}, rad ) {};
|
||||
: CircleColider( { x, y }, rad ){};
|
||||
|
||||
CircleColider::CircleColider( const Vec2D< double > ¢er, double rad )
|
||||
: CollisionPolygon( center ), original_rad( rad ) {}
|
||||
|
||||
bool CircleColider::colidesWith( const SDLPP::CollisionPolygon &other ) const {
|
||||
if ( other.isCircle() ) {
|
||||
int otherRad = ( other.rightmost() - other.leftmost() ) / 2;
|
||||
/* check if distance of centers is lower than radiuses added together */
|
||||
int otherRad =
|
||||
dynamic_cast< const SDLPP::CircleColider & >( other ).getRadius();
|
||||
int thisRad = getRadius();
|
||||
int totalDist = otherRad + thisRad;
|
||||
int xdiff = other.leftmost() + otherRad - ( leftmost() + thisRad );
|
||||
int ydiff = other.topmost() + otherRad - ( topmost() + thisRad );
|
||||
int xdiff = other.getX() - getX();
|
||||
int ydiff = other.getY() - getY();
|
||||
return ( xdiff * xdiff + ydiff * ydiff ) <= totalDist * totalDist;
|
||||
} else if ( other.isInfinite() ) {
|
||||
return infinityIntersection( other, *this );
|
||||
}
|
||||
int rad = rad_;
|
||||
int centerx = getX();
|
||||
int centery = getY();
|
||||
if ( other.topmost() <= centery && other.bottommost() >= centery ) {
|
||||
return other.leftmost() <= rightmost() &&
|
||||
other.rightmost() >= leftmost();
|
||||
} else if ( other.leftmost() <= centerx && other.rightmost() >= centerx ) {
|
||||
return other.topmost() <= bottommost() &&
|
||||
other.bottommost() >= topmost();
|
||||
/* other is not a circle */
|
||||
int rad = getRadius();
|
||||
for ( auto &line : other.getLines() ) {
|
||||
auto distance = pointLineDistance( position, line );
|
||||
if ( distance * distance <= rad * rad )
|
||||
return true;
|
||||
}
|
||||
int pointx = 0, pointy = 0;
|
||||
if ( centerx > other.rightmost() ) {
|
||||
pointx = other.rightmost();
|
||||
} else {
|
||||
pointx = other.leftmost();
|
||||
}
|
||||
if ( centery < other.topmost() ) {
|
||||
pointy = other.topmost();
|
||||
} else {
|
||||
pointy = other.bottommost();
|
||||
}
|
||||
int distancesquared = ( pointx - centerx ) * ( pointx - centerx ) +
|
||||
( pointy - centery ) * ( pointy - centery );
|
||||
return distancesquared <= rad * rad;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CircleColider::isCircle() const {
|
||||
@@ -61,12 +48,12 @@ int CircleColider::rightmost() const {
|
||||
}
|
||||
|
||||
void CircleColider::updateCollision( int x, int y, int w, int h ) {
|
||||
position = Vec2D<int> ( original.getX() * w + x, original.getY() * h + y );
|
||||
position = Vec2D< int >( original.getX() * w + x, original.getY() * h + y );
|
||||
rad_ = original_rad * w;
|
||||
}
|
||||
|
||||
void CircleColider::render( Renderer &renderer,
|
||||
const std::tuple< int, int, int, int > &color ) {
|
||||
void CircleColider::render( Renderer &renderer, const SDL_Color &color,
|
||||
const SDL_Color &outline_color ) {
|
||||
std::vector< int > rect = { leftmost(), topmost(), rightmost(),
|
||||
bottommost() };
|
||||
auto center_x = getX();
|
||||
@@ -76,14 +63,13 @@ void CircleColider::render( Renderer &renderer,
|
||||
auto xdiff = center_x - i;
|
||||
auto xdist = xdiff * xdiff;
|
||||
auto allowed_rad = sqrt( radsq - xdist );
|
||||
SDL_SetRenderDrawColor( renderer.getRendererPtr(),
|
||||
std::get< 0 >( color ), std::get< 1 >( color ),
|
||||
std::get< 2 >( color ), 0x40 );
|
||||
SDL_SetRenderDrawColor( renderer.getRendererPtr(), color.r, color.g,
|
||||
color.b, color.a );
|
||||
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
|
||||
center_y - allowed_rad, i, center_y + allowed_rad );
|
||||
SDL_SetRenderDrawColor( renderer.getRendererPtr(),
|
||||
std::get< 0 >( color ), std::get< 1 >( color ),
|
||||
std::get< 2 >( color ), 0x80 );
|
||||
SDL_SetRenderDrawColor( renderer.getRendererPtr(), outline_color.r,
|
||||
outline_color.g, outline_color.b,
|
||||
outline_color.a );
|
||||
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
|
||||
center_y - allowed_rad, i,
|
||||
center_y - allowed_rad + 2 );
|
||||
@@ -91,39 +77,18 @@ void CircleColider::render( Renderer &renderer,
|
||||
center_y + allowed_rad, i,
|
||||
center_y + allowed_rad - 2 );
|
||||
}
|
||||
SDL_SetRenderDrawColor( renderer.getRendererPtr(), 0xFF, 0, 0, 0xFF );
|
||||
SDL_RenderDrawLine( renderer.getRendererPtr(), center_x, center_y,
|
||||
center_x + rad_, center_y );
|
||||
SDL_RenderDrawLine( renderer.getRendererPtr(), center_x, center_y, center_x,
|
||||
center_y + rad_ );
|
||||
SDL_RenderDrawLine( renderer.getRendererPtr(), center_x, center_y,
|
||||
center_x - rad_, center_y );
|
||||
SDL_RenderDrawLine( renderer.getRendererPtr(), center_x, center_y, center_x,
|
||||
center_y - rad_ );
|
||||
}
|
||||
|
||||
void CircleColider::render( Renderer &renderer, const SDL_Color &color ) {
|
||||
auto input_color = color;
|
||||
auto outline_color = color;
|
||||
input_color.a = 0x40;
|
||||
outline_color.a = 0x80;
|
||||
render( renderer, input_color, outline_color );
|
||||
}
|
||||
|
||||
void CircleColider::render( Renderer &renderer ) {
|
||||
std::vector< int > rect = { leftmost(), topmost(), rightmost(),
|
||||
bottommost() };
|
||||
auto center_x = getX();
|
||||
auto center_y = getY();
|
||||
auto radsq = rad_ * rad_;
|
||||
for ( int i = rect[0]; i <= rect[2]; i++ ) {
|
||||
auto xdiff = center_x - i;
|
||||
auto xdist = xdiff * xdiff;
|
||||
auto allowed_rad = sqrt( radsq - xdist );
|
||||
SDL_SetRenderDrawColor( renderer.getRendererPtr(), sdl_color.r,
|
||||
sdl_color.g, sdl_color.b, sdl_color.a );
|
||||
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
|
||||
center_y - allowed_rad, i, center_y + allowed_rad );
|
||||
SDL_SetRenderDrawColor( renderer.getRendererPtr(), sdl_outline.r,
|
||||
sdl_outline.g, sdl_outline.b, sdl_outline.a );
|
||||
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
|
||||
center_y - allowed_rad, i,
|
||||
center_y - allowed_rad + 2 );
|
||||
SDL_RenderDrawLine( renderer.getRendererPtr(), i,
|
||||
center_y + allowed_rad, i,
|
||||
center_y + allowed_rad - 2 );
|
||||
}
|
||||
render( renderer, sdl_color, sdl_outline );
|
||||
}
|
||||
|
||||
int CircleColider::getRadius() const {
|
||||
@@ -133,4 +98,8 @@ int CircleColider::getRadius() const {
|
||||
std::shared_ptr< CollisionPolygon > CircleColider::copySelf() {
|
||||
return std::make_shared< CircleColider >( *this );
|
||||
}
|
||||
|
||||
std::vector< Line< int > > CircleColider::getLines() const {
|
||||
return {};
|
||||
}
|
||||
} // namespace SDLPP
|
||||
|
||||
Reference in New Issue
Block a user