在游戏中动画的设计很中要。

在QML中,它提供了丰富的animation。可是有时我们须要对图像进行变化,就像放电影一样。在今天的这篇文章中,我们将设计一个能够变化图像的动画。

我们能够通过Qt所提供的Sprite功能来实现。

为了设计的方便,我们先设计一个我们自己的bear动画,这个动画的图像大小为: 2048x256。它刚好是8副图256x256

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="800" height="150" alt="">

在我们的Sprite设计中,我们想依照上述图像显示的顺序依次显示每一个图像,这样就能够形成一个能够连续变化的动画效果。

直接把我们的动画设计文件BearSprite贴出来:

BearSprite.qml

import QtQuick 2.0

Item  {
width: 256
height: 256 SpriteSequence {
id: fishSprite
anchors.fill: parent
interpolate: false
goalSprite: "" Sprite {
name: "first"
source: "./gfx/Bear2.png"
frameWidth: 256
frameHeight: 256
frameCount: 1
frameDuration: 800
frameDurationVariation: 400
to: { "second" : 1 }
} Sprite {
name: "second"
source: "./gfx/Bear2.png"
frameCount: 1
frameX: 256
frameWidth: 256
frameHeight: 256
frameDuration: 800
frameDurationVariation: 400
to: { "third" : 1 }
} Sprite {
name: "third"
source: "./gfx/Bear2.png"
frameCount: 1
frameX: 256*2
frameWidth: 256
frameHeight: 256
frameDuration: 800
frameDurationVariation: 400
to: { "fourth" : 1 }
} Sprite {
name: "fourth"
source: "./gfx/Bear2.png"
frameCount: 1
frameX: 256*3
frameWidth: 256
frameHeight: 256
frameDuration: 800
frameDurationVariation: 400
to: { "fifth" : 1 }
} Sprite {
name: "fifth"
source: "./gfx/Bear2.png"
frameCount: 1
frameX: 256*4
frameWidth: 256
frameHeight: 256
frameDuration: 800
frameDurationVariation: 400
to: { "sixth" : 1 }
} Sprite {
name: "sixth"
source: "./gfx/Bear2.png"
frameCount: 1
frameX: 256*5
frameWidth: 256
frameHeight: 256
frameDuration: 800
frameDurationVariation: 400
to: { "seventh" : 1 }
} Sprite {
name: "seventh"
source: "./gfx/Bear2.png"
frameCount: 1
frameX: 256*6
frameWidth: 256
frameHeight: 256
frameDuration: 800
frameDurationVariation: 400
to: { "eighth" : 1 }
} Sprite {
name: "eighth"
source: "./gfx/Bear2.png"
frameCount: 1
frameX: 256*7
frameWidth: 256
frameHeight: 256
frameDuration: 800
frameDurationVariation: 400
to: { "first" : 1 }
} Sprite { //WORKAROUND: This prevents the triggering of a rendering error which is currently under investigation.
name: "dummy"
source: "./gfx/Bear2.png"
frameCount: 8
frameWidth: 256
frameHeight: 256
frameX: 0
frameDuration: 200
}
} }


在上面的设计中,我们使用了一个SpriteSequence,里面放了一些我们所须要的Sprite。

        Sprite {
name: "sixth"
source: "./gfx/Bear2.png"
frameCount: 1
frameX: 256*5
frameWidth: 256
frameHeight: 256
frameDuration: 800
frameDurationVariation: 400
to: { "seventh" : 1 }
}

这里的每一个Sprite的设计都差点儿都差点儿相同。每一个Sprite都有一个自己的名字。这里注意frameX。它事实上是在我们上面显示的图里的x坐标位置。比方256x5。表示的是滴5副图。另外,我们的frameHeight和frameWidth也是和原图的大小是一样的,尽管在实际的显示中这个大小能够在Main.qml中能够设置。

使用相同的方法,我们能够做一个FishSprite。

FishSprite.qml




import QtQuick 2.0
import QtMultimedia 5.0 Item {
width: 64
height: 64
property real hp: 3 SoundEffect {
id: spawnSound
source: "./audio/catch.wav"
loops:SoundEffect.Infinite
} SoundEffect {
id: killedSound
source: "./audio/catch-action.wav"
} SpriteSequence {
id: fishSprite
anchors.fill: parent
interpolate: false
goalSprite: "" Sprite {
name: "left"
source: "./gfx/mob-idle.png"
frameWidth: 64
frameHeight: 64
frameCount: 1
frameDuration: 800
frameDurationVariation: 400
to: { "front" : 1 }
} Sprite {
name: "front"
source: "./gfx/mob-idle.png"
frameCount: 1
frameX: 64
frameWidth: 64
frameHeight: 64
frameDuration: 800
frameDurationVariation: 400
to: { "left" : 1, "right" : 1 }
} Sprite {
name: "right"
source: "./gfx/mob-idle.png"
frameCount: 1
frameX: 128
frameWidth: 64
frameHeight: 64
frameDuration: 800
frameDurationVariation: 400
to: { "front" : 1 }
} Sprite { //WORKAROUND: This prevents the triggering of a rendering error which is currently under investigation.
name: "dummy"
source: "./gfx/melee-idle.png"
frameCount: 8
frameWidth: 64
frameHeight: 64
frameX: 0
frameDuration: 200
} NumberAnimation on x {
id: fishSwim
running: false
property bool goingLeft: fishSprite.currentSprite == "right"
to: goingLeft ? -360 : 360
duration: 300
} Component.onCompleted: {
spawnSound.play()
}
} SpriteSequence {
id: bubble
width: 64
height: 64
scale: 0.4 + (0.2 * hp)
interpolate: false
goalSprite: "" Behavior on scale {
NumberAnimation { duration: 150; easing.type: Easing.OutBack }
} Sprite {
name: "big"
source: "./gfx/catch.png"
frameCount: 1
to: { "burst" : 0 }
} Sprite {
name: "burst"
source: "./gfx/catch-action.png"
frameCount: 3
frameX: 64
frameDuration: 200
} Sprite { //WORKAROUND: This prevents the triggering of a rendering error which is currently under investigation.
name: "dummy"
source: "./gfx/melee-idle.png"
frameCount: 8
frameWidth: 64
frameHeight: 64
frameX: 0
frameDuration: 200
}
SequentialAnimation on width {
loops: Animation.Infinite
NumberAnimation { from: width * 1; to: width * 1.1; duration: 800; easing.type: Easing.InOutQuad }
NumberAnimation { from: width * 1.1; to: width * 1; duration: 1000; easing.type: Easing.InOutQuad }
}
SequentialAnimation on height {
loops: Animation.Infinite
NumberAnimation { from: height * 1; to: height * 1.15; duration: 1200; easing.type: Easing.InOutQuad }
NumberAnimation { from: height * 1.15; to: height * 1; duration: 1000; easing.type: Easing.InOutQuad }
}
}
}


Main.qml


import QtQuick 2.0
import Ubuntu.Components 1.1 /*!
\brief MainView with a Label and Button elements.
*/ MainView {
// objectName for functional testing purposes (autopilot-qt5)
objectName: "mainView" // Note! applicationName needs to match the "name" field of the click manifest
applicationName: "sprite.liu-xiao-guo" /*
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(60)
height: units.gu(85) Page {
id: page
title: i18n.tr("sprite") Column {
anchors.fill: parent FishSprite {
height: units.gu(30)
width: units.gu(30)
} BearSprite {
id: bear
height: units.gu(30)
width: units.gu(30) NumberAnimation on x {
to: page.width
duration: 8*800 onRunningChanged: {
if ( running == false) {
bear.x = 0
start()
}
}
}
}
}
}
}

执行我们的QML应用:

  

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" width="200" height="300" alt="">   



最新文章

  1. [Android Pro] AsyncTaskLoader vs AsyncTask
  2. ASCII、Unicode、GBK和UTF-8字符编码的区别联系
  3. 彻底弄懂js循环中的闭包问题
  4. 从零学习storm(一) 环境的安装配置
  5. navjs
  6. 三层架构实例 VB.NET版
  7. SegmentFault 2014黑客马拉松 北京 作品demo
  8. 请不要用SECONDS_BEHIND_MASTER来衡量MYSQL主备的延迟时间
  9. Java Timer, TimerTask
  10. 【Android开发经验】移动设备的“声波通信/验证”的实现——SinVoice开源项目介绍(一)
  11. 【录教程必备】推荐几款屏幕录制工具(可录制GIF)
  12. 剑指OFFER——合并两个有序的链表
  13. Future与Promise
  14. composer安装laravel指定版本
  15. jenkins安装详细教程
  16. 微信小程序注册60s倒计时功能 使用JS实现注册60s倒计时功能
  17. Docker 空间大小设置 - 十
  18. VueJs相关学习网址
  19. PyQt4程序图标
  20. C1WPF制作OLAP Cube浏览工具

热门文章

  1. 12.jsp概述及指令
  2. P1133 教主的花园 (动态规划)
  3. 【2018.10.1】【JSOI2016】最佳团体(bzoj4753)
  4. HashMap构造函数有哪些
  5. TYVJ3680 找妹子
  6. zTree 用法小例
  7. SGU112
  8. [Bzoj1112][POI2008]砖块Klo(splay)
  9. 51 NOD 1383 整数分解为2的幂
  10. BZOJ1016最小生成树计数 最小生成树 + 排列组合