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

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

第三部分DisplayPart.qml

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

首先,屏幕上要随机的滑过空格或者箭头,每一个图片就是一个项目,那么就要动态的创建项目。动态创建项目方法有三种(我所知道的),第一种是通过JavaScript调用Qt.createComponent(),Qt.createQmlObject()来创建对象,这里要注意的是创建时必须传父对象,因为图形项目没有父对象是无法显示在场景上的;第二种是使用重复器Repeater,但是Repeater元素是用来创建大量相似项目的;第三种是使用Loader元素加载组件创建对象,Loader元素可以使用source属性加载一个QML文件或者使用sourceComponent属性创建一个对象,但是如果source或者sourceComponent更改了,任何先前实例化的项目都会被销毁;在本游戏中source肯定要随机切换,所以不能选第三种,各个对象之间也是不一样的,所以我选了第一种方法使用JS调用来动态创建对象。

并且,使用JS来产生随机数也非常简单,使用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!");
    }

    width: 500
    height: 200
    color: "lightblue"

    Rectangle {
        id: rowDisplay

        z: 1; width: 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

        width: 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;
    }

    width: 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
                }
            }

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2025-01-17 02:49:07

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

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

接上篇<qml自学笔记------自己写类似于劲舞团的按键小游戏(中)> 第四部分 PauseButton.qml 和 RestartButton.qml 第四部分其实就是两个按键,一个是暂停,一个是重新开始. 暂停按键按下时就将Timer定时器的running属性设成false,将按键上的text属性设成"开始",就这么两件事.但是,由于点击重新开始时暂停按键也需要有所改变,换而言之即其他对象要改变这个按键的属性,因此给按键添加了两个属性stat和pauseText,st

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

接上篇<qml自学笔记------自己写类似于劲舞团的按键小游戏(上)> 第三部分DisplayPart.qml 代码的其它部分都是渣,就这里花了点时间,整个小游戏就靠这个文件. 首先,屏幕上要随机的滑过空格或者箭头,每个图片就是一个项目,那么就要动态的创建项目. 动态创建项目方法有三种(我所知道的),第一种是通过JavaScript调用Qt.createComponent(),Qt.createQmlObject()来创建对象,这里要注意的是创建时必须传父对象,由于图形项目没有父对象是无法显

python写的第一个简单小游戏-猜数字

1 #Filename:game1.py 2 3 guess=10 4 running=True 5 while running: 6 try: 7 answer=int(raw_input('Guess what i think:')) 8 except: 9 print 'Please input interga\n' 10 continue 11 12 if answer<guess: 13 print 'Your answer is too small\n' 14 continue 15

Unity3D 学习笔记 - Garen Pick the Balls 捡球小游戏设计

注:本游戏开发环境为Unity 3D v4.6 老师说这星期作业比较简单,所以我决定写得规整一些. 开发时间:8小时 游戏要求: 小游戏争分夺秒:随机位置生成七个球,控制主角在地图拾取七个球,十秒钟内必须完成,否则失败具体要求: 1 随机位置在地图上生成七个球(球可以用系统自带的球体) 2 用键盘控制本课程中的角色移动,鼠标左键攻击到达打击帧时,拾取碰到的球. 3 通过Time类显示每次拾取球花费的时间 经过试验,十秒根本捡不完= =,15秒还可以... 首先来看看帅气万分的主角Garen哥 .

Unity客户端框架笔记(状态模式和策略模式在游戏中的应用)

最近花了几天时间梳理了一下新游戏的客户端框架,虽然本身就有相对明确的方向,但是在一开始写的时候还是有些混乱,不过最终梳理完成后,个人感觉代码清爽很多. 这篇文章不是设计模式的教学,而是自己的一些想法和实践,我把代码梳理成自己喜欢的结构,保证逻辑和结构的清晰,但是这并不意味者它是符合所有人习惯的. 我之前有写过一两篇文章讨论客户端的结构,也吐槽过一些其他人的设计.可以说我在写代码之初就有一个相对明确的方向,多年的经验也可以告诉我什么样的代码是漂亮的,什么样的代码是有坏味道的. 首先我把客户端结构分

Unity3D 学习笔记 - Garen Pick the Balls 捡球小游戏设计 (二) Macanim 动画状态机

注:本游戏开发环境为Unity3D 5.3.4 本星期要求: 模仿 AnimationEvent 编写一个 StateEvents 类 用户可以创建一个指定时间.指定状态触发的事件类 事件可以采用反射机制,调用调用客户的方法:或使用订阅发布方法调用客户的方法. 在你的动画控制程序中使用 StateEvents 类 我采用的是上星期的Garen Pick the Balls小游戏,将Legacy动画部分用Mecanim重写. 要点: 1. 初次状态机开发,尚未实现Run和Attack同时进行(Bl

使用 shell 脚本写一个猜价格的小游戏

[[email protected] 3]# vim game.sh #!/bin/bash a=$(expr $RANDOM % 1000) b=0 echo "商品的价格范围为0-999,猜猜看是多少?" while true do read -p "请输入你猜测的价格:" c let b++ if [ $c -eq $a ] ; then echo "恭喜你答对了,实际价格是 $a " echo "你总共猜了 $b 次"

用Python写一个小游戏

刚学Python时间不长,但也知道了一点,看别人的参考写了一个猜数字小游戏,也算是禹学于乐吧. #!/usr/bin/env   python #coding=utf-8 import random secret = random.randint(1,100) guess,tries = 0,0 print u"已经给出了一个1-99的数字" while guess != secret and tries < 5: print u"请给出你猜的数字:" pri

python自学笔记

python自学笔记 python自学笔记 1.输出 2.输入 3.零碎 4.数据结构 4.1 list 类比于java中的数组 4.2 tuple 元祖 5.条件判断和循环 5.1 条件判断 5.2 循环 6.使用dict和set 6.1 dict 6.2 set 7.函数的使用 7.1函数返回多个值,同时接受多个值 7.2函数参数的默认值 7.3可变参数的函数 7.4可变个数带参数名的入参 7.5参数类型组合 8.关于函数递归 9.python的高级特性 9.1切片 9.2遍历 9.3列表生