QML 高级教程 2 - 填充游戏画布
在 JavaScript 中生成块
既然我们已经编写了一些类型,那就开始编写游戏吧。
第一项任务是生成游戏块。每次点击 "新建游戏 "按钮时,游戏画布上就会填充一组新的、随机的图块。由于我们需要为每个新游戏动态生成新的游戏块,因此我们不能使用Repeater 来定义游戏块。相反,我们将在 JavaScript 中创建区块。
下面是生成区块的 JavaScript 代码,包含在一个新文件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()
返回空值(即加载对象时出错),则打印错误信息。 - 将图块放置在棋盘上的相应位置,并设置其宽度和高度。同时,将其存储到块数组中,以备将来参考。
- 最后,如果由于某种原因无法加载组件(如文件丢失),则在控制台中打印错误信息。
将 JavaScript 组件连接到 QML
现在,我们需要从 QML 文件中调用samegame.js
中的 JavaScript 代码。为此,我们在samegame.qml
中添加这一行,将 JavaScript 文件作为模块导入:
import "samegame.js" as SameGame
这样,我们就可以使用 "SameGame "作为前缀来引用samegame.js
中的任何函数:例如,SameGame.startNewGame()
或SameGame.createBlock()
。这意味着我们现在可以将 "新建游戏"(New Game)按钮的onClicked
处理程序连接到startNewGame()
函数,就像这样:
Button { anchors { left: parent.left; verticalCenter: parent.verticalCenter } text: "New Game" onClicked: SameGame.startNewGame() }
因此,当您点击 "新游戏 "按钮时,startNewGame()
就会被调用,并生成一个区块字段,就像这样:
现在,我们有了一个方块屏幕,可以开始添加游戏机制了。
© 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.