Taro3

View on GitHub

シーンの設定

これでQt3Dのコードを書き始めることができるようになりました。最初のステップは、シーンのルートを定義することです。GameArea.qmlという名前の新しいファイルを作成します。

import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Extras 2.0

Entity {
    id: root

    property alias gameRoot: root

    Camera {
        id: camera
        property real x: 24.5
        property real y: 14.0

        projectionType: CameraLens.PerspectiveProjection
        fieldOfView: 45
        aspectRatio: 16/9
        nearPlane : 0.1
        farPlane : 1000.0
        position: Qt.vector3d( x, y, 33.0 )
        upVector: Qt.vector3d( 0.0, 1.0, 0.0 )
        viewCenter: Qt.vector3d( x, y, 0.0 )
    }

    RenderSettings {
        id: frameFraph
        activeFrameGraph: ForwardRenderer {
            clearColor: Qt.rgba(0, 0, 0, 1)
            camera: camera
        }
    }

    components: [frameFraph]
}

最初に行うことは、カメラを作成し、それを配置することです。OpenGLでは、座標は右手の親指が左を指すように追従していることを覚えておいてください

image

カメラをQt.vector3d(x, y, 33)に配置することで、カメラを「画面の外」に出して、まだ作成されていないエンタテイの座標を単純なx, y軸で表現できるようにしています。upVectorです。Qt.vector3d(0.0, 1.0, 0.0)でカメラのアップベクトルを指定します。最後に、Qt.vector(x, y, 0)を指定します。

全体的な目的は、座標表現を単純化することです。このようにカメラを配置することで、座標0,0にオブジェクトを配置するとウィンドウの左下の部分に配置され、座標50,28はウィンドウの右上の部分を意味します。

また、2つのプロパティを定義するForwardRenderedでRenderSettingsを構成します。

シーンをレンダリングする準備ができましたが、ユーザー入力、つまりキーボードを処理する必要があります。 キーボードイベントをキャプチャするには、GameArea.qmlを以下のように変更します。

import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0

Entity {
    ...
    RenderSettings {
    ...
    }

    KeyboardDevice {
        id: keyboardController
    }

    InputSettings { id: inputSettings }

    KeyboardHandler {
        id: input
        sourceDevice: keyboardController
        focus: true
        onPressed: { }
    }

    components: [frameFraph, input]
}

KeyboardDevice要素は、アクティブなKeyboardHandler、すなわちinputへのキーイベントのディスパッチを担当しています。KeyboardHandler コンポーネントはコントローラにアタッチされており、キーが押されるたびに onPressed() 関数が呼び出されます。KeyboardHandlerはコンポーネントなので、GameAreaのコンポーネントリストに追加する必要があります。

GameAreaの最後の欠けている部分は、エンジンの実行を事前に行うことです(初期化と update)を使用しています。

import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import QtQuick 2.6 as QQ2

Entity {
    id: root

    property alias gameRoot: root
    property alias timerInterval: timer.interval
    property int initialTimeInterval: 80
    property int initialSnakeSize: 5
    property string state: ""
    ...

    KeyboardDevice {
        id: keyboardController
    }

    QQ2.Component.onCompleted: {
        console.log("Start game...");
        timer.start()
    }

    QQ2.Timer {
        id: timer
        interval: initialTimeInterval
        repeat: true
        onTriggered: {}
    }

    components: [frameFraph, input]
}

ここでは、Qt3DにQt Quick要素を組み合わせています。名前の衝突の可能性があるため、別名QQ2を使ってモジュールをインポートする必要があります。Component.onCompletedは、第5章「モバイルUIを支配する」ですでに紹介しました。その仕事は、ゲームエンジンを起動し、直後に定義されたtimerを起動することです。

このtimer変数は、80ミリ秒ごとに(initialTimeIntervalプロパティで定義されているように)繰り返し、エンジンのupdate()関数を呼び出します。この関数については、この章の後半でエンジンのコードを作成するときに説明します。目標は、オリジナルのスネークゲームを可能な限り忠実にエミュレートすることです。ゲーム全体のロジックは、通常のフレーム更新間隔ではなく、この間隔で更新されます。update() を呼び出すたびに、スネークは前進します。その結果、蛇の動きは滑らかではなく、むしろぎこちないものになります。これは明らかにレトロゲーミング感を出すためのデザイン選択です。

ヘビがリンゴを食べるたびに、2つのことが起こります。

タイマー間隔を短くすることで、蛇の方向管理が非常に困難になるまで蛇の前進が速くなります。


戻る