Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: strange behaviour caused by a simple variable change  (Read 264 times)

0 Members and 3 Guests are viewing this topic.

floppa_dev

  • Newbie
  • *
  • Posts: 18
    • View Profile
strange behaviour caused by a simple variable change
« on: January 14, 2025, 02:23:01 pm »
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<<&#39; &#39;<<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<<&#39;\n&#39;;
            }
        }
        /*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<<&#39;\n&#39;<<fx-sx<<&#39; &#39;<<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();
        }
    }
}


eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11084
    • View Profile
    • development blog
    • Email
Re: strange behaviour caused by a simple variable change
« Reply #2 on: January 16, 2025, 01:38:46 pm »
Not sure if anyone has the patience to analyze your physics code.

I recommend to use a debugger with break points to step through your code and see where exactly the math breaks.
Official FAQ: https://www.sfml-dev.org/faq/
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

floppa_dev

  • Newbie
  • *
  • Posts: 18
    • View Profile
Re: strange behaviour caused by a simple variable change
« Reply #3 on: January 16, 2025, 08:16:20 pm »
rewriting?  :-\
also can you please tell some way to generate a fast collision system?
thank you so much for your time