134 lines
5.3 KiB
C++
134 lines
5.3 KiB
C++
// TODO render function like in rectangle
|
|
#include "sdlpp_circlecolider.hpp"
|
|
|
|
namespace SDLPP {
|
|
CircleColider::CircleColider( double x, double y, double rad )
|
|
: CollisionPolygon( x, y ) {
|
|
original_rad = rad;
|
|
}
|
|
|
|
bool CircleColider::colidesWith( const SDLPP::CollisionPolygon &other ) const {
|
|
if ( other.isCircle() ) {
|
|
int otherRad = ( other.rightmost() - other.leftmost() ) / 2;
|
|
int thisRad = getRadius();
|
|
int totalDist = otherRad + thisRad;
|
|
int xdiff = other.leftmost() + otherRad - ( leftmost() + thisRad );
|
|
int ydiff = other.topmost() + otherRad - ( topmost() + thisRad );
|
|
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();
|
|
}
|
|
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;
|
|
}
|
|
|
|
bool CircleColider::isCircle() const {
|
|
return true;
|
|
}
|
|
int CircleColider::topmost() const {
|
|
return getY() - rad_;
|
|
}
|
|
int CircleColider::bottommost() const {
|
|
return getY() + rad_;
|
|
}
|
|
int CircleColider::leftmost() const {
|
|
return getX() - rad_;
|
|
}
|
|
int CircleColider::rightmost() const {
|
|
return getX() + rad_;
|
|
}
|
|
|
|
void CircleColider::updateCollision( int x, int y, int w, int h ) {
|
|
position_x = original_x * w + x;
|
|
position_y = original_y * h + y;
|
|
rad_ = original_rad * w;
|
|
}
|
|
|
|
void CircleColider::render( Renderer &renderer,
|
|
const std::tuple< int, int, int, int > &color ) {
|
|
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(),
|
|
std::get< 0 >( color ), std::get< 1 >( color ),
|
|
std::get< 2 >( color ), 0x40 );
|
|
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_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 );
|
|
}
|
|
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 ) {
|
|
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 );
|
|
}
|
|
}
|
|
|
|
int CircleColider::getRadius() const {
|
|
return rad_;
|
|
}
|
|
} // namespace SDLPP
|