From c7f3e7c741cbef590e3520d6922acee16c52b160 Mon Sep 17 00:00:00 2001 From: zvon Date: Fri, 11 Sep 2020 14:24:54 +0200 Subject: [PATCH] TETRIS: lines --- Makefile | 8 +-- sdlpp.hpp | 167 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tetris.cpp | 50 +++++++++++----- 3 files changed, 206 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 277b171..dad3b6c 100644 --- a/Makefile +++ b/Makefile @@ -14,13 +14,13 @@ test: test.o sdlpp.o $(CXX) $(CFLAGS) -o $@ $^ ${LDFLAGS} main.o: main.cpp sdlpp.hpp - $(CXX) $(CFLAGS) -c -o $@ $< ${LDFLAGS} + $(CXX) $(CFLAGS) -c -o $@ $< sdlpp.o: sdlpp.cpp sdlpp.hpp - $(CXX) $(CFLAGS) -c -o $@ $< ${LDFLAGS} + $(CXX) $(CFLAGS) -c -o $@ $< test.o: tests/test.cpp sdlpp.hpp tests/catch.hpp - $(CXX) $(CFLAGS) -c -o $@ $< ${LDFLAGS} + $(CXX) $(CFLAGS) -c -o $@ $< tetris.o: tetris.cpp sdlpp.hpp - $(CXX) $(CFLAGS) -c -o $@ $< ${LDFLAGS} + $(CXX) $(CFLAGS) -c -o $@ $< clean: rm -Rf *.o test demo diff --git a/sdlpp.hpp b/sdlpp.hpp index 9c4020d..99239bb 100644 --- a/sdlpp.hpp +++ b/sdlpp.hpp @@ -877,6 +877,173 @@ private: int rad_; }; +class LineRenderer : public RenderObject { +public: + LineRenderer() = delete; + virtual ~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( double x1, double y1, double x2, double y2, const std::shared_ptr< Renderer > &r, + const std::string &color ) + : LineRenderer( x1, y1, x2, y2, r ) { + setColor( color ); + } + virtual void setColor( const std::string &color ) override { + _color = getColorsHEX( color ); + } + virtual void specialAction( int /*UNUSED*/ ) override{}; + virtual void render() override { + if ( !getHidden() ) { + SDL_SetRenderDrawColor( 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 ); + } + if ( hasCollisions() && renderer->getRenderColiders() && + !getHidden() ) { + for ( const auto &col : getCollisions() ) + col->render( *renderer, colider_color ); + } + } + virtual void move( int ticks ) override { + if ( permanent ) + return; + auto addx = + static_cast< double >( movementSpeed * movementDirection.first ) * + ( static_cast< double >( ticks ) / 1000 ); + auto addy = + static_cast< double >( movementSpeed * movementDirection.second ) * + ( static_cast< double >( ticks ) / 1000 ); + if ( std::isnan( addx ) || std::isnan( addy ) ) + return; + + og_x1 += addx; + og_x2 += addx; + og_y1 += addy; + og_y2 += addy; + + custom_move( ticks ); + + updateSizeAndPosition(); + } + virtual void custom_move( int /*UNUSED*/ ) override {} + virtual void setPos( double x, double y ) override { + 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; + updateSizeAndPosition(); + } + virtual void setPos(const std::pair &pos) override { + setPos(pos.first, pos.second); + } + virtual std::pair< double, double > getPos() const override { + return { og_x1, og_y1 }; + } + virtual int leftmost() override { + return pixel_x1 < pixel_x2 ? pixel_x1 : pixel_x2; + } + virtual int topmost() override { + return pixel_y1 < pixel_y2 ? pixel_y1 : pixel_y2; + } + virtual int rightmost() override { + return pixel_x1 > pixel_x2 ? pixel_x1 : pixel_x2; + } + virtual int bottommost() override { + return pixel_y1 > pixel_y2 ? pixel_y1 : pixel_y2; + } + virtual int collisionPushX() override { + return leftmost(); + } + virtual int collisionPushY() override { + return topmost(); + } + virtual int collisionWidth() override { + return rightmost() - leftmost(); + } + virtual int collisionHeight() override { + return bottommost() - topmost(); + } + virtual void updateSizeAndPosition() override { + 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); + std::cout << "x1: " << pixel_x1 << ", y1: " << pixel_y1 << ", x2: " << pixel_x2 << ", y2: " << pixel_y2 << std::endl; + for ( auto &x : collisions ) { + x->updateCollision( collisionPushX(), collisionPushY(), + collisionWidth(), collisionHeight() ); + } + } + virtual void centerX() override { + centerx = true; + updateSizeAndPosition(); + } + virtual std::shared_ptr copySelf() override { + // TODO ACTUALLY copy, don't just copy pointers to textures and whatnot, create new textures!!! + return std::make_shared(*this); + } + + virtual SDL_Rect getRect() override { + return {leftmost(), topmost(), rightmost() - leftmost(), bottommost() - topmost()}; + } + virtual std::pair< std::pair< double, double >, + std::pair< double, double > > + getDoubleRect() const override { + return {{og_x1, og_y1}, {og_x2 - og_x1, og_y2 - og_y1}}; + } + void setOutlineColor( const std::string &/*UNUSED*/ ) override {} + +protected: + void updateXY() { + if ( !centerx ) { + x1_ = og_x1; + y1_ = og_y1; + x2_ = og_x2; + y2_ = og_y2; + return; + } + auto width = renderer->getWidth(); + auto height = renderer->getHeight(); + 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; + } else { + x1_ = og_x1; + x2_ = og_x2; + } + y1_ = og_y1; + y2_ = og_y2; + } + 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{}; + bool centerx = false; + std::tuple< int, int, int, int > _color; +}; + class RectangleRender : public RenderObject { public: RectangleRender() = delete; diff --git a/tetris.cpp b/tetris.cpp index 6d5a929..f56b324 100644 --- a/tetris.cpp +++ b/tetris.cpp @@ -483,19 +483,51 @@ void addStuff( SDLPP::Scene &scene, std::shared_ptr< SDLPP::Renderer > &r ) { "#222222", true ); bg->setPermanent(); scene.addObject( bg ); + + double posy = 1; + for ( int i = 0; i < 20; i++ ) { + posy -= BLOCK_SIZE; + auto colider = std::make_shared< SDLPP::RectangleRender >( + LEFT_BORDER, posy, RIGHT_BORDER - LEFT_BORDER, BLOCK_SIZE, r ); + colider->addCollision(SDLPP::Rect( 0.01, 0.1, 0.98, 0.8 )); + colider->setId( COLIDER_ID ); + colider->setStatic(); + colider->centerX(); + line_coliders.push_back( colider ); + scene.addObject( colider ); + } + + posy = 1; + for ( int i = 0; i < 20; i++ ) { + posy -= BLOCK_SIZE; + auto line = std::make_shared< SDLPP::LineRenderer >( LEFT_BORDER, posy, RIGHT_BORDER, posy, r, "#AAAAAA" ); + line->setStatic(); + line->centerX(); + scene.addObject( line ); + } + + auto posx = RIGHT_BORDER; + for ( int i = 0; i < 9; i++ ) { + posx -= BLOCK_SIZE; + auto line = std::make_shared< SDLPP::LineRenderer >( posx, TOP_BORDER + BLOCK_SIZE, posx, BOTTOM_BORDER, r, "#AAAAAA" ); + line->setStatic(); + line->centerX(); + scene.addObject( line ); + } + auto left_barrier = std::make_shared< SDLPP::RectangleRender >( - LEFT_BORDER - 0.02, 0, 0.02, BOTTOM_BORDER, r, "#FF000080", true ); + LEFT_BORDER - 0.02, 0, 0.02, BOTTOM_BORDER, r, "#AA0000", true ); left_barrier->centerX(); left_barrier->setStatic(); scene.addObject( left_barrier ); auto right_barrier = std::make_shared< SDLPP::RectangleRender >( - RIGHT_BORDER, 0, 0.02, BOTTOM_BORDER, r, "#FF000080", true ); + RIGHT_BORDER, 0, 0.02, BOTTOM_BORDER, r, "#AA0000", true ); right_barrier->centerX(); right_barrier->setStatic(); scene.addObject( right_barrier ); auto bottom_barrier = std::make_shared< SDLPP::RectangleRender >( LEFT_BORDER - 0.02, BOTTOM_BORDER, RIGHT_BORDER - LEFT_BORDER + 0.04, - 0.02, r, "#FF000080", true ); + 0.02, r, "#AA0000", true ); bottom_barrier->centerX(); bottom_barrier->setStatic(); scene.addObject( bottom_barrier ); @@ -510,7 +542,6 @@ void addStuff( SDLPP::Scene &scene, std::shared_ptr< SDLPP::Renderer > &r ) { next->centerX(); next->setStatic(); scene.addObject( next ); - double posy = 1; auto gameover = std::make_shared< SDLPP::RectangleRender >( 0.5, 0, 0, TOP_BORDER + BLOCK_SIZE, r ); auto gameover_collision = SDLPP::Rect( -1, 0, -1, 0.9 ); @@ -533,17 +564,6 @@ void addStuff( SDLPP::Scene &scene, std::shared_ptr< SDLPP::Renderer > &r ) { score_texture->centerX(); score_texture->setStatic(); scene.addObject( score_texture ); - for ( int i = 0; i < 20; i++ ) { - posy -= BLOCK_SIZE; - auto colider = std::make_shared< SDLPP::RectangleRender >( - LEFT_BORDER, posy, RIGHT_BORDER - LEFT_BORDER, BLOCK_SIZE, r ); - colider->addCollision(SDLPP::Rect( 0.01, 0.1, 0.98, 0.8 )); - colider->setId( COLIDER_ID ); - colider->setStatic(); - colider->centerX(); - line_coliders.push_back( colider ); - scene.addObject( colider ); - } auto shcol = std::make_shared< SDLPP::RectangleRender >( 0, TOP_BORDER, BLOCK_SIZE, BOTTOM_BORDER - TOP_BORDER, r ); shcol->addCollision(SDLPP::Rect( 0.1, 0.01, 0.8, 0.98 ));