有一个canvas 序列帧动画画,怎么知道现在播放到了第几帧

【Cocos2d-x v3.x官方文档】序列帧动画
招聘信息:
Cocos2d-x中,动画的具体内容是依靠精灵显示出来的,为了显示动态图片,我们需要不停切换精灵显示的内容,通过把静态的精灵变为动画播放器从而实现动画效果。动画由帧组成,每一帧都是一个纹理,我们可以使用一个纹理序列来创建动画。
我们使用Animation类描述一个动画,而精灵显示动画的动作则是一个Animate对象。动画动作Animate是精灵显示动画的动作,它由一个动画对象创建,并由精灵执行。
1. &手动添加序列帧到Animation类
2. &使用文件初始化Animation类
手动添加的方法需要将每一帧要显示的精灵有序添加到Animation类中,并设置每帧的播放时间,让动画能够匀速播放。另外,还要通过`setRestoreOriginalFrame`来设置是否在动画播放结束后恢复到第一帧。创建好Animation实例后,需要创建一个Animate实例来播放序列帧动画。
auto&animation&=&Animation::create();&for(&int&i=1;i<15;i++)&{&&&&char&szName[100]&=&{0};&&&&sprintf(szName,&"Images/grossini_dance_%02d.png",&i);&&&&animation->addSpriteFrameWithFile(szName);&}&&&&animation->setDelayPerUnit(2.8f&/&14.0f);&animation->setRestoreOriginalFrame(true);&auto&action&=&Animate::create(animation);&_grossini->runAction(Sequence::create(action,&action->reverse(),&NULL));&
在创建Animation实例时会用到以下几个接口:
1.&addSpriteFrame&,添加精灵帧到Animation实例
2. &setDelayUnits&,设置每一帧持续时间,以秒为单位
3. &setRestoreOriginalFrame&,设置是否在动画播放结束后恢复到第一帧
4. &clone&,克隆一个该Animation实例
首先我们来了解下需要用到的AnimationCache类。AnimationCache可以加载xml/plist文件,plist文件里保存了组成动画的相关信息,通过该类获取到plist文件里的动画。
在使用AnimationCache类时会用到以下几个接口:
1.&addAnimationsWithFile&,添加动画文件到缓存,plist文件
2.&getAnimation&,从缓存中获取动画对象
3.&getInstance&,获取动画缓存实例对象
使用文件添加的方法只需将创建好的plist文件添加到动画缓存里面,plist文件里包含了序列帧的相关信息。再用动画缓存初始化Animation实例,用Animate实例来播放序列帧动画。
auto&cache&=&AnimationCache::getInstance();&cache->addAnimationsWithFile("animations/animations-2.plist");&auto&animation2&=&cache->getAnimation("dance_1");&auto&action2&=&Animate::create(animation2);&_tamara->runAction(Sequence::create(action2,&action2->reverse(),&NULL));&
注意:3.0开始,Cocos2d-x使用getInstance来获取单例实例。
动画缓存(AnimationCache)
通常情况下,对于一个精灵动画,每次创建时都需要加载精灵帧,按顺序添加到数组,再创建对应动作类,这是一个非常烦琐的计算过程。对于使用频率高的动画,比如走路动画,将其加入缓存可以有效降低每次创建的巨大消耗。由于这个类的目的和缓存内容都非常简单直接,所以其接口也是最简单了的,如下所示:
1. static AnimationCache* getInstance(),全局共享的单例
2. void addAnimation(Animation *animation, const std::string& name),添加一个动画到缓存
3. void addAnimationsWithFile(const std::string& plist),添加动画文件到缓存
4. void removeAnimation(const std::string& name),移除一个指定的动画
5. Animation* getAnimation(const std::string& name),获得事先存入的动画
建议:在内存警告时我们应该加入如下的清理缓存操作:
void&releaseCaches()&{&AnimationCache::destroyInstance();&SpriteFrameCache::getInstance()->removeUnusedSpriteFrames();&TextureCache::getInstance()->removeUnuserdTextures();&}&
值得注意的是清理的顺序,我们推荐先清理动画缓存,然后清理,最后是。按照引用层级由高到低,以保证释放引用有效。
原帖地址:
微信扫一扫
订阅每日移动开发及APP推广热点资讯公众号:CocoaChina
您还没有登录!请或
点击量8911点击量7989点击量6410点击量6383点击量4406点击量3935点击量3090点击量3028点击量2687
&2016 Chukong Technologies,Inc.
京公网安备89君,已阅读到文档的结尾了呢~~
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
如何使用拼合图播放一个序列帧动画
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-4.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口您所在的位置: &
使用脚本实现序列帧动画
使用脚本实现序列帧动画
清华大学出版社
《Unity3D\2D手机游戏开发》第5章2D游戏,本章将介绍如何使用Unity开发2D游戏,包括Sprite的创建、动画的制作、2D物理的使用,以及一个2D捕鱼游戏的示例。本节为大家介绍使用脚本实现序列帧动画。
5.3.2& 使用脚本实现序列帧动画
因为2D的序列帧动画只是将图片一张张按顺序显示出来,因此使用脚本实现序列帧动画比较简单,如果是批量生产,比如从配置文件中读取资源数据,使用脚本实现动画效果效率也更高一些,下面是一个示例。
新建一个工程,复制资源文件目录rawdata/2d下的player0016.png等贴图文件到当前工程的Resources目录内。
在Unity的菜单栏选择【GameObject】&【Create Empty】创建一个空的游戏体,为这个游戏体添加一个脚本,命名为SpriteAnimator。
在SpriteAnimator.cs脚本中添加代码如下:
using&UnityE &using&System.C &&///&Sprite&动画播放器 &public&class&SpriteAnimator&:&MonoBehaviour&{ &&&&&&///&Sprite渲染器 &&&&&protected&SpriteRenderer&m_ &&&&&///&Sprite动画帧 &&&&&protected&Sprite[]&m_ &&&&&///&动画计时器(默认每隔0.1秒更新一帧) &&&&&protected&float&timer&=&0.1f; &&&&&///&贴图文件名前缀 &&&&&public&string&m_sprite_name&=&&player00&; &&&&&///&贴图文件起始帧数字 &&&&&public&int&m_start_frame&=&0; &&&&&///&动画的帧数 &&&&&public&int&m_frame_count&=8; &&&&&///&跳帧数量 &&&&&public&int&m_offset_frame&=&4; &&&&&///&当前的帧数 &&&&&protected&int&m_frame&=&0; &}&
SpriteRenderer是Sprite的渲染器,只有通过它才能在屏幕上显示出Sprite的图像。
m_clips是一个Sprite数组,用来保存动画所需要的Sprite。
在这个例子中,我们使用的动画贴图文件命名都采用数字后缀,表示动画帧,并且跳帧,如&player0016,player0020,player0024&&&。m_start_frame表示第一帧的数字,在这个例子中是指16, m_offset_frame表示跳帧,在这个例子中是指4。出现跳帧数字是因为这些图像都是通过3D软件渲染而成,在渲染的时候进行了跳帧设置,否则这个动画需要几十张图片来表现。
在Start函数中添加代码如下:
void&Start&()&{ &&&&&&&&&//&初始化动画帧数组 &&&&&&&&&m_clips&=&new&Sprite[m_frame_count]; &&&&&&&&&for&(int&i&=&0;&i&&;&i++) &&&&&&&&&{ &&&&&&&&&&&&&//&当前帧 &&&&&&&&&&&&&int&currentframe&=&m_start_frame&+&i&*&m_offset_ &&&&&&&&&&&&&//&计算贴图名称 &&&&&&&&&&&&&string&spritename&=&string.Format(m_sprite_name&+&&{0:D2}&,&currentframe); &&&&&&&&&&&&&//&从Resources目录读取贴图 &&&&&&&&&&&&&Texture2D&texture&=&(Texture2D)Resources.Load(spritename); &&&&&&&&&&&&&//&由贴图创建出Sprite &&&&&&&&&&&&&m_clips[i]&=&Sprite.Create(texture,& &&&&&&&&&&&&&&&&&&&&&new&Rect(0,&0,&texture.width,&texture.height),& &&&&&&&&&&&&&&&&&&&&&new&Vector2(0.5f,&0.2f)); &&&&&&&&&} &&&&&&&&&//&为当前GameObject添加一个Sprite渲染器 &&&&&&&&&m_sprite&=&this.gameObject.AddComponent(); &&&&&&&&&//&设置第1帧的Sprite &&&&&&&&&m_sprite.sprite&=&m_clips[m_frame]; &&&&&}&
在Start函数中,首先创建了一个Sprite数组m_clips,这个数组用来保存动画帧图像。我们从Resources目录内读取贴图文件,然后使用Sprite.Create创建Sprite,并放到m_clips数组中。注意,在创建Sprite的时候,需要设置Rect矩形面积,我们可以只取得原始贴图的一部分图像,当前的例子我们获取了整个图像。
在Update函数中添加代码如下:
void&Update&()&{ &&&&&&&&&//&更新时间 &&&&&&&&&timer-=Time.deltaT &&&&&&&&&if&(&timer=0&) &&&&&&&&&{ &&&&&&&&&&&&&timer&=&0.1f; &&&&&&&&&&&&&//&更新帧 &&&&&&&&&&&&&m_frame++; &&&&&&&&&&&&&if&(m_frame&=&m_frame_count) &&&&&&&&&&&&&&&&&m_frame&=&0; &&&&&&&&&&&&&//&更新Sprite动画 &&&&&&&&&&&&&m_sprite.sprite&=&m_clips[m_frame]; &&&&&&&&&} &&&&&}&
这里的代码每隔0.1秒,更新到下一帧Sprite,因此产生了动画效果。如果动画已经播放到最后一帧,则回到第1帧。
现在运行游戏,可以看到与5.3.1节类似的动画效果,不过存放在Resources中的Sprite并不能使用Sprite Packer工具。本节的示例工程文件保存在资源文件目录chapter05_scriptanimation中。
喜欢的朋友可以添加我们的微信账号:
51CTO读书频道二维码
51CTO读书频道活动讨论群:【责任编辑: TEL:(010)】&&&&&&
关于&&&&的更多文章
本书以实例教学为主线,循序渐进地介绍了Unity在游戏开发方面的
本书描述了黑客用默默无闻的行动为数字世界照亮了一条道路的故事。
讲师: 325人学习过讲师: 84人学习过讲师: 40人学习过
本书由基础知识、安装与部署、研发与维护、进阶知识、
本书主要包括JavaScript知识、JavaScript编程基础、程
作为开源硬件的代表之一,Arduino包含一套硬件和软件
本书将介绍如何创建可交互的Web站点,包括从最简单的订单表单到复杂的安全电子商务站点。而且,读者还将了解如何使用开放源代码
51CTO旗下网站animator怎么获取当前播放的动画运行的帧数?_unity3d吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:60,875贴子:
animator怎么获取当前播放的动画运行的帧数?收藏
大神全靠你了
unity3d,学习专业的游戏引擎-unity3d.达内游戏主程培训,一般要4-16周,就可掌握.变高端游戏达人-薪资翻番.unity3d费用根据培训课时定,上海官方咨询-unity3d.
知道GetCurrentAnimatorStateInfo这个函数,但是不知道该怎么用
每秒24贞的话,乘以秒数
AnimatorStateInfo类里面的normalizedTime这个返回了当前动作的时间,整数表示已经循环了几次,小数点后的数字表示目前动作执行的进度。
我知道unity阿凡达系统里有个加载事件的方式在动画播放到第几帧的时候发送个信息到指定的物体上。
顶起来。。。。很多伤害和事件都是靠动画播放程度来触发的,而且通常不是播放完成阶段。。。
谢谢4楼,4楼正解。。。
我想知道怎么判断当前的animator的播放状态,比如这个动画目前是否已经播放结束了什么的要如何判断啊?
笨方法,获取动画时间,然后乘30
但是 animation.PlayQueued 用这个方法播放的动画 获得的normalizedTime 总是 0怎么办
,好物精选,辞旧迎新放大&价&!新年全天24小时24万件商品1元秒!京东数码,正品行货,多仓直发,急速配送,享受轻松购物,就上JD.com!
神都在发问了,真正的神在哪
看timer走到1秒时,i是几,帧频就是几。public class test : MonoBehaviour {// Use this for initialization
public int i = 0;
public float timer=0;void Start () {
}// Update is called once per framevoid Update () {
i = i + 1;
timer = timer + Time.deltaT
Debug.Log(i);
Debug.Log(timer);}}
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或逐帧动画实现的四种方式
逐帧动画实现CSS3 or JavaScript
我们经常会在H5页面中看到一段序列帧动画,最近小编对此实现方法非常感兴趣,就总结了实现逐帧动画常用的几种实现方法。比如,现在需要实现这个小动画
一、GIF动图
打开PS6,点击窗口→时间轴,在时间轴窗口中有6张不同的图片,通过一帧一帧的播放来实现这个动画。
GIF动画优缺点:
好处:实现简单、可维护性高、工作成本低
缺点:只适合简单的动画效果,不能动态控制动画
在实际的项目中,我们往往根据需求而需要把动画做的更加灵活,那就不是gif动图所能完成的了。下面,我们先探讨有哪些技术可以实现我所说的功能~~~
二、使用CSS3动画
(1)通过切换6张图片的方式来实现,具体代码实现参考如下(篇幅考虑仅列出webkit的写法):
#anim{width:120 height:120 position: top: 50%; left: 50%; margin-top: -60 margin-left: -60 -webkit-animation: auto-circle 0.5s step- display:}@-webkit-keyframes auto-circle{ 0%{background-image:url(images/anim-01.png);}
20%{background-image:url(images/anim-02.png);} 40%{background-image:url(images/anim-03.png);} 60%{background-image:url(images/anim-04.png);} 80%{background-image:url(images/anim-05.png);} 100%{background-image:url(images/anim-06.png);}}
演示demo链接
6张图片合成1张,通过切换背景图片位置来实现,具体代码实现参考如下(篇幅考虑仅列出webkit的写法):
#anim{ background-image: url(images/anim.png); width:120 height:120 position: top: 50%; left: 50%; margin-top: -60 margin-left: -60 -webkit-animation: auto-circle 0.5s steps(5) }@-webkit-keyframes auto-circle{ 100%{background-position-x:
演示demo链接
当然,用雪碧图&#43;CSS3实现还有一些其他的方法:
#anim{ background-image: url(images/anim.png); width:120 height:120 position: top: 50%; left: 50%; margin-top: -60 margin-left: -60 -webkit-animation: auto-circle 0.5s step- }@-webkit-keyframes auto-circle{ 0%{background-position-x:
0;} 20%{background-position-x: 120} 40%{background-position-x: 240} 60%{ background-position-x: 360} 80%{background-position-x: 480} 100%{background-position-x: 600}}
演示demo链接
#animbg{ width:120 height:120 position: top: 50%; left: 50%; margin-top: -60 margin-left: -60 overflow: }#anim{-webkit-animation: auto-circle 0.5s step-;}@-webkit-keyframes auto-circle{ 0%{-webkit-transform:translate3d(0,0,0);}
20%{-webkit-transform:translate3d(-120px,0,0);} 40%{-webkit-transform:translate3d(-240px,0,0);} 60%{-webkit-transform:translate3d(-360px,0,0);} 80%{-webkit-transform:translate3d(-480px,0,0);} 100%{-webkit-transform:translate3d(-600px,0,0);}}
演示demo链接
分析使用6张图片和1张雪碧图这两种方式
实现起来会比较简单,但带来额外的5个请求数
6张图片总大小为:56.5k
加载时间:
需要设计雪碧图,并量取背景位置,请求数少
雪碧图大小为:44.9k
加载时间:
由上面的分析可以看出,多张图片合成的雪碧图比6张图片还少 11.6k 外,还可以减少5个HTTP请求,并且加载时间也会大大减少,当然加载时间有时也会根据用户当前所处的网络环境而有所不同,综上所述,还是使用切换背景位置方式是比较好的。
三:使用JavaScript操作CSS属性
(1)采用6张图片依次显隐的方式,具体代码实现参考如下:
$(function(){ var animImg = 1; var animImages = setInterval(function () { animImg&#43;&#43;; if (animImg &= 7) { animImg = 1; } $(&.animImg&).hide(); $(&.animImg& &#43; animImg).show(); }, 100); });
演示demo链接
(2)采用雪碧图,通过javascript不断的改变帧图片的background-position,具体代码实现参考如下:
(function(){ window.frameAnimation = { anims:(function(){ /* obj=&需要执行背景动画的对象; width:图片的总宽度 steps=&需要的帧数; eachtime=&一次完整动画需要的时间; times=&动画执行的次数 0表示无限反复 */ return function(obj,width,steps,eachtime,times, callback){ var runing = var handler = //obj,width,steps,eachtime,times定时器
var step = 0; //当前帧 var time = 0; //当前第几轮 var speed = eachtime*500/ //间隔时间 var oneStepWidth = width/ function _play(){ if(step &= steps){ step = 0; time&#43;&#43;; } if(0 == times || time & times){ obj.css('background-position', -oneStepWidth * step &#43;
'px 0px'); step&#43;&#43;; }else{ control.stop(); callback && callback(); } } var control = { start:function(){ if(!runing){ runing = step = time = 0; handler = setInterval(_play, speed); } } ,stop:function(restart){ if(runing){ runing =
if(handler){ clearInterval(handler); handler = } if(restart){ obj.css('background-position', '0 0'); step = 0; time = 0; } } } ,dispose:function(){ this.stop(); //console.log('anim dispose'); } }; } })() }})(window);function play(){ var
anim = frameAnimation.anims($('#anim'),720,6,1,0); anim.start();}
演示demo链接
四、使用Canvas
说到帧动画,很容易就联想到canvas,将图片绘制到canvas上面,不断重绘就能得到我们想要的效果。使用canvas的好处是,只要有一个基于canvas模拟帧动画的类库,就可以随意使用。操作JavaScript比操作css要灵活,可以传递各种参数实现不同的要求,还可以使用回调函数来设置动画结束时的操作。缺点是老式浏览器不兼容canvas,而且如果需求简单的话,使用canvas有些大材小用。一个最简单的循环动画类如下所示:
window.onload=function(){stage = new createjs.Stage('animCanvas');//创建舞台w=stage.canvas.h=stage.canvas.$('#animCanvas').css({'height':120&#43;'px','width':120&#43;'px'});//适配用manifest = [{src: 'anim.png', id: 'img'},];//预加载loader
= new createjs.LoadQueue(false);loader.addEventListener('complete', handleComplete);//加载完成 调用handleComplete函数loader.addEventListener('progress', handleFileProgress);//加载完成 调用handleFileProgress函数loader.loadManifest(manifest, true, 'images/');}function handleComplete(){//加载完成调用函数var
spriteSheet = new createjs.SpriteSheet({//创建精灵framerate: 60,'images': [loader.getResult('img')],'frames': {'regX':0, 'height':120, 'count':6, 'regY': 0, 'width': 120},'animations': {'anim': [0, 5, 'anim'],}});img = new createjs.Sprite(spriteSheet, 'anim');stage.addChild(img);//将img加载到舞台上createjs.Ticker.addEventListener('tick',
tick);//刷新createjs.Ticker.setFPS(10); //每秒调用tick函数 3次 控制动画快慢}function handleFileProgress(event){//加载中函数console.log(loader.progress*100|0&#43;'%');}function tick(e){//tick函数stage.update(event);//更新舞台 }
演示demo链接
综上所述,现在使用一个简单的表&#26684;来汇总逐帧动画常见的制作手法,希望读完本文的小伙伴们都可以在下次遇见这类动画效果时,第一时间挖掘出它背后的制作原理,好好运用这四种实现方法,(表&#26684;中所阐述的性能损耗和实现成本等仅作参考)。
上面表&#26684;看起来还是有些杂乱,还是弄一个简单的表吧,如下表所示:
四种方法各有优势和劣势。如果明确了浏览器的型号和版本支持css3时,推荐使用CSS3的方法。如果是为了广泛使用,推荐使用JavaScript的方法。当序列帧很简单的时候,不建议使用canvas来实现功能。当需要实现复杂动画或者做游戏开发的时候,使用canvas较好,可以灵活的对动画进行操作设置。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:3493次
排名:千里之外
原创:27篇
转载:11篇
(15)(6)(2)(2)(1)(3)(2)(1)(1)}

我要回帖

更多关于 序列帧动画素材 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信