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

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

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

Студворк — интернет-сервис помощи студентам
Добрый день. Пишу код игры про волейбол. Решил реализовать прием мяча в прыжке ( то есть удар) и прием стоя. Имею почти два одинаковых условия этих событий. Проблема в том, что когда мой персонаж на земле (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
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
29.12.2020, 14:02
Ответы с готовыми решениями:

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

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

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

6
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
29.12.2020, 17:28
Цитата Сообщение от matrixoidr Посмотреть сообщение
Буду благодарен, если кто разъяснит в чем проблема, или укажет на возможные её причины. Заранее спасибо!
Покажи-ка код полностью, а не какие-то куски неизвестно откуда.
0
0 / 0 / 0
Регистрация: 29.12.2020
Сообщений: 21
29.12.2020, 17:34  [ТС]
https://pastebin.com/6VbEeZ0Z
0
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
29.12.2020, 17:43
Лучший ответ Сообщение было отмечено matrixoidr как решение

Решение

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

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
6772 / 4565 / 1844
Регистрация: 07.05.2019
Сообщений: 13,726
29.12.2020, 17:50
Лучший ответ Сообщение было отмечено 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
 Аватар для zayats80888
6352 / 3523 / 1428
Регистрация: 07.02.2019
Сообщений: 8,995
29.12.2020, 17:52
Цитата Сообщение от 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
29.12.2020, 17:52
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
Модель микоризы: классовый агентный подход 3
anaschu 06.01.2026
aa0a7f55b50dd51c5ec569d2d10c54f6/ O1rJuneU_ls https:/ / vkvideo. ru/ video-115721503_456239114
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR
ФедосеевПавел 06.01.2026
Owen Logic: О недопустимости использования связки «аналоговый ПИД» + RegKZR ВВЕДЕНИЕ Введу сокращения: аналоговый ПИД — ПИД регулятор с управляющим выходом в виде числа в диапазоне от 0% до. . .
Модель микоризы: классовый агентный подход 2
anaschu 06.01.2026
репозиторий https:/ / github. com/ shumilovas/ fungi ветка по-частям. коммит Create переделка под биомассу. txt вход sc, но sm считается внутри мицелия. кстати, обьем тоже должен там считаться. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru