QML(Qt Meta-Object Language,Qt元對象語言)是一個用來描述應用程序的用戶界面的聲明式語言。花了點時間看完霍亞飛的《Qt及Qt Quick開發實戰精解》後,爲了鞏固一下的所學,自己寫了一個類似於勁舞團的按鍵小遊戲。遊戲如下圖,根據經過粉紅色豎線圖片的指示,按空格、上、下、左和右鍵,按對得分,按錯不得分,遊戲不多說,上代碼!
首先主畫面文件名:KeyGame.qml
整個主畫面用了五個組件,ScorePart:用於顯示當前得分以及滑過的圖片的數目;OperationPart:用於顯示按下的鍵,例如當按下鍵盤的space鍵時遊戲中的space鍵會變紅,其他鍵同;DisplayPart:用於定時的隨機滑過空格或箭頭圖片,當圖片經過粉紅色豎線時檢測是否得分;另外兩個組件就是“暫停/開始”和“重新開始”兩個按鍵,功能如文字提示。
import QtQuick 1.1
Rectangle {
id: mainWindow
property int currentScore : 0
property int currentNum : 0
property int level: 3000
width: 500
height: 700
ScorePart {
id: scorePart
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
}
OperationPart {
id: operationPart
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
DisplayPart {
id: displayPart
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
}
}
PauseButton {
id: pauseButton
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
anchors.right: parent.horizontalCenter
anchors.rightMargin: 20
}
RestartButton {
id: restartButton
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
anchors.left: parent.horizontalCenter
anchors.rightMargin: 20
}
}
KeyGame.qml文件沒有太多內容,主要是anchors的使用,每一個項目都可以認爲有一組無形的“錨線”,分別是:left、horizontalCenter、right、top、verticalCenter、baseline和bottom。anchors佈局相當於相對佈局,而使用x,y等就是絕對佈局。anchors佈局不能與絕對佈局混用!接下來是第一部分ScorePart.qml
這部分非常簡單,簡單的來說就是一個矩形中有三個Text文本用於顯示標題(hello world)、當前得分和當前滑過。
import QtQuick 1.1
Rectangle {
width: parent.width; height: 100
Text {
id: title
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
text: "Hello World"
}
Text {
id: score
property string stringScore : "當前的分:%1".arg(mainWindow.currentScore)
anchors.bottom: parent.bottom
anchors.rightMargin: 30
anchors.right: parent.horizontalCenter
width: 200; height: 50
font.pointSize: 20
text: stringScore
}
Text {
id: number
property string stringNum : "當前滑過:%1".arg(mainWindow.currentNum)
anchors.bottom: parent.bottom
anchors.leftMargin: 30
anchors.left: parent.horizontalCenter
width: 200; height: 50
font.pointSize: 20
text: stringNum
}
}
這部分主要內容是對按鍵事件的處理,所有基於Item的可見元素都可以通過Keys附加屬性來進行按鍵處理。按鍵事件是隻會傳遞給有焦點的項目(focus = true),而且獲得焦點的項目如果沒有接收按鍵事件(event.accepted = true),那麼事件會遞歸的傳遞到每一個項目的父項目,直到被接受,或者到達根項目。在主畫面KeyGame.qml中我特意讓DisplayPart作爲OperationPart的子項目,目的就是讓DisplayPart處理了按鍵事件後,不接收傳遞給OperationPart,否則OperationPart將收不到按鍵事件。OperationPart收到按鍵事件,處理完後將事件接收。
import QtQuick 1.1
Rectangle {
width: parent.width
height: 500
focus: true
Keys.onSpacePressed: {
space.color = "red"; event.accepted = true
//console.log("space key pressed !")
}
Keys.onUpPressed: {
upDirection.color = "red"; event.accepted = true
//console.log("up key pressed !")
}
Keys.onDownPressed: {
downDirection.color = "red"; event.accepted = true
//console.log("down key pressed !")
}
Keys.onLeftPressed: {
leftDirection.color = "red"; event.accepted = true
//console.log("left key pressed !")
}
Keys.onRightPressed: {
rightDirection.color = "red"; event.accepted = true
//console.log("right key pressed !")
}
Keys.onReleased: {
space.color = "lightgreen"
upDirection.color = "lightgreen"
downDirection.color = "lightgreen"
leftDirection.color = "lightgreen"
rightDirection.color = "lightgreen"
event.accepted = true
}
Rectangle {
id: space
width: 120; height: 40
border.color: "yellow"
border.width: 3
radius: 10
color: "lightgreen"
anchors.right: parent.horizontalCenter
anchors.rightMargin: 60
anchors.top: parent.verticalCenter
anchors.topMargin: 100
Text {
id: spaceText
anchors.centerIn: parent
color: "blue"
text: "space"
font.pointSize: 20
}
}
Rectangle {
id: direction
width: 140; height: 140
anchors.left: parent.horizontalCenter
anchors.leftMargin: 60
anchors.top: parent.verticalCenter
anchors.topMargin: 50
Rectangle {
id: upDirection
color: "lightgreen"
width: 40; height: 40
border.color: "yellow"
border.width: 3
radius: 10
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
Text {
id: upDirectionText
anchors.centerIn: parent
color: "blue"
text: "up"
font.pointSize: 10
}
}
Rectangle {
id: leftDirection
color: "lightgreen"
width: 40; height: 40
border.color: "yellow"
border.width: 3
radius: 10
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
Text {
id: leftDirectionText
anchors.centerIn: parent
color: "blue"
text: "left"
font.pointSize: 10
}
}
Rectangle {
id: downDirection
color: "lightgreen"
width: 40; height: 40
border.color: "yellow"
border.width: 3
radius: 10
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
Text {
id: downDirectionText
anchors.centerIn: parent
color: "blue"
text: "down"
font.pointSize: 10
}
}
Rectangle {
id: rightDirection
color: "lightgreen"
width: 40; height: 40
border.color: "yellow"
border.width: 3
radius: 10
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
Text {
id: rightDirectionText
anchors.centerIn: parent
color: "blue"
text: "right"
font.pointSize: 10
}
}
}
}