Combine uma animação em queda com uma animação de subida ao clicar

1

Estou tentando fazer um sprite em movimento cair do canto superior esquerdo para o canto esquerdo para baixo. Essa função está funcionando corretamente com o componente SequentialAnimation. Além disso, quando você clica (ou toca) na janela, o sprite deve subir alguns pixels e continuar caindo a partir daí. Quando tento fazer isso, a única coisa que pareço ser capaz de fazer é redefinir as coordenadas y, fazendo com que o sprite suba até a tela e continue onde ele estava antes, e não onde estava.

Aqui está o código:

import QtQuick 2.0
import Ubuntu.Components 1.1

import "PelicanFunctions.js" as PelicanFunction

/*!
    \brief Flappy Bird like game
*/

MainView {
    id: root
    // objectName for functional testing purposes (autopilot-qt5)
    objectName: "mainView"

    // Note! applicationName needs to match the "name" field of the click manifest
    applicationName: "com.ubuntu.developer.vitimiti.saltybird"

    /*
     This property enables the application to change orientation
     when the device is rotated. The default is false.
    */
    //automaticOrientation: true

    // Removes the old toolbar and enables new features of the new header.
    useDeprecatedToolbar: false

    width: units.gu(100)
    height: units.gu(75)

    MouseArea {
        id: playArea
        objectName: "playArea"

        width: parent.width
        height: parent.height

        Image {
            id: pelicanSprite
            objectName: "pelicanSprite"

            x: units.gu(2)
            y: units.gu(2)
            width: units.gu(6)
            height: units.gu(6)
            source: "Pelican1.png"

            SequentialAnimation on source {
                id: flyAnimation
                objectName: "flyAnimation"

                loops: Animation.Infinite

                PropertyAnimation {
                    to: "Pelican1.png"
                }

                PropertyAnimation {
                    to: "Pelican2.png"
                }
            }

            SequentialAnimation on y {
                id: fallingBird
                objectName: "fallingBird"

                NumberAnimation {
                    from: y
                    to: playArea.height - pelicanSprite.height
                    duration: 5000
                }

                onRunningChanged: {
                    if (running !== true && pelicanSprite.y === playArea.height
                            - pelicanSprite.height)
                    {
                        flyAnimation.stop()
                        pelicanSprite.source = "Pelican_Death.png"
                    }
                }
            }

            SequentialAnimation on y {
                id: upBird
                objectName: "upBird"

                running: false

                NumberAnimation {
                    from: y
                    to: y + units.gu(9)
                    duration: 800
                }
            }
        }

        onClicked: {
            fallingBird.stop()
            upBird.start()
            fallingBird.start()
        }
    }
}
    
por Víctor Matía Rodríguez 04.11.2014 / 16:28

1 resposta

2

Eu corri com este código:

import QtQuick 2.0
import Ubuntu.Components 1.1

Page {
    id: gamePage
    objectName: "gamePage"

    title: i18n.tr("Salty Bird")
    width: parent.width
    height: parent.height

    Component.onCompleted: {
        header.visible = false
    }

    MouseArea {
        id: playArea
        objectName: "playArea"

        width: parent.width
        height: parent.height

        Image {
            id: pelicanSprite
            objectName: "pelicanSprite"

            x: root.margins
            y: root.margins
            width: units.gu(6)
            height: units.gu(6)
            source: "Pelican1.png"

            SequentialAnimation on source {
                id: flyAnimation
                objectName: "flyAnimation"

                loops: Animation.Infinite

                PropertyAnimation {
                    to: "Pelican1.png"
                }

                PropertyAnimation {
                    to: "Pelican2.png"
                }
            }

            SequentialAnimation on y {
                id: fallingBird
                objectName: "fallingBird"

                NumberAnimation {
                    from: pelicanSprite.y
                    to: playArea.height - pelicanSprite.height
                    duration: (playArea.height - pelicanSprite.y
                               - pelicanSprite.height) / 120 * 1000
                }

                onRunningChanged: {
                    if (running !== true && pelicanSprite.y === playArea.height
                            - pelicanSprite.height)
                    {
                        flyAnimation.stop()
                        pelicanSprite.source = "Pelican_Death.png"
                        playArea.enabled = false
                    }
                }
            }

            SequentialAnimation on y {
                id: upBird
                objectName: "upBird"

                running: false

                NumberAnimation {
                    from: pelicanSprite.y
                    to: pelicanSprite.y - units.gu(9)
                    duration: 200
                }

                onRunningChanged: {
                    if (running !== true)
                        fallingBird.start()
                }
            }
        }

        Image {
            id: menuImage
            objectName: "menuImage"

            x: playArea.width - pauseImage.width - width - root.margins
               - root.spacing
            y: root.margins
            width: units.gu(3)
            height: units.gu(3)

            source: "menu.svg"
        }

        Image {
            id: pauseImage
            objectName: "pauseImage"

            x: playArea.width - width - root.margins
            y: root.margins
            width: units.gu(3)
            height: units.gu(3)

            source: "pause.svg"

            MouseArea {
                id: pauseArea
                objectName: "pauseArea"

                width: parent.width
                height: parent.height

                onClicked: {
                    fallingBird.running === true ? fallingBird.stop() :
                                                   fallingBird.start()

                    flyAnimation.running === true ? flyAnimation.stop() :
                                                    flyAnimation.start()

                    flyAnimation.running === true ? playArea.enabled = true :
                                                    playArea.enabled = false

                    flyAnimation.running === true ?
                                pauseImage.source = "pause.svg" :
                                pauseImage.source = "start.svg"
                }
            }
        }

        onClicked: {
            if (pelicanSprite.y > (pelicanSprite.height + root.margins +
                                   root.spacing + pauseImage.height))
            {
                fallingBird.stop()
                upBird.start()
            }
        }
    }
}

Há também agora um botão de pausa de trabalho e um botão de menu que não funciona. O problema foi resolvido combinando a função onClicked do playArea e o onRunningChanged da animação upBird. Além disso, a duração deve ser definida dependendo do que resta para o pelicano, para que a velocidade seja constante, não importa onde você clique. Caso contrário, quanto mais próximo do final você clicou, mais lento ele iria, tentando correr em 5 segundos a uma distância menor.

A opção y foi alterada para pelicanSprite.y em vez de simplesmente y, também, para que funcione corretamente.

    
por Víctor Matía Rodríguez 05.11.2014 / 12:27