Evgenii Legotckoi
Evgenii Legotckoi14. Juli 2016 05:00

Spiel auf QML - Lektion 2. Hinzufügen von Schussspuren und Punktesystem

Nachdem die Spielarena erstellt und die Scheiben hinzugefügt wurden, war es an der Zeit, die Treffer auf die Scheiben, Fehlschüsse und das System für die Wertung und den Abzug von Punkten zu implementieren.

Das System zum Bewerten und Abschreiben von Punkten sieht wie folgt aus:

  • Im Falle von Fehlschüssen schlage ich vor, Spuren von Einschusslöchern verschiedener Art zu machen und einen Punkt vom Spielkonto abzuschreiben.
  • Im Falle des Verschwindens des Ziels, ohne es zu treffen, schreiben Sie auch einen Punkt vom Spielkonto ab.
  • Im Falle eines Treffers auf das Ziel werden ein bis fünf Punkte vergeben, je nachdem, wie nahe der Treffer am Zentrum war.

Die Punktzahl wird oben auf dem Spielfeld angezeigt.

Projektstruktur

Um diese Idee zu implementieren, müssen Sie zusätzlich zur Änderung einiger Dateien die folgenden Dateien hinzufügen:

  • InfoBar.qml - zeigt Informationen über das Konto an;
  • Bullet.qml - eine Datei mit einer Beschreibung des Typs des Einschusslochs;
  • bullet-1.png, bullet-2.png, bullet-3.png, bullet-4.png, bullet-5.png, bullet-6.png – Dateien mit Bildern von Einschusslöchern;

Mögliche Optionen für Einschusslöcher werden in den Grafikordner gelegt, das Zielbild wurde auch dorthin verschoben.


Bilder von Einschusslöchern

Zur Abwechslung werden mehrere Arten von ähnlichen Einschusslöchern verwendet.

GameArea.qml

Bevor wir uns mit den Inhalten der neuen Dateien befassen, wenden wir uns den geänderten Inhalten der Datei GameArea.qml sowie dem Javascript-Logikkern in der Datei logic.js zu.

Die wichtigsten Neuerungen hier sind das Erscheinen der Eigenschaft scores für die Wertung, das Erscheinen der InfoBar und der Mausklick-Handler innerhalb der Spielarena.

Die Eigenschaft scores enthält die aktuelle Punktzahl und ihr Wert wird an die Eigenschaft scores in der infoBar übergeben, um dem Spieler die aktuelle Punktzahl anzuzeigen.

Bei einem Klick auf die Spielarena, der einem Fehlschuss gleichkommt, wird ein Einschussobjekt erstellt und der aktuelle Punktestand um eins reduziert. Das Einschussloch wird auf die gleiche Weise erstellt, wie die Erstellung von Zielen in der vorherigen Lektion implementiert wurde, d. h. unter Verwendung des Logic-Logikkerns, der sich in der Datei logic.js befindet.

import QtQuick 2.7
import "logic.js" as Logic

Rectangle {
    id: grid

    ...

    property int scores: 0      // Очки

    ...

    InfoBar {
        id: infoBar
        scores: grid.scores
    }

    // Создаём след от пули при клике по игровой арене
    MouseArea {
        anchors.fill: parent
        onClicked: {
            Logic.createBullet(grid, mouse.x, mouse.y)
            grid.scores--;
        }
    }

    ...
}

logic.js

Wir werden nur die Schaffung von Einschusslöchern zum logischen Kern des Spiels hinzufügen. Die Verarbeitung der Zieltrefferlogik wird in der Datei hinzugefügt, die das Ziel beschreibt.

... 

// Создаём заготовку для мишеней
var bulletComponent = Qt.createComponent("Bullet.qml");

...

// Создаём след от пули
function createBullet(parent, x, y)
{
    bulletComponent.createObject(parent, {"x": x, "y": y});
}

...

InfoBar.qml

Die InfoLeiste ist ein normales RowLayout , das an den oberen Rand der Spielarena genagelt und auf seine Breite gestreckt wird. Die aktuelle Punktzahl wird im Textfeld mit id: scores angezeigt. Um den externen Zugriff auf die Texteigenschaft eines bestimmten Textfelds festzulegen, verwenden Sie die Eigenschaft Eigenschaftsalias .

import QtQuick 2.7
import QtQuick.Layouts 1.1

RowLayout {
    height: 40
    anchors.left: parent.left
    anchors.right: parent.right
    anchors.top: parent.top
    anchors.leftMargin: 6
    anchors.rightMargin: 6
    spacing: 6
    z: 100

    // Данное свойство устанавливает доступ к текстовому полю,
    // в которое будет устанавливаться текущий счёт
    property alias scores: scores.text

    Text {
        text: qsTr("Scores")

        font.pixelSize: 20
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
    }

    Text {
        // Текстовое поле с текущим счётом
        id: scores

        font.pixelSize: 20
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
    }

    // Своеобразный Spacer, который в RowLayout сдвинет текстовые поля к левому краю InfoBar
    Item {
        Layout.fillHeight: true
        Layout.fillWidth: true
    }
}

Bullet.qml

Das Verhalten des Einschusslochs ähnelt dem Verhalten des Ziels. Die Lebensdauer eines Einschusslochs ist begrenzt und nach dem Verschwinden wird dieses Objekt zerstört. Der Unterschied besteht darin, dass die Koordinate (0, 0) auf die Mitte des Objekts verschoben wird, sodass die Mitte des Objekts genau mit der Mitte des Klickpunkts zusammenfällt. Der Unterschied besteht auch darin, dass das Objekt über ein Array mit Bildern verfügt, aus denen während der Erstellung eine zufällige Auswahl des Aussehens des Einschusslochs durchgeführt wird.

import QtQuick 2.7
import QtQuick.Window 2.2
import "logic.js" as Logic

Image {
    id: root
    width: 40
    height: 40

    // Устанавливаем смещение координаты (0, 0) в центр изображения
    transform: Translate {
        x: -width / 2
        y: -height / 2
    }

    // Задаём список массив возможных изображений выстрела пули
    property variant bullets: ["graphics/bullet-1.png", "graphics/bullet-2.png", "graphics/bullet-3.png",
                               "graphics/bullet-4.png", "graphics/bullet-5.png", "graphics/bullet-6.png"]

    // При создании объекта выбираем случайное изображение
    source: bullets[Logic.getRandomRound(0, 5)]

    // Таймер, который будет отсчитывать случайную величину от 3500 до 10000 мс
    // и по окончании запускать исчезновение следа от пули
    Timer {
        interval: Logic.getRandomRound(3500, 10000); running: true; repeat: false
        onTriggered: root.opacity = 0.0
    }

    // Когда изображение станет прозрачным. мы уничтожим сам объект
    onOpacityChanged: {
        if (opacity == 0.0) {
            root.destroy()
        }
    }

    // Задаём поведение анимации свойства прозрачности объекта
    Behavior on opacity { PropertyAnimation { duration: 100 } }
}

Target.qml

Nun, das ganze Salz trifft das Ziel. Wie Sie sehen, gibt es hier fünf Felder, denen wir einen unterschiedlichen Wert von 1 bis 5 Punkten zuweisen werden.

Um den Treffer auf diesen Flächen korrekt zu berechnen, müssen wir den Satz des Pythagoras anwenden. Denken Sie daran? Aus dem Kurs der Schultrigonometrie. Das Quadrat der Hypotenuse ist gleich der Summe der Quadrate der Schenkel.

[latex]a 2 + b 2 = c^2[/latex]

Dieselbe Hypotenuse ist also der Abweichungsbereich des Treffers von der Mitte des Ziels, aber die Tatsache, dass ein bestimmter Bereich getroffen wird, wird durch den Radius des Kreises bestimmt, beginnend mit dem kleinsten Kreis. Diese Prüfungen werden in der in dieser Datei deklarierten Funktion isHit() durchgeführt.

Auch hier ist eine Nuance, dass das Zielbild in einem Quadrat platziert ist, was bedeutet, dass der Klickbereich auch quadratisch ist. Wenn der Klick also nicht in den Bereich des größten Kreises des Ziels fällt, geben wir 0 und zurück Pass den Klick weiter zur Spielarena. Dazu müssen Sie propagateComposedEvents auf true setzen und accept -Mausereignisse deaktivieren, dann wird es zu den zugrunde liegenden Objekten in der Z-Koordinate gehen.

Vergessen Sie auch nicht, die Punktzahl des Spiels um eins zu verringern, wenn das Ziel von selbst ohne Einfluss des Spielers verschwunden ist. Dies erfolgt über ein gemeinsam genutztes Objekt aus dem logischen Kern des Spiels, das den Zustand der Spielarena speichert. Das heißt, durch Logic.gameState.scores.

import QtQuick 2.7
import "logic.js" as Logic

Image {
    id: root

    ...

    // Когда изображение станет прозрачным. мы уничтожим сам объект
    onOpacityChanged: {
        if (opacity == 0.0) {
            Logic.gameState.scores--
            Logic.destroyTarget(row, col)
            root.destroy()
        }
    }

    MouseArea {
        id: mouseArea
        anchors.fill: parent
        // Данное свойство определяет, будут ли передаваться события клика
        // в ниже лежащие элементы, то есть те, которые по координате z
        // находятся ниже мишени
        propagateComposedEvents: true
        onClicked: {
            var scores =  isHit(root.width/2, root.height/2, mouse.x, mouse.y);
            if (scores != 0) {
                // Если количество очков отлично от нуля, то фиксируем попадание
                // Увеличиваем счёт и уничтожаем мишень
                Logic.gameState.scores += scores;
                Logic.destroyTarget(row, col);
                root.destroy();
            } else {
                // В противном случае передаём событие клика в ниже лежащие элементы
                // по координате z
                mouse.accepted = false;
            }
        }
    }

    ...

    // Проверка попадания по мишени.
    // Проверяем длину линии от центра до места попадания по мишени
    // В зависимости от длины этой линии относительно радиуса 5-ти окружностей, из которых состоит мишень
    // определяем сколько очков получаем за попадание
    // a, b - координаты центра мишени
    // x, y - координаты точки попадания
    function isHit(a, b, x, y)
    {
        var length = Math.sqrt(Math.pow(Math.abs(a - x), 2) + Math.pow(Math.abs(b - y), 2));
        if (length <= 5.6) {
            return 5;
        } else if (length <= 11.2) {
            return 4;
        } else if (length <= 16.8) {
            return 3;
        } else if (length <= 22.4) {
            return 2;
        } else if (length <= 28) {
            return 1;
        } else {
            // В данном случае мы попали в зону MouseArea,
            // которая является прямоугольником, но промахнулись
            // по самой мишени, которая является кругом
            return 0;
        }
    }
}

Insgesamt

Jetzt haben wir ein Konto und das Aussehen der Anwendung ist wie folgt.

Quelle herunterladen von QML-Spielbeispiel von GitHub

Die ganze Unterrichtsreihe

Videoanleitung

Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

Kommentare

Nur autorisierte Benutzer können Kommentare posten.
Bitte Anmelden oder Registrieren
Letzte Kommentare
ИМ
Игорь Максимов5. Oktober 2024 07:51
Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas55. Juli 2024 11:02
QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssr8. Februar 2024 18:43
Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
EVA
EVA25. Dezember 2023 10:30
Boost - statisches Verknüpfen im CMake-Projekt unter Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
Jetzt im Forum diskutieren
J
JacobFib17. Oktober 2024 03:27
добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
JW
Jhon Wick1. Oktober 2024 15:52
Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
КГ
Кирилл Гусарев27. September 2024 09:09
Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
F
Fynjy22. Juli 2024 04:15
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

Folgen Sie uns in sozialen Netzwerken