5 个版本 (稳定版)
2.0.3 | 2024年4月3日 |
---|---|
2.0.2 | 2023年12月11日 |
2.0.1 | 2023年2月19日 |
2.0.0 | 2023年1月1日 |
0.0.0 | 2020年8月11日 |
#8 in 数据格式
每月 218 次下载
在 tether-artnet-controller 中使用
89KB
1.5K SLoC
tween
tween
是一个 std-optional 缓动库,专为游戏和动画使用而设计。
快速入门
要安装,请在您的 Cargo.toml 中添加以下内容
tween = "2.0.2"
您可以创建一个 Tweener,如下所示
use tween::Tweener;
let (start, end) = (0, 100);
let duration = 15.0;
let mut tweener = Tweener::sine_in_out(start, end, duration);
let mut position = 0;
const DT: f32 = 1.0 / 60.0;
// and then in your main loop...
loop {
position = tweener.move_by(DT);
if tweener.is_finished() {
break;
}
}
assert_eq!(position, 100, "we've moved to the end of the tween");
概述
Tween
是一个函数,它返回从指定数值到另一个指定数值的值,在指定的时间内。每个人最熟悉的 Tween
就是 lerp
,或“线性插值”。在这个库中,它被称为 Linear
-- 线性缓动通过公式 start * (1.0 - p) + end * p
从起始值移动到结束值,其中 p
是缓动中经过的时间百分比。所以在时间 0
或 0%
时,你得到的是 start
值,而在时间 1
或 100%
时,你得到的是结束值。
当然,除了线性之外,还有很多种缓动方式;它们都可以产生感觉和动画!我们通常使用缓动在游戏中移动对象的位子,但您也可以使用缓动来动画精灵、选择行为、音频处理,甚至使用立方贝塞尔缓动来绘制字体。
本库为您提供了由Robert Penner最初创建的所有缓动函数的访问权限 -- 您可以在此处查看它们的效果。
本库公开了三种类型的结构体
- 零大小缓动函数,实现了
Tween
特征。它们还天生暴露了tween
方法,因此您可以轻松地使用它们进行缓动,例如tween::Linear.tween
。 - 包装缓动函数,实现了
Tween
特征。这些是Looper
、Oscillator
和Extrapolator
。这些都围绕其他缓动函数进行包装。请参阅它们的文档以获取更多信息。 Tweener
和FixedTweener
,都是用来驱动Tween
的。在固定时间步长应用程序中,您应使用FixedTweener
;否则,使用Tweener
。虽然您可以直接使用Tween
,但Tweener
会为您管理所有缓动状态。
对于99%的用户,您将想要使用缓动函数构建Tweener
或FixedTweener
,偶尔循环或振荡它们。
自己创建缓动函数
如果您想创建自己的缓动函数,绝对可以!为此,您需要查看本库的主要特征:Tween
。您可以使用简单的闭包来原型设计自己的Tween
实现,因为FnMut(value_delta: Value, percent: f32) -> Value
实现了Tween
,或者直接使用它。闭包非常出色,因为您可以通过添加或组合缓动函数来以有趣的方式使用它们。
例如,这里有一个Linear
缓动函数与一个SineIn
缓动函数的平均值
use tween::{Tweener, SineIn, Linear};
Tweener::new(0.0, 10.0, 10, |value_delta, percent| {
(Linear.tween(value_delta, percent) + SineIn.tween(value_delta, percent)) / 2.0
});
要查看Cubic Bezier缓动函数的示例文档,请参阅examples/cubic_bezier.rs
。
存储缓动函数
在游戏或动画引擎中,您通常希望根据它们的作用对象来存储缓动函数,而不用担心它是哪种类型的缓动函数示例。为此,您需要在Tweener中将缓动函数装箱。由于本库中所有缓动函数都是ZST,因此Box实际上不会分配,但您必须使用动态访问(这将会足够快)。
use tween::{Tweener, Looper, Linear, SineIn, Tween};
// very often game engines need sync/sync
type SendSyncTween<Value, Time> = Tweener<Value, Time, Box<dyn Tween<Value> + Send + Sync>>;
let mut my_tweener: SendSyncTween<i32, i32> = Tweener::new(0, 100, 100, Box::new(Linear));
let mut going_up = true;
// we lerp from 0 to 100 over 100 frames, and then we flip our tween back
// into a SineIn tween over 10 frames, so this looks like a slowwwwwww buildup
// and then a SHARP drop down.
//
// we put this in a thread here to demonstrate `Send + Sync`
std::thread::spawn(move || {
loop {
let _output_assigned_somewhere = my_tweener.move_by(1);
if my_tweener.is_finished() {
my_tweener = if going_up {
Tweener::new(100, 0, 10, Box::new(SineIn))
} else {
Tweener::new(0, 100, 100, Box::new(Linear))
};
going_up = !going_up;
}
}
});
要查看已擦除Tweener的示例文档,请参阅examples/erased.rs
。
实现TweenValue
本库使用两个特征:TweenTime
和TweenValue
。您可以自己实现这些特征,但实现TweenTime
只有相当晦涩的用途。
另一方面,TweenValue
需要为任何可缓动值实现。默认情况下,所有数值类型已在本库中实现。此外,一些数学库有功能标志(见下文),它们为适当的结构体提供了一个实现。
快速运行⚡️
本库最终是一个数学库,从发布模式中受益极大。
功能
tween
有以下功能
std
:默认启用,通过Box
提供对更快浮点数数学和辅助方法的访问libm
:启用此功能,而不启用默认功能,用于无std缓动glam
:启用此功能,以便为glam
类型实现TweenValue
nalgebra
:为nalgebra
类型启用此功能以实现TweenValue
vek
:为vek
类型启用此功能以实现TweenValue
ultraviolet
:为ultraviolet
类型启用此功能以实现TweenValue
ultraviolet-f64
:为ultraviolet/f64
类型启用此功能以实现TweenValue
cgmath
:为cgmath
类型启用此功能以实现TweenValue
此库支持glam
作为其一等数学库。
Std Optional
此库使用带有默认功能的std
。要获得无-std体验,请禁用默认功能并启用libm
。(我们需要使用libm
进行浮点数数学),如下所示
tween = { verison = "2.0.1", default_features = false, features = ["libm"] }
MSRV和安全性
此crate尚无MSRV。如果得到良好采用,将决定MSRV策略。
此外,此crate具有#![deny(unsafe_code)]
,因为不需要不安全代码。更改此策略将构成轻微的破坏性更改。
破坏性更改
此crate遵循正常的破坏性更改规则,但glam
以外的数学库除外。我们不保证我们将与数学库完美更新--如果您有版本处理需求,我们鼓励您为该仓库创建分支。
路线图
此库的下一步是处理Tweeners的样条曲线。
许可证
双许可MIT或APACHE 2.0。
依赖关系
~0–2MB
~45K SLoC