Add infinite rectangles, make scene move when player gets near the screen's edge

This commit is contained in:
zvon 2020-07-28 19:35:31 +02:00
parent 847b5cbd8e
commit 9db93cd72c
3 changed files with 88 additions and 18 deletions

View File

@ -89,8 +89,10 @@ void addStuff(SDLPP::Scene &scene, std::shared_ptr<SDLPP::Renderer> &r) {
x->setId(PLAYER_ID); x->setId(PLAYER_ID);
scene.addObject(x); scene.addObject(x);
player = x; player = x;
auto z = std::make_shared<SDLPP::RectangleRender>(0,2.5,100,100,r); auto z = std::make_shared<SDLPP::RectangleRender>(0,2.5,0,0,r);
z->addCollision(SDLPP::Rect(0,0,1,1)); auto z_col = SDLPP::Rect(-1,0,-1,-1);
z_col.setInfinite();
z->addCollision(z_col);
z->setId(DEATH); z->setId(DEATH);
scene.addObject(z); scene.addObject(z);
} }
@ -203,6 +205,16 @@ void doInput(std::shared_ptr<SDLPP::Scene> scene) {
} }
} }
player->setGravity(gravity); player->setGravity(gravity);
auto playerX = player->getRect().x;
auto width = scene->getWidth();
auto rightBarrier = width * 0.7;
auto leftBarrier = width * 0.3;
auto rightmostX = scene->rightmost()->getRect().x + scene->rightmost()->getRect().w;
auto leftmostX = scene->leftmost()->getRect().x;
scene->moveEverything(
(playerX > rightBarrier && rightmostX > width) * (rightBarrier - playerX)/width, 0);
scene->moveEverything(
(playerX < leftBarrier && leftmostX < 0) * (leftBarrier - playerX)/width, 0);
} }
} }
@ -229,7 +241,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

@ -69,6 +69,8 @@ bool SDLPP::Rect::colidesWith(const SDLPP::CollisionPolygon &other) const {
if(other.isInfinite() ) { if(other.isInfinite() ) {
return infinityIntersection(other, *this); return infinityIntersection(other, *this);
} }
if(isInfinite())
return infinityIntersection(*this, other);
return intersects(*this, other); return intersects(*this, other);
} }

View File

@ -4,6 +4,7 @@
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include <SDL2/SDL_image.h> #include <SDL2/SDL_image.h>
#include <iostream> #include <iostream>
#include <limits>
#include <memory> #include <memory>
#include <vector> #include <vector>
@ -51,22 +52,22 @@ public:
SDL_Renderer *getRendererPtr() { SDL_Renderer *getRendererPtr() {
return renderer; return renderer;
} }
std::pair<int, int> getDimensions() { std::pair<int, int> getDimensions() const {
int width = 0, height = 0; int width = 0, height = 0;
SDL_GetRendererOutputSize(renderer, &width, &height); SDL_GetRendererOutputSize(renderer, &width, &height);
return {width, height}; return {width, height};
} }
int getWidth() { int getWidth() const {
return getDimensions().first; return getDimensions().first;
} }
int getHeight() { int getHeight() const {
return getDimensions().second; return getDimensions().second;
} }
int getSmallerSide() { int getSmallerSide() const {
auto dimensions = getDimensions(); auto dimensions = getDimensions();
return dimensions.first < dimensions.second ? dimensions.first : dimensions.second; return dimensions.first < dimensions.second ? dimensions.first : dimensions.second;
} }
int getLargerSide() { int getLargerSide() const {
auto dimensions = getDimensions(); auto dimensions = getDimensions();
return dimensions.first > dimensions.second ? dimensions.first : dimensions.second; return dimensions.first > dimensions.second ? dimensions.first : dimensions.second;
} }
@ -151,7 +152,8 @@ public:
virtual ~CollisionPolygon() {} virtual ~CollisionPolygon() {}
virtual bool colidesWith(const CollisionPolygon &other) const = 0; virtual bool colidesWith(const CollisionPolygon &other) const = 0;
virtual bool isCircle() const = 0; virtual bool isCircle() const = 0;
virtual bool isInfinite() const = 0; virtual bool isInfinite() const { return infinite; }
virtual void setInfinite() { infinite = true; }
virtual int topmost() const = 0; virtual int topmost() const = 0;
virtual int bottommost() const = 0; virtual int bottommost() const = 0;
virtual int leftmost() const = 0; virtual int leftmost() const = 0;
@ -171,6 +173,7 @@ protected:
double original_y; double original_y;
int position_x; int position_x;
int position_y; int position_y;
bool infinite = false;
}; };
class RenderObject { class RenderObject {
@ -180,6 +183,8 @@ public:
virtual void render() = 0; virtual void render() = 0;
virtual int leftmost() = 0; virtual int leftmost() = 0;
virtual int topmost() = 0; virtual int topmost() = 0;
virtual int rightmost() = 0;
virtual int bottommost() = 0;
virtual int collisionPushX() = 0; virtual int collisionPushX() = 0;
virtual int collisionPushY() = 0; virtual int collisionPushY() = 0;
virtual int collisionWidth() = 0; virtual int collisionWidth() = 0;
@ -240,6 +245,7 @@ public:
} }
virtual void move(int ticks) = 0; virtual void move(int ticks) = 0;
virtual void updateSizeAndPosition() = 0; virtual void updateSizeAndPosition() = 0;
virtual SDL_Rect getRect() = 0;
protected: protected:
std::vector<std::shared_ptr<CollisionPolygon>> collisions; std::vector<std::shared_ptr<CollisionPolygon>> collisions;
std::shared_ptr<Texture> texture; std::shared_ptr<Texture> texture;
@ -256,12 +262,24 @@ public:
SDL_SetRenderDrawColor(renderer->getRendererPtr(), 0xFF, 0xFF, 0xFF, 0xFF); SDL_SetRenderDrawColor(renderer->getRendererPtr(), 0xFF, 0xFF, 0xFF, 0xFF);
prev_ticks = SDL_GetTicks(); prev_ticks = SDL_GetTicks();
} }
template<class T> void addObject(const std::shared_ptr<RenderObject> &obj) {
void addObject(std::shared_ptr<T> &obj) {
renderObjects.push_back(obj); renderObjects.push_back(obj);
if(obj->hasCollisions()) { if(obj->hasCollisions()) {
collisionObjects.push_back(obj); collisionObjects.push_back(obj);
} }
if(renderObjects.size() == 1) {
leftmost_obj = obj;
rightmost_obj = obj;
} else {
auto rect = obj->getDoubleRect();
auto leftmost_rect = leftmost_obj->getDoubleRect();
if(rect.first.first < leftmost_rect.first.first)
leftmost_obj = obj;
auto rightmost_rect = rightmost_obj->getDoubleRect();
if(rect.first.first + rect.second.first > rightmost_rect.first.first + rightmost_rect.second.first)
rightmost_obj = obj;
}
} }
std::shared_ptr<RenderObject> getObject(int index) { std::shared_ptr<RenderObject> getObject(int index) {
return renderObjects[index]; return renderObjects[index];
@ -303,12 +321,35 @@ public:
x->updateSizeAndPosition(); x->updateSizeAndPosition();
} }
} }
void moveEverything(double x, double y) {
for( auto &obj : renderObjects ) {
auto curPos = obj->getDoubleRect();
obj->setPos( curPos.first.first + x, curPos.first.second + y );
}
}
const std::shared_ptr<RenderObject> &leftmost() {
return leftmost_obj;
}
const std::shared_ptr<RenderObject> &rightmost() {
return rightmost_obj;
}
std::pair<int, int> getDimensions() const {
return renderer->getDimensions();
}
int getWidth() const {
return renderer->getWidth();
}
int getHeight() const {
return renderer->getHeight();
}
private: private:
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;
std::shared_ptr<Texture> background; std::shared_ptr<Texture> background;
int prev_ticks = 0; int prev_ticks = 0;
std::shared_ptr<RenderObject> leftmost_obj;
std::shared_ptr<RenderObject> rightmost_obj;
}; };
class RectangleRender : public RenderObject { class RectangleRender : public RenderObject {
@ -365,6 +406,12 @@ public:
virtual int topmost() { virtual int topmost() {
return rect.y; return rect.y;
} }
virtual int rightmost() {
return rect.x + rect.w;
}
virtual int bottommost() {
return rect.y + rect.h;
}
virtual int collisionPushX() { virtual int collisionPushX() {
return rect.x; return rect.x;
} }
@ -384,6 +431,9 @@ public:
rect.w = w_ * dimension; rect.w = w_ * dimension;
rect.h = h_ * dimension; rect.h = h_ * dimension;
} }
virtual SDL_Rect getRect() {
return rect;
}
protected: protected:
double x_; double x_;
double y_; double y_;
@ -436,11 +486,18 @@ public:
virtual ~Rect() {} virtual ~Rect() {}
virtual bool colidesWith(const CollisionPolygon &other) const override; virtual bool colidesWith(const CollisionPolygon &other) const override;
virtual bool isCircle() const override { return false; } virtual bool isCircle() const override { return false; }
virtual bool isInfinite() const override { return false; } virtual int topmost() const override {
virtual int topmost() const override { return getY(); } return (!isInfinite() || original_y != -1) * getY() + isInfinite() * -1;
virtual int bottommost() const override { return getY() + pixel_h; }; }
virtual int leftmost() const override { return getX(); } virtual int bottommost() const override {
virtual int rightmost() const override { return getX() + pixel_w; } return (!isInfinite() || h_ != -1) * (getY() + pixel_h) + isInfinite() * -1;
};
virtual int leftmost() const override {
return (!isInfinite() || original_x != -1) * getX() + isInfinite() * -1;
}
virtual int rightmost() const override {
return (!isInfinite() || w_ != -1) * (getX() + pixel_w) + isInfinite() * -1;
}
virtual void updateCollision(int x, int y, int w, int h) override { virtual void updateCollision(int x, int y, int w, int h) override {
position_x = original_x * w + x; position_x = original_x * w + x;
position_y = original_y * h + y; position_y = original_y * h + y;
@ -462,7 +519,6 @@ public:
virtual ~Circle() {} virtual ~Circle() {}
virtual bool colidesWith(const CollisionPolygon &other) const; virtual bool colidesWith(const CollisionPolygon &other) const;
virtual bool isCircle() const { return true; } virtual bool isCircle() const { return true; }
virtual bool isInfinite() const { return false; }
virtual int topmost() const { return getY() - rad_; } virtual int topmost() const { return getY() - rad_; }
virtual int bottommost() const { return getY() + rad_; }; virtual int bottommost() const { return getY() + rad_; };
virtual int leftmost() const { return getX() - rad_; } virtual int leftmost() const { return getX() - rad_; }