С Новым годом! Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
0 / 0 / 0
Регистрация: 29.12.2020
Сообщений: 21
1

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

29.12.2020, 14:02. Показов 2096. Ответов 6

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

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

C++
1
2
3
4
5
6
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;
Проверка на контакт двух тел:

C++
1
2
3
4
5
6
7
8
9
10
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;
      }
    }
Условие приема мяча на земле:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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);
      }
    }
Условие приема мяча в прыжке (в воздухе):

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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);
      }
    }
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
29.12.2020, 14:02
Ответы с готовыми решениями:

Вычислить энергию удара двух тел
Вычислить энергию удара автомобиля “Запорожец-968”, массой m=780 кг, двигавшегося со скоростью v,...

Материал какого из двух тел разных материалов имеет большую плотность?
даны объемы и массы двух тел из разных материалов, материал какого из тел имеет большую плотность

Даны объемы и массы двух тел из разных материалов. Материал какого из тел имеет большую плотность?
Даны объемы и массы двух тел из разных материалов. Материал какого из тел имеет большую плотность?

Проблема с подключением сот. тел. к ПК, LG M4410
Помогите с проблемой подклю чения сот.тел. к ПК!!!:confused: Подсоединяю через дата-кабель при...

6
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
29.12.2020, 17:28 2
Цитата Сообщение от matrixoidr Посмотреть сообщение
Буду благодарен, если кто разъяснит в чем проблема, или укажет на возможные её причины. Заранее спасибо!
Покажи-ка код полностью, а не какие-то куски неизвестно откуда.
0
0 / 0 / 0
Регистрация: 29.12.2020
Сообщений: 21
29.12.2020, 17:34  [ТС] 3
https://pastebin.com/6VbEeZ0Z
0
6340 / 3511 / 1427
Регистрация: 07.02.2019
Сообщений: 8,977
29.12.2020, 17:43 4
Лучший ответ Сообщение было отмечено matrixoidr как решение

Решение

Цитата Сообщение от matrixoidr Посмотреть сообщение
Проблема в том, что когда мой персонаж на земле (onGround == true), контакт между двумя телами (персонажем и мячом) не обнаруживается
Это потому, что когда персонаж onGround, то else ветка
Цитата Сообщение от matrixoidr Посмотреть сообщение
Условие приема мяча в прыжке (в воздухе):
переписывает изменения, сделанные в
Цитата Сообщение от matrixoidr Посмотреть сообщение
Условие приема мяча на земле:
Логика не корректна.
1
0 / 0 / 0
Регистрация: 29.12.2020
Сообщений: 21
29.12.2020, 17:47  [ТС] 5
так сделать? или по другому?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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));
            }
            //анимация приема мяча
            if (ball->GetPosition().y < 29)
            {
                sprite_player_1_move.setTextureRect(IntRect(0, 960, 270, 480));
            }
            else if (ball->GetPosition().y > 28)
            {
                sprite_player_1_move.setTextureRect(IntRect(270, 960, 270, 480));
            }
        }
        
 
        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);
            }
        }
0
6770 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
29.12.2020, 17:50 6
Лучший ответ Сообщение было отмечено matrixoidr как решение

Решение

Цитата Сообщение от matrixoidr Посмотреть сообщение
так сделать? или по другому?
Разбей свои if на два
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if (Keyboard::isKeyPressed(Keyboard::Q))
{
 
    if (onGround)
    {
      .......................
    }
    else
    {
      .......................
    }
}
else
{
.........................
}
1
6340 / 3511 / 1427
Регистрация: 07.02.2019
Сообщений: 8,977
29.12.2020, 17:52 7
Цитата Сообщение от matrixoidr Посмотреть сообщение
или по другому?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        if (Keyboard::isKeyPressed(Keyboard::Q))
        {
            if (onGround) { /* doOnGround(); */ }
            else { /* doOnAir(); */ }
        }
        else {
            for (b2Fixture* fix = ball->GetFixtureList(); fix; fix = fix->GetNext())
            {
                b2Filter filter = fix->GetFilterData();
 
                filter.categoryBits = 0x0008;
                filter.maskBits = 0x0002;
                fix->SetFilterData(filter);
            }
        }
1
29.12.2020, 17:52
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
29.12.2020, 17:52
Помогаю со студенческими работами здесь

СИСТЕМА ДВУХ ТЕЛ
ОПРЕДЕЛЕНИЕ РЕАКЦИЙ ОПОР составной конструкции Конструкция состоит из двух частей АС и СВ,...

Соударение двух тел
даны два тела, происходит их столкновение. В случае когда мы имее дело с прямым столкновением шаров...

Движение двух тел
Под мостом моторная лодка обогнала плот. Плот, пройдя 10 км, не меняя работы двигателя, развернулся...

Пересечение двух тел в пространстве
Привет всем! У меня есть небольшое увлечение - иногда делаю карты к сетевым 3д бегалкам,...

Моделирование движения двух тел
Доброго времени суток всем, такой вопрос, скоро дипломная работа по теме &quot;Моделирование движения...

Гравитация для двух тел
Доброго времени суток! Моделирую гравитационные силы для двух тел по формуле F = G*(m1*m2)/r*r. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru