I'm making a physics engine, as of current I'm implementing gravity. I've implemented it fine, however I preferably want multiple shapes to play around with. So, I created a function
std::vector<RectangleData> CreateRectangle(int Amount, std::vector<sf::Vector2f> Pos);
, in which RectangleData is a union consisting of an sf::RectangleShape pointer, bounciness of the rectangle, it's current fall speed, and it's terminal velocity.
So then, in the function, I create the RectangleShape, set the pointer in the RectangleData union to be pointing to it, set all the other values, add it to the return array, however when drawing it, it segfaults. After testing this, it appears to be segfaulting as the pointer in the union is a null pointer, despite I set it to be pointing. Here is my code:
#include <SFML/Graphics.hpp>
#include <iostream>
#include <vector>
union RectangleData {
sf::RectangleShape *Rectangle=nullptr;
double RectangleTerminalVelocity;
double RectangleBouncyness;
double RectangleFallSpd;
};
bool IsInside(sf::Vector2f Size, sf::Vector2i Pos1, sf::Vector2f Pos2);
std::vector<RectangleData> CreateRectangle(int Amount, std::vector<sf::Vector2f>Pos);
//void HandleRectanglePhysics(std::vector<*sf::RectangleShape> Rectangles, std::vector<double> TerminalVelocity, std::vector<double>Bouncyness);
int main() {
std::vector<RectangleData> Rectangles = CreateRectangle(1, {sf::Vector2f(100, 0)});
double WantedFps = 60;
double AccelerationSpd = 1.5;
double Rectangle1TerminalVelocity =4;
double Rectangle1Bouncyness = 1.525;
sf::RenderWindow Window(sf::VideoMode(800, 600), "Physics Engine");
sf::RectangleShape Rectangle1(sf::Vector2f(50, 50));
double Rectangle1FallSpd =0;
sf::Clock Frame;
while (Window.isOpen()){
if (Frame.getElapsedTime() >= sf::seconds(1/WantedFps)){
if (sf::Mouse::isButtonPressed(sf::Mouse::Left) && IsInside(Rectangle1.getSize(), sf::Mouse::getPosition(Window), Rectangle1.getPosition())){
Rectangle1.setPosition(static_cast<sf::Vector2f>(sf::Mouse::getPosition(Window)));
Rectangle1.move(sf::Vector2f(Rectangle1.getSize().x/-2, Rectangle1.getSize().y/-2));
Rectangle1FallSpd = 0;
}
else {
Rectangle1FallSpd += AccelerationSpd/WantedFps;
Rectangle1.move(sf::Vector2f(0, Rectangle1FallSpd));
if (Rectangle1FallSpd >= Rectangle1TerminalVelocity){
Rectangle1FallSpd = Rectangle1TerminalVelocity;
}
}
if (Rectangle1.getPosition().y >= 550){
Rectangle1.setPosition(sf::Vector2f(Rectangle1.getPosition().x, 550));
Rectangle1FallSpd -= Rectangle1FallSpd*Rectangle1Bouncyness;
}
sf::Event Event;
while (Window.pollEvent(Event)){
if (Event.type == sf::Event::Closed){
Window.close();
}
}
Window.clear();
Window.draw(Rectangle1);
//Window.draw(*Rectangles.at(0).Rectangle);
Window.display();
Frame.restart();
}
}
}
bool IsInside(sf::Vector2f Size, sf::Vector2i Pos1i, sf::Vector2f Pos2){
sf::Vector2f Pos1 = static_cast<sf::Vector2f>(Pos1i);
if (Pos2.x + Size.x >= Pos1.x && Pos2.y + Size.y >= Pos1.y && Pos1.x >= Pos2.x && Pos1.y >= Pos2.y){
return true;
}
return false;
}
std::vector<RectangleData> CreateRectangle(int Amount, std::vector<sf::Vector2f> Pos){
std::vector<RectangleData> RectangleDataVec;
for (int i=0; i<Amount; i++){
sf::RectangleShape RectangleInstance(sf::Vector2f(50, 50));
RectangleInstance.setPosition(Pos.at(i));
RectangleData RectInstance;
RectInstance.Rectangle = &RectangleInstance;
RectInstance.RectangleTerminalVelocity = 4;
RectInstance.RectangleFallSpd = 0;
RectInstance.RectangleBouncyness=1.525;
RectangleDataVec.push_back(RectInstance);
std::cout << RectInstance.Rectangle << "\n" << &RectangleInstance;
}
return RectangleDataVec;
}