qml自学笔记------自己写相似于劲舞团的按键小游戏(中)

接上篇《qml自学笔记------自己写类似于劲舞团的按键小游戏(上)

第三部分DisplayPart.qml

代码的其它部分都是渣,就这里花了点时间,整个小游戏就靠这个文件。

首先,屏幕上要随机的滑过空格或者箭头,每个图片就是一个项目,那么就要动态的创建项目。

动态创建项目方法有三种(我所知道的),第一种是通过JavaScript调用Qt.createComponent(),Qt.createQmlObject()来创建对象,这里要注意的是创建时必须传父对象,由于图形项目没有父对象是无法显示在场景上的;另外一种是使用反复器Repeater,可是Repeater元素是用来创建大量相似项目的;第三种是使用Loader元素载入组件创建对象,Loader元素能够使用source属性载入一个QML文件或者使用sourceComponent属性创建一个对象,可是假设source或者sourceComponent更改了,不论什么先前实例化的项目都会被销毁;在本游戏中source肯定要随机切换,所以不能选第三种,各个对象之间也是不一样的,所以我选了第一种方法使用JS调用来动态创建对象。

而且,使用JS来产生随机数也很easy。使用Math.random()调用就好。要是使用QML来产生随机数我还真不会尴尬

随机问题攻克了就使用Timer定时器,定时的动态创建项目。

interval属性设置时间间隔,单位毫秒;repeat属性设置是否反复触发;running属性设置定时器的开启关闭;onTriggered属性设置处理函数,等等。。。

然后就是最头疼的判决是否得分的问题了,一開始我想的实现方法是当项目到达某个坐标时開始计时,到走出计时结束,在计时的这段时间里看是否有跟项目图片一致的按键事件,并且依据时间距离中心时间的长短来判决得分是perfect、good或者OK等等级。经过一番折腾,诶... 毕竟是做工控的。没做过游戏,有点难度(这又让我想起了那丑陋的界面。诶...  感觉自己全然没有艺术细胞呀)。

于是我换了一种思路。当按键按下时。判决处于某坐标的项目的图片是否和按键事件是一样的。这样会简单非常多,于是就有了例如以下代码。

import QtQuick 1.1

Rectangle {
    id: m_displayPart

    property bool timerRunning: false

    function startGame(){
        var rand = Math.floor(5*Math.random()+1);
        switch(rand){
            case 1:
                var componetImageUP = Qt.createComponent("ImageUp.qml");
                componetImageUP.createObject(rowDisplay);
                break;
            case 2:
                var componetImageDown = Qt.createComponent("ImageDown.qml");
                componetImageDown.createObject(rowDisplay);
                break;
            case 3:
                var componetImageLeft = Qt.createComponent("ImageLeft.qml");
                componetImageLeft.createObject(rowDisplay);
                break;
            case 4:
                var componetImageRight = Qt.createComponent("ImageRight.qml");
                componetImageRight.createObject(rowDisplay);
                break;
            case 5:
                var componetImageSpace = Qt.createComponent("ImageSpace.qml");
                componetImageSpace.createObject(rowDisplay);
                break;
            default:
                break;
        }

        //imageLoader.source = "ImageUp.qml"
        if(++mainWindow.currentNum > 99) {
            displayPart.timerRunning = false;
            pauseButton.pauseText = "又一次開始";
            pauseButton.stat = false;
        }
    }

    function score(){
       m_displayPart.color = "lightgreen";
        mainWindow.currentScore++;
        //console.log("score!");
    }

    function unScore(){
        m_displayPart.color = "red";
        //console.log("un score!");
    }

     500
    height: 200
    color: "lightblue"

    Rectangle {
        id: rowDisplay

        z: 1;  500; 
        anchors.verticalCenter: parent.verticalCenter
        focus: true

        Keys.onPressed: {
            if(childAt(250,0)===null) {
                unScore();
            }
            else if( (event.key===Qt.Key_Up)&&(childAt(250,0).getValue()===1) ) {
                score();
            }
            else if( (event.key === Qt.Key_Down)&&(childAt(250,0).getValue()===2) ) {
                score();
            }
            else if( (event.key === Qt.Key_Left)&&(childAt(250,0).getValue()===3) ) {
                score();
            }
            else if( (event.key === Qt.Key_Right)&&(childAt(250,0).getValue()===4) )
                score();
            else if( (event.key === Qt.Key_Space)&&(childAt(250,0).getValue()===5) )
                score();
            else
                unScore();

            //event.accepted = true;
        }

        Keys.onReleased: {m_displayPart.color = "lightblue"}

    }

    Rectangle {
        id: pjLine

         10; height: parent.height
        z: 0
        color: "pink"
        anchors.horizontalCenter: parent.horizontalCenter

    }

    Timer {
        id: timerDisplay

        interval: 600
        running: timerRunning
        repeat: true
        onTriggered: startGame();

    }

}


动态创建的项目有五个。分别相应着五个按键:ImageUp.qml   ImageDown.qml  ImageLeft.qml  ImageRight.qml  ImageSpace.qml

五个文件非常类似,以ImageUp为例。使用source属性载入图片;使用states属性设置状态;使用transitions属性设置切换效果。

这个效果大概就是先创建。等创建完毕后从x=0的位置滑动到x=500的位置。历时duration:3000毫秒。滑动效果用easing.type: Easing.InOutQuad来设置。

import QtQuick 1.1

Image {
    id: upimage

    function getValue(){
        return 1;
    }

     60
    height: 60
    anchors.verticalCenter: parent.verticalCenter

    source: "../img/up.png"

    states: State {
        name: "loaded"; when: upimage.status === Image.Ready
        PropertyChanges { target: upimage; x: 500}
    }

    transitions: Transition {
                NumberAnimation {
                    to: 500; from: 0
                    duration: 3000
                    properties: "x"; easing.type: Easing.InOutQuad
                }
            }

}



原文地址:https://www.cnblogs.com/mfmdaoyou/p/6740171.html