• Qt移动应用开发(三):使用精灵图片实现帧动画


    Qt移动应用开发():使用精灵图片实现帧动画

           上一篇博文讲到了Qt Quick对于动画的一般支持。动画的形式多样,配合不同的插值函数,能够差点儿实现全部想要的动画效果,而对于游戏的一些特殊的效果比方说帧动画,Qt更是有专门的类来实现。以下我们就来看看Qt Quick中到底是对帧动画是怎样实现的吧。

    原创文章。反对未声明的引用。

    原博客地址:http://blog.csdn.net/gamesdev/article/details/33743527

           一般2D的游戏引擎都将帧动画作为一项非常重要的功能特性加以宣传,比方说cocos2d-x也有非常强大的帧动画效果,其实,一个良好的设计能够让帧动画有无限的变种形式,从而给设计人员无限的灵感空间。Qt Quick的帧动画做得非常完好。不仅能够单独渲染成动画的形式,并且能够和粒子系统相搭配,获得更炫的样例效果。

           其实帧动画为了节省显存的空间,通常会採用一张大图的形式来保存一个角色的所帧信息。以下两个样例就是帧动绘图片:


           帧动画的实现通常须要状态机系统的辅助。由于除了解析这张大图的任务外,为角色的每一个动作赋予对应的状态也是帧动画的重要任务。所以一款游戏会将角色的某个动作的不同帧作为一组来分类播放。最后形成角色的行为动作。这是Qt自带的样例bear whack的截图:

    以下我就使用一个实例来向大家介绍一下Qt怎样使用Sprite和SpriteSequence来实现帧动画的。

    import QtQuick 2.2
    import QtQuick.Controls 1.1
    
    ApplicationWindow {
        visible: true
         640
        height: 480
        title: qsTr("Sprite測试")
    
        menuBar: MenuBar {
            Menu {
                title: qsTr("文件")
                MenuItem {
                    text: qsTr("退出")
                    onTriggered: Qt.quit( );
                }
            }
        }
    
        SpriteSequence
        {
            id: spriteSequence
            anchors.centerIn: parent
             256
            height: 256
            interpolate: false
            running: true
            sprites:
            [
                Sprite
                {
                    name: "floating"
                    source: "Bear1.png"
                    frameCount: 9
                    frameWidth: 256
                    frameHeight: 256
                    frameDuration: 80
                }
            ]
        }
    
        Text
        {
            anchors.top: spriteSequence.bottom
            anchors.horizontalCenter: spriteSequence.horizontalCenter
            text: qsTr("本例用来測试Sprite的使用情况。

    ") } }


    我们直接将Qt样例中的小熊帧动画拿过来了。以下是程序的截图:

           SpriteSequence类的作用是为帧动画提供一个显示的容器,而且控制Sprite的执行情况。而Sprite呢,则类似于一个动作组,它能够指定角色的动作由哪些帧组成。上面的样例是通过使用frameCount、frameWidth、frameHeight和frameDuration来达到目的。

    Sprite的容器能够不是SpriteSequence,比方说将帧动画应用在粒子系统上就须要ImageParticle作为Sprite的容器了。比方说Qt自带的样例bear whack就使用了类似的手法。

           除了上面的方法外,另一种将SpriteSequence和Sprite结合起来的更加简单的方法来指定动画,那就是AnimateSprite。还是上面的样例。我们这样改写:

    AnimatedSprite
    {
        id: animatedSprite
        anchors.centerIn: parent
         256
        height: 256
        frameCount: 9
        frameWidth: 256
        frameHeight: 256
    frameDuration: 80
    interpolate: false
        source: "Bear1.png"
    }

    效果和上面一样,并且语法更加简单。事实上正是Qt去掉了自己定义transition(过渡)的效果而推出的一个简单类。很适合仅仅有单个动作的角色。大多数情况下我们使用它就足够了。

           在我制作的游戏《吃药了》中,我也受益于AnimatedSprite类,事实上在时间紧迫的情况下,我仅仅绘制出了两帧:

    于是在AnimatedSprite的帮助下,实现细菌的帧动画就变得很easy:

    // 细菌
    import QtQuick 2.2
    import "GameController.js" as Controller
    
    Block
    {
        id: bacterium
        type: Controller.TYPE_BACTERIUM
        property alias source: sprite.source
    
        AnimatedSprite
        {
            id: sprite
             parent.width
            height: parent.height
    
            frameWidth: 128
            frameHeight: 128
            frameCount: 2
            frameRate: 2
            running: true
        }
    
        function setSource( color )
        {
            var imageResources = ["bacterium-red.png",
                                  "bacterium-yellow.png",
                                  "bacterium-blue.png"];
            source = "../../images/" + imageResources[color];
        }
    
        function setInvisible( )
        {
            sprite.visible = false;
        }
    }

    本文參加了CSDN博文大赛。请大家支持我。为我投一票!

  • 相关阅读:
    prometheus基础概念
    Prometheus告警处理
    什么是prometheus?
    Prometheus的PromQL
    Prometheus的Exporter详解
    leetcode unique path I&&II
    leetcode Palindrome Partitioning
    leetcode 最大子矩阵(5星推荐)
    leetcode Sum Root to Leaf Numbers 二叉树所有叶节点的路径和
    leetcode Spiral Matrix I
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/5379267.html
Copyright © 2020-2023  润新知