
对动画系统而言,为了实现动画,它需要做三件事儿:1确定画面变化的规律;2根据这个规律,设定动画周期,启动动画;3定期获取当前动画的值,不断地微调、重绘画面。
这三件事情对应到 Flutter 中,就是 Animation、AnimationController 与 Listener:
1Animation 是 Flutter 动画库中的核心类,会根据预定规则,在单位时间内持续输出动画的当前状态。Animation 知道当前动画的状态(比如,动画是否开始、停止、前进或者后退,以及动画的当前值),但却不知道这些状态究竟应用在哪个组件对象上。换句话说,Animation 仅仅是用来提供动画数据,而不负责动画的渲染。
2AnimationController 用于管理 Animation,可以用来设置动画的时长、启动动画、暂停动画、反转动画等。
3Listener 是 Animation 的回调函数,用来监听动画的进度变化,我们需要在这个回调函数中,根据动画的当前值重新渲染组件,实现动画的渲染。
class NormalAnimateWidget extends StatefulWidget {
@override
StatecreateState()=>_NormalAnimateState();
}
class _NormalAnimateState extends Statewith SingleTickerProviderStateMixin{
AnimationControllercontroller;
Animationanimation;
@override
void initState() {
// TODO: implement initState
superinitState();
/
AnimationController
AnimationController用于控制动画,它包含动画的启动forward()、停止stop() 、反向播放 reverse()等方法。
AnimationController会在动画的每一帧,就会生成一个新的值。
默认情况下,AnimationController在给定的时间段内线性的生成从 00 到10(默认区间)的数字。
/
/Ticker
当创建一个AnimationController时,需要传递一个vsync参数,
它接收一个TickerProvider类型的对象,它的主要职责是创建Ticker,定义如下:
abstract class TickerProvider {
//通过一个回调创建一个Ticker
Ticker createTicker(TickerCallback onTick);
}
Flutter 应用在启动时都会绑定一个SchedulerBinding,
通过SchedulerBinding可以给每一次屏幕刷新添加回调,
而Ticker就是通过SchedulerBinding来添加屏幕刷新回调,这样一来,
每次屏幕刷新都会调用TickerCallback。
使用Ticker(而不是Timer)来驱动动画会防止屏幕外动画(动画的UI不在当前屏幕时,如锁屏时)
消耗不必要的资源,因为Flutter中屏幕刷新时会通知到绑定的SchedulerBinding,
而Ticker是受SchedulerBinding驱动的,
由于锁屏后屏幕会停止刷新,所以Ticker就不会再触发。
/
// 创建动画周期为1秒的AnimationController对象
controller =AnimationController(
vsync:this, duration:const Duration(milliseconds:3000));
/
Curve
动画过程可以是匀速的、匀加速的或者先加速后减速等。
Flutter中通过Curve(曲线)来描述动画过程,
我们把匀速动画称为线性的(Curveslinear),而非匀速动画称为非线性的。
我们可以通过CurvedAnimation来指定动画的曲线,如:
final CurvedAnimation curve =
CurvedAnimation(parent: controller, curve: CurveseaseIn);
Curves曲线 动画过程
linear 匀速的
decelerate 匀减速
ease 开始加速,后面减速
easeIn 开始慢,后面快
easeOut 开始快,后面慢
easeInOut 开始慢,然后加速,最后再减速
当然我们也可以创建自己Curve,例如我们定义一个正弦曲线:
class ShakeCurve extends Curve {
@override
double transform(double t) {
return mathsin(t mathPI 2);
}
}
/
final CurvedAnimation curve =CurvedAnimation(
parent:controller!, curve:Curveslinear);
/
Animation
Animation是一个抽象类,它本身和UI渲染没有任何关系,
而它主要的功能是保存动画的插值和状态;其中一个比较常用的Animation类是Animation。
Animation对象是一个在一段时间内依次生成一个区间(Tween)之间值的类。
Animation对象在整个动画执行过程中输出的值可以是线性的、曲线的、一个步进函数或者任何其他曲线函数等等,
这由Curve来决定。 根据Animation对象的控制方式,
动画可以正向运行(从起始状态开始,到终止状态结束),
也可以反向运行,甚至可以在中间切换方向。
Animation还可以生成除double之外的其他类型值
,如:Animation 或Animation。
在动画的每一帧中,我们可以通过Animation对象的value属性获取动画的当前状态值。
#动画通知
我们可以通过Animation来监听动画每一帧以及执行状态的变化,Animation有如下两个方法:
addListener();它可以用于给Animation添加帧监听器,
在每一帧都会被调用。
帧监听器中最常见的行为是改变状态后调用setState()来触发UI重建。
addStatusListener();
它可以给Animation添加“动画状态改变”监听器;
动画开始、结束、正向或反向(见AnimationStatus定义)时会调用状态改变的监听器。
/
// 创建从50到200线性变化的Animation对象
// 普通动画需要手动监听动画状态,刷新UI
animation =Tween(begin:100, end:2000)animate(curve)
addListener(()=>setState((){}));
/
Tween
默认情况下,AnimationController对象值的范围是[00,10]。
如果我们需要构建UI的动画值在不同的范围或不同的数据类型,
则可以使用Tween来添加映射以生成不同的范围或数据类型的值。
Tween构造函数需要begin和end两个参数。
Tween的唯一职责就是定义从输入范围到输出范围的映射。
输入范围通常为[00,10],但这不是必须的,我们可以自定义需要的范围。
/
// 启动动画
controller!repeat(reverse:true);
//
// 第二段
// animation!addStatusListener((status) {
// if (status == AnimationStatuscompleted) {
// controller!reverse();// 动画结束时反向执行
// } else if (status == AnimationStatusdismissed) {
// controller!forward();// 动画反向执行完毕时,重新执行
// }
// });
// controller!forward();// 启动动画
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home:Scaffold(
body:Center(
child:Container(
width:animation!value,// 将动画的值赋给 widget 的宽高
height:animation!value,//
child:FlutterLogo(),
)
)
)
);
}
@override
void dispose() {
// 释放资源
controller!dispose();
superdispose();
}
}
如果是导入的模型,在导入设置的Rig面板中选择Legacy,表示是旧版的动画系统,之后就可以用animation组件了。
如果是Unity内置GameObject,先把animator组件删除,然后手动添加animation组件,然后再把K好的动画添加到组件当中。
Unity3D的动画播放实际上都是通过AnimationState来进行控制的,Animation组件中提供的CrossFade,Play等方法其实就是将一系列对AnimationState参数进行设置的 *** 作进行了封装。
其中主要相关的参数有四个:
layer: 该动画片段(AnimationClip)所在的播放层次。
weight: 该动画片段在动画混合中所占的权重(0~1)
enable: 该动画片段是否进行播放
编,程,回,忆,录,之unity3d
blendMode: 混合方式,有两种Blend和Additive
默认初始化情况下Animation组件中的全部AnimationState的layer=0,weight=0, enable=false。Animation组件默认播放的AnimationState的layer=0, weight=1, enable=true。
这个问题也是我这两天遇到的,跟你说一下吧!unity出了新动画系统后,你在animation面板中制作动画默认是用于animator组件使用的,不能用animation组件来使用。如果你仔细观察会发现,在你制作动画时,你的gameobject上面会自动添加一个animator。当然,如果你想使用老的动画系统也可以,先在你的gameobject上面放个animation组件,然后再制作动画,这样就可以使用,你可以自己试试看!!!
上一篇文章写了星星生成的逻辑,详情请看 Cocos Creator开发游戏消灭星星——星星生成
星星消除是发生在用户点击之后,所以需要处理用户触摸 *** 作。在上一篇制作星星预制时有提及,在脚本组件 starCtrjs 的start函数里监听触摸。
消除星星是消除上下左右相连的星星,所以需要根据用户点击的星星找到其他相连的星星。在Utils中增加方法needRemoveList:
现在来完成触摸处理逻辑:
通过用户点击的星星坐标找到与其相连的星星们,然后发射delete_stars事件,通知地图消除星星。关于监听和发射时间参考官方文档 监听和发射事件 。
在matrixCtrjs的onLoad方法中添加事件监听
先添加几个属性来记录消除数据
在回调函数中处理消除逻辑
上一篇 说过,动画和特效主要放在节点 ActionRoot 中处理。如图,combo特效就在combNode节点中播放。
asset、atlasAsset分别存储骨骼动画资源,combName中存储骨骼动画的名字,和资源数组一一对应,_anim是dragonBones组件。
playComb即是播放特效的方法。
combCtr是脚本组件matrixCtr中的属性,即是场景中ActionRoot节点的脚本组件。
将需要消除的星星对应的坐标清空(赋值-1)
按规则星星是一个一个消除的,所以bomb会递归调用,直到所有星星都消除。在消除星星的同时,有分数计算和动画逻辑。
星星的移除是在方法 bombStar 中处理的,在创建星星的时候使用了对象池,所以移除时把它重新放入对象池。
在移除星星的同时,伴随有星星爆炸的特效。 starParticle 是一个预制,层级很简单,在一个空节点中,添加Particle System组件和脚本组件particleCtr。
Particle System组件设置自动移除,在属性检查器中勾选 Auto Remove On Finish 选项。
我们知道一次消除星星方块越多,得分越高。
分数动画有几种:
动画在actionCtrjs中处理:
因为分数也会被频繁的创建和移除,所以也使用了对象池,分数的预制制作后面介绍。
与单个方块的分数动画一样,消除总得分动画:
层级结构很简单,都是空节点下加一个Label节点。父节点上都有一个脚本组件partScore、totalScore。
脚本也很简单,setScore方法给Label赋值。
与单个分数不同的,总得分的Label动画使用Creator的Animation编辑器制作。所以,预制中需要在节点label中添加Animation组件,在这里我们在添加一个脚本组件totalScoreLabel,这个脚本主要处理Animation动画的事件回调方法。
以上就是关于Flutter 之 动画1全部的内容,包括:Flutter 之 动画1、unity4.3版怎么用旧版的Animation阿、求帮忙unity等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)