Hello again! Last week I posted a question about compiling SFML, now I need some help in my code.
I inserted two clips that show the problem: objects glitch through eachother after about 10 objects inserted.
My assumtion is the following:
1.The vector in col when is cleared it remains with a zero? so that messes up the collision tehnique
2.the function build_col is wrong and needs to be redone
I am trying to implement square trees or what are they called to improve my naive collision system
Code:
main.cpp
#include "header.hpp"
#include <fstream>
int main()
{
pushing(0, WINHEIGHT - 1, WINWIDTH, 100, 1);
// std::cout<<pool[0].obj.getPosition().y<<' '<<pool[0].obj.getPosition().y;
srand(time(NULL));
sf::RenderWindow window(sf::VideoMode({WINWIDTH, WINHEIGHT}), "Physics");
window.setFramerateLimit(60);
Clock clock;
clock.start();
while (window.isOpen())
{
delete_col();
build_col();
for (int k = 0; k < pool.size(); k++)
{
pool[k].obj.setPosition(pool[k].obj.getPosition() + Vector2f(float(pool[k].momentumx), float(pool[k].momentumy)));
}
/*for (int i = 1; i <= part; i++)
{
for (int j = 1; j <= part; j++)
{
std::cout<<"\n ."<<col[i][j].size();
}
}*/
int s = 0;
for (int i = 1; i <= part; i++)
{
for (int j = 1; j <= part; j++)
{
s += int(col[i][j].size());
for (int k = 0; k < int(col[i][j].size()) - 1; k++)
{
for (int r = k + 1; r < int(col[i][j].size()); r++)
{
if (colision(pool[k], pool[r]) == 1)
{
if (r == col[i][j].size())
std::cout << 1;
pool[k].momentumy = pool[k].momentumx = pool[r].momentumx = pool[r].momentumy = 0;
}
}
}
std::cout<<'\n';
}
}
/*for (int i = 0; i < pool.size(); i++)
{
//naive
pool[i].obj.setPosition(pool[i].obj.getPosition() + Vector2f(0, float(pool[i].momentumy)));
for(int j = i + 1; j<pool.size(); j++)
{
if(colision(pool[i], pool[j]) == 1)
{
pool[i].momentumx=pool[i].momentumy=0;
pool[j].momentumx=pool[j].momentumy=0;
}
}
}*/
//
if (clock.getElapsedTime() >= seconds(1))
{
for (int i = 0; i < pool.size(); i++)
{
if (pool[i].obj.getPosition().y > WINHEIGHT || pool[i].obj.getPosition().y + pool[i].obj.getSize().y < 0)
pool.erase(pool.begin() + i);
}
clock.restart();
}
while (const std::optional event = window.pollEvent())
{
if (event->is<sf::Event::Closed>())
window.close();
else if (event->is<Event::MouseButtonPressed>())
{
int Mousex, Mousey;
Mousex = Mouse::getPosition(window).x;
Mousey = Mouse::getPosition(window).y;
pushing(Mousex, Mousey, 50, 50);
}
}
window.clear(Color::Black);
for (int i = 0; i < pool.size(); i++)
window.draw(pool[i].obj);
window.display();
}
return 0;
}
header.hpp
#include <SFML/Graphics.hpp>
#include <vector>
#include <iostream>
#include <random>
#define WINWIDTH 1000
#define WINHEIGHT 800
#define part 4 // this is the problem first recording the part was set to 2
using namespace sf;
const int gravity = 10;
class object
{
public:
RectangleShape obj;
Vector2f pos;
float mass = 0.5;
bool physics = true;
float momentumx=0,momentumy = 0;
int collisioncoef = 0;
bool immutable = false;
object() : obj(Vector2f(100.f, 100.f)) {}
void create(int x, int y, Color color, bool imm, int Xsize, int Ysize);
};
void object::create(int x, int y, Color color, bool imm = true, int Xsize=100, int Ysize=100)
{
pos = Vector2f(static_cast<float>(x), static_cast<float>(y));
obj.setSize({static_cast<float>(Xsize), static_cast<float>(Ysize)});
//std::cout<<pos.y;
obj.setPosition(pos);
obj.setFillColor(color);
immutable = imm;
momentumy = gravity * (!immutable);
}
std::vector<object> pool;
void pushing(int Xpos = -1, int Ypos = -1, int Xsize = 100, int Ysize = 100, bool imm = false)
{
object r;
int getsizex = WINWIDTH - Xsize;
int getsizey = WINHEIGHT - Ysize;
if (Xpos == -1 || Ypos == -1)
{
Xpos = rand() % getsizex;
Ypos = rand() % getsizey;
}
Color randomcolor(rand() % 256, rand() % 256, rand() % 256);
r.create(Xpos, Ypos, randomcolor, imm, Xsize, Ysize);
pool.push_back(r);
}
bool colision(object &o1, object &o2)
{
if(o1.obj.getGlobalBounds().findIntersection(o2.obj.getGlobalBounds()))
{
if(o1.obj.getPosition().y<o2.obj.getPosition().y)
{
o1.obj.setPosition(Vector2f(o1.obj.getPosition().x, o2.obj.getPosition().y) + Vector2f(0,float(-o1.obj.getSize().y)));
}
else
{
o2.obj.setPosition(Vector2f(o2.obj.getPosition().x, o1.obj.getPosition().y)+ Vector2f(0,float(-o2.obj.getSize().y)));
}
return 1;
}
return 0;
}
std::vector<int> col[part + 4][part + 4];
int px = WINWIDTH / part, py = WINHEIGHT / part;
void build_col()
{
//lazy way
/* object col2[part+1][part+1];
//lazy init
for(int i = 1; i<=part; i++)
{
for(int j = 1; j<=part; j++)
{
col2[i][j].create((i-1)*px, (j-1)*py, Color::Red,true,px,py);
}
}*/
int sx,sy,fx,fy;//from where to start and to finish pushing back the value
int posx,posy,sizex,sizey;
//std::cout<<1;
for(int i = 0; i<pool.size(); i++)
{
posx = pool[i].obj.getPosition().x;
posy = pool[i].obj.getPosition().y;
sizex = pool[i].obj.getSize().x;
sizey = pool[i].obj.getSize().y;
sx = posx/px + !bool(posx%px);
sy = posy/py + !bool(posy%py);
posx+=sizex;
posy+=sizey;
fx = posx/px + !bool(!posx%px);
fy = posy/py + !bool(!posy%py);
// std::cout<<'\n'<<fx-sx<<' '<<fy-fx;
for(int j = sx; j<=fx; j++)
{
for(int k = sy; k<=fy; k++)
{
col[j][k].push_back(i);
}
}
}
// std::cout<<1;
}
void delete_col()
{
for(int i = 0; i<=part; i++)
{
for(int j = 0; j<=part; j++)
{
col[i][j].clear();
}
}
}