diff --git a/main.cpp b/main.cpp index 78fac44..213c484 100644 --- a/main.cpp +++ b/main.cpp @@ -7,6 +7,8 @@ #define STONE_ID 0x00000002 #define DEATH 0x00000003 +#define DESTROYABLE_DESTROY 0x00000001 + bool pause = false; class Player : public SDLPP::RectangleRender { @@ -82,15 +84,51 @@ private: bool jumping = false; }; +class Destroyable : public SDLPP::RectangleRender { +public: + Destroyable(double x, double y, double w, double h, std::shared_ptr &r) : SDLPP::RectangleRender(x,y,w,h,r) {} + Destroyable(double x, double y, double w, double h, std::shared_ptr &r, int destruction_time) : SDLPP::RectangleRender(x,y,w,h,r) { + destruction_countdown = destruction_time; + } + virtual void specialAction(int code) { + if(code == DESTROYABLE_DESTROY) + startDestruction(); + } + virtual void move(int ticks) { + /* copied from sdlpp*/ + auto dimension = renderer->getSmallerSide(); + auto addx = static_cast(movementSpeed * movementDirection.first)*(static_cast(ticks)/1000); + auto addy = static_cast(movementSpeed * movementDirection.second)*(static_cast(ticks)/1000); + x_ += addx; + y_ += addy; + rect.x = x_ * dimension; + rect.y = y_ * dimension; + for( auto &x : collisions ) { + x->updateCollision(collisionPushX(), collisionPushY(), collisionWidth(), collisionHeight()); + } + if(destruction) { + destruction_countdown -= ticks; + if(destruction_countdown <= 0) + destroy(); + } + } +private: + void startDestruction() { + destruction = true; + } + bool destruction = false; + int destruction_countdown = 3000; +}; + std::shared_ptr player; std::vector> bgtextures; bool quit = false; void addStuff(SDLPP::Scene &scene, std::shared_ptr &r) { - std::shared_ptr stone; + std::shared_ptr stone; double posx = 0; while(posx < 3) { - stone = std::make_shared(posx,0.5,0.15,0.1,r); + stone = std::make_shared(posx,0.5,0.15,0.1,r, 1000); stone->addCollision(SDLPP::Rect(0,0,1,1)); stone->setTexture("stone.png"); stone->setId(STONE_ID); @@ -146,7 +184,7 @@ void handleKeyDown(SDL_Keycode key, SDLPP::Scene &scene) { player->addMovement(1,0); break; case SDLK_w: - if(!player->isJumping()) { + if(!player->isJumping() && !pause) { player->setLastStand(); player->jump(); } @@ -176,7 +214,6 @@ void handleKeyUp(SDL_Keycode key) { player->addMovement(-1,0); break; case SDLK_w: - break; case SDLK_s: default: break; @@ -228,7 +265,7 @@ void doInput(std::shared_ptr scene) { player->setPos(newPX, newPY); player->setLastStand(); } -// x->setHidden(true); + x->specialAction(DESTROYABLE_DESTROY); } if( x->getId() == DEATH ) { std::cout << "Oh no, you died!" << std::endl; @@ -273,7 +310,7 @@ int main() { SDL_setFramerate(&gFPS, 60); std::thread inputThread(doInput, main_scene); while( !quit ) { - SDL_framerateDelay(&gFPS); +// SDL_framerateDelay(&gFPS); main_scene->renderScene(); main_scene->presentScene(); frames++; diff --git a/sdlpp.hpp b/sdlpp.hpp index cff11f8..38be827 100644 --- a/sdlpp.hpp +++ b/sdlpp.hpp @@ -3,10 +3,12 @@ #include #include +#include #include #include #include #include +#include #include namespace SDLPP { @@ -157,6 +159,8 @@ protected: bool infinite = false; }; +class Scene; + class RenderObject { public: RenderObject(std::shared_ptr &r) : renderer(r) {} @@ -170,6 +174,7 @@ public: virtual int collisionPushY() = 0; virtual int collisionWidth() = 0; virtual int collisionHeight() = 0; + virtual void specialAction(int code) = 0; virtual std::pair,std::pair> getDoubleRect() = 0; virtual void setPos(double x, double y) = 0; bool colidesWith(const RenderObject &other) const { @@ -230,6 +235,13 @@ public: bool getHidden() const { return hidden; } + void destroy() { + setHidden(true); + kill = true; + } + bool getKilled() { + return kill; + } void setColiderColor(const std::string &color) { colider_color = getColorsHEX(color); } @@ -245,7 +257,14 @@ protected: std::vector> colidedWith; uint64_t id; bool hidden = false; + bool kill = false; std::tuple colider_color = {0x00, 0xFF, 0xFF}; + uint64_t scene_id; +private: + void setSceneID(int id) { + scene_id = id; + } + friend Scene; }; class Scene { @@ -255,7 +274,9 @@ public: prev_ticks = SDL_GetTicks(); } void addObject(const std::shared_ptr &obj) { + render_mutex.lock(); renderObjects.push_back(obj); + obj->setSceneID(++max_object_id); if(obj->hasCollisions()) { collisionObjects.push_back(obj); } @@ -272,16 +293,20 @@ public: if(rect.first.first + rect.second.first > rightmost_rect.first.first + rightmost_rect.second.first) rightmost_obj = obj; } + render_mutex.unlock(); } std::shared_ptr getObject(int index) { return renderObjects[index]; } void movement() { + checkKilled(); + render_mutex.lock(); int now_ticks = SDL_GetTicks(); for( const auto &x : renderObjects ) { x->move(now_ticks - prev_ticks); } prev_ticks = now_ticks; + render_mutex.unlock(); } std::vector> getCollisions(RenderObject &r) { if(r.getHidden()) @@ -295,11 +320,14 @@ public: return ret; } void renderScene() { + checkKilled(); + render_mutex.lock(); SDL_RenderClear(renderer->getRendererPtr()); SDL_RenderCopy(renderer->getRendererPtr(), background->getTexturePtr(), NULL, NULL); for( const auto &x : renderObjects ) { x->render(); } + render_mutex.unlock(); } void presentScene() { SDL_RenderPresent(renderer->getRendererPtr()); @@ -311,18 +339,24 @@ public: background = std::make_shared(renderer, img_path); } void updateSizeAndPosition() { + checkKilled(); + render_mutex.lock(); for( auto &x : renderObjects ) { x->updateSizeAndPosition(); for( auto &col : x->getCollisions() ) { col->updateCollision(x->collisionPushX(), x->collisionPushY(), x->collisionWidth(), x->collisionHeight()); } } + render_mutex.unlock(); } void moveEverything(double x, double y) { + checkKilled(); + render_mutex.lock(); for( auto &obj : renderObjects ) { auto curPos = obj->getDoubleRect(); obj->setPos( curPos.first.first + x, curPos.first.second + y ); } + render_mutex.unlock(); } const std::shared_ptr &leftmost() { return leftmost_obj; @@ -346,6 +380,20 @@ public: prev_ticks = ticks; } private: + void checkKilled() { + render_mutex.lock(); + std::vector killed; + for( long unsigned int i = 0; i < renderObjects.size(); i++ ) { + if(renderObjects[i]->getKilled()) + killed.push_back(i); + } + std::reverse(killed.begin(), killed.end()); + for(auto &index : killed) { + renderObjects.erase(renderObjects.begin() + index); + } + render_mutex.unlock(); + } + std::vector> renderObjects; std::vector> collisionObjects; std::shared_ptr renderer; @@ -353,6 +401,8 @@ private: int prev_ticks = 0; std::shared_ptr leftmost_obj; std::shared_ptr rightmost_obj; + uint64_t max_object_id = 0; + std::mutex render_mutex; }; class RectangleRender : public RenderObject { @@ -377,6 +427,7 @@ public: auto texture = std::make_shared(r, img_path); setTexture(texture); } + virtual void specialAction(int /*UNUSED*/) {}; virtual void render() { if(texture != NULL && !getHidden()) SDL_RenderCopy(renderer->getRendererPtr(), texture->getTexturePtr(), NULL, &rect);