Trying to switch to more object-oriented

This commit is contained in:
2021-03-12 22:33:46 +01:00
parent fbe122a5b9
commit 258ce51cfe
32 changed files with 693 additions and 249 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ RM = del
else
UNAME_S := $(shell uname -s)
CXX ?= g++
CXXFLAGS = -std=c++14 -Wall -Wextra -pedantic
CXXFLAGS = -std=c++14 -Wall -Wextra -pedantic -g
OBJEXT = o
endif
+4
View File
@@ -17,4 +17,8 @@
#include "sdlpp_texture.hpp"
#include "sdlpp_window.hpp"
#include "sdlpp_line.hpp"
#include "sdlpp_vector.hpp"
#include "sdlpp_geometry.hpp"
#endif
+5 -5
View File
@@ -2,9 +2,10 @@
namespace SDLPP {
CircleColider::CircleColider( double x, double y, double rad )
: CollisionPolygon( x, y ) {
original_rad = rad;
}
: CircleColider( {x, y}, rad ) {};
CircleColider::CircleColider( const Vec2D< double > &center, double rad )
: CollisionPolygon( center ), original_rad( rad ) {}
bool CircleColider::colidesWith( const SDLPP::CollisionPolygon &other ) const {
if ( other.isCircle() ) {
@@ -60,8 +61,7 @@ int CircleColider::rightmost() const {
}
void CircleColider::updateCollision( int x, int y, int w, int h ) {
position_x = original_x * w + x;
position_y = original_y * h + y;
position = Vec2D<int> ( original.getX() * w + x, original.getY() * h + y );
rad_ = original_rad * w;
}
+1
View File
@@ -10,6 +10,7 @@ namespace SDLPP {
class SDLPPSCOPE CircleColider : public CollisionPolygon {
public:
CircleColider( double x, double y, double rad );
CircleColider( const Vec2D<double> &center, double rad );
virtual ~CircleColider() {}
virtual bool colidesWith( const CollisionPolygon &other ) const override;
+41 -27
View File
@@ -6,28 +6,41 @@
namespace SDLPP {
CircleRender::CircleRender( double x, double y, double rad,
std::shared_ptr< Renderer > &r )
: RenderObject( r ) {
og_x = x_ = x;
og_y = y_ = y;
og_r = r_ = rad;
}
: CircleRender( { x, y }, rad, r ) {}
CircleRender::CircleRender( double x, double y, double rad,
std::shared_ptr< Renderer > &r,
std::shared_ptr< Texture > &t )
: CircleRender( x, y, rad, r ) {
throw "I don't support textures yet!!!";
}
: CircleRender( { x, y }, rad, r, t ) {}
CircleRender::CircleRender( double x, double y, double rad,
std::shared_ptr< Renderer > &r,
const std::string &img_or_color,
bool is_polygon )
: CircleRender( x, y, rad, r ) {
if(!is_polygon) {
const std::string &img_or_color, bool is_polygon )
: CircleRender( { x, y }, rad, r, img_or_color, is_polygon ) {}
CircleRender::CircleRender( Vec2D< double > center, double rad,
std::shared_ptr< Renderer > &r )
: RenderObject( r ) {
original = center;
current = center;
og_r = r_ = rad;
}
CircleRender::CircleRender( Vec2D< double > center, double rad,
std::shared_ptr< Renderer > &r,
std::shared_ptr< Texture > &t )
: CircleRender( center, rad, r ) {
throw "I don't support textures yet!!!";
}
CircleRender::CircleRender( Vec2D< double > center, double rad,
std::shared_ptr< Renderer > &r,
const std::string &img_or_color, bool is_polygon )
: CircleRender( center, rad, r ) {
if ( !is_polygon ) {
throw "I don't support textures yet!!!";
} else {
setColor(img_or_color);
setColor( img_or_color );
color = img_or_color;
}
}
@@ -50,9 +63,9 @@ void CircleRender::setOutlineColor( const std::string &color ) {
polygon->setOutlineColor( color );
}
std::pair< std::pair< double, double >, std::pair< double, double > >
std::pair< Vec2D<double>, Vec2D<double> >
CircleRender::getDoubleRect() const {
return { { og_x - og_r, og_y - og_r }, { 2 * og_r, 2 * og_r } };
return { { original.getX() - og_r, original.getY() - og_r }, { 2 * og_r, 2 * og_r } };
}
int CircleRender::leftmost() {
@@ -90,10 +103,10 @@ int CircleRender::collisionHeight() {
void CircleRender::updateSizeAndPosition() {
updateXY();
auto dimension = renderer->getSmallerSide();
rect.x = std::round( (x_ - r_) * dimension );
rect.y = std::round( (y_ - r_) * dimension );
rect.w = std::round( ( x_ + r_ ) * dimension ) - rect.x;
rect.h = std::round( ( y_ + r_ ) * dimension ) - rect.y;
rect.x = std::round( ( current.getX() - r_ ) * dimension );
rect.y = std::round( ( current.getY() - r_ ) * dimension );
rect.w = std::round( ( current.getX() + r_ ) * dimension ) - rect.x;
rect.h = std::round( ( current.getY() + r_ ) * dimension ) - rect.y;
if ( polygon )
polygon->updateCollision( collisionPushX(), collisionPushY(),
collisionWidth(), collisionHeight() );
@@ -114,12 +127,12 @@ void CircleRender::centerX() {
std::shared_ptr< RenderObject > CircleRender::copySelf() {
auto ret = std::make_shared< CircleRender >( *this );
copyTo(ret);
copyTo( ret );
return ret;
}
void CircleRender::copyTo(std::shared_ptr<RenderObject> other) {
RenderObject::copyTo(other);
void CircleRender::copyTo( std::shared_ptr< RenderObject > other ) {
RenderObject::copyTo( other );
}
std::string CircleRender::getColor() const {
@@ -128,19 +141,20 @@ std::string CircleRender::getColor() const {
void CircleRender::updateXY() {
if ( !centerx ) {
x_ = og_x;
y_ = og_y;
current = original;
return;
}
auto width = renderer->getWidth();
auto height = renderer->getHeight();
double x_, y_;
if ( width > height ) {
auto multiplier =
static_cast< double >( width ) / static_cast< double >( height );
x_ = og_x + static_cast< double >( multiplier - 1 ) / 2;
x_ = original.getX() + static_cast< double >( multiplier - 1 ) / 2;
} else {
x_ = og_x;
x_ = original.getX();
}
y_ = og_y;
y_ = original.getY();
current = { x_, y_ };
}
} // namespace SDLPP
+7 -2
View File
@@ -16,12 +16,17 @@ public:
std::shared_ptr< Texture > &t );
CircleRender( double x, double y, double rad, std::shared_ptr< Renderer > &r,
const std::string &img_or_color, bool is_polygon = false );
CircleRender( Vec2D<double> center, double rad, std::shared_ptr< Renderer > &r );
CircleRender( Vec2D<double> center, double rad, std::shared_ptr< Renderer > &r,
std::shared_ptr< Texture > &t );
CircleRender( Vec2D<double> center, double rad, std::shared_ptr< Renderer > &r,
const std::string &img_or_color, bool is_polygon = false );
virtual void setColor( const std::string &color ) override;
virtual void setOutlineColor( const std::string &color ) override;
virtual void specialAction( int /*UNUSED*/ ) override{}
virtual void custom_move( int /*UNUSED*/ ) override{}
virtual std::pair< std::pair< double, double >,
std::pair< double, double > >
virtual std::pair< Vec2D<double>, Vec2D<double> >
getDoubleRect() const override;
virtual int leftmost() override;
virtual int topmost() override;
+9 -9
View File
@@ -1,11 +1,12 @@
#include "sdlpp_collision.hpp"
namespace SDLPP {
CollisionPolygon::CollisionPolygon( double x, double y ) {
original_x = x;
original_y = y;
position_x = 0;
position_y = 0;
CollisionPolygon::CollisionPolygon( double x, double y )
: CollisionPolygon( Vec2D<double>( x, y ) ) {}
CollisionPolygon::CollisionPolygon( const Vec2D< double > &input ) {
original = input;
position = { 0, 0 };
}
bool CollisionPolygon::isInfinite() const {
@@ -16,15 +17,14 @@ void CollisionPolygon::setInfinite() {
}
void CollisionPolygon::updateCollision( int x, int y, int w, int h ) {
position_x = original_x * w + x;
position_y = original_y * h + y;
position = Vec2D< int >( original.getX() * w + x, original.getY() * h + y );
}
int CollisionPolygon::getX() const {
return position_x;
return position.getX();
}
int CollisionPolygon::getY() const {
return position_y;
return position.getY();
}
void CollisionPolygon::setColor( const std::string &color ) {
+5 -5
View File
@@ -3,12 +3,14 @@
#include "sdlpp_common.hpp"
#include "sdlpp_renderer.hpp"
#include "sdlpp_vector.hpp"
#include <memory>
namespace SDLPP {
class SDLPPSCOPE CollisionPolygon {
public:
CollisionPolygon( double x, double y );
CollisionPolygon( const Vec2D<double> &input );
virtual ~CollisionPolygon() {}
virtual bool colidesWith( const CollisionPolygon &other ) const = 0;
virtual bool isCircle() const = 0;
@@ -26,13 +28,11 @@ public:
int getY() const;
void setColor( const std::string &color );
void setOutlineColor( const std::string &color );
virtual std::shared_ptr<CollisionPolygon> copySelf() = 0;
virtual std::shared_ptr< CollisionPolygon > copySelf() = 0;
protected:
double original_x;
double original_y;
int position_x;
int position_y;
Vec2D<double> original;
Vec2D<int> position;
bool infinite = false;
SDL_Color sdl_color = { 0, 0, 0, 0 };
SDL_Color sdl_outline = { 0, 0, 0, 0 };
+7
View File
@@ -0,0 +1,7 @@
#ifndef SDLPP_HPP_GEOMETRY
#define SDLPP_HPP_GEOMETRY
#include "sdlpp_geometry_vector.hpp"
#include "sdlpp_geometry_line.hpp"
#endif
+30
View File
@@ -0,0 +1,30 @@
#ifndef SDLPP_HPP_GEOMETRY_LINE
#define SDLPP_HPP_GEOMETRY_LINE
#include "sdlpp_common.hpp"
#include "sdlpp_vector.hpp"
#include "sdlpp_line.hpp"
#include <algorithm>
namespace SDLPP {
template<typename T>
Vec2D<T> pointProjectionOnLine( const Vec2D<T> &point, const Line<T> &line ) {
/* from here -
* https://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
*/
auto length_squared = line.lengthSquared();
if ( length_squared == 0.0 )
return point;
auto t =
std::max( 0.0, std::min( 1.0, ( ( point - line.getStart() ) *
( line.getEnd() - line.getStart() ) ) /
length_squared ) );
return line.getStart() + t * ( line.getEnd() - line.getStart() );
}
template<typename T>
double pointLineDistance( const Vec2D<T> &point, const Line<T> &line ) {
return vecDistance( point, pointProjectionOnLine( point, line ) );
}
} // namespace SDLPP
#endif
+31
View File
@@ -0,0 +1,31 @@
#ifndef SDLPP_HPP_GEOMETRY_VECTOR
#define SDLPP_HPP_GEOMETRY_VECTOR
#include "sdlpp_common.hpp"
#include "sdlpp_vector.hpp"
#include <cmath>
namespace SDLPP {
template<typename T>
double vecDotProduct( const Vec2D<T> &a, const Vec2D<T> &b ) {
return a * b;
}
template<typename T>
double vecLengthSquared( const Vec2D<T> &vec ) {
return vecDotProduct( vec, vec );
}
template<typename T>
double vecLength( const Vec2D<T> &vec ) {
return std::sqrt( vecLengthSquared( vec ) );
}
template<typename T>
double vecDistanceSquared( const Vec2D<T> &a, const Vec2D<T> &b ) {
return vecLengthSquared( a - b );
}
template<typename T>
double vecDistance( const Vec2D<T> &a, const Vec2D<T> &b ) {
return vecLength( a - b );
}
} // namespace SDLPP
#endif
+52
View File
@@ -0,0 +1,52 @@
#ifndef SDLPP_HPP_LINE
#define SDLPP_HPP_LINE
#include "sdlpp_common.hpp"
#include "sdlpp_vector.hpp"
namespace SDLPP {
template<typename T>
class SDLPPSCOPE Line {
public:
Line() = delete;
~Line() = default;
Line( const Vec2D<T> &start, const Vec2D<T> &end )
: _start( start ), _end( end ) {}
Line( T x_1, T y_1, T x_2, T y_2 )
: _start( { x_1, y_1 } ), _end( { x_2, y_2 } ) {}
Line( const Vec2D<T> &start, const Vec2D<T> &end, bool infinite )
: _start( start ), _end( end ), _infinite( infinite ) {}
Line( T x_1, T y_1, T x_2, T y_2, bool infinite )
: _start( { x_1, y_1 } ), _end( { x_2, y_2 } ),
_infinite( infinite ) {}
const Vec2D<T> &getStart() const {
return _start;
}
const Vec2D<T> &getEnd() const {
return _end;
}
double length() const {
return vecDistance( _start, _end );
}
double lengthSquared() const {
return vecDistanceSquared( _start, _end );
}
void setInfinite( bool infinite ) {
_infinite = infinite;
}
bool isInfinite() {
return _infinite;
}
void add(const Vec2D<T> &vec) {
_start += vec;
_end += vec;
}
private:
Vec2D<T> _start;
Vec2D<T> _end;
bool _infinite = false;
};
} // namespace SDLPP
#endif
+56 -45
View File
@@ -4,17 +4,21 @@
namespace SDLPP {
LineRenderer::LineRenderer( double x1, double y1, double x2, double y2,
const std::shared_ptr< Renderer > &r )
: RenderObject( r ) {
og_x1 = x1_ = x1;
og_y1 = y1_ = y1;
og_x2 = x2_ = x2;
og_y2 = y2_ = y2;
updateSizeAndPosition();
}
: LineRenderer( { { x1, y1 }, { x2, y2 } }, r ) {}
LineRenderer::LineRenderer( double x1, double y1, double x2, double y2,
const std::shared_ptr< Renderer > &r,
const std::string &color )
: LineRenderer( x1, y1, x2, y2, r ) {
: LineRenderer( { { x1, y1 }, { x2, y2 } }, r, color ) {}
LineRenderer::LineRenderer( const Line< double > &line,
const std::shared_ptr< Renderer > &r )
: RenderObject( r ) {
original = current = line;
updateSizeAndPosition();
}
LineRenderer::LineRenderer( const Line< double > &line,
const std::shared_ptr< Renderer > &r,
const std::string &color )
: LineRenderer( line, r ) {
setColor( color );
}
void LineRenderer::setColor( const std::string &color ) {
@@ -26,8 +30,10 @@ void LineRenderer::render() {
renderer->getRendererPtr(), std::get< 0 >( _color ),
std::get< 1 >( _color ), std::get< 2 >( _color ),
std::get< 3 >( _color ) );
SDL_RenderDrawLine( renderer->getRendererPtr(), pixel_x1, pixel_y1,
pixel_x2, pixel_y2 );
SDL_RenderDrawLine(
renderer->getRendererPtr(), pixel_line.getStart().getX(),
pixel_line.getStart().getY(), pixel_line.getEnd().getX(),
pixel_line.getEnd().getY() );
}
if ( hasCollisions() && renderer->getRenderColiders() && !getHidden() ) {
for ( const auto &col : getCollisions() )
@@ -46,41 +52,46 @@ void LineRenderer::move( int ticks ) {
if ( std::isnan( addx ) || std::isnan( addy ) )
return;
og_x1 += addx;
og_x2 += addx;
og_y1 += addy;
og_y2 += addy;
original.add( { addx, addy } );
custom_move( ticks );
updateSizeAndPosition();
}
void LineRenderer::setPos( double x, double y ) {
auto diffx = og_x2 - og_x1;
auto diffy = og_y2 - og_y1;
og_x1 = x;
og_y1 = y;
og_x2 = og_x1 + diffx;
og_y2 = og_y1 + diffy;
auto diffx = original.getEnd().getX() - original.getStart().getX();
auto diffy = original.getEnd().getY() - original.getStart().getY();
original = { { x, y }, { x + diffx, y + diffy } };
updateSizeAndPosition();
}
void LineRenderer::setPos( const std::pair< double, double > &pos ) {
setPos( pos.first, pos.second );
}
std::pair< double, double > LineRenderer::getPos() const {
return { og_x1, og_y1 };
void LineRenderer::setPos( const Vec2D<double> &vec ) {
setPos( vec.getX(), vec.getY() );
}
Vec2D< double > LineRenderer::getPos() const {
return original.getStart();
}
int LineRenderer::leftmost() {
return pixel_x1 < pixel_x2 ? pixel_x1 : pixel_x2;
return pixel_line.getStart().getX() < pixel_line.getEnd().getX()
? pixel_line.getStart().getX()
: pixel_line.getEnd().getX();
}
int LineRenderer::topmost() {
return pixel_y1 < pixel_y2 ? pixel_y1 : pixel_y2;
return pixel_line.getStart().getY() < pixel_line.getEnd().getY()
? pixel_line.getStart().getY()
: pixel_line.getEnd().getY();
}
int LineRenderer::rightmost() {
return pixel_x1 > pixel_x2 ? pixel_x1 : pixel_x2;
return pixel_line.getStart().getX() > pixel_line.getEnd().getX()
? pixel_line.getStart().getX()
: pixel_line.getEnd().getX();
}
int LineRenderer::bottommost() {
return pixel_y1 > pixel_y2 ? pixel_y1 : pixel_y2;
return pixel_line.getStart().getY() > pixel_line.getEnd().getY()
? pixel_line.getStart().getY()
: pixel_line.getEnd().getY();
}
int LineRenderer::collisionPushX() {
return leftmost();
@@ -97,10 +108,11 @@ int LineRenderer::collisionHeight() {
void LineRenderer::updateSizeAndPosition() {
updateXY();
auto dimension = renderer->getSmallerSide();
pixel_x1 = std::round( x1_ * dimension );
pixel_x2 = std::round( x2_ * dimension );
pixel_y1 = std::round( y1_ * dimension );
pixel_y2 = std::round( y2_ * dimension );
pixel_line = Line< int >(
Vec2D< int >( std::round( current.getStart().getX() * dimension ),
std::round( current.getStart().getY() * dimension ) ),
Vec2D< int >( std::round( current.getEnd().getX() * dimension ),
std::round( current.getEnd().getY() * dimension ) ) );
for ( auto &x : collisions ) {
x->updateCollision( collisionPushX(), collisionPushY(),
collisionWidth(), collisionHeight() );
@@ -112,42 +124,41 @@ void LineRenderer::centerX() {
}
std::shared_ptr< RenderObject > LineRenderer::copySelf() {
auto ret = std::make_shared< LineRenderer >( *this );
copyTo(ret);
copyTo( ret );
return ret;
}
void LineRenderer::copyTo(std::shared_ptr<RenderObject> other) {
RenderObject::copyTo(other);
void LineRenderer::copyTo( std::shared_ptr< RenderObject > other ) {
RenderObject::copyTo( other );
}
SDL_Rect LineRenderer::getRect() {
return { leftmost(), topmost(), rightmost() - leftmost(),
bottommost() - topmost() };
}
std::pair< std::pair< double, double >, std::pair< double, double > >
std::pair< Vec2D<double>, Vec2D<double> >
LineRenderer::getDoubleRect() const {
return { { og_x1, og_y1 }, { og_x2 - og_x1, og_y2 - og_y1 } };
return { original.getStart(), original.getEnd() - original.getStart() };
}
void LineRenderer::updateXY() {
if ( !centerx ) {
x1_ = og_x1;
y1_ = og_y1;
x2_ = og_x2;
y2_ = og_y2;
current = original;
return;
}
auto width = renderer->getWidth();
auto height = renderer->getHeight();
double x1_, x2_, y1_, y2_;
if ( width > height ) {
auto multiplier =
static_cast< double >( width ) / static_cast< double >( height );
x1_ = og_x1 + static_cast< double >( multiplier - 1 ) / 2;
x2_ = og_x2 + static_cast< double >( multiplier - 1 ) / 2;
x1_ = original.getStart().getX() + static_cast< double >( multiplier - 1 ) / 2;
x2_ = original.getEnd().getX() + static_cast< double >( multiplier - 1 ) / 2;
} else {
x1_ = og_x1;
x2_ = og_x2;
x1_ = original.getStart().getX();
x2_ = original.getEnd().getX();
}
y1_ = og_y1;
y2_ = og_y2;
y1_ = original.getStart().getY();
y2_ = original.getEnd().getY();
current = {{x1_, y1_}, {x2_, y2_}};
}
} // namespace SDLPP
+13 -15
View File
@@ -2,7 +2,9 @@
#define SDLPP_HPP_LINE_RENDERER
#include "sdlpp_common.hpp"
#include "sdlpp_line.hpp"
#include "sdlpp_renderobject.hpp"
#include "sdlpp_vector.hpp"
namespace SDLPP {
class SDLPPSCOPE LineRenderer : public RenderObject {
@@ -14,6 +16,11 @@ public:
LineRenderer( double x1, double y1, double x2, double y2,
const std::shared_ptr< Renderer > &r,
const std::string &color );
LineRenderer( const Line<double> &line,
const std::shared_ptr< Renderer > &r );
LineRenderer( const Line<double> &line,
const std::shared_ptr< Renderer > &r,
const std::string &color );
virtual void setColor( const std::string &color ) override;
virtual void specialAction( int /*UNUSED*/ ) override{};
virtual void render() override;
@@ -21,7 +28,8 @@ public:
virtual void custom_move( int /*UNUSED*/ ) override {}
virtual void setPos( double x, double y ) override;
virtual void setPos( const std::pair< double, double > &pos ) override;
virtual std::pair< double, double > getPos() const override;
virtual void setPos( const Vec2D<double> &vec ) override;
virtual Vec2D<double> getPos() const override;
virtual int leftmost() override;
virtual int topmost() override;
virtual int rightmost() override;
@@ -35,26 +43,16 @@ public:
virtual std::shared_ptr< RenderObject > copySelf() override;
virtual SDL_Rect getRect() override;
virtual std::pair< std::pair< double, double >,
std::pair< double, double > >
virtual std::pair< Vec2D<double>, Vec2D<double>>
getDoubleRect() const override;
void setOutlineColor( const std::string & /*UNUSED*/ ) override {}
protected:
virtual void copyTo(std::shared_ptr<RenderObject> other) override;
void updateXY();
double og_x1;
double og_y1;
double x1_;
double y1_;
double og_x2;
double og_y2;
double x2_;
double y2_;
int pixel_x1{};
int pixel_y1{};
int pixel_x2{};
int pixel_y2{};
Line<double> original = {{0, 0}, {0, 0}};
Line<double> current = {{0, 0}, {0, 0}};
Line<int> pixel_line = {{0, 0}, {0, 0}};
bool centerx = false;
std::tuple< int, int, int, int > _color;
};
+44 -15
View File
@@ -1,12 +1,30 @@
#include "sdlpp_rectcolider.hpp"
namespace SDLPP {
RectColider::RectColider( double x, double y, double w, double h )
: CollisionPolygon( x, y ) {
w_ = w;
h_ = h;
double RectColider::width() const {
return _size.getX();
}
double RectColider::height() const {
return _size.getY();
}
int RectColider::pixel_width() const {
return _size_pixel.getX();
}
int RectColider::pixel_height() const {
return _size_pixel.getY();
}
RectColider::RectColider( double x, double y, double w, double h )
: RectColider( { x, y }, { w, h } ) {}
RectColider::RectColider( const Vec2D< double > &top_left,
const Vec2D< double > &size )
: CollisionPolygon( top_left ), _size( size ) {}
bool RectColider::colidesWith( const SDLPP::CollisionPolygon &other ) const {
if ( other.isCircle() ) {
return other.colidesWith( *this );
@@ -23,25 +41,25 @@ bool RectColider::isCircle() const {
return false;
}
int RectColider::topmost() const {
return ( !isInfinite() || original_y != -1 ) * getY() + isInfinite() * -1;
return ( !isInfinite() || original.getY() != -1 ) * getY() +
isInfinite() * -1;
}
int RectColider::bottommost() const {
return ( !isInfinite() || h_ != -1 ) * ( getY() + pixel_h ) +
return ( !isInfinite() || height() != -1 ) * ( getY() + pixel_height() ) +
isInfinite() * -1;
}
int RectColider::leftmost() const {
return ( !isInfinite() || original_x != -1 ) * getX() + isInfinite() * -1;
return ( !isInfinite() || original.getX() != -1 ) * getX() +
isInfinite() * -1;
}
int RectColider::rightmost() const {
return ( !isInfinite() || w_ != -1 ) * ( getX() + pixel_w ) +
return ( !isInfinite() || width() != -1 ) * ( getX() + pixel_width() ) +
isInfinite() * -1;
}
void RectColider::updateCollision( int x, int y, int w, int h ) {
position_x = original_x * w + x;
position_y = original_y * h + y;
pixel_w = w_ * w;
pixel_h = h_ * h;
position = Vec2D< int >( original.getX() * w + x, original.getY() * h + y );
_size_pixel = Vec2D< int >( width() * w, height() * h );
}
void RectColider::render( Renderer &renderer,
@@ -71,7 +89,7 @@ void RectColider::render( Renderer &renderer ) {
SDL_Rect RectColider::getRect() {
if ( !isInfinite() )
return { leftmost(), topmost(), pixel_w, pixel_h };
return { leftmost(), topmost(), pixel_width(), pixel_height() };
SDL_Rect r = { 0, 0, 0, 0 };
if ( ( r.x = leftmost() ) == -1 )
@@ -81,11 +99,11 @@ SDL_Rect RectColider::getRect() {
if ( rightmost() == -1 )
r.w = std::numeric_limits< int >::max();
else
r.w = pixel_w;
r.w = pixel_width();
if ( bottommost() == -1 )
r.h = std::numeric_limits< int >::max();
else
r.h = pixel_h;
r.h = pixel_height();
return r;
}
@@ -93,4 +111,15 @@ std::shared_ptr< CollisionPolygon > RectColider::copySelf() {
return std::make_shared< RectColider >( *this );
}
std::vector< Line< double > > RectColider::getLines() {
std::vector< Line< double > > ret{};
ret.emplace_back( original, original + Vec2D< double >( width(), 0 ) );
ret.emplace_back( original + Vec2D< double >( width(), 0 ),
original + _size );
ret.emplace_back( original, original + Vec2D< double >( 0, height() ) );
ret.emplace_back( original + Vec2D< double >( 0, height() ),
original + _size );
return ret;
}
} // namespace SDLPP
+12 -4
View File
@@ -3,13 +3,17 @@
#include "sdlpp_common.hpp"
#include "sdlpp_collision.hpp"
#include "sdlpp_vector.hpp"
#include "sdlpp_line.hpp"
#include <limits>
#include <vector>
namespace SDLPP {
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 );
virtual ~RectColider() {}
virtual bool colidesWith( const CollisionPolygon &other ) const override;
virtual bool isCircle() const override;
@@ -23,14 +27,18 @@ public:
const std::tuple< int, int, int, int > &color ) override;
virtual void render( Renderer &renderer ) override;
virtual std::shared_ptr<CollisionPolygon> copySelf() override;
virtual std::vector<Line<double>> getLines();
private:
SDL_Rect getRect();
double w_;
double h_;
int pixel_w;
int pixel_h;
double width() const;
double height() const;
int pixel_width() const;
int pixel_height() const;
Vec2D<double> _size;
Vec2D<int> _size_pixel;
};
} // end of namespace SDLPP
#endif
+68 -29
View File
@@ -4,33 +4,67 @@
namespace SDLPP {
RectangleRender::RectangleRender( double x, double y, double w, double h,
const std::shared_ptr< Renderer > &r )
: RenderObject( r ) {
og_x = x_ = x;
og_y = y_ = y;
og_w = w_ = w;
og_h = h_ = h;
updateSizeAndPosition();
}
: RectangleRender( { x, y }, { w, h }, r ) {}
RectangleRender::RectangleRender( double x, double y, double w, double h,
const std::shared_ptr< Renderer > &r,
const std::shared_ptr< Texture > &t,
int source_x, int source_y, int source_width,
int source_height )
: RectangleRender( x, y, w, h, r ) {
setTexture( t, source_x, source_y, source_width, source_height );
}
: RectangleRender( { x, y }, { w, h }, r, t, source_x, source_y,
source_width, source_height ) {}
RectangleRender::RectangleRender( double x, double y, double w, double h,
const std::shared_ptr< Renderer > &r,
const std::shared_ptr< Texture > &t,
const SDL_Rect &source_rect )
: RectangleRender( x, y, w, h, r ) {
setTexture( t, source_rect );
}
: RectangleRender( { x, y }, { w, h }, r, t, source_rect ) {}
RectangleRender::RectangleRender( double x, double y, double w, double h,
const std::shared_ptr< Renderer > &r,
const std::string &img_or_color,
bool is_polygon )
: RectangleRender( x, y, w, h, r ) {
: RectangleRender( { x, y }, { w, h }, r, img_or_color, is_polygon ) {}
RectangleRender::RectangleRender( double x, double y, double w, double h,
const std::shared_ptr< Renderer > &r,
const std::string &img, int source_x,
int source_y, int source_width,
int source_height )
: RectangleRender( { x, y }, { w, h }, r, img, source_x, source_y,
source_width, source_height ) {}
RectangleRender::RectangleRender( double x, double y, double w, double h,
const std::shared_ptr< Renderer > &r,
const std::string &img,
const SDL_Rect &source_rect )
: RectangleRender( { x, y }, { w, h }, r, img, source_rect ) {}
RectangleRender::RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r )
: RenderObject( r ) {
original = top_left;
original_size = size;
updateSizeAndPosition();
}
RectangleRender::RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::shared_ptr< Texture > &t,
int source_x, int source_y, int source_width,
int source_height )
: RectangleRender( top_left, size, r ) {
setTexture( t, source_x, source_y, source_width, source_height );
}
RectangleRender::RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::shared_ptr< Texture > &t,
const SDL_Rect &source_rect )
: RectangleRender( top_left, size, r ) {
setTexture( t, source_rect );
}
RectangleRender::RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::string &img_or_color,
bool is_polygon )
: RectangleRender( top_left, size, r ) {
if ( !is_polygon ) {
setTexture( img_or_color );
} else {
@@ -38,19 +72,21 @@ RectangleRender::RectangleRender( double x, double y, double w, double h,
color = img_or_color;
}
}
RectangleRender::RectangleRender( double x, double y, double w, double h,
RectangleRender::RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::string &img, int source_x,
int source_y, int source_width,
int source_height )
: RectangleRender( x, y, w, h, r ) {
: RectangleRender( top_left, size, r ) {
setTexture( img, source_x, source_y, source_width, source_height );
}
RectangleRender::RectangleRender( double x, double y, double w, double h,
RectangleRender::RectangleRender( const Vec2D< double > &top_left,
const Vec2D< double > &size,
const std::shared_ptr< Renderer > &r,
const std::string &img,
const SDL_Rect &source_rect )
: RectangleRender( x, y, w, h, r ) {
: RectangleRender( top_left, size, r ) {
setTexture( img, source_rect );
}
void RectangleRender::setColor( const std::string &color ) {
@@ -69,9 +105,9 @@ void RectangleRender::setOutlineColor( const std::string &color ) {
}
polygon->setOutlineColor( color );
}
std::pair< std::pair< double, double >, std::pair< double, double > >
std::pair< Vec2D< double >, Vec2D< double > >
RectangleRender::getDoubleRect() const {
return { { og_x, og_y }, { og_w, og_h } };
return { original, original_size };
}
int RectangleRender::leftmost() {
return rect.x;
@@ -100,10 +136,12 @@ int RectangleRender::collisionHeight() {
void RectangleRender::updateSizeAndPosition() {
updateXY();
auto dimension = renderer->getSmallerSide();
rect.x = std::round( x_ * dimension );
rect.y = std::round( y_ * dimension );
rect.w = std::round( ( x_ + w_ ) * dimension ) - rect.x;
rect.h = std::round( ( y_ + h_ ) * dimension ) - rect.y;
rect.x = std::round( current.getX() * dimension );
rect.y = std::round( current.getY() * dimension );
rect.w =
std::round( ( current.getX() + original_size.getX() ) * dimension ) - rect.x;
rect.h =
std::round( ( current.getY() + original_size.getY() ) * dimension ) - rect.y;
if ( polygon )
polygon->updateCollision( collisionPushX(), collisionPushY(),
collisionWidth(), collisionHeight() );
@@ -133,19 +171,20 @@ std::string RectangleRender::getColor() const {
void RectangleRender::updateXY() {
if ( !centerx ) {
x_ = og_x;
y_ = og_y;
current = original;
return;
}
auto width = renderer->getWidth();
auto height = renderer->getHeight();
double x_, y_;
if ( width > height ) {
auto multiplier =
static_cast< double >( width ) / static_cast< double >( height );
x_ = og_x + static_cast< double >( multiplier - 1 ) / 2;
x_ = original.getX() + static_cast< double >( multiplier - 1 ) / 2;
} else {
x_ = og_x;
x_ = original.getX();
}
y_ = og_y;
y_ = original.getY();
current = { x_, y_ };
}
} // namespace SDLPP
+24 -7
View File
@@ -31,13 +31,32 @@ public:
RectangleRender( double x, double y, double w, double h,
const std::shared_ptr< Renderer > &r,
const std::string &img, const SDL_Rect &source_rect );
RectangleRender( const Vec2D<double> &top_left, const Vec2D<double> &size,
const std::shared_ptr< Renderer > &r );
RectangleRender( const Vec2D<double> &top_left, const Vec2D<double> &size,
const std::shared_ptr< Renderer > &r,
const std::shared_ptr< Texture > &t, int source_x,
int source_y, int source_width, int source_height );
RectangleRender( const Vec2D<double> &top_left, const Vec2D<double> &size,
const std::shared_ptr< Renderer > &r,
const std::shared_ptr< Texture > &t,
const SDL_Rect &source_rect = { -1, -1, -1, -1 } );
RectangleRender( const Vec2D<double> &top_left, const Vec2D<double> &size,
const std::shared_ptr< Renderer > &r,
const std::string &img_or_color, bool is_polygon = false );
RectangleRender( const Vec2D<double> &top_left, const Vec2D<double> &size,
const std::shared_ptr< Renderer > &r,
const std::string &img, int source_x, int source_y,
int source_width, int source_height );
RectangleRender( const Vec2D<double> &top_left, const Vec2D<double> &size,
const std::shared_ptr< Renderer > &r,
const std::string &img, const SDL_Rect &source_rect );
virtual void setColor( const std::string &color ) override;
virtual void setOutlineColor( const std::string &color ) override;
virtual void specialAction( int /*UNUSED*/ ) override {}
virtual void custom_move( int /*UNUSED*/ ) override {}
virtual std::pair< std::pair< double, double >,
std::pair< double, double > >
getDoubleRect() const override;
virtual std::pair< Vec2D<double>, Vec2D<double> > getDoubleRect() const override;
virtual int leftmost() override;
virtual int topmost() override;
virtual int rightmost() override;
@@ -55,10 +74,8 @@ public:
protected:
virtual void copyTo( std::shared_ptr< RenderObject > other ) override;
void updateXY();
double og_w;
double og_h;
double w_;
double h_;
Vec2D<double> original_size;
Vec2D<double> size;
std::string color = "";
};
} // end of namespace SDLPP
+7 -6
View File
@@ -28,15 +28,17 @@ void RenderObject::render() {
}
}
void RenderObject::setPos( double x, double y ) {
og_x = x;
og_y = y;
original = { x, y };
updateSizeAndPosition();
}
void RenderObject::setPos( const std::pair< double, double > &pos ) {
setPos( pos.first, pos.second );
}
std::pair< double, double > RenderObject::getPos() const {
return { og_x, og_y };
void RenderObject::setPos( const Vec2D<double> &vec ) {
setPos( vec.getX(), vec.getY() );
}
Vec2D< double > RenderObject::getPos() const {
return original;
}
bool RenderObject::colidesWith( const RenderObject &other ) const {
if ( !hasCollisions() || !other.hasCollisions() || getHidden() ||
@@ -161,8 +163,7 @@ void RenderObject::move( int ticks ) {
if ( std::isnan( addx ) || std::isnan( addy ) )
return;
og_x += addx;
og_y += addy;
original += { addx, addy };
custom_move( ticks );
+6 -7
View File
@@ -5,6 +5,7 @@
#include "sdlpp_collision.hpp"
#include "sdlpp_renderer.hpp"
#include "sdlpp_texture.hpp"
#include "sdlpp_vector.hpp"
#include <memory>
#include <vector>
@@ -26,12 +27,12 @@ public:
virtual int collisionWidth() = 0;
virtual int collisionHeight() = 0;
virtual void specialAction( int code ) = 0;
virtual std::pair< std::pair< double, double >,
std::pair< double, double > >
virtual std::pair< Vec2D< double >, Vec2D< double > >
getDoubleRect() const = 0;
virtual void setPos( double x, double y );
virtual void setPos( const std::pair< double, double > &pos );
virtual std::pair< double, double > getPos() const;
virtual void setPos( const Vec2D<double> &vec );
virtual Vec2D< double > getPos() const;
bool colidesWith( const RenderObject &other ) const;
template < class T > void addCollision( const T &p ) {
collisions.push_back( std::make_shared< T >( p ) );
@@ -131,10 +132,8 @@ private:
friend Scene;
protected:
double og_x;
double og_y;
double x_;
double y_;
Vec2D< double > original;
Vec2D< double > current;
};
} // end of namespace SDLPP
+6 -5
View File
@@ -20,11 +20,11 @@ void Scene::addObject( const std::shared_ptr< RenderObject > &obj ) {
} else {
auto rect = obj->getDoubleRect();
auto leftmost_rect = leftmost_obj->getDoubleRect();
if ( rect.first.first < leftmost_rect.first.first )
if ( rect.first.getX() < leftmost_rect.first.getX() )
leftmost_obj = obj;
auto rightmost_rect = rightmost_obj->getDoubleRect();
if ( rect.first.first + rect.second.first >
rightmost_rect.first.first + rightmost_rect.second.first )
if ( rect.first.getX() + rect.second.getX() >
rightmost_rect.first.getX() + rightmost_rect.second.getX() )
rightmost_obj = obj;
}
}
@@ -123,8 +123,9 @@ void Scene::renderScene( bool clear_renderer ) {
if ( background && background->getTexturePtr() )
SDL_RenderCopy( renderer->getRendererPtr(), background->getTexturePtr(),
NULL, NULL );
for ( const auto &x : render_objects )
for ( const auto &x : render_objects ) {
x->render();
}
}
void Scene::presentScene() {
SDL_RenderPresent( renderer->getRendererPtr() );
@@ -153,7 +154,7 @@ void Scene::moveEverything( double x, double y ) {
if ( obj->getPermanent() )
continue;
auto curPos = obj->getDoubleRect();
obj->setPos( curPos.first.first + x, curPos.first.second + y );
obj->setPos( curPos.first.getX() + x, curPos.first.getY() + y );
}
}
const std::shared_ptr< RenderObject > &Scene::leftmost() {
+56
View File
@@ -0,0 +1,56 @@
#ifndef SDLPP_HPP_VECTOR
#define SDLPP_HPP_VECTOR
#include "sdlpp_common.hpp"
namespace SDLPP {
template<typename T>
class SDLPPSCOPE Vec2D {
public:
Vec2D() = default;
~Vec2D() = default;
Vec2D(T x, T y) : _x(x), _y(y) {}
T getX() const {
return _x;
}
T getY() const {
return _y;
}
Vec2D operator-(const Vec2D &other) const {
return Vec2D( getX() - other.getX(), getY() - other.getY() );
}
Vec2D operator+(const Vec2D &other) const {
return Vec2D( getX() + other.getX(), getY() + other.getY() );
}
Vec2D operator*(double multiplier) const {
return Vec2D( getX() * multiplier, getY() * multiplier );
}
Vec2D operator/(double divisor) const {
return *this * ( 1.0 / divisor );
}
T operator*(const Vec2D &other) const {
return getX() * other.getX() + getY() * other.getY();
}
Vec2D &operator+=(const Vec2D &other) {
*this = *this + other;
return *this;
}
Vec2D &operator-=(const Vec2D &other) {
*this = *this - other;
return *this;
}
private:
T _x = 0.0;
T _y = 0.0;
};
template<typename T>
Vec2D<T> operator*(double multiplier, const Vec2D<T> &vec) {
return vec * multiplier;
}
template<typename T>
Vec2D<T> operator/(double divisor, const Vec2D<T> &vec) {
return vec / divisor;
}
}
#endif