• 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
                    }
                }
    
    }
    



  • 相关阅读:
    第二章作业第2题--苏志华
    小学生四则运算应用软件(一)
    YOLO1至YOLOV3方法讲解
    C++ STL中的二分查找
    C++ 中的prioriy_queue 优先级队列 转
    C++ 中的容器(栈、堆、队列) 转
    从尾到头打印链表
    替换空格
    C++中vector<vector<int> >
    对称平方数
  • 原文地址:https://www.cnblogs.com/mfmdaoyou/p/6740171.html
Copyright © 2020-2023  润新知