#include "sdlpp_circlecolider.hpp" #include "sdlpp_geometry.hpp" namespace SDLPP { CircleColider::CircleColider( double x, double y, double rad ) : CircleColider( { x, y }, rad ) {} CircleColider::CircleColider( const Vec2D< double > ¢er, double rad ) : CollisionPolygon( center ), original_rad( rad ) {} CircleColider::CircleColider( double x, double y, double rad, uint64_t id ) : CircleColider( { x, y }, rad, id ) {} CircleColider::CircleColider( const Vec2D< double > ¢er, double rad, uint64_t id ) : CircleColider( center, rad ) { _id = id; } bool CircleColider::colidesWith( const SDLPP::CollisionPolygon &other ) const { if ( other.isCircle() ) { /* 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.getX() - getX(); int ydiff = other.getY() - getY(); return ( xdiff * xdiff + ydiff * ydiff ) <= totalDist * totalDist; } else if ( other.isInfinite() ) { return infinityIntersection( other, *this ); } /* 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; } return false; } 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, uint64_t id ) { position = Vec2D< int >( original.getX() * w + x, original.getY() * h + y ); rad_ = original_rad * w; if ( _id == static_cast< uint64_t >( -1 ) ) _id = id; } 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(); 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(), 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(), 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 ); SDL_RenderDrawLine( renderer.getRendererPtr(), i, center_y + allowed_rad, i, center_y + allowed_rad - 2 ); } } 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 ) { render( renderer, sdl_color, sdl_outline ); } int CircleColider::getRadius() const { return rad_; } std::shared_ptr< CollisionPolygon > CircleColider::copySelf() { return std::make_shared< CircleColider >( *this ); } std::vector< Line< int > > CircleColider::getLines() const { return {}; } } // namespace SDLPP