Implementing States with QML



  • Hi everybody,

    I spent some days struggling with a nice implementation of states for a little game. From other projects, I'm used to implementing a small state-machine that provides the following attributes for each state:

    1. actions on entering state
    2. sub states with default state
    3. action on leaving state
    4. transition between states (action/methods that can be invoked)
    5. automatic transition to another state if state is complete (e.g. after loading, etc.)

    Although QML transition seem to be nice for small animation demos, they feel immature when it comes to logic and structure.

    I want to implement the following state-chart:

    [url]http://www.pixtur.de/pub/game-state-chart.png[/url]

    Some of my questions:

    1. Why are are states identified by Strings instead of IDs ?
    2. Why can't Transitions be normal objects of a state (instead of items in the transitions property list?
    3. How can I easily define to jump from one state to another after a timeout or a keypress?

    My current implementation looks like this:

    @
    import Qt 4.7
    import "ovilogo"
    import "warp5"

    Item {
    id: main
    width: 864
    height: 480

    Component.onCompleted: {
        main.state = "OVI_LOGO";
        console.log("onCompleted");
    }
    
    
    Image {
        anchors.fill:  parent
        source:  "images/game-background.jpg"
    }
    
    Image {
        anchors.fill:  parent
        source:  "images/game-shading-with-playfields.png"
    }
    
    
    Component {
        id: ovilogo
        Ovilogo {  }
    }
    Component {
        id: warp5
        Warp5 { id:qmlRef }
    }
    
    Game {
        id:game
        visible: false
    }
    
    Loader {
        anchors.fill:  parent
        id:mainLoader
    }
    
    states: [
        State {
            name: "OVI_LOGO"
        },
        State {
            name: "WARP5_LOGO"
        },
        State {
            name: "GAME"
        }
    ]
    
    
    transitions: [
        Transition {
            to: "OVI_LOGO"
            SequentialAnimation {
                ScriptAction {
                    script: { console.log("mainLoader"); mainLoader.sourceComponent = ovilogo;}
                }
                PauseAnimation { duration: 2000 }
                ScriptAction {
                    script: { console.log("settings state to warp5..."); main.state = "WARP5_LOGO"; }
                }
            }
        },
    
        Transition {
            to: "WARP5_LOGO"
            SequentialAnimation {
                ScriptAction {
                    script: { console.log("setting source to warp5..."); mainLoader.sourceComponent = warp5;}
                }
                PauseAnimation { duration: 5000 }
                ScriptAction { script: { console.log("settings state to game...");  main.state = "GAME";}  }
            }
        },
    
        Transition {
            to: "GAME"
            ScriptAction {
                script: { console.log("setting source to warp5..."); mainLoader.visible = false; game.visible = true;}
            }
        }
    ]
    

    }
    @


    ps: Is there a link how formatting works on this forum?

    [edit : Code highlighted properly / Denis Kormalev]



  • Just use @ tags



  • [quote author="pixtur" date="1289313223"]
    Although QML transition seem to be nice for small animation demos, they feel immature when it comes to logic and structure.
    [/quote]

    Yes, QML states certainly don't provide the level of sophistication found in e.g. the Qt C++ "State Machine Framework":http://doc.qt.nokia.com/4.7/statemachine-api.html

    [quote author="pixtur" date="1289313223"]

    1. Why are are states identified by Strings instead of IDs ?
      [/quote]

    In part so they can be easily manipulated outside the component in which they are defined.

    [quote author="pixtur" date="1289313223"]

    1. Why can't Transitions be normal objects of a state (instead of items in the transitions property list?
      [/quote]

    One transition can apply to multiple state changes, which is why they aren't associated with a single state.

    [quote author="pixtur" date="1289313223"]

    1. How can I easily define to jump from one state to another after a timeout or a keypress?
      [/quote]

    A keypress could be accomplished with something like:
    @
    // in OVI_LOGO state
    PropertyChanges {
    target: main
    Keys.onPressed: main.state = "WARP5_LOGO"
    }
    @



  • Hi,

    thanks for these answers. Most of them makes sense. However, I am still convinced that transitions and states are not so closely related as it is enforced by QML. To me, states are more about logic, than about properties and assigned transitions. Thus the most important thing would not be transitions but onEnter, onLeave, onUpdate handlers and of course custom methods/actions. From these I could easily invoke any transition, which would more become a collection of Animations. This would nicely decouple the two things, and I could even reusing transitions for different states or objects or even refactor them into a separate file.

    I have to try your key-press example. I guess, I'm slowly understanding what you are doing there. :-)

    Powerful stuff, once you understood QML's potential...


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.