Sur cette page

Tutoriel QML avancé 2 - Remplir le canevas du jeu

Générer les blocs en JavaScript

Maintenant que nous avons écrit quelques types, commençons à écrire le jeu.

La première tâche consiste à générer les blocs du jeu. Chaque fois que l'on clique sur le bouton Nouveau jeu, le canevas du jeu est rempli avec un nouvel ensemble aléatoire de blocs. Comme nous devons générer dynamiquement de nouveaux blocs pour chaque nouveau jeu, nous ne pouvons pas utiliser Repeater pour définir les blocs. Au lieu de cela, nous allons créer les blocs en JavaScript.

Voici le code JavaScript pour générer les blocs, contenu dans un nouveau fichier, samegame.js. Le code est expliqué ci-dessous.

var blockSize = 40;
var maxColumn = 10;
var maxRow = 15;
var maxIndex = maxColumn * maxRow;
var board = new Array(maxIndex);
var component;

//Index function used instead of a 2D array
function index(column, row) {
    return column + (row * maxColumn);
}

function startNewGame() {
    //Delete blocks from previous game
    for (var i = 0; i < maxIndex; i++) {
        if (board[i] != null)
            board[i].destroy();
    }

    //Calculate board size
    maxColumn = Math.floor(background.width / blockSize);
    maxRow = Math.floor(background.height / blockSize);
    maxIndex = maxRow * maxColumn;

    //Initialize Board
    board = new Array(maxIndex);
    for (var column = 0; column < maxColumn; column++) {
        for (var row = 0; row < maxRow; row++) {
            board[index(column, row)] = null;
            createBlock(column, row);
        }
    }
}

function createBlock(column, row) {
    if (component == null)
        component = Qt.createComponent("Block.qml");

    // Note that if Block.qml was not a local file, component.status would be
    // Loading and we should wait for the component's statusChanged() signal to
    // know when the file is downloaded and ready before calling createObject().
    if (component.status == Component.Ready) {
        var dynamicObject = component.createObject(background);
        if (dynamicObject == null) {
            console.log("error creating block");
            console.log(component.errorString());
            return false;
        }
        dynamicObject.x = column * blockSize;
        dynamicObject.y = row * blockSize;
        dynamicObject.width = blockSize;
        dynamicObject.height = blockSize;
        board[index(column, row)] = dynamicObject;
    } else {
        console.log("error loading block component");
        console.log(component.errorString());
        return false;
    }
    return true;
}

La fonction startNewGame() supprime les blocs créés dans le jeu précédent et calcule le nombre de lignes et de colonnes de blocs nécessaires pour remplir la fenêtre de jeu du nouveau jeu. Elle crée ensuite un tableau pour stocker tous les blocs du jeu et appelle createBlock() pour créer suffisamment de blocs pour remplir la fenêtre du jeu.

La fonction createBlock() crée un bloc à partir du fichier Block.qml et déplace le nouveau bloc à sa position sur le canevas du jeu. Cette opération comporte plusieurs étapes :

  • Qt.createComponent() est appelé pour générer un type à partir de Block.qml. Si le composant est prêt, nous pouvons appeler createObject() pour créer une instance de l'élément Block.
  • Si createObject() renvoie null (c'est-à-dire s'il y a eu une erreur lors du chargement de l'objet), il faut imprimer l'information d'erreur.
  • Placez le bloc à sa position sur le tableau et définissez sa largeur et sa hauteur. Stockez-le également dans le tableau des blocs pour référence ultérieure.
  • Enfin, imprimez les informations d'erreur sur la console si le composant n'a pas pu être chargé pour une raison quelconque (par exemple, si le fichier est manquant).
Connecter les composants JavaScript à QML

Nous devons maintenant appeler le code JavaScript dans samegame.js à partir de nos fichiers QML. Pour ce faire, nous ajoutons cette ligne à samegame.qml qui importe le fichier JavaScript en tant que module:

import "samegame.js" as SameGame

Cela nous permet de faire référence à n'importe quelle fonction de samegame.js en utilisant "SameGame" comme préfixe : par exemple, SameGame.startNewGame() ou SameGame.createBlock(). Cela signifie que nous pouvons maintenant connecter le gestionnaire onClicked du bouton Nouveau jeu à la fonction startNewGame(), comme ceci :

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

Ainsi, lorsque vous cliquez sur le bouton New Game, la fonction startNewGame() est appelée et génère un champ de blocs, comme ceci :

Nous avons maintenant un écran de blocs et nous pouvons commencer à ajouter les mécanismes du jeu.

Exemple de projet @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.