I am making an Asteroids clone in SDL2. I think the kind of world asteroids takes place in is called toroidal map. I'm refering to the fact that the edges of the world are connected so when you exit from one side, you appear at the opposite.
My first approach was with SDL_DrawRect(), but I don't know how to "break" the rectangle in order for it to appear in two (or more) sides at once. I faked the effect by creating another rectangle, like a shadow, when the original rectangle was touching an edge. It worked somehow, but I wanted the real deal: render the diferent parts of the rectangle in different edges.
My second approach is creating the rectangle by SDL_FPoints in a std::vector, like this:
struct SpaceObject {
std::vector<SDL_FPoint> shape_;
// more members
void generateSquareShape(const SDL_FPoint& where);
void move(float delta_time, const SDL_Point& screen_size);
void render(SDL_Renderer& renderer) const;
void warpCoordinates(SDL_FPoint& point, const SDL_Point& screen_size);
// more functions
};
The shape is generated once with generateSquareShape(). It just sets the appropiate coordinates to each SDL_FPoint. The movement function is just applying deltas to each point:
void SpaceObject::move(float delta_time, const SDL_Point& screen_size) {
for (auto& point: shape_) {
point.x += delta_.x * delta_time;
point.y += delta_.y * delta_time;
warpCoordinates(point, screen_size);
}
}
Render is more of the same, another vector travesal:
void SpaceObject::render(SDL_Renderer& renderer) const {
for (const auto& point: shape_) {
SDL_RenderDrawPointF(&renderer, point.x, point.y);
}
}
The warpCoordinates() is called at every move to check if a point must go to another side:
void SpaceObject::warpCoordinates(SDL_FPoint& point, const SDL_Point& screen_size) {
if (point.x < 0) {
point.x = screen_size.x + point.x;
} else if (point.x > screen_size.x - 1u) {
point.x = point.x - screen_size.x;
}
if (point.y < 0) {
point.y = screen_size.y + point.y;
} else if (point.y > screen_size.y - 1u) {
point.y = point.y - screen_size.y;
}
}
All in all it accomplishes with the effect nicely, but I think it performs poorly (at least in my laptop i5 2,6ghz, 6gb RAM, win10) and it hasn't collision detection yet. One optimization I think is moving and rendering on the same function so it only loops through the points vector once, but I think that breaks the one function, one job, doesn't it?
So, is there anything I'm missing to improve performance? A faster algorithm to implement this toroidal world? Maybe a most suitable SDL class to work with? Or some C++ technique I'm not using and I should? Thanks in advance, any help appreciated.
Using win10, SDL2.0.12, and the latest visualC++ compiler.