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);
scene.addObject(x);
player = x;
auto z = std::make_shared<SDLPP::RectangleRender>(0,2.5,100,100,r);
z->addCollision(SDLPP::Rect(0,0,1,1));
auto z = std::make_shared<SDLPP::RectangleRender>(0,2.5,0,0,r);
auto z_col = SDLPP::Rect(-1,0,-1,-1);
z_col.setInfinite();
z->addCollision(z_col);
z->setId(DEATH);
scene.addObject(z);
}
@ -203,6 +205,16 @@ void doInput(std::shared_ptr<SDLPP::Scene> scene) {
}
}
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);
std::thread inputThread(doInput, main_scene);
while( !quit ) {
SDL_framerateDelay(&gFPS);
// SDL_framerateDelay(&gFPS);
main_scene->renderScene();
main_scene->presentScene();
frames++;

View File

@ -66,9 +66,11 @@ bool SDLPP::Rect::colidesWith(const SDLPP::CollisionPolygon &other) const {
if(other.isCircle()) {
return other.colidesWith(*this);
}
if(other.isInfinite()) {
if(other.isInfinite() ) {
return infinityIntersection(other, *this);
}
if(isInfinite())
return infinityIntersection(*this, other);
return intersects(*this, other);
}

View File

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