Добрый день. Пишу код игры про волейбол. Решил реализовать прием мяча в прыжке ( то есть удар) и прием стоя. Имею почти два одинаковых условия этих событий. Проблема в том, что когда мой персонаж на земле (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); } }
я заранее извиняюсь. мне кажется Ваш код в принципе не верен. не в отношении написания, а в отношении концепции работы с боксом. все что нужно, для того, чтобы было взаимодействие двух тел -это фильтр, который позволяет это сделать (либо его отсутствие). Судя по проблеме, в коде есть зависимость от ground/!ground хотя боксу абсолютно наплевать на пользовательские флаги. ему надо тело и фикстуру
Проблема решена, спасибо за помощь!
Тема в архиве.