Qt Quick 3D 物理引擎 - 大炮示例

演示了如何生成物理对象。

本示例演示了如何在需要时创建和删除物理对象。场景由一些箱子堆组成。您可以使用 WASD 和鼠标移动,按 空格 射击球。

场景设置了常用的 Qt Quick 3D 对象,如图形、照相机和光源

PerspectiveCamera {
    id: camera
    position: Qt.vector3d(-4000, 5000, 10000)
    eulerRotation: Qt.vector3d(-20, -20, 0)
    clipFar: 500000
    clipNear: 100
}
DirectionalLight {
    eulerRotation: Qt.vector3d(-45, 45, 0)
    castsShadow: true
    brightness: 1
    shadowMapQuality: Light.ShadowMapQualityVeryHigh
    shadowFactor: 100
}

我们还添加了一个静态地板

StaticRigidBody {
    eulerRotation: Qt.vector3d(-90, 0, 0)
    collisionShapes: PlaneShape {}
    Model {
        source: "#Rectangle"
        scale: Qt.vector3d(2000, 2000, 1)
        materials: PrincipledMaterial {
            baseColor: "green"
        }
        castsShadows: false
        receivesShadows: true
    }
}

我们创建了一个节点,用作对象的生成器,并将其放入我们的视图中

Node {
    id: shapeSpawner
    property var instancesBoxes: []
    property var instancesSpheres: []
    property int stackCount: 0
    property var boxComponent: Qt.createComponent("Box.qml")
    property var sphereComponent: Qt.createComponent("Sphere.qml")

    function createStack(stackZ, numStacks) {
        let size = 10
        let extents = 400

        for (var i = 0; i < size; i++) {
            for (var j = 0; j < size - i; j++) {
                let x = j * 2 - size + i
                let y = i * 2 + 1
                let z = 5 * (stackZ - numStacks)
                let center = Qt.vector3d(x, y, z).times(0.5 * extents)
                let box = boxComponent.incubateObject(shapeSpawner, {
                                                          "position": center,
                                                          "xyzExtents": extents
                                                      })
                instancesBoxes.push(box)
            }
        }
    }

    function createBall(position, forward) {
        var diameter = 600
        var speed = 20000
        let settings = {
            "position": position,
            "sphereDiameter": diameter
        }
        let sphere = sphereComponent.createObject(shapeSpawner, settings)
        sphere.setLinearVelocity(forward.times(speed))
        instancesSpheres.push(sphere)

        if (sphere === null) {
            console.log("Error creating object")
        }
    }

    function reset() {
        // Only run method if previous stack has been created fully
        for (var i = 0; i < instancesBoxes.length; i++)
            if (!instancesBoxes[i].object)
                return

        instancesSpheres.forEach(sphere => {
                                     sphere.collisionShapes = []
                                     sphere.destroy()
                                 })
        instancesBoxes.forEach(box => {
                                   box.object.collisionShapes = []
                                   box.object.destroy()
                               })
        instancesSpheres = []
        instancesBoxes = []

        for (var stackI = 0; stackI < stackSlider.value; stackI++) {
            shapeSpawner.createStack(stackI, stackSlider.value)
        }
    }
}

我们有三个方法: createStack 用于创建堆栈,createBall 用于创建具有速度的球,以及 reset 用于重置场景。实际生成的箱子和球体存储在自己的 qml 文件中(box.qmlsphere.qml)。

文件

© 2024 The Qt Company Ltd。本文件中的文档贡献是各自所有者的版权。本文件提供的文档受GNU 自由文档许可版本 1.3 的条款约束,由自由软件基金会发布。Qt 及其 respective logos 是 The Qt Company Ltd. 在芬兰和/或世界其他国家的商标。所有其他商标均为其各自所有者的财产。