SDLPP: add collider IDs
This commit is contained in:
parent
19e66bf34a
commit
dd6f37264c
@ -7,6 +7,13 @@ CircleColider::CircleColider( double x, double y, double 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() ) {
|
||||
@ -47,9 +54,11 @@ int CircleColider::rightmost() const {
|
||||
return getX() + rad_;
|
||||
}
|
||||
|
||||
void CircleColider::updateCollision( int x, int y, int w, int h ) {
|
||||
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,
|
||||
|
@ -11,6 +11,8 @@ class SDLPPSCOPE CircleColider : public CollisionPolygon {
|
||||
public:
|
||||
CircleColider( double x, double y, double rad );
|
||||
CircleColider( const Vec2D< double > ¢er, double rad );
|
||||
CircleColider( double x, double y, double rad, uint64_t id );
|
||||
CircleColider( const Vec2D< double > ¢er, double rad, uint64_t id );
|
||||
virtual ~CircleColider() {}
|
||||
|
||||
virtual bool colidesWith( const CollisionPolygon &other ) const override;
|
||||
@ -20,7 +22,8 @@ public:
|
||||
virtual int leftmost() const override;
|
||||
virtual int rightmost() const override;
|
||||
|
||||
virtual void updateCollision( int x, int y, int w, int h ) override;
|
||||
virtual void updateCollision( int x, int y, int w, int h,
|
||||
uint64_t id ) override;
|
||||
virtual void render( Renderer &renderer, const SDL_Color &color,
|
||||
const SDL_Color &outline_color ) override;
|
||||
virtual void render( Renderer &renderer, const SDL_Color &color ) override;
|
||||
|
@ -49,7 +49,8 @@ void CircleRender::setColor( const std::string &color ) {
|
||||
if ( !polygon ) {
|
||||
polygon = std::make_shared< CircleColider >( 0, 0, 1 );
|
||||
polygon->updateCollision( collisionPushX(), collisionPushY(),
|
||||
collisionWidth(), collisionHeight() );
|
||||
collisionWidth(), collisionHeight(),
|
||||
getId() );
|
||||
}
|
||||
polygon->setColor( color );
|
||||
}
|
||||
@ -58,7 +59,8 @@ void CircleRender::setOutlineColor( const std::string &color ) {
|
||||
if ( !polygon ) {
|
||||
polygon = std::make_shared< CircleColider >( 0, 0, 1 );
|
||||
polygon->updateCollision( collisionPushX(), collisionPushY(),
|
||||
collisionWidth(), collisionHeight() );
|
||||
collisionWidth(), collisionHeight(),
|
||||
getId() );
|
||||
}
|
||||
polygon->setOutlineColor( color );
|
||||
}
|
||||
@ -110,10 +112,11 @@ void CircleRender::updateSizeAndPosition() {
|
||||
rect.h = std::round( ( current.getY() + r_ ) * dimension ) - rect.y;
|
||||
if ( polygon )
|
||||
polygon->updateCollision( collisionPushX(), collisionPushY(),
|
||||
collisionWidth(), collisionHeight() );
|
||||
collisionWidth(), collisionHeight(),
|
||||
getId() );
|
||||
for ( auto &x : collisions ) {
|
||||
x->updateCollision( collisionPushX(), collisionPushY(),
|
||||
collisionWidth(), collisionHeight() );
|
||||
collisionWidth(), collisionHeight(), getId() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,12 @@ CollisionPolygon::CollisionPolygon( const Vec2D< double > &input ) {
|
||||
original = input;
|
||||
position = { 0, 0 };
|
||||
}
|
||||
CollisionPolygon::CollisionPolygon( double x, double y, uint64_t id )
|
||||
: CollisionPolygon( Vec2D< double >( x, y ), id ) {}
|
||||
CollisionPolygon::CollisionPolygon( const Vec2D< double > &input, uint64_t id )
|
||||
: CollisionPolygon( input ) {
|
||||
_id = id;
|
||||
}
|
||||
|
||||
bool CollisionPolygon::isInfinite() const {
|
||||
return infinite;
|
||||
@ -17,7 +23,10 @@ void CollisionPolygon::setInfinite() {
|
||||
infinite = true;
|
||||
}
|
||||
|
||||
void CollisionPolygon::updateCollision( int x, int y, int w, int h ) {
|
||||
void CollisionPolygon::updateCollision( int x, int y, int w, int h,
|
||||
uint64_t id ) {
|
||||
if ( _id == static_cast< uint64_t >( -1 ) )
|
||||
_id = id;
|
||||
position = Vec2D< int >( original.getX() * w + x, original.getY() * h + y );
|
||||
}
|
||||
|
||||
@ -34,6 +43,12 @@ void CollisionPolygon::setColor( const std::string &color ) {
|
||||
void CollisionPolygon::setOutlineColor( const std::string &color ) {
|
||||
sdl_outline = getSDLColorHEX( color );
|
||||
}
|
||||
void CollisionPolygon::setId( uint64_t id ) {
|
||||
_id = id;
|
||||
}
|
||||
uint64_t CollisionPolygon::getId() {
|
||||
return _id;
|
||||
}
|
||||
|
||||
bool infinityIntersection( const SDLPP::CollisionPolygon &infinite,
|
||||
const SDLPP::CollisionPolygon &other ) {
|
||||
|
@ -13,6 +13,8 @@ class SDLPPSCOPE CollisionPolygon {
|
||||
public:
|
||||
CollisionPolygon( double x, double y );
|
||||
CollisionPolygon( const Vec2D< double > &input );
|
||||
CollisionPolygon( double x, double y, uint64_t id );
|
||||
CollisionPolygon( const Vec2D< double > &input, uint64_t id );
|
||||
virtual ~CollisionPolygon() {}
|
||||
virtual bool colidesWith( const CollisionPolygon &other ) const = 0;
|
||||
virtual bool isCircle() const = 0;
|
||||
@ -22,7 +24,8 @@ public:
|
||||
virtual int bottommost() const = 0;
|
||||
virtual int leftmost() const = 0;
|
||||
virtual int rightmost() const = 0;
|
||||
virtual void updateCollision( int x, int y, int w, int h );
|
||||
virtual void updateCollision( int x, int y, int w, int h,
|
||||
uint64_t objectId );
|
||||
virtual void render( Renderer &renderer, const SDL_Color &color,
|
||||
const SDL_Color &outline_color ) = 0;
|
||||
virtual void render( Renderer &renderer, const SDL_Color &color ) = 0;
|
||||
@ -33,6 +36,8 @@ public:
|
||||
void setOutlineColor( const std::string &color );
|
||||
virtual std::shared_ptr< CollisionPolygon > copySelf() = 0;
|
||||
virtual std::vector< Line< int > > getLines() const = 0;
|
||||
uint64_t getId();
|
||||
void setId( uint64_t id );
|
||||
|
||||
protected:
|
||||
Vec2D< double > original;
|
||||
@ -40,6 +45,7 @@ protected:
|
||||
bool infinite = false;
|
||||
SDL_Color sdl_color = { 0, 0, 0, 0 };
|
||||
SDL_Color sdl_outline = { 0, 0, 0, 0 };
|
||||
uint64_t _id = -1;
|
||||
};
|
||||
|
||||
SDLPPSCOPE bool infinityIntersection( const SDLPP::CollisionPolygon &infinite,
|
||||
|
@ -94,7 +94,7 @@ void LineRenderer::updateSizeAndPosition() {
|
||||
std::round( current.getEnd().getY() * dimension ) ) );
|
||||
for ( auto &x : collisions ) {
|
||||
x->updateCollision( collisionPushX(), collisionPushY(),
|
||||
collisionWidth(), collisionHeight() );
|
||||
collisionWidth(), collisionHeight(), getId() );
|
||||
}
|
||||
}
|
||||
void LineRenderer::centerX() {
|
||||
|
@ -25,6 +25,15 @@ RectColider::RectColider( const Vec2D< double > &top_left,
|
||||
const Vec2D< double > &size )
|
||||
: CollisionPolygon( top_left ), _size( size ) {}
|
||||
|
||||
RectColider::RectColider( double x, double y, double w, double h, uint64_t id )
|
||||
: RectColider( { x, y }, { w, h }, id ) {}
|
||||
|
||||
RectColider::RectColider( const Vec2D< double > &top_left,
|
||||
const Vec2D< double > &size, uint64_t id )
|
||||
: RectColider( top_left, size ) {
|
||||
_id = id;
|
||||
}
|
||||
|
||||
bool RectColider::colidesWith( const SDLPP::CollisionPolygon &other ) const {
|
||||
if ( other.isCircle() ) {
|
||||
return other.colidesWith( *this );
|
||||
@ -57,9 +66,11 @@ int RectColider::rightmost() const {
|
||||
isInfinite() * -1;
|
||||
}
|
||||
|
||||
void RectColider::updateCollision( int x, int y, int w, int h ) {
|
||||
void RectColider::updateCollision( int x, int y, int w, int h, uint64_t id ) {
|
||||
position = Vec2D< int >( original.getX() * w + x, original.getY() * h + y );
|
||||
_size_pixel = Vec2D< int >( width() * w, height() * h );
|
||||
if ( _id == static_cast< uint64_t >( -1 ) )
|
||||
_id = id;
|
||||
}
|
||||
|
||||
void RectColider::render( Renderer &renderer, const SDL_Color &color,
|
||||
|
@ -14,6 +14,9 @@ class SDLPPSCOPE RectColider : public CollisionPolygon {
|
||||
public:
|
||||
RectColider( double x, double y, double w, double h );
|
||||
RectColider( const Vec2D< double > &top_left, const Vec2D< double > &size );
|
||||
RectColider( double x, double y, double w, double h, uint64_t id );
|
||||
RectColider( const Vec2D< double > &top_left, const Vec2D< double > &size,
|
||||
uint64_t id );
|
||||
virtual ~RectColider() {}
|
||||
virtual bool colidesWith( const CollisionPolygon &other ) const override;
|
||||
virtual bool isCircle() const override;
|
||||
@ -21,7 +24,8 @@ public:
|
||||
virtual int bottommost() const override;
|
||||
virtual int leftmost() const override;
|
||||
virtual int rightmost() const override;
|
||||
virtual void updateCollision( int x, int y, int w, int h ) override;
|
||||
virtual void updateCollision( int x, int y, int w, int h,
|
||||
uint64_t id ) override;
|
||||
virtual void render( Renderer &renderer, const SDL_Color &color,
|
||||
const SDL_Color &outline_color ) override;
|
||||
virtual void render( Renderer &renderer, const SDL_Color &color ) override;
|
||||
|
@ -93,7 +93,8 @@ void RectangleRender::setColor( const std::string &color ) {
|
||||
if ( !polygon ) {
|
||||
polygon = std::make_shared< RectColider >( 0, 0, 1, 1 );
|
||||
polygon->updateCollision( collisionPushX(), collisionPushY(),
|
||||
collisionWidth(), collisionHeight() );
|
||||
collisionWidth(), collisionHeight(),
|
||||
getId() );
|
||||
}
|
||||
polygon->setColor( color );
|
||||
}
|
||||
@ -101,7 +102,8 @@ void RectangleRender::setOutlineColor( const std::string &color ) {
|
||||
if ( !polygon ) {
|
||||
polygon = std::make_shared< RectColider >( 0, 0, 1, 1 );
|
||||
polygon->updateCollision( collisionPushX(), collisionPushY(),
|
||||
collisionWidth(), collisionHeight() );
|
||||
collisionWidth(), collisionHeight(),
|
||||
getId() );
|
||||
}
|
||||
polygon->setOutlineColor( color );
|
||||
}
|
||||
@ -146,10 +148,11 @@ void RectangleRender::updateSizeAndPosition() {
|
||||
rect.y;
|
||||
if ( polygon )
|
||||
polygon->updateCollision( collisionPushX(), collisionPushY(),
|
||||
collisionWidth(), collisionHeight() );
|
||||
collisionWidth(), collisionHeight(),
|
||||
getId() );
|
||||
for ( auto &x : collisions ) {
|
||||
x->updateCollision( collisionPushX(), collisionPushY(),
|
||||
collisionWidth(), collisionHeight() );
|
||||
collisionWidth(), collisionHeight(), getId() );
|
||||
}
|
||||
}
|
||||
SDL_Rect RectangleRender::getRect() {
|
||||
|
@ -22,6 +22,13 @@ Vec2D< int > Renderer::getDimensions() const {
|
||||
SDL_GetRendererOutputSize( renderer, &width, &height );
|
||||
return { width, height };
|
||||
}
|
||||
Vec2D< double > Renderer::getDoubleDimensions() const {
|
||||
auto dimensions = getDimensions();
|
||||
double smaller = dimensions.getX() < dimensions.getY() ? dimensions.getX()
|
||||
: dimensions.getY();
|
||||
return { static_cast< double >( dimensions.getX() ) / smaller,
|
||||
static_cast< double >( dimensions.getY() ) / smaller };
|
||||
}
|
||||
int Renderer::getWidth() const {
|
||||
return getDimensions().getX();
|
||||
}
|
||||
|
@ -24,6 +24,7 @@ public:
|
||||
bool getRenderColiders();
|
||||
void clearRenderer();
|
||||
void presentRenderer();
|
||||
Vec2D< double > getDoubleDimensions() const;
|
||||
|
||||
private:
|
||||
SDL_Renderer *renderer = NULL;
|
||||
|
@ -41,18 +41,20 @@ void RenderObject::setPos( const Vec2D< double > &vec ) {
|
||||
Vec2D< double > RenderObject::getPos() const {
|
||||
return original;
|
||||
}
|
||||
bool RenderObject::colidesWith( const RenderObject &other ) const {
|
||||
std::vector< uint64_t >
|
||||
RenderObject::colidesWith( const RenderObject &other ) const {
|
||||
if ( !hasCollisions() || !other.hasCollisions() || getHidden() ||
|
||||
other.getHidden() ) {
|
||||
return false;
|
||||
return {};
|
||||
}
|
||||
std::vector< uint64_t > ret = {};
|
||||
for ( const auto &x : collisions ) {
|
||||
for ( const auto &y : other.getCollisions() ) {
|
||||
if ( x->colidesWith( *y ) )
|
||||
return true;
|
||||
ret.push_back( x->getId() );
|
||||
}
|
||||
}
|
||||
return false;
|
||||
return ret;
|
||||
}
|
||||
bool RenderObject::hasCollisions() const {
|
||||
return !collisions.empty();
|
||||
|
@ -34,12 +34,12 @@ public:
|
||||
virtual void setPos( const std::pair< double, double > &pos );
|
||||
virtual void setPos( const Vec2D< double > &vec );
|
||||
virtual Vec2D< double > getPos() const;
|
||||
bool colidesWith( const RenderObject &other ) const;
|
||||
std::vector< uint64_t > colidesWith( const RenderObject &other ) const;
|
||||
template < class T > void addCollision( const T &p ) {
|
||||
collisions.push_back( std::make_shared< T >( p ) );
|
||||
collisions.back()->updateCollision( collisionPushX(), collisionPushY(),
|
||||
collisionWidth(),
|
||||
collisionHeight() );
|
||||
collisionWidth(), collisionHeight(),
|
||||
getId() );
|
||||
}
|
||||
bool hasCollisions() const;
|
||||
const std::vector< std::shared_ptr< CollisionPolygon > > &
|
||||
|
@ -20,11 +20,15 @@ void Scene::addObject( const std::shared_ptr< RenderObject > &obj ) {
|
||||
} else {
|
||||
auto rect = obj->getDoubleRect();
|
||||
auto leftmost_rect = leftmost_obj->getDoubleRect();
|
||||
if ( rect.first.getX() < leftmost_rect.first.getX() )
|
||||
if ( ( rect.first.getX() < leftmost_rect.first.getX() &&
|
||||
!obj->getPermanent() ) ||
|
||||
( leftmost_obj->getPermanent() && !obj->getPermanent() ) )
|
||||
leftmost_obj = obj;
|
||||
auto rightmost_rect = rightmost_obj->getDoubleRect();
|
||||
if ( rect.first.getX() + rect.second.getX() >
|
||||
rightmost_rect.first.getX() + rightmost_rect.second.getX() )
|
||||
if ( ( rect.first.getX() + rect.second.getX() >
|
||||
rightmost_rect.first.getX() + rightmost_rect.second.getX() &&
|
||||
!obj->getPermanent() ) ||
|
||||
( rightmost_obj->getPermanent() && !obj->getPermanent() ) )
|
||||
rightmost_obj = obj;
|
||||
}
|
||||
}
|
||||
@ -95,33 +99,35 @@ void Scene::updateScene() {
|
||||
}
|
||||
prev_ticks = now_ticks;
|
||||
}
|
||||
std::vector< std::shared_ptr< RenderObject > >
|
||||
std::vector< std::pair< uint64_t, std::shared_ptr< RenderObject > > >
|
||||
Scene::getCollisions( RenderObject &r ) {
|
||||
if ( r.getHidden() )
|
||||
return {};
|
||||
std::vector< std::shared_ptr< RenderObject > > ret{};
|
||||
std::vector< std::pair< uint64_t, std::shared_ptr< RenderObject > > > ret{};
|
||||
for ( const auto &x : collision_objects ) {
|
||||
if ( x->colidesWith( r ) ) {
|
||||
ret.push_back( x );
|
||||
for ( auto id : r.colidesWith( *x ) ) {
|
||||
ret.emplace_back( id, x );
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
void Scene::visitCollisions( RenderObject &r, Visitor &v ) {
|
||||
for ( auto &collision : getCollisions( r ) ) {
|
||||
collision->visit(v);
|
||||
v.fromId( collision.first );
|
||||
collision.second->visit( v );
|
||||
}
|
||||
}
|
||||
std::vector< std::shared_ptr< RenderObject > >
|
||||
std::vector< std::pair< uint64_t, std::shared_ptr< RenderObject > > >
|
||||
Scene::getCollisions( RenderObject &r,
|
||||
const std::unordered_set< int > &objectIDs ) {
|
||||
if ( r.getHidden() )
|
||||
return {};
|
||||
std::vector< std::shared_ptr< RenderObject > > ret{};
|
||||
std::vector< std::pair< uint64_t, std::shared_ptr< RenderObject > > > ret{};
|
||||
for ( const auto &x : collision_objects ) {
|
||||
if ( objectIDs.find( x->getId() ) != objectIDs.end() &&
|
||||
x->colidesWith( r ) ) {
|
||||
ret.push_back( x );
|
||||
if ( objectIDs.find( x->getId() ) != objectIDs.end() ) {
|
||||
for ( auto id : r.colidesWith( *x ) ) {
|
||||
ret.push_back( { id, x } );
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -154,7 +160,8 @@ void Scene::updateSizeAndPosition() {
|
||||
x->updateSizeAndPosition();
|
||||
for ( auto &col : x->getCollisions() ) {
|
||||
col->updateCollision( x->collisionPushX(), x->collisionPushY(),
|
||||
x->collisionWidth(), x->collisionHeight() );
|
||||
x->collisionWidth(), x->collisionHeight(),
|
||||
x->getId() );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -164,8 +171,7 @@ void Scene::moveEverything( double x, double y ) {
|
||||
for ( auto &obj : render_objects ) {
|
||||
if ( obj->getPermanent() )
|
||||
continue;
|
||||
auto curPos = obj->getDoubleRect();
|
||||
obj->setPos( curPos.first.getX() + x, curPos.first.getY() + y );
|
||||
obj->setPos( obj->getDoubleRect().first + Vec2D< double >( x, y ) );
|
||||
}
|
||||
}
|
||||
const std::shared_ptr< RenderObject > &Scene::leftmost() {
|
||||
|
@ -27,10 +27,10 @@ public:
|
||||
std::vector< std::shared_ptr< RenderObject > >
|
||||
getObjects( const std::unordered_set< int > &objectIDs );
|
||||
void updateScene();
|
||||
std::vector< std::shared_ptr< RenderObject > >
|
||||
std::vector< std::pair< uint64_t, std::shared_ptr< RenderObject > > >
|
||||
getCollisions( RenderObject &r );
|
||||
void visitCollisions( RenderObject &r, Visitor &v );
|
||||
std::vector< std::shared_ptr< RenderObject > >
|
||||
std::vector< std::pair< uint64_t, std::shared_ptr< RenderObject > > >
|
||||
getCollisions( RenderObject &r,
|
||||
const std::unordered_set< int > &objectIDs );
|
||||
void renderScene( bool clear_renderer = true );
|
||||
|
@ -11,6 +11,7 @@ class SDLPPSCOPE Visitor {
|
||||
public:
|
||||
Visitor() {}
|
||||
virtual void visit( const RenderObject &obj ) = 0;
|
||||
virtual void fromId( uint64_t id ) = 0;
|
||||
};
|
||||
|
||||
} // namespace SDLPP
|
||||
|
Loading…
Reference in New Issue
Block a user