Box2DФорумОбщее

Проблема траектории объекта при воздействии на него другого объека в Box2D.

#0
18:21, 18 дек 2020

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

Пример траектории мяча:
Пример траектории мяча | Проблема траектории объекта при воздействии на него другого объека в Box2D.

Вот код игры:

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...///////////////////////////////////// 
  }
}
#1
18:38, 18 дек 2020

Здравствуй!Можно добавить гравитацию и она все сделает за тебя

почти...

#2
19:32, 18 дек 2020

matrixoidr
В заголовок темы на форуме выноси суть проблемы, а не "Добрый День"

Box2DФорумОбщее

Тема в архиве.