QML 고급 튜토리얼 2 - 게임 캔버스 채우기

자바스크립트로 블록 생성하기

이제 몇 가지 유형을 작성했으니 게임 작성을 시작해 보겠습니다.

첫 번째 작업은 게임 블록을 생성하는 것입니다. 새 게임 버튼을 클릭할 때마다 게임 캔버스는 새로운 무작위 블록 세트로 채워집니다. 새 게임마다 새 블록을 동적으로 생성해야 하므로 Repeater 을 사용하여 블록을 정의할 수 없습니다. 대신 자바스크립트로 블록을 생성합니다.

다음은 새 파일( samegame.js)에 포함된 블록 생성을 위한 자바스크립트 코드입니다. 코드는 아래에 설명되어 있습니다.

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;
}

startNewGame() 함수는 이전 게임에서 생성된 블록을 삭제하고 새 게임의 게임 창을 채우는 데 필요한 블록의 행과 열 수를 계산합니다. 그런 다음 모든 게임 블록을 저장할 배열을 생성하고 createBlock() 함수를 호출하여 게임 창을 채울 수 있는 충분한 블록을 생성합니다.

createBlock() 함수는 Block.qml 파일에서 블록을 생성하고 새 블록을 게임 캔버스의 해당 위치로 이동합니다. 여기에는 여러 단계가 포함됩니다:

  • Qt.createComponent()를 호출하여 Block.qml 에서 유형을 생성합니다. 컴포넌트가 준비되면 createObject() 을 호출하여 Block 항목의 인스턴스를 생성할 수 있습니다.
  • createObject() 이 null을 반환하는 경우(즉, 객체를 로드하는 동안 오류가 발생한 경우) 오류 정보를 인쇄합니다.
  • 블록을 보드의 해당 위치에 배치하고 너비와 높이를 설정합니다. 또한 나중에 참조할 수 있도록 블록 배열에 저장합니다.
  • 마지막으로 어떤 이유로 컴포넌트를 로드할 수 없는 경우(예: 파일이 누락된 경우) 콘솔에 오류 정보를 인쇄합니다.
자바스크립트 컴포넌트를 QML에 연결하기

이제 QML 파일에서 samegame.js 의 JavaScript 코드를 호출해야 합니다. 이를 위해 이 줄을 samegame.qml 에 추가하여 자바스크립트 파일을 모듈로 가져옵니다:

import "samegame.js" as SameGame

이렇게 하면 SameGame.startNewGame() 또는 SameGame.createBlock() 와 같이 접두사로 "SameGame"을 사용하여 samegame.js 내의 모든 함수를 참조할 수 있습니다. 이제 새 게임 버튼의 onClicked 핸들러를 다음과 같이 startNewGame() 함수에 연결할 수 있습니다:

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

따라서 새 게임 버튼을 클릭하면 startNewGame() 이 호출되어 다음과 같은 블록 필드를 생성합니다:

이제 블록 화면이 생겼으니 게임 메커니즘을 추가할 수 있습니다.

예제 프로젝트 @ code.qt.io

© 2025 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.