C

Qt Quick Ultralite sprite_animations Example

Demonstrates how to create a sprite animation.

Overview

The sprite_animations example shows how to create a sprite animation from multiple frames in an image file.

The image source for this example consist of 16 frames, where each frame size is 180x160.

Target platforms

Project structure

CMake project file

The CMake project file contains a basic build script.

cmake_minimum_required (VERSION 3.21.1)

project(sprite_animations VERSION 0.0.1 LANGUAGES C CXX ASM)
if (NOT TARGET Qul::Core)
    find_package(Qul)
endif()

qul_add_target(sprite_animations QML_PROJECT mcu_sprite_animations.qmlproject)

app_target_setup_os(sprite_animations)
app_target_default_entrypoint(sprite_animations sprite_animations)
QmlProject file

The Qmlproject file includes the required Qml and Image files.

import QmlProject 1.3

Project {
    QmlFiles {
        files: [
            "sprite_animations.qml",
            "ToggleButton.qml"
        ]
    }
    ImageFiles {
        files: [
            "qt-image-sequence.png"
        ]
        MCU.resourceAnimatedSpriteFrameWidth: 180
        MCU.resourceAnimatedSpriteFrameHeight: 160
    }
}
Application UI

The sprite_animations.qml file defines AnimatedSprite type. It defines the size of a single frame, number of frames in an image, and source of the image. When a user clicks the screen, it runs or stops the animations based on the current running value.

    AnimatedSprite {
        id: sprite
        anchors.centerIn: parent
        source: "qt-image-sequence.png"

        frameDuration: 80
        frameCount: 16
        frameWidth: 180
        frameHeight: 160
        running: false

        loops: AnimatedSprite.Infinite

        onFinished: {
            txtMsg.text = "Finished"
        }

        onRunningChanged: {
            if (sprite.running) {
                txtMsg.text = ""
            }
        }

        MouseArea {
            anchors.fill: parent
            onClicked: {
                if (sprite.running) {
                    sprite.stop()
                } else {
                    sprite.start()
                }
            }
        }
    }

On the top-left corner of the UI, the number and the duration of the current frame (in milliseconds) of each frame of the animation.

    Column {
        id: spriteInfo
        anchors.top: parent.top
        anchors.left: parent.left
        anchors.margins: 16
        spacing: 4

        Text {
            id: txtFrameNo
            text: "frame: " + (sprite.currentFrame + 1) + " / " + sprite.frameCount
            font.pixelSize: 14
            color: "white"
        }
        Text {
            id: txtDuration
            text: "duration: " + sprite.frameDuration
            font.pixelSize: 14
            color: "white"
        }
        Text {
            id: txtMsg
            font.pixelSize: 14
            text: ""
            color: "white"
        }
    }

The application has a button on the top-right corner to toggle the loops property value between AnimatedSprite.Infinite and 1.

    ToggleButton {
        id: toggleLoops
        width: parent.width / 4
        height: parent.height / 9
        anchors.right: parent.right
        anchors.top: parent.top
        anchors.margins: 8
        checkedText: "Infinite"
        uncheckedText: "Once"
        onCheckedChanged: {
            if (toggleLoops.checked) {
                sprite.loops = AnimatedSprite.Infinite
            } else {
                sprite.loops = 1
            }
        }
    }

The ToggleButton is defined using the simple visual QML types such as Rectangle, MouseArea, Text, and Row.

import QtQuick 2.15

Rectangle {
    id: control
    color: "white"

    property bool checked: true
    readonly property color foregroundColor: "black"
    readonly property int borderWidth: 1
    readonly property alias checkedText: txtChecked.text
    readonly property alias uncheckedText: txtUnchecked.text

    Row {
        x: control.borderWidth
        y: control.borderWidth
        spacing: control.borderWidth

        Rectangle {
            id: leftPart
            width: (control.width - control.borderWidth * 3) / 2
            height: (control.height - control.borderWidth * 2)
            color: control.checked? control.color : control.foregroundColor

            Text {
                id: txtChecked
                anchors.centerIn: parent
                color: control.checked? control.foregroundColor : control.color
                font.pixelSize: 14
            }
        }
        Rectangle {
            id: rightPart
            width: leftPart.width
            height: leftPart.height
            color: control.checked? control.foregroundColor : control.color

            Text {
                id: txtUnchecked
                anchors.centerIn: parent
                color: control.checked? control.color : control.foregroundColor
                font.pixelSize: 14
            }
        }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: control.checked = !control.checked
    }
}

Files:

Images:

Available under certain Qt licenses.
Find out more.