Destroyable

This commit is contained in:
zvon 2020-08-21 21:40:15 +02:00
parent eaa463fb85
commit 618786f885
2 changed files with 94 additions and 6 deletions

View File

@ -7,6 +7,8 @@
#define STONE_ID 0x00000002 #define STONE_ID 0x00000002
#define DEATH 0x00000003 #define DEATH 0x00000003
#define DESTROYABLE_DESTROY 0x00000001
bool pause = false; bool pause = false;
class Player : public SDLPP::RectangleRender { class Player : public SDLPP::RectangleRender {
@ -82,15 +84,51 @@ private:
bool jumping = false; bool jumping = false;
}; };
class Destroyable : public SDLPP::RectangleRender {
public:
Destroyable(double x, double y, double w, double h, std::shared_ptr<SDLPP::Renderer> &r) : SDLPP::RectangleRender(x,y,w,h,r) {}
Destroyable(double x, double y, double w, double h, std::shared_ptr<SDLPP::Renderer> &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<double>(movementSpeed * movementDirection.first)*(static_cast<double>(ticks)/1000);
auto addy = static_cast<double>(movementSpeed * movementDirection.second)*(static_cast<double>(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> player; std::shared_ptr<Player> player;
std::vector<std::shared_ptr<SDLPP::Texture>> bgtextures; std::vector<std::shared_ptr<SDLPP::Texture>> bgtextures;
bool quit = false; bool quit = false;
void addStuff(SDLPP::Scene &scene, std::shared_ptr<SDLPP::Renderer> &r) { void addStuff(SDLPP::Scene &scene, std::shared_ptr<SDLPP::Renderer> &r) {
std::shared_ptr<SDLPP::RectangleRender> stone; std::shared_ptr<Destroyable> stone;
double posx = 0; double posx = 0;
while(posx < 3) { while(posx < 3) {
stone = std::make_shared<SDLPP::RectangleRender>(posx,0.5,0.15,0.1,r); 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::Rect(0,0,1,1));
stone->setTexture("stone.png"); stone->setTexture("stone.png");
stone->setId(STONE_ID); stone->setId(STONE_ID);
@ -146,7 +184,7 @@ void handleKeyDown(SDL_Keycode key, SDLPP::Scene &scene) {
player->addMovement(1,0); player->addMovement(1,0);
break; break;
case SDLK_w: case SDLK_w:
if(!player->isJumping()) { if(!player->isJumping() && !pause) {
player->setLastStand(); player->setLastStand();
player->jump(); player->jump();
} }
@ -176,7 +214,6 @@ void handleKeyUp(SDL_Keycode key) {
player->addMovement(-1,0); player->addMovement(-1,0);
break; break;
case SDLK_w: case SDLK_w:
break;
case SDLK_s: case SDLK_s:
default: default:
break; break;
@ -228,7 +265,7 @@ void doInput(std::shared_ptr<SDLPP::Scene> scene) {
player->setPos(newPX, newPY); player->setPos(newPX, newPY);
player->setLastStand(); player->setLastStand();
} }
// x->setHidden(true); x->specialAction(DESTROYABLE_DESTROY);
} }
if( x->getId() == DEATH ) { if( x->getId() == DEATH ) {
std::cout << "Oh no, you died!" << std::endl; std::cout << "Oh no, you died!" << std::endl;
@ -273,7 +310,7 @@ int main() {
SDL_setFramerate(&gFPS, 60); SDL_setFramerate(&gFPS, 60);
std::thread inputThread(doInput, main_scene); std::thread inputThread(doInput, main_scene);
while( !quit ) { while( !quit ) {
SDL_framerateDelay(&gFPS); // SDL_framerateDelay(&gFPS);
main_scene->renderScene(); main_scene->renderScene();
main_scene->presentScene(); main_scene->presentScene();
frames++; frames++;

View File

@ -3,10 +3,12 @@
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <SDL2/SDL_image.h> #include <SDL2/SDL_image.h>
#include <algorithm>
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
#include <limits> #include <limits>
#include <memory> #include <memory>
#include <mutex>
#include <vector> #include <vector>
namespace SDLPP { namespace SDLPP {
@ -157,6 +159,8 @@ protected:
bool infinite = false; bool infinite = false;
}; };
class Scene;
class RenderObject { class RenderObject {
public: public:
RenderObject(std::shared_ptr<Renderer> &r) : renderer(r) {} RenderObject(std::shared_ptr<Renderer> &r) : renderer(r) {}
@ -170,6 +174,7 @@ public:
virtual int collisionPushY() = 0; virtual int collisionPushY() = 0;
virtual int collisionWidth() = 0; virtual int collisionWidth() = 0;
virtual int collisionHeight() = 0; virtual int collisionHeight() = 0;
virtual void specialAction(int code) = 0;
virtual std::pair<std::pair<double,double>,std::pair<double,double>> getDoubleRect() = 0; virtual std::pair<std::pair<double,double>,std::pair<double,double>> getDoubleRect() = 0;
virtual void setPos(double x, double y) = 0; virtual void setPos(double x, double y) = 0;
bool colidesWith(const RenderObject &other) const { bool colidesWith(const RenderObject &other) const {
@ -230,6 +235,13 @@ public:
bool getHidden() const { bool getHidden() const {
return hidden; return hidden;
} }
void destroy() {
setHidden(true);
kill = true;
}
bool getKilled() {
return kill;
}
void setColiderColor(const std::string &color) { void setColiderColor(const std::string &color) {
colider_color = getColorsHEX(color); colider_color = getColorsHEX(color);
} }
@ -245,7 +257,14 @@ protected:
std::vector<std::shared_ptr<RenderObject>> colidedWith; std::vector<std::shared_ptr<RenderObject>> colidedWith;
uint64_t id; uint64_t id;
bool hidden = false; bool hidden = false;
bool kill = false;
std::tuple<int,int,int> colider_color = {0x00, 0xFF, 0xFF}; std::tuple<int,int,int> colider_color = {0x00, 0xFF, 0xFF};
uint64_t scene_id;
private:
void setSceneID(int id) {
scene_id = id;
}
friend Scene;
}; };
class Scene { class Scene {
@ -255,7 +274,9 @@ public:
prev_ticks = SDL_GetTicks(); prev_ticks = SDL_GetTicks();
} }
void addObject(const std::shared_ptr<RenderObject> &obj) { void addObject(const std::shared_ptr<RenderObject> &obj) {
render_mutex.lock();
renderObjects.push_back(obj); renderObjects.push_back(obj);
obj->setSceneID(++max_object_id);
if(obj->hasCollisions()) { if(obj->hasCollisions()) {
collisionObjects.push_back(obj); collisionObjects.push_back(obj);
} }
@ -272,16 +293,20 @@ public:
if(rect.first.first + rect.second.first > rightmost_rect.first.first + rightmost_rect.second.first) if(rect.first.first + rect.second.first > rightmost_rect.first.first + rightmost_rect.second.first)
rightmost_obj = obj; rightmost_obj = obj;
} }
render_mutex.unlock();
} }
std::shared_ptr<RenderObject> getObject(int index) { std::shared_ptr<RenderObject> getObject(int index) {
return renderObjects[index]; return renderObjects[index];
} }
void movement() { void movement() {
checkKilled();
render_mutex.lock();
int now_ticks = SDL_GetTicks(); int now_ticks = SDL_GetTicks();
for( const auto &x : renderObjects ) { for( const auto &x : renderObjects ) {
x->move(now_ticks - prev_ticks); x->move(now_ticks - prev_ticks);
} }
prev_ticks = now_ticks; prev_ticks = now_ticks;
render_mutex.unlock();
} }
std::vector<std::shared_ptr<RenderObject>> getCollisions(RenderObject &r) { std::vector<std::shared_ptr<RenderObject>> getCollisions(RenderObject &r) {
if(r.getHidden()) if(r.getHidden())
@ -295,11 +320,14 @@ public:
return ret; return ret;
} }
void renderScene() { void renderScene() {
checkKilled();
render_mutex.lock();
SDL_RenderClear(renderer->getRendererPtr()); SDL_RenderClear(renderer->getRendererPtr());
SDL_RenderCopy(renderer->getRendererPtr(), background->getTexturePtr(), NULL, NULL); SDL_RenderCopy(renderer->getRendererPtr(), background->getTexturePtr(), NULL, NULL);
for( const auto &x : renderObjects ) { for( const auto &x : renderObjects ) {
x->render(); x->render();
} }
render_mutex.unlock();
} }
void presentScene() { void presentScene() {
SDL_RenderPresent(renderer->getRendererPtr()); SDL_RenderPresent(renderer->getRendererPtr());
@ -311,18 +339,24 @@ public:
background = std::make_shared<Texture>(renderer, img_path); background = std::make_shared<Texture>(renderer, img_path);
} }
void updateSizeAndPosition() { void updateSizeAndPosition() {
checkKilled();
render_mutex.lock();
for( auto &x : renderObjects ) { for( auto &x : renderObjects ) {
x->updateSizeAndPosition(); x->updateSizeAndPosition();
for( auto &col : x->getCollisions() ) { for( auto &col : x->getCollisions() ) {
col->updateCollision(x->collisionPushX(), x->collisionPushY(), x->collisionWidth(), x->collisionHeight()); col->updateCollision(x->collisionPushX(), x->collisionPushY(), x->collisionWidth(), x->collisionHeight());
} }
} }
render_mutex.unlock();
} }
void moveEverything(double x, double y) { void moveEverything(double x, double y) {
checkKilled();
render_mutex.lock();
for( auto &obj : renderObjects ) { for( auto &obj : renderObjects ) {
auto curPos = obj->getDoubleRect(); auto curPos = obj->getDoubleRect();
obj->setPos( curPos.first.first + x, curPos.first.second + y ); obj->setPos( curPos.first.first + x, curPos.first.second + y );
} }
render_mutex.unlock();
} }
const std::shared_ptr<RenderObject> &leftmost() { const std::shared_ptr<RenderObject> &leftmost() {
return leftmost_obj; return leftmost_obj;
@ -346,6 +380,20 @@ public:
prev_ticks = ticks; prev_ticks = ticks;
} }
private: private:
void checkKilled() {
render_mutex.lock();
std::vector<int> 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<std::shared_ptr<RenderObject>> renderObjects; std::vector<std::shared_ptr<RenderObject>> renderObjects;
std::vector<std::shared_ptr<RenderObject>> collisionObjects; std::vector<std::shared_ptr<RenderObject>> collisionObjects;
std::shared_ptr<Renderer> renderer; std::shared_ptr<Renderer> renderer;
@ -353,6 +401,8 @@ private:
int prev_ticks = 0; int prev_ticks = 0;
std::shared_ptr<RenderObject> leftmost_obj; std::shared_ptr<RenderObject> leftmost_obj;
std::shared_ptr<RenderObject> rightmost_obj; std::shared_ptr<RenderObject> rightmost_obj;
uint64_t max_object_id = 0;
std::mutex render_mutex;
}; };
class RectangleRender : public RenderObject { class RectangleRender : public RenderObject {
@ -377,6 +427,7 @@ public:
auto texture = std::make_shared<Texture>(r, img_path); auto texture = std::make_shared<Texture>(r, img_path);
setTexture(texture); setTexture(texture);
} }
virtual void specialAction(int /*UNUSED*/) {};
virtual void render() { virtual void render() {
if(texture != NULL && !getHidden()) if(texture != NULL && !getHidden())
SDL_RenderCopy(renderer->getRendererPtr(), texture->getTexturePtr(), NULL, &rect); SDL_RenderCopy(renderer->getRendererPtr(), texture->getTexturePtr(), NULL, &rect);