Войти
Box2D

Box2D


СтатьиДокументацияФорумИнфо

Форум

Создание b2ContactListener8 янв. 202120:17matrixoidr
Добрый день. У меня есть class CONTACT_LISTENER : public b2ContactListener{...}, и класс игрока и мяча. Проблема заключается в том, что ContactListener не обнаруживает контакт двух тел (в каждой функции ContactListener я поставил вывод сообщений, и ни одно сообщение не выводилось). Хотя я запускал обычный цикл вне класса ContactListener и контакт находился. Мне кажется, что проблема состоит в SetContactListener, или как по сути активировать ContactListener. В статье я нашел следующие строки и использую их:
CONTACT_LISTENER contact_listener_instance;
World.SetContactListener(&contact_listener_instance);

Классы персонажа и мяча:

class PLAYER
    {
    public:
        Texture texture_player_move;
        Sprite sprite_player_move;
        b2BodyDef body_def;
        b2PolygonShape player_shape;
        b2Body *body;
        b2FixtureDef body_fixture;
        PLAYER* player_data = this;
     
        bool canHit = false;
     
        PLAYER(String path, int X_rect, int Y_rect, int W_rect, int H_rect,  float X_pos, float Y_pos)
        {
            std::cout << "player ready";
            texture_player_move.loadFromFile(path);
            texture_player_move.setSmooth(true);
            sprite_player_move.setTexture(texture_player_move);
            sprite_player_move.setOrigin(135, 240);
            sprite_player_move.setTextureRect(IntRect(X_rect, Y_rect, W_rect, H_rect));
     
            body_def.type = b2_dynamicBody;
            body_def.position.Set(X_pos, Y_pos);
            player_shape.SetAsBox(60 / SCALE, 160 / SCALE);
            body = World.CreateBody(&body_def);
     
            body_fixture.shape = &player_shape;
            body_fixture.filter.categoryBits = 0xFFFF; // 0x0004
            body_fixture.filter.maskBits = 0xFFFF; // 0x0002 | 0x0008
            body_fixture.density = 1;
            body->CreateFixture(&body_fixture);
            body->SetFixedRotation(true);
            body->SetUserData(this);
        }
    };
     
     
    class BALL
    {
    public:
        Texture texture_ball;
        Sprite sprite_ball;
        b2BodyDef body_def;
        b2CircleShape ball_shape;
        b2Body* ball;
        b2FixtureDef ball_fixture;
        BALL* ball_data = this;
        BALL()
        {
            texture_ball.loadFromFile("C://Users/1/source/repos/Game Volley/Game Volley/images/ball.png");
            texture_ball.setSmooth(true);
            sprite_ball.setTexture(texture_ball);
            sprite_ball.setOrigin(32, 32);
     
            body_def.type = b2_dynamicBody;
            body_def.position.Set(10, -5);
            ball_shape.m_radius = 32 / SCALE;
            ball = World.CreateBody(&body_def);
     
            ball_fixture.shape = &ball_shape;
            ball_fixture.filter.categoryBits = 0xFFFF; //0x0008
            ball_fixture.filter.maskBits = 0xFFFF; //0x0002
            ball_fixture.restitution = 0.75;
            ball_fixture.density = 0.2;
            ball->CreateFixture(&ball_fixture);
            ball->SetUserData(this);
        }
    };

ContactListener:

class CONTACT_LISTENER : public b2ContactListener
    {
        void BeginContact(b2Contact* contact)
        {
            std::cout << "beginContact";
        }
     
        void EndContact(b2Contact* contact)
        {
            std::cout << "endContact";
        }
     
        void PreSolve(b2Contact* contact, b2Manifold* oldManifold)
        {
            std::cout << "preSolve";
            if (contact->GetFixtureA()->GetBody() == Player_1.body && contact->GetFixtureB()->GetBody() == Ball.ball
                || contact->GetFixtureA()->GetBody() == Ball.ball && contact->GetFixtureB()->GetBody() == Player_1.body)
            {
                if (Player_1.canHit and onGround) {
                    std::cout << "preSolve";
                    //меняем направление
                    float ball_x = Ball.ball->GetPosition().x; // нахожу позицию мяча по X
                    float Distance = (1920 / 2) - (ball_x * SCALE); //Окно 1920x1080, делю на 2 - нахожу центр, перевожу в метры и отнимаю позицию мяча по X.
                    float Height = 250; //высота моей сетки 250 пикселей, делю, перевожу в метры
                    float Time = Height / 9.81; //Рассчет времени
                    Ball.ball->SetLinearVelocity(b2Vec2(Distance / Time, Time)); //Изменение скорости мяча
                }
                contact->SetEnabled(false);
            }
        }
     
        void PostSolve(b2Contact* contact, b2ContactImpulse* impulse)
        {
            std::cout << "postSolve";
        }
    };

Буду рад помощи! Заранее спасибо!

Проблема контакта двух тел.27 дек. 202019:03matrixoidr
Добрый день. Пишу код игры про волейбол. Решил реализовать прием мяча в прыжке ( то есть удар) и прием стоя. Имею почти два одинаковых условия этих событий. Проблема в том, что когда мой персонаж на земле (onGround == true), контакт между двумя телами (персонажем и мячом) не обнаруживается, а когда персонаж в прыжке (onGround == false) - все отлично выполняется, контакт находится. Буду благодарен, если кто разъяснит в чем проблема, или укажет на возможные её причины. Заранее спасибо!

Проверка персонажа на нахождение на земле:

onGround = false;
    position = body_1->GetPosition();
    position.y += 161 / SCALE;
    for (b2Body* it = World.GetBodyList(); it != 0; it = it->GetNext())
      for (b2Fixture *f = it->GetFixtureList(); f != 0; f = f->GetNext())
        if (f->TestPoint(position))  onGround = true;

Проверка на контакт двух тел:

is_contact = false;
    for (b2Contact* contact = World.GetContactList(); contact; contact = contact->GetNext())
    {
      if ((contact->GetFixtureA()->GetBody() == body_1 && contact->GetFixtureB()->GetBody() == ball)
        || (contact->GetFixtureA()->GetBody() == ball && contact->GetFixtureB()->GetBody() == body_1))
      {
        is_contact = true;
        break;
      }
    }

Условие приема мяча на земле:

if (Keyboard::isKeyPressed(Keyboard::Q) and onGround)
    {
      //std::cout << "удар на земле " << onGround;
      for (b2Fixture* fix = ball->GetFixtureList(); fix; fix = fix->GetNext())
      {
        b2Filter filter = fix->GetFilterData();

        filter.categoryBits = 0x0008;
        filter.maskBits = 0x0002 | 0x0004;
        fix->SetFilterData(filter);
      }
      std::cout << "Контакт: " << is_contact << std::endl;
      if (is_contact)
      {
        ball->SetLinearVelocity(b2Vec2(20, -20));
      }
    }
else {
      for (b2Fixture* fix = ball->GetFixtureList(); fix; fix = fix->GetNext())
      {
        b2Filter filter = fix->GetFilterData();

        filter.categoryBits = 0x0008;
        filter.maskBits = 0x0002;
        fix->SetFilterData(filter);
      }
    }

Условие приема мяча в прыжке (в воздухе):

if (Keyboard::isKeyPressed(Keyboard::Q) and !onGround)
    {
      //std::cout << "удар на воздухе " << onGround;
      for (b2Fixture* fix = ball->GetFixtureList(); fix; fix = fix->GetNext())
      {
        b2Filter filter = fix->GetFilterData();

        filter.categoryBits = 0x0008;
        filter.maskBits = 0x0002 | 0x0004;
        fix->SetFilterData(filter);
      }
      //std::cout << "Контакт: " << is_contact << std::endl;
      if (is_contact)
      {
        float S = 35 - ball->GetPosition().Length();
        float h = 250 / SCALE;
        float t = h / 9.81;
        ball->SetLinearVelocity(b2Vec2((S / t), t));
      }
    }
else {
      for (b2Fixture* fix = ball->GetFixtureList(); fix; fix = fix->GetNext())
      {
        b2Filter filter = fix->GetFilterData();

        filter.categoryBits = 0x0008;
        filter.maskBits = 0x0002;
        fix->SetFilterData(filter);
      }
    }

Правка: 29 дек. 2020 14:05

Проблема многократного прыжка персонажа26 дек. 202020:03matrixoidr
Я столкнулся с проблемой многократного прыжка персонажа, то есть при нажатии одной клавиши игрок прыгает, и при повторном нажатии игрок прыгает не с земли, а с воздуха. Я считаю, что для решения этой проблемы нужна проверка на нахождение игрока на земли. Другими словами: игрок может прыгать только тогда, когда он на земле, и когда нажата клавиша для прыжка. Сделать это легко, если у твоего персонажа нет анимации (текущего кадра, переключения спрайтов). Но в моей игре я уже добавил анимацию... Возможно ли реализовать прыжок при таких условиях? Буду рад помощи!

Вот код моего удара в прыжке(4 кадра анимации):

if (Keyboard::isKeyPressed(Keyboard::W) and Keyboard::isKeyPressed(Keyboard::Q)) //vertical jump + attack
    {
      if (position.y*SCALE >= 400)
      {
        if (CurrentJumpFrame > 3.5 or !(Keyboard::isKeyPressed(Keyboard::W)))
        {
          if (onGround)
          {
            std::cout << " На земле ";
            sprite_player_1_move.setTextureRect(IntRect(0, 480, 270, 480));
            velocity.y = 0;
            CurrentJumpFrame = 0;
          }
          else
          {
            std::cout << " Конец прыжка! ";
            sprite_player_1_move.setTextureRect(IntRect(270, 0, 270, 480));
            velocity.y = 0.4*time;
          }
        }
        else {
          std::cout << " Прыжок! ";
          CurrentJumpFrame += player_1_speed * time;
          sprite_player_1_move.setTextureRect(IntRect(int(CurrentJumpFrame) * 270, 0, 270, 480));
          velocity.y = -0.2*time;
          std::cout << CurrentJumpFrame << std::endl;
        }
        std::cout << sprite_player_1_move.getTextureRect().width << std::endl;
      }
    }

Вот код проверки, находится ли персонаж на земле (Но я его не использую, т.к. не знаю куда его впихнуть учитывая анимацию):

bool onGround = false;
    position = body_1->GetPosition();
    position.y += 161 / SCALE;
    for (b2Body* it = World.GetBodyList(); it != 0; it = it->GetNext())
      for (b2Fixture *f = it->GetFixtureList(); f != 0; f = f->GetNext())
        if (f->TestPoint(position))  onGround = true;

Ошибка в Box2D (C++).20 дек. 202016:28matrixoidr
Пишу взаимодействие персонажа и мяча в игре (волейбол), то есть их столкновение. При выполнении кода появляется ошибка. Буду рад, если кто поможет решить проблему.

Ошибка:

Assertion failed: fixture->m_body == this, file d:\c++\box2d_v2.3.0\box2d\box2d\dynamics\b2body.cpp, line 222

Код создания мяча:

body_def.position.Set(10, 0);
  b2CircleShape ball_shape;
  ball_shape.m_radius = 32 / SCALE;
  b2Body* ball = World.CreateBody(&body_def);

  b2FixtureDef ball_fixture;
  ball_fixture.shape =  &ball_shape;
  ball_fixture.filter.categoryBits = 0x2;
  ball_fixture.filter.maskBits = 0x4;

  ball_fixture.restitution = 0.75;
  ball_fixture.density = 0.5;
  b2Fixture* fixture = ball->CreateFixture(&ball_fixture);

  const char* ball_name[] = { "ball" };
  ball->SetUserData(ball_name);

Условие нажатия клавиши:

if (Keyboard::isKeyPressed(Keyboard::Q)) 
    {
      ball->DestroyFixture(fixture);

      // Creating CircleShape object
      b2CircleShape ball_shape;
      ball_shape.m_radius = 32 / SCALE;
      b2Body* ball = World.CreateBody(&body_def);

      b2FixtureDef ball_fixture;
      ball_fixture.shape = &ball_shape;
      ball_fixture.restitution = 0.75;
      ball_fixture.density = 0.5;

      ball_fixture.filter.categoryBits = 0x3;
      ball_fixture.filter.maskBits = 0x3;

      //b2Fixture* ball->CreateFixture(ball_fixture);
      b2Fixture* fixture = ball->CreateFixture(&ball_fixture);

      const char* ball_name[] = { "ball" };
      ball->SetUserData(ball_name);

      position = ball->GetPosition();
      int a = position.y;
      position = body_1->GetPosition();
      int b = position.y;
      if (a < b) {
        if (is_contact)
        {
          std::cout << position.Length() << std::endl;
          float S = 35 - ball->GetPosition().Length();  //расстояние от центра поля до мяча
          float h = 250 / SCALE;  //высота сетки
          float t = h / 9.81;
          ball->SetLinearVelocity(b2Vec2((S / t) * 8, t * 32));
          std::cout << S << " " << h << " " << t << " (" << (S / t) << ", " << t * 2 << ")" << std::endl;
        }
      }
    }

Правка: 16:29

Проблема траектории объекта при воздействии на него другого объека в Box2D.18 дек. 202018:21matrixoidr
Напоминаю, что я делаю 2D Волейбол используя Box2D, SFML и C++.
Мне надо сделать такую физику, что при нажатии определенной клавиши 'Q' к примеру, игрок отправлял мяч на сторону площадки противника по параболе. То есть в зависимости от близости игрока к сетки или дальности строилась определенная траектория мяча в виде параболы.

Пример траектории мяча:
Пример траектории мяча |

Вот код игры:

void game_2_players(RenderWindow & window)
{
  window.setFramerateLimit(60);
  Texture texture_court, texture_ball, texture_player_1, texture_player_2;
  texture_court.loadFromFile("C://Users/1/source/repos/Game Volley/Game Volley/images/court.png");
  texture_ball.loadFromFile("C://Users/1/source/repos/Game Volley/Game Volley/images/ball.png");
  texture_player_1.loadFromFile("C://Users/1/source/repos/Game Volley/Game Volley/images/player_1.png");
  texture_player_2.loadFromFile("C://Users/1/source/repos/Game Volley/Game Volley/images/player_2.png");
  texture_court.setSmooth(true);
  texture_ball.setSmooth(true);
  texture_player_1.setSmooth(true);
  texture_player_2.setSmooth(true);

  Sprite sprite_background(texture_court), sprite_ball(texture_ball), sprite_player_1(texture_player_1), sprite_player_2(texture_player_2);
  sprite_player_1.setOrigin(110, 145);
  sprite_player_2.setOrigin(110, 145);
  sprite_ball.setOrigin(32, 32);


  //////////////////////////////////////Box2D/////////////////////////////////////


  seting_walls(0, 849, 2000, 10); //нижняя 
  seting_walls(960, 830, 95, 350); //центральная
  seting_walls(0, 0, 70, 2000); //боковая левая
  seting_walls(1920, 0, 70, 2000); //боковая правая

  b2BodyDef body_def;
  body_def.type = b2_dynamicBody;


  //////////////////////////////////////Box2D.../////////////////////////////////////


  //////////////////////////////////////players/////////////////////////////////////


  //1


  body_def.position.Set(4, 10); //4 28
  b2CircleShape player_1_shape;
  player_1_shape.m_radius = 32 / SCALE;
  b2Body *body_1 = World.CreateBody(&body_def);

  b2FixtureDef body_1_fixture;
  body_1_fixture.shape = &player_1_shape;
  body_1->CreateFixture(&body_1_fixture);

  body_1->SetFixedRotation(true);
  const char* player1[] = { "player1" };
  body_1->SetUserData(player1);

  //2

  body_def.position.Set(60, 28);
  b2CircleShape player_2_shape;
  player_2_shape.m_radius = 32 / SCALE;
  b2Body *body_2 = World.CreateBody(&body_def);
  b2FixtureDef body_2_fixture;
  body_2_fixture.shape = &player_2_shape;
  body_2->CreateFixture(&body_2_fixture);
  body_2->SetFixedRotation(true);
  const char* player2[] = { "player2" };
  body_2->SetUserData(player2);


  //////////////////////////////////////players.../////////////////////////////////////


  //////////////////////////////////////ball/////////////////////////////////////


  body_def.position.Set(5, 1);
  b2CircleShape ball_shape;
  ball_shape.m_radius = 32 / SCALE;
  b2Body *ball = World.CreateBody(&body_def);
  b2FixtureDef ball_fixture;
  ball_fixture.shape = &ball_shape;
  ball_fixture.restitution = 0.95;
  ball_fixture.density = 0.2;
  ball->CreateFixture(&ball_fixture);
  ball->CreateFixture(&ball_fixture);
  const char* ball_name[] = { "ball" };
  ball->SetUserData(ball_name);


  //////////////////////////////////////ball/////////////////////////////////////


  while (window.isOpen())
  {
    Event event;
    while (window.pollEvent(event))
    {
      if (event.type == Event::Closed)
        window.close();
    }


    b2Vec2 velocity;
    b2Vec2 position;

    //////////////////////////////////////speed/////////////////////////////////////


    for (int speed = 0; speed < 2; speed++) 
      World.Step(1 / 60.f, 8, 3);


    //////////////////////////////////////speed...////////////////////////////////////


    //is_contact


    bool is_contact = false;
    for (b2Contact* contact = World.GetContactList(); contact; contact = contact->GetNext())
    {
      if ((contact->GetFixtureA()->GetBody() == body_1 && contact->GetFixtureB()->GetBody() == ball)
        || (contact->GetFixtureA()->GetBody() == ball && contact->GetFixtureB()->GetBody() == body_1))
      {
        if ((ball->GetPosition().Length() < body_1->GetPosition().Length())) {
          is_contact = true;
          std::cout << "Есть контакт ";
          break;
        }
      }
    }


    //is_contact...
    

    //////////////////////////////////////player_1///////////////////////////////////// 


    //check if player 1 on ground


    bool onGround = false;
    position = body_1->GetPosition();
    position.y += 17 / SCALE;
    for (b2Body* it = World.GetBodyList(); it != 0; it = it->GetNext())
      for (b2Fixture *f = it->GetFixtureList(); f != 0; f = f->GetNext())
        if (f->TestPoint(position))  onGround = true;
  

    //check if player 1 on ground...


    position = body_1->GetPosition();
    velocity = body_1->GetLinearVelocity();


    if (Keyboard::isKeyPressed(Keyboard::D)) velocity.x = 5;
    if (Keyboard::isKeyPressed(Keyboard::A)) velocity.x = -5; 
    if (Keyboard::isKeyPressed(Keyboard::W) and onGround)
    {
      if (position.y*SCALE >= 400) velocity.y = -10;
    }
    if (!Keyboard::isKeyPressed(Keyboard::D))
      if (!Keyboard::isKeyPressed(Keyboard::A))
        velocity.x = 0;

    if (Keyboard::isKeyPressed(Keyboard::Q)) {
      if (is_contact) {
        velocity = ball->GetLinearVelocity();
        ball->SetLinearVelocity(30 / velocity.Length() * velocity);
        //ball->SetAngularVelocity(45);
      }
    }

    body_1->SetLinearVelocity(velocity);


    //////////////////////////////////////player_1...///////////////////////////////////// 

    
    //////////////////////////////////////player_2///////////////////////////////////// 


    //check if player 2 on ground


    bool onGround_2 = false;
    position = body_2->GetPosition();
    position.y += 17 / SCALE;
    for (b2Body* it = World.GetBodyList(); it != 0; it = it->GetNext())
      for (b2Fixture *f = it->GetFixtureList(); f != 0; f = f->GetNext())
        if (f->TestPoint(position))  onGround_2 = true;


    //check if player 2 on ground...


    position = body_2->GetPosition();
    velocity = body_2->GetLinearVelocity();


    if (Keyboard::isKeyPressed(Keyboard::Right))  velocity.x = 5;
    if (Keyboard::isKeyPressed(Keyboard::Left))  velocity.x = -5;
    if (Keyboard::isKeyPressed(Keyboard::Up) and onGround_2)
    {
      if (position.y*SCALE >= 400)
      {
        velocity.y = -10;
      }
    }
    if (!Keyboard::isKeyPressed(Keyboard::Right))
      if (!Keyboard::isKeyPressed(Keyboard::Left))
        velocity.x = 0;

    body_2->SetLinearVelocity(velocity);


    //////////////////////////////////////player_2...///////////////////////////////////// 


    //////////////////////////////////////ball max speed///////////////////////////////////// 


    velocity = ball->GetLinearVelocity();
    if (velocity.Length() > 15) ball->SetLinearVelocity(15 / velocity.Length() * velocity);


    //////////////////////////////////////ball max speed...///////////////////////////////////// 


    //////////////////////////////////////draw///////////////////////////////////// 


    window.draw(sprite_background);

    for (b2Body* it = World.GetBodyList(); it != 0; it = it->GetNext())
    {
      b2Vec2 position = it->GetPosition();
      float angle = it->GetAngle();

      if (it->GetUserData() == player1)
      {
        sprite_player_1.setPosition(position.x*SCALE, position.y*SCALE);
        sprite_player_1.setRotation(angle*DEG);
        window.draw(sprite_player_1);
      }

      if (it->GetUserData() == player2)
      {
        sprite_player_2.setPosition(position.x*SCALE, position.y*SCALE);
        sprite_player_2.setRotation(angle*DEG);
        window.draw(sprite_player_2);
      }

      if (it->GetUserData() == ball_name)
      {
        sprite_ball.setPosition(position.x*SCALE, position.y*SCALE);
        sprite_ball.setRotation(angle*DEG);
        //std::cout << angle;
        sprite_ball.setColor(Color::Red);
        window.draw(sprite_ball);
        
      }
    }
    window.display();


    //////////////////////////////////////draw...///////////////////////////////////// 
  }
}
Проблема контакта объектов в Box2D.17 дек. 202019:17matrixoidr
В ходе написания кода возникла проблема с приемом мяча игроком. Иными словами, как сделать так, чтобы игрок мог отбивать мяч не всегда, а при нажатии допустим клавиши "Space"? Если в Box2D сделать объект, то при контакте с мячом он будет отбиваться всегда. Возможно ли сделать моего игрока делать объектом не всегда, или какими-то другими способами решить эту проблему?

Вот код функции:

void game_2_players(RenderWindow & window) 
{
  window.setFramerateLimit(60);
  Texture t1, t2, t3, t4;
  t1.loadFromFile("C://Users/1/source/repos/Game Volley/Game Volley/images/court.png");
  t2.loadFromFile("C://Users/1/source/repos/Game Volley/Game Volley/images/ball.png");
  t3.loadFromFile("C://Users/1/source/repos/Game Volley/Game Volley/images/player_1.png");
  t4.loadFromFile("C://Users/1/source/repos/Game Volley/Game Volley/images/player_2.png");
  t1.setSmooth(true);
  t2.setSmooth(true);
  t3.setSmooth(true);
  t4.setSmooth(true);

  Sprite sBackground(t1), sBall(t2), sPlayer_1(t3), sPlayer_2(t4);
  sPlayer_1.setOrigin(110, 145);
  sPlayer_2.setOrigin(110, 145);
  sBall.setOrigin(32, 32);

  /////////box2d///////////
  setWall(960, 840, 2000, 10); //нижняя 
  setWall(960, 830, 95, 350); //центральная
  setWall(0, 0, 70, 2000); //боковая левая
  setWall(1920, 0, 70, 2000); //боковая правая

  b2BodyDef body_def;
  body_def.type = b2_dynamicBody;

  /////players/////////

  //1

  //НЕДОПИСАННЫЙ КОД, ДУМАЛ КАК РЕШИТЬ ПРОБЛЕМУ...

  body_def.position.Set(4, 28);
  b2PolygonShape shape_1;
  shape_1.SetAsBox(1.0f, 1.0f);
  //circle_1.m_radius = 20 / SCALE; 
  //circle_1.m_p.Set(0, 0 / SCALE);

  b2Body* body_1 = World.CreateBody(&body_def);
  b2FixtureDef fixture_def_1;
  fixture_def_1.shape = &shape_1;
  fixture_def_1.density = 1.0f;

  body_1->CreateFixture(&fixture_def_1);
  body_1->SetFixedRotation(true);
  const char* player1[] = { "player1" };
  body_1->SetUserData(player1);

  //2

  body_def.position.Set(60, 28);
  b2CircleShape circle_2;
  circle_2.m_radius = 0 / SCALE;
  //circle_2.m_p.Set(0, 0 / SCALE);
  b2Body *body_2 = World.CreateBody(&body_def);
  body_2->CreateFixture(&circle_2, 5);
  body_2->SetFixedRotation(true);
  const char* player2[] = { "player2" };
  body_2->SetUserData(player2);

  //////ball//////
  body_def.position.Set(5, 1); //7 27
  b2CircleShape circle;
  //circle.m_radius = 32 / SCALE;
  b2Body *ball = World.CreateBody(&body_def);
  b2FixtureDef fdef;
  fdef.shape = &circle;
  fdef.restitution = 0.95;
  fdef.density = 0.2;
  ball->CreateFixture(&fdef);
  const char* ball_name[] = { "ball" };
  ball->SetUserData(ball_name);
  /////////////////////////


  while (window.isOpen())
  {
    Event e;
    while (window.pollEvent(e))
    {
      if (e.type == Event::Closed)
        window.close();
    }

    for (int n = 0; n < 2; n++) // 2 - speed
      World.Step(1 / 60.f, 8, 3);

    
    //player1 

    /////check if player 1 on ground//////
    bool onGround = false;
    b2Vec2 pos = body_1->GetPosition();
    pos.y += 17 / SCALE;
    for (b2Body* it = World.GetBodyList(); it != 0; it = it->GetNext())
      for (b2Fixture *f = it->GetFixtureList(); f != 0; f = f->GetNext())
        if (f->TestPoint(pos))  onGround = true;
    /////////////////////////////

    pos = body_1->GetPosition();
    b2Vec2 vel = body_1->GetLinearVelocity();


    if (Keyboard::isKeyPressed(Keyboard::D))  vel.x = 5;
    if (Keyboard::isKeyPressed(Keyboard::A))   vel.x = -5;
    if (Keyboard::isKeyPressed(Keyboard::W) and onGround)
    {
      if (pos.y*SCALE >= 400) vel.y = -10;
    }
    if (!Keyboard::isKeyPressed(Keyboard::D))
      if (!Keyboard::isKeyPressed(Keyboard::A))
        vel.x = 0;


    body_1->SetLinearVelocity(vel);

    
    //player2 

    /////check if player 2 on ground//////
    bool onGround_2 = false;
    pos = body_2->GetPosition();
    pos.y += 17 / SCALE;
    for (b2Body* it = World.GetBodyList(); it != 0; it = it->GetNext())
      for (b2Fixture *f = it->GetFixtureList(); f != 0; f = f->GetNext())
        if (f->TestPoint(pos))  onGround_2 = true;
    /////////////////////////////

    pos = body_2->GetPosition();
    vel = body_2->GetLinearVelocity();


    if (Keyboard::isKeyPressed(Keyboard::Right))  vel.x = 5;
    if (Keyboard::isKeyPressed(Keyboard::Left))  vel.x = -5;
    if (Keyboard::isKeyPressed(Keyboard::Up) and onGround_2)
    {
      if (pos.y*SCALE >= 400)
      {
        vel.y = -10;
      }
    }
    if (!Keyboard::isKeyPressed(Keyboard::Right))
      if (!Keyboard::isKeyPressed(Keyboard::Left))
        vel.x = 0;

    body_2->SetLinearVelocity(vel);

    //ball max speed
    vel = ball->GetLinearVelocity();
    if (vel.Length() > 15) ball->SetLinearVelocity(15 / vel.Length() * vel);

    //////////Draw///////////////
    window.draw(sBackground);

    for (b2Body* it = World.GetBodyList(); it != 0; it = it->GetNext())
    {
      b2Vec2 pos = it->GetPosition();
      float angle = it->GetAngle();

      if (it->GetUserData() == player1)
      {
        sPlayer_1.setPosition(pos.x*SCALE, pos.y*SCALE);
        sPlayer_1.setRotation(angle*DEG);
        window.draw(sPlayer_1);
      }

      if (it->GetUserData() == player2)
      {
        sPlayer_2.setPosition(pos.x*SCALE, pos.y*SCALE);
        sPlayer_2.setRotation(angle*DEG);
        window.draw(sPlayer_2);
      }

      if (it->GetUserData() == ball_name)
      {
        sBall.setPosition(pos.x*SCALE, pos.y*SCALE);
        sBall.setRotation(angle*DEG);
        window.draw(sBall);
      }
    }
    window.display();
  }
}

Правка: 19:22

Подскажите, пожалуйста, почему машинка не едет?1 янв. 19703:00SourceOfDeath
Смена ориентации сложного тела. Движение вправо и влево1 янв. 19703:00NSX
Движение объекта в зависимости от угла1 янв. 19703:00ProQsy
Уперания объекта об угол1 янв. 19703:00ProQsy
Автосалон Hyundai https://www.hyundai-losinyostrov.ru/ на Ярославском шоссе. , Интересуют саженцы, цена в питомнике роз будет доступной. , http://medlinks.ru טיפול פסיכולוגי: סוגים טיפולים פסיכולוגיים איזה טיפול פסיכולוגי.