Qt開発ケースの戦闘:QML高度なチュートリアル3-ゲームロジックの実装

Qtはクロスプラットフォームフレームワークであり、通常はグラフィカルツールキットとして使用されます。CLIアプリケーションの作成に非常に役立つだけではありません。また、3つの主要なデスクトップオペレーティングシステムとモバイルオペレーティングシステム(Symbian、Nokia Belle、Meego Harmattan、MeeGo、BB10など)、組み込みデバイス、Android(Necessitas)、iOSポートでも実行できます。今、私たちはあなたに無料の試用版を提供します。

Qt6の最新の試用版をダウンロードする

Qtコンポーネントの推奨事項:

  • QtitanRibbonダウンロードして試す:QtテクノロジのMicrosoftリボンUIパラダイムに準拠し、Windows、Linux、およびMac OSX用のフル機能のリボンコンポーネントの提供に取り組んでいるリボンUIコンポーネント。
  • QtitanChart  | ダウンロードして試す :は、アプリケーションに美しく豊富なグラフをすばやく提供できるようにする一連のコントロールを表すC ++ライブラリです。そして、すべての主要なデスクトップをサポートします。
  • QtitanNavigation  | ダウンロードして試す :Microsoft Dynamics CRM-2016 / Office365ナビゲーションインターフェイスとQt.C ++アプリケーションのユーザーエクスペリエンスを向上させるための一連のコントロールをシミュレートするQtitanNavigationコンポーネント。

最初の2つの章(の説明を通じて、ゲームのキャンバスとブロックを作成しゲームのキャンバスを埋める)、今私たちは、すべてのゲームの要素を持って、我々はプレーヤーの相互作用ブロックとし、どのように再生する方法を規定しているゲームロジックを追加することができます彼らが勝つか負けるまでゲーム。

この目的のために、samegame.jsに次の関数を追加します。

  • handleClick(x、y)
  • FloodFill(xIdx、yIdx、type)
  • shuffleDown()
  • VictoryCheck()
  • FloodMoveCheck(xIdx、yIdx、type)

これはQMLのチュートリアルであり、ゲームデザインのチュートリアルではないため、ここでは、handleClick()とvictoryCheck()についてのみ説明します。これらはQMLタイプと直接対話するためです。ここでのゲームロジックはJavaScriptで記述されていますが、注意してください。

マウスクリック操作を有効にする

より便利なJavaScriptコードインターフェイスとQMLタイプのために、gameCanvasというプロジェクトをsamegame.qmlに追加しました。背景をブロックを含むプロジェクトに置き換えます。また、ユーザーからのマウス入力も受け付けます。これは製品コードです:

  Item {
            id: gameCanvas

            property int score: 0
            property int blockSize: 40

            width: parent.width - (parent.width % blockSize)
            height: parent.height - (parent.height % blockSize)
            anchors.centerIn: parent

            MouseArea {
                anchors.fill: parent
                onClicked: SameGame.handleClick(mouse.x, mouse.y)
            }
        }

gameCanvasアイテムはボードの正確なサイズであり、スコア属性とマウスクリックを処理するためのMouseAreaがあります。これで、ブロックがサブアイテムとして作成され、そのサイズを使用してボードのサイズが決定されるため、使用可能な画面サイズに応じてアプリケーションをスケーリングできます。そのサイズはblockSizeの倍数にバインドされているため、blockSizeはsamegame.jsから移動され、QML属性としてsamegame.qmlに移動されます。スクリプトから引き続きアクセスできることに注意してください。

クリックすると、MouseAreaはsamegame.jsのhandleClick()を呼び出します。これにより、プレーヤーのクリックによってブロックが削除されるかどうかが決定され、必要に応じて、gameCanvas.scoreが現在のスコアで更新されます。これがhandleClick()関数です。

function handleClick(xPos, yPos) {
    var column = Math.floor(xPos / gameCanvas.blockSize);
    var row = Math.floor(yPos / gameCanvas.blockSize);
    if (column >= maxColumn || column < 0 || row >= maxRow || row < 0)
        return;
    if (board[index(column, row)] == null)
        return;
    //If it's a valid block, remove it and all connected (does nothing if it's not connected)
    floodFill(column, row, -1);
    if (fillFound <= 0)
        return;
    gameCanvas.score += (fillFound - 1) * (fillFound - 1);
    shuffleDown();
    victoryCheck();
}

スコアがsamegame.jsファイルのグローバル変数である場合、そのファイルにバインドされないことに注意してください。QML属性にのみバインドできます。

スコアを更新する

プレーヤーがブロックをクリックしてhandleClick()をトリガーすると、handleClick()はvictoryCheck()を呼び出してスコアを更新し、プレーヤーがゲームを完了したかどうかを確認します。これはvictoryCheck()コードです:

function victoryCheck() {
    //Award bonus points if no blocks left
    var deservesBonus = true;
    for (var column = maxColumn - 1; column >= 0; column--)
        if (board[index(column, maxRow - 1)] != null)
        deservesBonus = false;
    if (deservesBonus)
        gameCanvas.score += 500;

    //Check whether game has finished
    if (deservesBonus || !(floodMoveCheck(0, maxRow - 1, -1)))
        dialog.show("Game Over. Your score is " + gameCanvas.score);
}

gameCanvas.scoreゲームが終了すると、値が更新され、[ゲームオーバー]ダイアログボックスが表示されます。

「ゲームオーバー」ダイアログは、Dialogで定義されたタイプを使用して作成されたDialog.qmlです。これはDialog.qmlコードです。スクリプトファイルから関数とシグナルを介して強制的に使用する方法に注意してください。

import QtQuick 2.0

Rectangle {
    id: container

    function show(text) {
        dialogText.text = text;
        container.opacity = 1;
    }

    function hide() {
        container.opacity = 0;
    }

    width: dialogText.width + 20
    height: dialogText.height + 20
    opacity: 0

    Text {
        id: dialogText
        anchors.centerIn: parent
        text: ""
    }

    MouseArea {
        anchors.fill: parent
        onClicked: hide();
    }
}

これは、メインのsamegame.qmlファイルでの使用方法です。

   Dialog {
        id: dialog
        anchors.centerIn: parent
        z: 100
    }

ダイアログボックスに100のz値を割り当てて、他のコンポーネントの上に表示されるようにします。プロジェクトのデフォルトのz値は0です。

カラースプリント

すべてのブロックの色が同じである場合、「同じゲーム」をプレイするのは面白くないため、createBlock()関数samegame.jsを変更して、さまざまなタイプのブロック(赤、緑、または青)をランダムに作成しました。Block.qmlも変更され、タイプに応じて各ブロックに異なる画像が含まれるようになりました。

import QtQuick 2.0

Item {
    id: block

    property int type: 0

    Image {
        id: img

        anchors.fill: parent
        source: {
            if (type == 0)
                return "../shared/pics/redStone.png";
            else if (type == 1)
                return "../shared/pics/blueStone.png";
            else
                return "../shared/pics/greenStone.png";
        }
    }
}

仕事ゲーム

これで、正常に実行できるゲームができました。ブロックをクリックしたり、プレーヤーがスコアを付けたり、ゲームを終了したりできます(その後、新しいブロックを開始できます)。これは、これまでに完成したスクリーンショットです。

samegame.qmlは次のようになります。

import QtQuick 2.0
import "samegame.js" as SameGame

Rectangle {
    id: screen

    width: 490; height: 720

    SystemPalette { id: activePalette }

    Item {
        width: parent.width
        anchors { top: parent.top; bottom: toolBar.top }

        Image {
            id: background
            anchors.fill: parent
            source: "../shared/pics/background.jpg"
            fillMode: Image.PreserveAspectCrop
        }

        Item {
            id: gameCanvas

            property int score: 0
            property int blockSize: 40

            width: parent.width - (parent.width % blockSize)
            height: parent.height - (parent.height % blockSize)
            anchors.centerIn: parent

            MouseArea {
                anchors.fill: parent
                onClicked: SameGame.handleClick(mouse.x, mouse.y)
            }
        }
    }

    Dialog {
        id: dialog
        anchors.centerIn: parent
        z: 100
    }

    Rectangle {
        id: toolBar
        width: parent.width; height: 30
        color: activePalette.window
        anchors.bottom: screen.bottom

        Button {
            anchors { left: parent.left; verticalCenter: parent.verticalCenter }
            text: "New Game"
            onClicked: SameGame.startNewGame()
        }

        Text {
            id: score
            anchors { right: parent.right; verticalCenter: parent.verticalCenter }
            text: "Score: Who knows?"
        }
    }
}

ゲームは動作しますが、今は少し退屈です。スムーズなアニメーションの移行はどこにありますか?ハイスコ​​アはどこにありますか?QMLの専門家であれば、最初のイテレーションでこれらを記述できますが、このチュートリアルでは、次の章で説明します。アプリケーションはここで機能します。

================================================== ==

Qtテクニカルエクスチェンジグループがオープンしました。QQ検索グループ番号「765444821 または以下のQRコードをスキャンして参加してください

おすすめ

転載: blog.csdn.net/qq_42444778/article/details/115196450