我正在使用这个例子:QML Flipable Example。我用GridLayout
创建了矩形。我刚添加了我的新状态示例:
states: [
State {
name: 'back'
PropertyChanges { target: rotation; angle: 180 }
when: flipable.flipped
},
State {
name: 'remove'
PropertyChanges {
target: card
visible: false
}
}
]
当我点击矩形时,我想要检查矩形,它们是否打开以及它们是否相同。我的算法是:
property int card1: -1
property int card2: -1
property int remaining: 20
function cardClicked(index) {
var card = repeater.itemAt(index); // Selected card
if (!card.flipped) { // If selected card is not opened
card.flipped = true; // Open card
if (card1 === -1) { // If card is first selected card
card1 = index; // Set first selected card
} else { // If selected card is not first card, I mean that is second card because first card is already selected
card2 = index; // Set second card
area.enabled = false; // Disabled GridLayout (area)
delayTimer.start(); // Start `Timer` QML component
}
} else { // If card is opened so, close that card, because that card is opened and player clicked its
card.flipped = false; // Close that card
card1 = -1; // first card is not selected
}
}
function validateCards() {
var state = ''; // Default state: Close cards
if (imageIndexes[card1] === imageIndexes[card2]) { // If first card and second card are equal, you found same cards :)
state = 'remove'; // You found cards so, remove cards
--remaining; // If this equals 0, you found all cards
}
// If cards are not same, close cards but if they are same remove them
repeater.itemAt(card1).state = state;
repeater.itemAt(card2).state = state;
card1 = -1; // first card is not selected
card2 = -1; // second card is not selected
area.enabled = true; // Enabled area (GridLayout)
if (remaining === 0) { // If you found all cards, game over
console.log('Game Over!');
}
}
我将MouseArea
添加到Rectangle
s中:
MouseArea {
anchors.fill: parent
onClicked: cardClicked(index) // This index belongs to my `Repeater`.
}
我把Timer
用于动画正常工作并检查卡片:
Timer {
id: delayTimer
interval: 1000
onTriggered: validateCards()
}
这个示例和动画运行良好,但有时它们运行不正常: 我该如何解决这个动画bug?
UPDATE! 您可以在here上找到所有源代码。
我认为你通过使用计时器使应用程序变得复杂,因为你不知道项目是否已完成改变它的位置,在完成翻转字母时执行该任务是合适的。
我在你的代码中看到的另一个错误是你正在分配一个state = ""
。
我修改了以下部分:
GameArea.qml
GridLayout {
[...]
property variant imageIndexes: GameUtils.generateCardIndexes(
imageCount, repeatCount)
property int lastIndex : -1
Repeater {
id: repeater
model: 40
Card {
id: card
backImageSource: 'qrc:/images/img_' + area.imageIndexes[index] + '.jpg'
onFinished: verify(index)
}
}
function verify(index){
if(lastIndex == -1){
lastIndex = index
return
}
area.enabled = false
var lastItem = repeater.itemAt(lastIndex)
var currentItem = repeater.itemAt(index)
if(lastItem.backImageSource === currentItem.backImageSource){
lastItem.state = "remove"
currentItem.state = "remove"
}
else{
lastItem.flipped = false
currentItem.flipped = false
}
if(repeater.model === 0){
console.log("Winning")
}
lastIndex = -1
area.enabled = true
}
}
Card.qml
Item {
[...]
property alias state: flipable.state
signal finished()
Flipable {
[...]
transitions: Transition {
NumberAnimation { target: rotation; property: 'angle'; duration: 400 }
onRunningChanged: {
if ((state == "back") && (!running))
finished()
}
}
MouseArea {
anchors.fill: parent
onClicked: card.flipped = true
}
}
}
完整的代码可以在以下link找到