Войти
Box2DФорумОбщее

Создание b2ContactListener

#0
20:17, 8 янв. 2021

Добрый день. У меня есть class CONTACT_LISTENER : public b2ContactListener{...}, и класс игрока и мяча. Проблема заключается в том, что ContactListener не обнаруживает контакт двух тел (в каждой функции ContactListener я поставил вывод сообщений, и ни одно сообщение не выводилось). Хотя я запускал обычный цикл вне класса ContactListener и контакт находился. Мне кажется, что проблема состоит в SetContactListener, или как по сути активировать ContactListener. В статье я нашел следующие строки и использую их:

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";
        }
    };

Буду рад помощи! Заранее спасибо!


Box2DФорумОбщее