Как заставить два тела соединиться вместе на сторонах, ближайших к точке столкновения в QML Box2D? - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть проект QML Box2D, над которым я работаю, в котором есть несколько различных многоугольников в форме динамических тел Box2D с фиксаторами многоугольников, которые динамически движутся по всему миру.

Моя цель - сделать так, чтобы всякий раз, когда два разных тела сталкивались друг с другом, они оба соединялись с теми сторонами, с которыми они столкнулись изначально, сопоставляя две стороны лицом к лицу и, по существу, соединяясь в одно тело, но оставаясь как два отдельных тела, чтобы отслеживать их, используя логику игры.

Это будет что-то вроде двух магнитов, плавающих в пространстве и соединяющихся друг с другом, а затем обладающих двумя магнитными сторонами, притягивающими друг друга и соединяющимися в некотором смысле.

Хотя у меня не было проблем с созданием тел, и, аналогично, не было проблем с определением, когда происходят столкновения, и выполнением различных функций, когда они сталкиваются, я не могу заставить эти два объекта просто объединиться на одной стороне, ближайшей к столкновению. ..

Вот что я пытался сделать безуспешно:

Body {
    id: body
     world: physicsWorld

     property var vertices
     bodyType: Body.Dynamic
     target: gamePiece

     function beginContact(other) {
         if (other.getBody() !== wallBody) {
             var newObject = Qt.createQmlObject('import QtQuick 2.9; import Box2D 2.0; DistanceJoint { }', body, "dynamicSnippet1");
             newObject.bodyA = body;
             newObject.bodyB = other.getBody();
             newObject.length = 80;
             DistanceJoint.collideConnected = true;
             body.angularVelocity = 0;
             body.fixedRotation = true;
             console.log("Created Distance Joint " + newObject);
         } else {
             console.log("Skipping Body collision with wall");
         }
     }
     fixtures: Polygon {
         density: 2
         friction: 0.9
         restitution: 0.01
         vertices: body.vertices
         onBeginContact: { body.beginContact(other) }
     }

 }

Каждый объект, который сталкивается с другим Телом, как будто он просто полностью втягивается в сталкивающееся Тело, и стороны не совпадают вообще.

Как бы я определил, какие стороны Тела соприкасаются и как лучше всего их соединить?

1 Ответ

0 голосов
/ 20 ноября 2018

Я думаю, WeldJoint подходит гораздо лучше, например:

import QtQuick 2.11
import QtQuick.Window 2.11
import Box2D 2.0

Window {
    visible: true
    width: 800
    height: 600
    title: qsTr("Hello World")
    id: root

    World {
        id: physicsWorld
        gravity: Qt.point(0, 0)        
    }

    Repeater {
        model: [
            { "x": 0, "y": 0, "width": 10, "height": root.height },
            { "x": root.width - 10, "y": 0, "width": 10, "height": root.height },
            { "x": 10, "y": 0, "width": root.width - 20, "height": 10 },
            { "x": 10, "y": root.height - 10, "width": root.width - 20, "height": 10 }
        ]
        delegate: Rectangle {
            id: wall
            x: modelData.x
            y: modelData.y
            width: modelData.width
            height: modelData.height
            color: "lightgreen"
            Body {
                bodyType: Body.Static
                target: wall
                fixtures: Box {
                    width: wall.width
                    height: wall.height
                    friction: 0.5
                    density: 0.5
                }
            }
        }
    }

    Rectangle {
        id: item1
        height: 100
        width: 100
        color: "orange"
        antialiasing: true
        smooth: true
        x: 100
        y: 100
        Body {
            id: itemBody1
            bodyType: Body.Dynamic
            target: item1
            fixtures: Box {
                density: 0.1
                friction: 0.1
                restitution: 1
                width: item1.width
                height: item1.height
                onBeginContact: {
                    var body = other.getBody();
                    if(body === itemBody2)
                    {
                        var newJoint = linkJoint.createObject(root);
                        newJoint.bodyA = itemBody1;
                        newJoint.bodyB = body;
                    }                    
                }
            }
        }
        Component.onCompleted: {
            var x = ((Math.random() * 800) - 400) / 200;
            var y = ((Math.random() * 600) - 300) / 200;
            itemBody1.applyLinearImpulse(Qt.point(x, y), Qt.point(50,50))
        }
    }
    Rectangle {
        id: item2
        height: 100
        width: 100
        color: "lightblue"
        antialiasing: true
        smooth: true
        x: 600
        y: 100
        Body {
            id: itemBody2
            bodyType: Body.Dynamic
            target: item2
            fixtures: Box {
                density: 0.1
                friction: 0.1
                restitution: 1
                width: item1.width
                height: item1.height
            }
        }
        Component.onCompleted: {
            var x = ((Math.random() * 800) - 400) / 200;
            var y = ((Math.random() * 600) - 300) / 200;
            itemBody2.applyLinearImpulse(Qt.point(x, y), Qt.point(50,50))
        }
    }
    Component {
        id: linkJoint
        WeldJoint {
            localAnchorA: Qt.point(50, 50)
            localAnchorB: Qt.point(150, 150)
            collideConnected: true
        }
    }
}

Конечно, вы должны играть с расстояниями и углами, чтобы соответствовать вашим потребностям.

...