Trying to switch to more object-oriented

This commit is contained in:
zv0n 2021-03-12 22:33:46 +01:00
parent fbe122a5b9
commit 258ce51cfe
32 changed files with 693 additions and 249 deletions

View File

@ -1,25 +1,65 @@
CXX ?= g++
CFLAGS ?= -O2 -Wall -Wextra -g
PREFIX ?= /usr/local/bin
ifeq ($(OS),Windows_NT)
UNAME_S := Windows
CXX = cl
CXXFLAGS = -MD -EHsc
OBJEXT = obj
LDFLAGS =
OUTPUTFLAG = -Fo
else
UNAME_S := $(shell uname -s)
CXX ?= g++
CXXFLAGS = -std=c++14 -Wall -Wextra -pedantic -O2 -DDEBUG -DFEATURE # -g -fsanitize=address
OBJEXT = o
LDFLAGS ?= -lSDL2 -lSDL2_image -lSDL2_gfx -lSDL2_ttf -pthread
OUTPUTFLAG = -o
endif
TEST_OBJECTS = test.${OBJEXT}
ifeq ($(UNAME_S),Linux)
TEST_OBJECTS += libsdlpp.so
endif
ifeq ($(UNAME_S),Darwin)
TEST_OBJECTS += libsdlpp.dylib
endif
ifeq ($(UNAME_S),Windows)
TEST_OBJECTS += sdlpp/SDL2/SDL2_framerate.c sdlpp/SDL2/SDL2_gfxPrimitives.c sdlpp/SDL2/SDL2_imageFilter.c sdlpp/SDL2/SDL2_rotozoom.c
SDLLIB = libsdlpp.dll
endif
.PHONY: default
default: demo
default: test
demo: main.o sdlpp.o
$(CXX) $(CFLAGS) -o $@ $^ ${LDFLAGS}
test: test.o sdlpp.o
$(CXX) $(CFLAGS) -o $@ $^ ${LDFLAGS}
ifeq ($(UNAME_S),Windows)
test: ${TEST_OBJECTS} ${SDLLIB}
$(CXX) $(CXXFLAGS) -Fe"$@" ${TEST_OBJECTS} /link sdlpp\SDL2.lib sdlpp\SDL2_ttf.lib sdlpp\SDL2_image.lib libsdlpp.lib
main.o: main.cpp sdlpp.hpp
$(CXX) $(CFLAGS) -c -o $@ $<
sdlpp.o: sdlpp.cpp sdlpp.hpp
$(CXX) $(CFLAGS) -c -o $@ $<
test.o: tests/test.cpp sdlpp.hpp tests/catch.hpp
$(CXX) $(CFLAGS) -c -o $@ $<
else
test: ${TEST_OBJECTS}
$(CXX) $(CXXFLAGS) -o $@ $^ ${LDFLAGS} -L $(shell pwd) -lsdlpp
endif
windows_tetris: sdlpp.hpp sdlpp.cpp tetris/tetris.cpp tetris/config.cpp tetris/global_vars.cpp tetris/scenes.cpp tetris/functions.cpp tetris/config.hpp tetris/global_vars.hpp tetris/scenes.hpp tetris/functions.hpp
cl -MD -EHsc -Fe"Tetris" sdlpp.cpp tetris/tetris.cpp tetris/config.cpp tetris/global_vars.cpp tetris/scenes.cpp tetris/functions.cpp SDL2/SDL2_framerate.c SDL2/SDL2_gfxPrimitives.c SDL2/SDL2_imageFilter.c SDL2/SDL2_rotozoom.c /link SDL2.lib SDL2_ttf.lib SDL2_image.lib
test.${OBJEXT}: test.cpp
$(CXX) $(CXXFLAGS) -c ${OUTPUTFLAG}$@ $<
libsdlpp.so: sdlpp
$(MAKE) clean -C sdlpp
$(MAKE) -C sdlpp
cp sdlpp/libsdlpp.so .
ln -sf libsdlpp.so libsdlpp.so.1
libsdlpp.dylib: sdlpp
$(MAKE) clean -C sdlpp
$(MAKE) -C sdlpp
cp sdlpp/libsdlpp.dylib .
libsdlpp.dll: ../sdlpp
$(MAKE) clean -C sdlpp
$(MAKE) -C sdlpp
cp sdlpp/libsdlpp.dll .
cp sdlpp/libsdlpp.lib .
start:
LD_LIBRARY_PATH=$$(pwd) ./test
clean:
rm -Rf *.o test demo
rm -Rf *.${OBJEXT} test

View File

@ -1,4 +1,4 @@
#include "sdlpp.hpp"
#include "sdlpp/sdlpp.hpp"
#include <thread>
#include <chrono>
#include <SDL2/SDL2_framerate.h>
@ -78,8 +78,8 @@ public:
}
if ( jump_ < 0 || jump_ > jump_speed )
jump_ = 0;
og_y += grav * time_portion;
og_y -= jump_ * time_portion;
double addition = grav * time_portion - jump_ * time_portion;
original += {0, addition};
}
private:
@ -135,7 +135,7 @@ void addStuff( SDLPP::Scene &scene, std::shared_ptr< SDLPP::Renderer > &r ) {
while ( posx < 3 ) {
stone =
std::make_shared< Destroyable >( posx, 0.5, 0.15, 0.1, r, 1000 );
stone->addCollision( SDLPP::Rect( 0, 0, 1, 1 ) );
stone->addCollision( SDLPP::RectColider( 0, 0, 1, 1 ) );
stone->setColor( "#222222FF" );
stone->setId( STONE_ID );
stone->setColiderColor( "FF0000" );
@ -143,24 +143,24 @@ void addStuff( SDLPP::Scene &scene, std::shared_ptr< SDLPP::Renderer > &r ) {
posx += 0.45;
}
auto x = std::make_shared< Player >( 0, 0, 0.2, 0.2, r );
x->addCollision( SDLPP::Rect( 0.3, 0.7, 0.05, 0.31 ) );
x->addCollision( SDLPP::Rect( 0.65, 0.7, 0.05, 0.31 ) );
x->addCollision( SDLPP::Rect( 0.2, 0.3, 0.6, 0.45 ) );
x->addCollision( SDLPP::Circle( 0.5, 0.15, 0.3 ) );
x->addCollision( SDLPP::RectColider( 0.3, 0.7, 0.05, 0.31 ) );
x->addCollision( SDLPP::RectColider( 0.65, 0.7, 0.05, 0.31 ) );
x->addCollision( SDLPP::RectColider( 0.2, 0.3, 0.6, 0.45 ) );
x->addCollision( SDLPP::CircleColider( 0.5, 0.15, 0.3 ) );
x->setColor( "E164B7" );
x->setId( PLAYER_ID );
x->setColiderColor( "00FF00" );
scene.addObject( x );
player = x;
auto z = std::make_shared< SDLPP::RectangleRender >( 0, 2.5, 0, 0, r );
auto z_col = SDLPP::Rect( -1, 0, -1, -1 );
auto z_col = SDLPP::RectColider( -1, 0, -1, -1 );
z_col.setInfinite();
z->addCollision( z_col );
z->setId( DEATH );
z->setColiderColor( "FF00FF" );
scene.addObject( z );
auto y = std::make_shared< SDLPP::TextRenderer >( 0, 0, 0.2, 0.1, r );
y->setText( *font, "DEMO", "#FFFFFF", "#000000", 5 );
y->setText( font, "DEMO", "#FFFFFF", "#000000", 5 );
y->setPermanent( true );
y->setId( 123 );
scene.addObject( y );
@ -173,20 +173,20 @@ void addPause( SDLPP::Scene &scene, std::shared_ptr< SDLPP::Renderer > &r ) {
bg->setPermanent( true );
scene.addObject( bg );
auto y = std::make_shared< SDLPP::TextRenderer >( 0.25, 0.1, 0.5, 0.3, r );
y->setText( *font, "PAUSED", "#FFFFFF", "#000000", 5 );
y->setText( font, "PAUSED", "#FFFFFF", "#000000", 5 );
y->setId( 0 );
y->centerX();
scene.addObject( y );
auto resume =
std::make_shared< SDLPP::TextRenderer >( 0.4, 0.5, 0.2, 0.1, r );
resume->setText( *font, "Resume", "#FFFFFF", "#000000", 5 );
resume->setText( font, "Resume", "#FFFFFF", "#000000", 5 );
resume->setColor( "#FFFFFF40" );
resume->centerX();
scene.addObject( resume );
pause_options.push_back( resume );
auto quit =
std::make_shared< SDLPP::TextRenderer >( 0.4, 0.7, 0.2, 0.1, r );
quit->setText( *font, "Quit Game", "#FFFFFF", "#000000", 5 );
quit->setText( font, "Quit Game", "#FFFFFF", "#000000", 5 );
quit->centerX();
scene.addObject( quit );
pause_options.push_back( quit );

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

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

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;
}

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;

View File

@ -6,24 +6,37 @@
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 ) {
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 {
@ -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() );
@ -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

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;

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 ) {

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;
@ -29,10 +31,8 @@ public:
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
sdlpp/sdlpp_geometry.hpp Normal file
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

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

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
sdlpp/sdlpp_line.hpp Normal file
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

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() );
@ -123,31 +135,30 @@ 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

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;
};

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

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

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

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

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 );

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

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,9 +123,10 @@ 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
sdlpp/sdlpp_vector.hpp Normal file
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

32
test.cpp Normal file
View File

@ -0,0 +1,32 @@
#include "sdlpp/sdlpp.hpp"
#include <SDL2/SDL2_framerate.h>
int main() {
SDLPP::init();
SDLPP::Window w("Test");
w.setResizable( true );
auto renderer = std::make_shared< SDLPP::Renderer >( w );
renderer->setBlendMode( SDL_BLENDMODE_BLEND );
auto main_scene = std::make_shared< SDLPP::Scene >( renderer );
auto bg = std::make_shared<SDLPP::RectangleRender>(0, 0, 10, 10, renderer, "#FF0000", true);
bg->setId(123);
bg->setPermanent(true);
main_scene->addObject(bg);
FPSmanager gFPS;
SDL_initFramerate( &gFPS );
SDL_setFramerate( &gFPS, 60 );
int base = SDL_GetTicks();
int frames = 0;
while(true) {
SDL_PumpEvents();
main_scene->renderScene();
main_scene->presentScene();
frames++;
if ( SDL_GetTicks() - base >= 1000 ) {
base = SDL_GetTicks();
printf( "FPS: %d\n", frames );
frames = 0;
}
}
}

18
tests/Makefile Normal file
View File

@ -0,0 +1,18 @@
PREFIX ?= /usr/local/bin
CXXFLAGS = -std=c++14 -Wall -Wextra -pedantic
OBJEXT=o
LDFLAGS ?= -lSDL2 -lSDL2_image -lSDL2_gfx -lSDL2_ttf -pthread
.PHONY: default
default: test
OBJECTFILES = sdlpp_circlecolider.${OBJEXT} sdlpp_circlerenderer.${OBJEXT} sdlpp_collision.${OBJEXT} sdlpp_common.${OBJEXT} sdlpp_font.${OBJEXT} sdlpp_linerenderer.${OBJEXT} sdlpp_rectcolider.${OBJEXT} sdlpp_rectrenderer.${OBJEXT} sdlpp_renderer.${OBJEXT} sdlpp_renderobject.${OBJEXT} sdlpp_scene.${OBJEXT} sdlpp_textrenderer.${OBJEXT} sdlpp_texture.${OBJEXT} sdlpp_window.${OBJEXT} sdlpp_vector.${OBJEXT} sdlpp_line.${OBJEXT} sdlpp_geometry.${OBJEXT}
%.${OBJEXT}: ../sdlpp/%.cpp
${CXX} ${CXXFLAGS} ${LIBRARYFLAGS} -c $< -o $@
test: test.cpp ${OBJECTFILES}
$(CXX) $(CXXFLAGS) -o $@ $^ ${LDFLAGS}
clean:
rm -Rf *.${OBJEXT} test

View File

@ -1,11 +1,12 @@
#define CATCH_CONFIG_MAIN
#include "catch.hpp"
#include "../sdlpp.hpp"
#include "../sdlpp/sdlpp.hpp"
#include <iostream>
// sdlpp.hpp
TEST_CASE( "Rect collisions" ) {
/*TEST_CASE( "Rect collisions" ) {
SDLPP::Rect r(0,0,10,10);
REQUIRE(r.colidesWith(r));
SDLPP::Rect r2(100,100,10,10);
@ -40,5 +41,52 @@ TEST_CASE( "Multiple collisions" ) {
REQUIRE(r.colidesWith(r1));
REQUIRE(r.colidesWith(r2));
REQUIRE_FALSE(r.colidesWith(r3));
}*/
TEST_CASE( "Point distances" ) {
SDLPP::Vec2D p1(0,0);
SDLPP::Vec2D p2(1,0);
auto dist = vecDistance(p1, p2);
REQUIRE( dist > 0.99 );
REQUIRE( dist < 1.01 );
dist = vecDistance(p2, p1);
REQUIRE( dist > 0.99 );
REQUIRE( dist < 1.01 );
p2 = SDLPP::Vec2D(0,1);
dist = vecDistance(p1, p2);
REQUIRE( dist > 0.99 );
REQUIRE( dist < 1.01 );
dist = vecDistance(p2, p1);
REQUIRE( dist > 0.99 );
REQUIRE( dist < 1.01 );
p2 = SDLPP::Vec2D(1,1);
dist = vecDistance(p1, p2);
REQUIRE( dist > 1.4142 );
REQUIRE( dist < 1.41422 );
}
TEST_CASE( "Point line distances" ) {
SDLPP::Vec2D p1(0,0);
SDLPP::Line line({-1,-1}, {1, -1});
auto dist = pointLineDistance(p1, line);
REQUIRE( dist > 0.99 );
REQUIRE( dist < 1.01 );
line = SDLPP::Line({-3,-1}, {-1,-1});
dist = pointLineDistance(p1, line);
REQUIRE( dist > 1.4142 );
REQUIRE( dist < 1.41422 );
line = SDLPP::Line({-3,-2}, {-2,-2});
dist = pointLineDistance(p1, line);
REQUIRE( dist > 2.8284 );
REQUIRE( dist < 2.82843 );
line = SDLPP::Line({-3,-1}, {-2,-2});
dist = pointLineDistance(p1, line);
std::cout << dist << std::endl;
line = SDLPP::Line({-3,-1}, {-2,-180});
dist = pointLineDistance(p1, line);
std::cout << dist << std::endl;
SDLPP::Vec2D p2(-3, -1);
dist = vecDistance(p1, p2);
std::cout << dist << std::endl;
}

View File

@ -10,7 +10,7 @@ OUTPUTFLAG = -Fo
else
UNAME_S := $(shell uname -s)
CXX ?= g++
CXXFLAGS = -std=c++14 -Wall -Wextra -pedantic -O2 # -DDEBUG -DFEATURE # -g -fsanitize=address
CXXFLAGS = -std=c++14 -Wall -Wextra -pedantic -O2 -DDEBUG -DFEATURE -g -fsanitize=address
OBJEXT = o
LDFLAGS ?= -lSDL2 -lSDL2_image -lSDL2_gfx -lSDL2_ttf -pthread
OUTPUTFLAG = -o

View File

@ -32,10 +32,10 @@ TetrisBlock::TetrisBlock( double x, double y, double w, double h,
}
TetrisBlock::TetrisBlock( const TetrisBlock &other )
: TetrisBlock( other.getDoubleRect().first.first,
other.getDoubleRect().first.second,
other.getDoubleRect().second.first,
other.getDoubleRect().second.second, other.getRenderer(),
: TetrisBlock( other.getDoubleRect().first.getX(),
other.getDoubleRect().first.getY(),
other.getDoubleRect().second.getX(),
other.getDoubleRect().second.getY(), other.getRenderer(),
other.getColor(), true, other._index, other._scene,
other.pieces_bag ) {}
@ -63,9 +63,9 @@ std::shared_ptr< TetrisBlock > TetrisBlock::copyInScene() {
bool TetrisBlock::isSamePos( const SDLPP::RenderObject &other ) const {
auto mypos = getPos();
auto otherpos = other.getPos();
auto diff1 = mypos.first - otherpos.first;
auto diff1 = mypos.getX() - otherpos.getX();
diff1 = ( diff1 < 0 ) * ( -1 ) * diff1 + ( diff1 > 0 ) * diff1;
auto diff2 = mypos.second - otherpos.second;
auto diff2 = mypos.getY() - otherpos.getY();
diff2 = ( diff2 < 0 ) * ( -1 ) * diff2 + ( diff2 > 0 ) * diff2;
return diff1 < 0.0001 && diff2 < 0.0001;
}
@ -152,23 +152,23 @@ void TetrisPiece::rotate() {
for ( unsigned long i = 0; i < pieces.size(); i++ ) {
auto &piece = pieces[i];
auto &positions = pieces_rel_position[i];
auto position = piece->getPos();
original_pos[i] = position;
position.first += positions[0] * BLOCK_SIZE;
position.first -= positions[1] * BLOCK_SIZE;
position.second += positions[2] * BLOCK_SIZE;
position.second -= positions[3] * BLOCK_SIZE;
auto piece_position = piece->getPos();
original_pos[i] = piece_position;
piece_position += { positions[0] * BLOCK_SIZE -
positions[1] * BLOCK_SIZE,
positions[2] * BLOCK_SIZE -
positions[3] * BLOCK_SIZE };
auto bottom = positions[3];
auto top = positions[2];
positions[3] = positions[1];
positions[2] = positions[0];
positions[1] = top;
positions[0] = bottom;
position.first -= positions[0] * BLOCK_SIZE;
position.first += positions[1] * BLOCK_SIZE;
position.second -= positions[2] * BLOCK_SIZE;
position.second += positions[3] * BLOCK_SIZE;
piece->setPos( position.first, position.second );
piece_position += { positions[1] * BLOCK_SIZE -
positions[0] * BLOCK_SIZE,
positions[3] * BLOCK_SIZE -
positions[2] * BLOCK_SIZE };
piece->setPos( piece_position );
}
}
@ -176,7 +176,7 @@ void TetrisPiece::revert() {
for ( unsigned long i = 0; i < pieces.size(); i++ ) {
auto &piece = pieces[i];
auto &positions = pieces_rel_position[i];
piece->setPos( original_pos[i].first, original_pos[i].second );
piece->setPos( original_pos[i] );
auto top = positions[1];
auto bottom = positions[0];
positions[1] = positions[3];
@ -207,14 +207,16 @@ void TetrisPiece::setPos( const std::pair< double, double > &pos ) {
setPos( pos.first, pos.second );
}
std::pair< double, double > TetrisPiece::getPos() {
void TetrisPiece::setPos( const SDLPP::Vec2D<double> &vec ) {
setPos( vec.getX(), vec.getY() );
}
SDLPP::Vec2D<double> TetrisPiece::getPos() {
auto &piece = pieces[0];
auto &relpositions = pieces_rel_position[0];
auto pos = piece->getPos();
pos.first += relpositions[0] * BLOCK_SIZE;
pos.first -= relpositions[1] * BLOCK_SIZE;
pos.second += relpositions[2] * BLOCK_SIZE;
pos.second -= relpositions[3] * BLOCK_SIZE;
pos += { relpositions[0] * BLOCK_SIZE - relpositions[1] * BLOCK_SIZE,
relpositions[2] * BLOCK_SIZE - relpositions[3] * BLOCK_SIZE };
return pos;
}
@ -258,7 +260,7 @@ bool TetrisPiece::isRight( const SDLPP::RenderObject &block ) const {
void TetrisPiece::movePiece( double x, double y ) {
for ( auto &block : getObjects() ) {
auto pos = block->getPos();
block->setPos( pos.first + x, pos.second + y );
block->setPos( pos + SDLPP::Vec2D<double>( x, y ) );
}
}

View File

@ -40,7 +40,8 @@ public:
std::vector< std::shared_ptr< TetrisBlock > > &getObjects();
void setPos( double x, double y );
void setPos( const std::pair< double, double > &pos );
std::pair< double, double > getPos();
void setPos( const SDLPP::Vec2D<double> &vec );
SDLPP::Vec2D<double> getPos();
void clear();
void startDescend();
void stopDescend();
@ -69,7 +70,7 @@ private:
std::vector< std::vector< int > > pieces_rel_position;
std::vector< std::shared_ptr< TetrisBlock > > pieces;
std::vector< std::pair< double, double > > original_pos;
std::vector< SDLPP::Vec2D<double> > original_pos;
bool descend = false;
int userMovement = 0;
bool rotate_allowed = true;

View File

@ -27,19 +27,19 @@ void updateShadow( SDLPP::Scene &scene ) {
auto &invalid_objects = g_cur_object->getObjects();
for ( auto &x : g_cur_shadow->getObjects() ) {
auto block_pos = x->getPos();
if ( BOTTOM_BORDER - block_pos.second < shadow_drop )
shadow_drop = BOTTOM_BORDER - block_pos.second;
if ( BOTTOM_BORDER - block_pos.getY() < shadow_drop )
shadow_drop = BOTTOM_BORDER - block_pos.getY();
// set colider column's position to current block's X position
g_shadow_colider->setPos( block_pos.first, TOP_BORDER );
g_shadow_colider->setPos( block_pos.getX(), TOP_BORDER );
auto collisions =
scene.getCollisions( *g_shadow_colider, { BRICK_ID } );
auto curY = block_pos.second;
auto curY = block_pos.getY();
for ( auto &col : collisions ) {
// if collision with g_cur_object, ignore
if ( std::find( invalid_objects.begin(), invalid_objects.end(),
col ) != invalid_objects.end() )
continue;
auto possible_drop = col->getPos().second - curY;
auto possible_drop = col->getPos().getY() - curY;
if ( possible_drop < shadow_drop && possible_drop >= 0 )
shadow_drop = possible_drop;
}
@ -47,7 +47,7 @@ void updateShadow( SDLPP::Scene &scene ) {
// we want the shadow to rest on top of the nearest floor
shadow_drop -= BLOCK_SIZE;
auto shadow_pos = g_cur_shadow->getPos();
g_cur_shadow->setPos( shadow_pos.first, shadow_pos.second + shadow_drop );
g_cur_shadow->setPos( shadow_pos.getX(), shadow_pos.getY() + shadow_drop );
}
void moveThem( std::shared_ptr< SDLPP::Scene > scene, int ticks ) {

View File

@ -457,11 +457,11 @@ void mainSceneInput(
for ( auto &col : collisions ) {
col->destroy();
}
auto colider_y = colider->getPos().second;
auto colider_y = colider->getPos().getY();
for ( auto &elem : scene->getObjects( { BRICK_ID } ) ) {
auto pos = elem->getPos();
if ( pos.second < colider_y && pos.first <= RIGHT_BORDER ) {
elem->setPos( pos.first, pos.second + BLOCK_SIZE );
if ( pos.getY() < colider_y && pos.getX() <= RIGHT_BORDER ) {
elem->setPos( pos.getX(), pos.getY() + BLOCK_SIZE );
}
}
using namespace std::chrono_literals;