Тёмная тема
Создание b2ContactListener | 8 янв. 2021 | 20:17 | matrixoidr |
---|
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 дек. 2020 | 19:03 | matrixoidr |
---|
Проверка персонажа на нахождение на земле:
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 дек. 2020 | 20:03 | matrixoidr |
---|
Вот код моего удара в прыжке(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 дек. 2020 | 16:28 | matrixoidr |
---|
Ошибка:
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 дек. 2020 | 18:21 | matrixoidr |
---|
Пример траектории мяча:
Вот код игры:
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 дек. 2020 | 19:17 | matrixoidr |
---|
Вот код функции:
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
Подскажите, пожалуйста, почему машинка не едет? | 27 окт. 2020 | 22:41 | SourceOfDeath |
---|
Смена ориентации сложного тела. Движение вправо и влево | 1 янв. 1970 | 3:00 | NSX |
---|
Движение объекта в зависимости от угла | 1 янв. 1970 | 3:00 | ProQsy |
---|
Уперания объекта об угол | 1 янв. 1970 | 3:00 | ProQsy |
---|