Evgenii Legotckoi
Evgenii LegotckoiШілде 14, 2016, 5:57 Т.Ж.

QML ойыны - 1-сабақ. Ойын аренасы және динамикалық нысандар

Android үшін Qt ойынын жазудың бірінші тәжірибесінен кейін мен осы тәжірибемен бөліскім келеді және бірге «Мольді өлтіру» стилінде қарапайым ойын жазуды ұсынамын. Бұл саңылаулардан шыққан меңдерді соғуға уақыт табу керек ойын, бірақ бұл жеңілдетілген ойын болатынын ескере отырып, мольдердің орнына біз ойын алаңында пайда болатын дөңгелек нысаналарды қолданамыз. Ойын алаңы ретінде 6-ға 6 ұяшықтан тұратын тор пайдаланылады. Бірақ GridLayout сияқты кейбір арнайы нысан өрісті жасау үшін пайдаланылмайды. Ойын өрісінде тор жолдар, бағандар саны мен шаршы ұяшықтың бүйірінің ұзындығынан қалыптасады. Ұяшықтың толықтығы туралы деректер javascript компонентінде қалыптасатын екі өлшемді массивте сақталады (QML JavaScript қолдауы бар декларативті JSON тәрізді тіл екенін ұмытпаңыз).

Жоба құрылымы

Жоба келесі файлдардан тұрады:

  • TargetGame.pro - жоба профилі;
  • deployment.pri - жоба файлын құру және орналастыру;
  • main.cpp - жобаның негізгі функциясы бар файл;
  • main.qml - қолданбаның негізгі терезесінің объектісі бар QML қабатының негізгі файлы;
  • Target.qml - мақсатты нысанның сипаттамасы бар QML файлы;
  • Target.png - нысананың көрінісі png кескіні;
  • GameArea.qml - нысаналарды қоюға арналған торы бар ойын аренасы;
  • logic.js - JavaScript ойын логикасы бар файл.

Жобаны құру кезінде әдепкі мазмұннан ерекшеленетін файлдардың ғана мазмұнын зерттейік.


main.qml

Негізгі қолданба терезесінде GameArea.qml. ішінде сипатталған GameArea түріндегі нысан бар. Ойын алаңының ені мен биіктігі тор мен тор ұяшықтарының өлшеміне байланысты автоматты түрде есептелетіндіктен, біз жай ғана орналастырамыз. қолданба терезесінің ортасында ойын алаңы.

Бұл файлдың ерекшелігі logic.js файлын Logic түрі ретінде қосу болып табылады, ол ойын логикасына жауап береді және осы файлда негізгі қолданба терезесінің нысанын жасағаннан кейін ойын алаңында, біз ойын алаңының ағымдағы күйін есте сақтау және ойын өрісін, сондай-ақ ойын алаңының массивін бастапқы инициализациялауды жүзеге асыру үшін ойын логикасының өзегіне ойын алаңына көрсеткішті береміз. , ол тор ұяшықтарының мазмұнына сәйкес келеді. Бұл newGameState(), функциясын шақыру және оны аргумент ретінде ойын алаңының идентификаторын беру арқылы орындалады. Бұл оқулықта біз ойынның күйін, яғни ойынның іске қосылғанын немесе тоқтағанын бақыламаймыз, сондықтан аренадағы ойын таймері қолданба басталғаннан кейін бірден іске қосылады.

import QtQuick 2.7
import QtQuick.Controls 1.5
import "logic.js" as Logic

ApplicationWindow {
    visible: true
    width: 420
    height: 480
    title: qsTr("Target")

    GameArea {
        id: gameArea
        anchors.centerIn: parent
    }

    // По окончании создания окна инициализируем состояние игрового поля
    Component.onCompleted: {
        Logic.newGameState(gameArea)
    }
}

GameArea.qml

JavaScript логикалық ядросы ойынның барлық аспектілерінде пайда болғандықтан, біз бұл файлды да осында қосамыз.

Ойын аренасы – алдын ала анықталған жолдар мен бағандардың қасиеттері, сондай-ақ ұяшықтың бір жағының өлшемі бар тіктөртбұрыш. Осы қасиеттерге байланысты ойын алаңының ені мен биіктігі есептеледі. Сондай-ақ ойын алаңында таймер бар, оның жұмысы кезінде нысаналар жасалады.

Мақсаттарды құру кездейсоқ таңдалған ұяшықтың болуын тексерумен бірге жүреді. Ұяшықтарды таңдау getRandomRound(min, max) функциясын пайдаланып, таңдалған диапазондағы ең аздан максимумға дейінгі кездейсоқ бүтін санды алу арқылы кездейсоқ жолды және бағанды таңдау арқылы жүзеге асырылады, ол бөлімінде де сипатталған. logic.js.

checkEmptyField(жол, баған) функциясы берілген ұяшықта кез келген нысанның бар-жоғын тексереді, ал ұяшық бос болса, мақсат createTarget(ата-ана, жол, баған) функциясы арқылы жасалады.

import QtQuick 2.7
import "logic.js" as Logic

Rectangle {
    id: grid
    property int squareSize: 64 // Размер ячейки игровой сетки
    property int rows: 6        // Количество строк сетки
    property int cols: 6        // Количество колонок сетки

    width: cols * squareSize    // Ширина и высота игровой арены
    height: rows * squareSize   // Будет зависеть от количества колонок, строк и размера одной ячейки

    // Таймер для создания мишеней
    Timer {
        id: createTargetsTimer
        interval: 350; running: true; repeat: true;
        // Раз в секунду выбираем случайную ячейку,
        // проверяем наличие мишени в ней, и если ячейка пустая,
        // то создаём мишень
        onTriggered: {
            var targetRow = Logic.getRandomRound(0, rows - 1);
            var targetColumns = Logic.getRandomRound(0, cols - 1);
            if (Logic.checkEmptyField(targetRow, targetColumns)) {
                Logic.createTarget(grid ,targetRow, targetColumns)
            }
        }
    }
}

Target.qml

Ойынның логикалық JavaScript ядросының мазмұнын қарастырмас бұрын, мақсатты нысанның сипаттамасын қарастырайық.

Мақсатты мінез-құлық логикасы келесідей. Жасалғаннан кейін мақсат кездейсоқ уақыттан кейін жоғалып кетуі керек. Және жай ғана жоғалып кетпейді, яғни ашықтық деңгейін өзгерту арқылы, бірақ өзін-өзі жою. Ол үшін destroy(), әдісі пайдаланылады, ол түбірлік нысанда, оның идентификаторында қолданылады: root. Сондай-ақ ойынның JavaScript өзегінде destroyTarget(жол, баған) функциясын көруге болады. Бұл функция екі өлшемді тор ақпарат массивінің ұяшығын тазалау үшін пайдаланылады.

Ұяшықтың өлшемі 64 пиксель, ал нысананың өлшемі 56 пиксель болғандықтан, қарапайым есептеулерді қолдана отырып, біз нысанның ойын өрісіндегі орнын оның алатын баған мен сызыққа байланысты анықтаймыз.

import QtQuick 2.7
import "logic.js" as Logic

Image {
    id: root
    property int row: 0
    property int col: 0

    width: 56
    height: 56
    x: (col * (width + 8)) + 4
    y: (row * (height + 8)) + 4

    source: "Target.png"  // Загружаем изображение мишени

    Timer {
        interval: Logic.getRandomRound(350, 1500); running: true; repeat: false
        onTriggered: root.opacity = 0.0
    }

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

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

logic.js

Бұл файлда .pragma library *. * мәлімдемесі бар.

.pragma library

Бұл ойын күйіне ( var gameState ) осы файл QML қабатына енгізілген кез келген жерден қол жеткізу қажеттілігіне байланысты жасалады. Іс жүзінде айнымалылар ойындағы әртүрлі нысандар үшін ортақ ресурстарға айналады. Ал ең маңызды ресурс – gameState (aka ойын алаңы GameArea ). Өйткені, егер біз ойын аренасында статикалық түрде жарияланған әртүрлі нысандардан немесе аренаның өзі жарияланған файлдан ойын алаңына тікелей id арқылы қол жеткізе алатын болсақ, онда динамикалық ресурстарда, мысалы * *Target .qml , бұл әдіс біз үшін жұмыс істемейді. Ол үшін logic.js сайтынан gameState пайдаланылады, ол нысанның статикалық түрде жарияланғанына қарамастан ойын алаңының күйін тексеруге мүмкіндік береді (күй бойынша, мен ойынның іске қосылып тұрғанын немесе кідіртілді, ол келесі мақалаларда қарастырылады).

Енді logic.js файлының мазмұнына көшейік. Мұнда ең қызықты екі нүкте бар:

  1. Бұл торда қамтылған объектілер туралы ақпараттық модель қызметін атқаратын javascript-те екі өлшемді массив құру және ұяшықта нысанның бар-жоғын тексеру.
  2. Бұл динамикалық мақсаттарды құру.

Егер бірінші кодпен бәрі жеткілікті түрде түсінікті болса, мен екіншісі туралы бірнеше сөз айтамын. Мақсатты динамикалық түрде жасау үшін бұл жағдайда Target.qml. файлынан жасалған бос құрамдас пайдаланылады.Сонымен қатар, тек бір ғана бос орын қажет, тіпті бір типті көптеген элементтер үшін де ойын.

var targetComponent = Qt.createComponent("Target.qml");

Ал ойын алаңында нысанның өзін жасау төмендегі келесі функцияда жүзеге асырылады.

function createTarget(parent, row, column)
{
    var target = targetComponent.createObject(parent, {"row": row, "col": column})
    gameField[row][column] = target;
}

Біздің жағдайда нысанды тектік нысанды, яғни нысана орналасатын нысанды көрсете отырып, мақсатты компонент бос бөлігінде createObject әдісін қолдану арқылы объект құру жеткілікті (бұл жағдайда ол ойын алаңы болады) ) және нысанды жасау кезінде орнатылуы тиіс параметрлерді тізімдеу, бұл жағдайда, бұл мақсат орналасатын жол мен баған.

Толық файлдар тізімі

// Объявляем, как библиотеку, чтобы иметь доступ
// к разделяемым ресурсам, например состоянию игры
.pragma library

var gameState       // Локальное объявление состояния игры
                    // в нашем случае это будет игровая область gameArea
function getGameState() { return gameState; }

var gameField;      // Игровое поле, игровая сетка
// Создаём заготовку для мишеней
var targetComponent = Qt.createComponent("Target.qml");

// Инициализируем новое состояние игры
function newGameState(gameArea)
{
    gameState = gameArea;
    // Игровой сеткой будет служить двумерный массив,
    // в котором будем сохранять информацию о наличии в ячейках объектов
    gameField = create2DArray(gameState.rows, gameState.cols);
    return gameState;
}
// Функция получения случайного целого числа
// в диапазоне чисел включительно
function getRandomRound(min, max)
{
    return Math.round(Math.random() * (max - min) + min);
}

// Создаём мишень из компонента заготовки
function createTarget(parent, row, column)
{
    var target = targetComponent.createObject(parent, {"row": row, "col": column})
    gameField[row][column] = target;
}

// Мишень удаляется из массива сетки
function destroyTarget(row, column)
{
    gameField[row][column] = null;
}

// Функция создания двумерного массива сетки
function create2DArray(rows, columns)
{
  var arr = [];

  for (var i=0;i<rows;i++) {
     arr[i] = [];
  }

  return arr;
}

// Проверка на предмет наличия какого либо объекта в выбранной ячейке
function checkEmptyField(row, column)
{
    if (gameField[row][column] == null) {
        return true;
    } else {
        return false;
    }
}

Барлығы

Нәтижесінде біз 6-дан 6-ға дейінгі ойын өрісі бар бағдарламаны аламыз, онда жоғалып кететін мақсаттар іске қосу кезінде жасалады.

Дереккөзді [GitHub сайтындағы QML ойынының мысалынан] жүктеп алыңыз (https://github.com/Legotckoi/TargetGame)

Барлық сабақтар топтамасы

Бейне оқулық

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
OI
  • Ora Iro
  • Жел. 24, 2024, 6:38 Т.Ж.

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:40ұпай,
  • Бағалау ұпайлары-8
AD

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:50ұпай,
  • Бағалау ұпайлары-4
m
  • molni99
  • Қаз. 26, 2024, 1:37 Т.Ж.

C++ - Тест 004. Указатели, Массивы и Циклы

  • Нәтиже:80ұпай,
  • Бағалау ұпайлары4
Соңғы пікірлер
ИМ
Игорь МаксимовҚар. 22, 2024, 11:51 Т.Ж.
Django - Оқулық 017. Теңшелген Django кіру беті Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
Evgenii Legotckoi
Evgenii LegotckoiҚаз. 31, 2024, 2:37 Т.Қ.
Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
A
ALO1ZEҚаз. 19, 2024, 8:19 Т.Ж.
Qt Creator көмегімен fb3 файл оқу құралы Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
ИМ
Игорь МаксимовҚаз. 5, 2024, 7:51 Т.Ж.
Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
d
dblas5Шілде 5, 2024, 11:02 Т.Ж.
QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
Енді форумда талқылаңыз
Evgenii Legotckoi
Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
t
tonypeachey1Қар. 15, 2024, 6:04 Т.Ж.
google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
NSProject
NSProjectМаусым 4, 2022, 3:49 Т.Ж.
Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
9
9AnonimҚаз. 25, 2024, 9:10 Т.Ж.
Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

Бізді әлеуметтік желілерде бақылаңыз