翻譯|使用教程|編輯:鮑佳佳|2021-03-24 11:04:48.113|閱讀 301 次
概述:現(xiàn)在我們已經(jīng)擁有了所有游戲組件,可以添加游戲邏輯了,該邏輯規(guī)定玩家如何與積木互動(dòng)以及如何玩游戲,直到贏或輸。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門(mén)軟控件火熱銷(xiāo)售中 >>
相關(guān)鏈接:
Qt是一個(gè)跨平臺(tái)框架,通常用作圖形工具包,它不僅創(chuàng)建CLI應(yīng)用程序中非常有用。而且它也可以在三種主要的臺(tái)式機(jī)操作系統(tǒng)以及移動(dòng)操作系統(tǒng)(如Symbian,Nokia Belle,Meego Harmattan,MeeGo或BB10)以及嵌入式設(shè)備,Android(Necessitas)和iOS的端口上運(yùn)行。現(xiàn)在我們?yōu)槟闾峁┝嗣赓M(fèi)的試用版。
Qt組件推薦:
通過(guò)前兩章的講解(創(chuàng)建游戲畫(huà)布和塊,填充游戲畫(huà)布),現(xiàn)在我們已經(jīng)擁有了所有游戲組件,可以添加游戲邏輯了,該邏輯規(guī)定玩家如何與積木互動(dòng)以及如何玩游戲,直到贏或輸。
為此,我們將以下功能添加到samegame.js:
由于這是關(guān)于QML的教程,而不是游戲設(shè)計(jì)的教程,因此我們將僅在下面進(jìn)行討論handleClick(),victoryCheck()因?yàn)樗鼈冎苯优cQML類型交互。請(qǐng)注意,盡管此處的游戲邏輯是用JavaScript編寫(xiě)的。
啟用鼠標(biāo)單擊交互
為了更方便的JavaScript代碼接口與QML類型,我們?cè)黾恿私凶鲰?xiàng)目gameCanvas來(lái)samegame.qml。它將背景替換為包含塊的項(xiàng)目。它還接受來(lái)自用戶的鼠標(biāo)輸入。這是商品代碼:
Item { id: gameCanvas property int score: 0 property int blockSize: 40 width: parent.width - (parent.width % blockSize) height: parent.height - (parent.height % blockSize) anchors.centerIn: parent MouseArea { anchors.fill: parent onClicked: SameGame.handleClick(mouse.x, mouse.y) } }
gameCanvas項(xiàng)是棋盤(pán)的精確尺寸,并有一個(gè)分?jǐn)?shù)屬性和一個(gè)MouseArea來(lái)處理鼠標(biāo)點(diǎn)擊。塊現(xiàn)在被創(chuàng)建為它的子項(xiàng)目,它的尺寸被用來(lái)確定棋盤(pán)的大小,這樣應(yīng)用程序就可以根據(jù)可用的屏幕尺寸進(jìn)行縮放。由于它的尺寸被綁定到blockSize的倍數(shù)上,blockSize被移出了samegame.js,作為一個(gè)QML屬性移到了samegame.qml中。注意,它仍然可以從腳本中訪問(wèn)。
當(dāng)點(diǎn)擊時(shí),MouseArea會(huì)調(diào)用samegame.js中的handleClick(),它決定玩家的點(diǎn)擊是否會(huì)導(dǎo)致任何塊被移除,如果需要的話,還會(huì)用當(dāng)前的分?jǐn)?shù)更新gameCanvas.score。這里是handleClick()函數(shù)。
function handleClick(xPos, yPos) { var column = Math.floor(xPos / gameCanvas.blockSize); var row = Math.floor(yPos / gameCanvas.blockSize); if (column >= maxColumn || column < 0 || row >= maxRow || row < 0) return; if (board[index(column, row)] == null) return; //If it's a valid block, remove it and all connected (does nothing if it's not connected) floodFill(column, row, -1); if (fillFound <= 0) return; gameCanvas.score += (fillFound - 1) * (fillFound - 1); shuffleDown(); victoryCheck(); }
請(qǐng)注意,如果score是samegame.js文件中的全局變量,則將無(wú)法綁定到該文件。您只能綁定到QML屬性。
更新分?jǐn)?shù)
當(dāng)玩家單擊一個(gè)塊并觸發(fā)時(shí)handleClick(),handleClick()還會(huì)調(diào)用victoryCheck()來(lái)更新比分并檢查玩家是否已完成游戲。這是victoryCheck()代碼:
function victoryCheck() { //Award bonus points if no blocks left var deservesBonus = true; for (var column = maxColumn - 1; column >= 0; column--) if (board[index(column, maxRow - 1)] != null) deservesBonus = false; if (deservesBonus) gameCanvas.score += 500; //Check whether game has finished if (deservesBonus || !(floodMoveCheck(0, maxRow - 1, -1))) dialog.show("Game Over. Your score is " + gameCanvas.score); }
gameCanvas.score如果游戲結(jié)束,則更新值并顯示“ Game Over”對(duì)話框。
“游戲結(jié)束”對(duì)話框是使用Dialog中定義的類型創(chuàng)建的Dialog.qml。這是Dialog.qml代碼。注意如何通過(guò)功能和信號(hào)從腳本文件中強(qiáng)制使用它:
import QtQuick 2.0 Rectangle { id: container function show(text) { dialogText.text = text; container.opacity = 1; } function hide() { container.opacity = 0; } width: dialogText.width + 20 height: dialogText.height + 20 opacity: 0 Text { id: dialogText anchors.centerIn: parent text: "" } MouseArea { anchors.fill: parent onClicked: hide(); } }
這就是它在主samegame.qml文件中的用法:
Dialog { id: dialog anchors.centerIn: parent z: 100 }
我們?yōu)閷?duì)話框指定z值100,以確保將其顯示在其他組件的頂部。項(xiàng)目的默認(rèn)z值為0。
色彩沖刺
如果所有塊都具有相同的顏色,玩“同一個(gè)游戲”并沒(méi)有什么樂(lè)趣,因此我們修改了createBlock()函數(shù),samegame.js以便每次調(diào)用時(shí)隨機(jī)創(chuàng)建不同類型的塊(用于紅色,綠色或藍(lán)色)。Block.qml還進(jìn)行了更改,以便每個(gè)塊包含一個(gè)不同的圖像,具體取決于其類型:
import QtQuick 2.0 Item { id: block property int type: 0 Image { id: img anchors.fill: parent source: { if (type == 0) return "../shared/pics/redStone.png"; else if (type == 1) return "../shared/pics/blueStone.png"; else return "../shared/pics/greenStone.png"; } } }
工作游戲
現(xiàn)在我們有了一款可以正常運(yùn)行的游戲!可以單擊塊,玩家可以得分,游戲可以結(jié)束(然后您可以開(kāi)始一個(gè)新的)。這是到目前為止已完成的屏幕截圖:
這是現(xiàn)在的samegame.qml樣子:
import QtQuick 2.0 import "samegame.js" as SameGame Rectangle { id: screen width: 490; height: 720 SystemPalette { id: activePalette } Item { width: parent.width anchors { top: parent.top; bottom: toolBar.top } Image { id: background anchors.fill: parent source: "../shared/pics/background.jpg" fillMode: Image.PreserveAspectCrop } Item { id: gameCanvas property int score: 0 property int blockSize: 40 width: parent.width - (parent.width % blockSize) height: parent.height - (parent.height % blockSize) anchors.centerIn: parent MouseArea { anchors.fill: parent onClicked: SameGame.handleClick(mouse.x, mouse.y) } } } Dialog { id: dialog anchors.centerIn: parent z: 100 } Rectangle { id: toolBar width: parent.width; height: 30 color: activePalette.window anchors.bottom: screen.bottom Button { anchors { left: parent.left; verticalCenter: parent.verticalCenter } text: "New Game" onClicked: SameGame.startNewGame() } Text { id: score anchors { right: parent.right; verticalCenter: parent.verticalCenter } text: "Score: Who knows?" } } }
游戲有效,但現(xiàn)在有點(diǎn)無(wú)聊。平滑的動(dòng)畫(huà)過(guò)渡在哪里?高分在哪里?如果您是QML專家,則可以在第一次迭代中編寫(xiě)這些內(nèi)容,但是在本教程中,我們將在下一章節(jié)中進(jìn)行講解----您的應(yīng)用程序?qū)⒃诖嘶钴S起來(lái)!
====================================================
想要了解或購(gòu)買(mǎi)Qt正版授權(quán)的朋友,歡迎
Qt技術(shù)交流群現(xiàn)已開(kāi)通,QQ搜索群號(hào)“765444821”或者掃描下方二維碼即可加入
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自: