为多个用户同步正在进行的动画 - 游戏开发
Sync ongoing animation for multiple users - Game dev
我目前正在研究命运之轮,它通过 node.js 和 websockets 同步到每个连接的设备。但是我想切断动画的开始,当用户加入时轮子已经在旋转了,所以它只会显示动画的最后几秒而不改变它的缓动。
jquery 动画由一个简单的步进动画组成,它使轮子旋转。我已经尝试更改步骤的 'fx' 对象的参数,例如 fx.start 或 fx.pos。虽然 fx.start 只是动画开始时的变量,例如 180 度,而 fx.pos 只是一种输出参数,用于将某些内容更改为动画中的给定时间,例如文本颜色或某物。然而,fx.pos 值不能改变,也不能改变动画当前设置的位置。我创建了一个函数来旋转命运之轮两次,然后它在给定的度数停止。
我也试着改变缓动,所以它是 50% 线性,50% 摆动,但这让动画看起来很垃圾,因为起初它以恒定速度旋转,突然它旋转得更快而不是更慢。
function spinRoulette(deg, duration = 10000) {
deg = Math.round(deg);
$("img.roulette").animate(
{ now: '+='+(720+deg-getRotation()) }, {
duration: duration,
...
step: function(now, fx) {
if(now >= 360)
now -= 360;
$(this).css("transform", "rotate("+now+"deg)");
}
});
}
如果持续时间少于 10 秒,动画的开始将被切断。所以,如果服务器在大约 5 秒前旋转了轮子,我的动画的前 5 秒应该被切断。
在任何时间点赶上缓动动画旋转
- 线性动画
t
从 0
到 1
,或从 0.N
到 1.0
( 0.6如果玩家在第 6 秒加入,最多 10 秒)$({t: t}).animate({t: 1},
- Ease! 在任何给定的 "now" 时间点,将当前 0.0-1.0 时间范围(
t_now
值)转换为使用 自定义缓动函数 的相应缓动 e_now
值
- 将缓动
e_now
结果乘以所需的 end 度数
而不是使用 "swing"
使用 "linear"
和 让我们控制缓动和时间 自定义缓动函数(您可以找到许多缓动片段online)。假设我们喜欢 easeInOutSine
:
const easeInOutSine = t => -(Math.cos(Math.PI * t) - 1) / 2;
例子
示例有 4 个人,一个人转动轮子,另一个人在第 2、4.5 和 8.7 秒之后[=]加入节目 65=]初始旋转开始:
const easeInOutSine = t => -(Math.cos(Math.PI * t) - 1) / 2;
function spinRoulette(sel, deg, duration = 10000) {
const $el = $(sel);
const maxDuration = 10000;
const deg_end = 720 + Math.round(deg); // 2 revolutions + server-generated degrees
const time = maxDuration - duration; // Start time in ms
const t = time / maxDuration; // Start time to 0.0-1.0 range
$({t: t}).animate({t: 1}, { // Custom jQuery anim. from 0.N to 1.0
duration: duration,
easing: "linear", // We need a linear 0.0 to 1.0
step: function(t_now) {
const e_now = easeInOutSine(t_now); // Current easing
const deg_now = e_now * deg_end; // Current degrees
$el.css({transform: `rotate(${ deg_now }deg)`});
}
});
}
// Person 1 spins!
spinRoulette("#r1", 45);
// Person 2 joins the room after 2s
setTimeout(() => spinRoulette('#r2', 45, 10000 - 2000), 2000);
// Person 3 joins the room after 4.5s
setTimeout(() => spinRoulette('#r3', 45, 10000 - 4500), 4500);
// Person 4 joins the room after 8.7s
setTimeout(() => spinRoulette('#r4', 45, 10000 - 8700), 8700);
img {height: 120px; display: inline-block;}
<img id="r1" src="https://i.stack.imgur.com/bScK3.png">
<img id="r2" src="https://i.stack.imgur.com/bScK3.png">
<img id="r3" src="https://i.stack.imgur.com/bScK3.png">
<img id="r4" src="https://i.stack.imgur.com/bScK3.png">
<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>
在上面的示例中,最后,您可以注意到(除了一些奇怪的光学错觉)车轮在任何时间点都以正确的旋转状态赶上,速度 ,并且所有这些都以相同的缓动同时完成,精确预定义 deg_end
度。
我目前正在研究命运之轮,它通过 node.js 和 websockets 同步到每个连接的设备。但是我想切断动画的开始,当用户加入时轮子已经在旋转了,所以它只会显示动画的最后几秒而不改变它的缓动。
jquery 动画由一个简单的步进动画组成,它使轮子旋转。我已经尝试更改步骤的 'fx' 对象的参数,例如 fx.start 或 fx.pos。虽然 fx.start 只是动画开始时的变量,例如 180 度,而 fx.pos 只是一种输出参数,用于将某些内容更改为动画中的给定时间,例如文本颜色或某物。然而,fx.pos 值不能改变,也不能改变动画当前设置的位置。我创建了一个函数来旋转命运之轮两次,然后它在给定的度数停止。
我也试着改变缓动,所以它是 50% 线性,50% 摆动,但这让动画看起来很垃圾,因为起初它以恒定速度旋转,突然它旋转得更快而不是更慢。
function spinRoulette(deg, duration = 10000) {
deg = Math.round(deg);
$("img.roulette").animate(
{ now: '+='+(720+deg-getRotation()) }, {
duration: duration,
...
step: function(now, fx) {
if(now >= 360)
now -= 360;
$(this).css("transform", "rotate("+now+"deg)");
}
});
}
如果持续时间少于 10 秒,动画的开始将被切断。所以,如果服务器在大约 5 秒前旋转了轮子,我的动画的前 5 秒应该被切断。
在任何时间点赶上缓动动画旋转
- 线性动画
t
从0
到1
,或从0.N
到1.0
( 0.6如果玩家在第 6 秒加入,最多 10 秒)$({t: t}).animate({t: 1},
- Ease! 在任何给定的 "now" 时间点,将当前 0.0-1.0 时间范围(
t_now
值)转换为使用 自定义缓动函数 的相应缓动 - 将缓动
e_now
结果乘以所需的 end 度数
e_now
值
而不是使用 "swing"
使用 "linear"
和 让我们控制缓动和时间 自定义缓动函数(您可以找到许多缓动片段online)。假设我们喜欢 easeInOutSine
:
const easeInOutSine = t => -(Math.cos(Math.PI * t) - 1) / 2;
例子
示例有 4 个人,一个人转动轮子,另一个人在第 2、4.5 和 8.7 秒之后[=]加入节目 65=]初始旋转开始:
const easeInOutSine = t => -(Math.cos(Math.PI * t) - 1) / 2;
function spinRoulette(sel, deg, duration = 10000) {
const $el = $(sel);
const maxDuration = 10000;
const deg_end = 720 + Math.round(deg); // 2 revolutions + server-generated degrees
const time = maxDuration - duration; // Start time in ms
const t = time / maxDuration; // Start time to 0.0-1.0 range
$({t: t}).animate({t: 1}, { // Custom jQuery anim. from 0.N to 1.0
duration: duration,
easing: "linear", // We need a linear 0.0 to 1.0
step: function(t_now) {
const e_now = easeInOutSine(t_now); // Current easing
const deg_now = e_now * deg_end; // Current degrees
$el.css({transform: `rotate(${ deg_now }deg)`});
}
});
}
// Person 1 spins!
spinRoulette("#r1", 45);
// Person 2 joins the room after 2s
setTimeout(() => spinRoulette('#r2', 45, 10000 - 2000), 2000);
// Person 3 joins the room after 4.5s
setTimeout(() => spinRoulette('#r3', 45, 10000 - 4500), 4500);
// Person 4 joins the room after 8.7s
setTimeout(() => spinRoulette('#r4', 45, 10000 - 8700), 8700);
img {height: 120px; display: inline-block;}
<img id="r1" src="https://i.stack.imgur.com/bScK3.png">
<img id="r2" src="https://i.stack.imgur.com/bScK3.png">
<img id="r3" src="https://i.stack.imgur.com/bScK3.png">
<img id="r4" src="https://i.stack.imgur.com/bScK3.png">
<script src="//code.jquery.com/jquery-3.4.1.min.js"></script>
在上面的示例中,最后,您可以注意到(除了一些奇怪的光学错觉)车轮在任何时间点都以正确的旋转状态赶上,速度 ,并且所有这些都以相同的缓动同时完成,精确预定义 deg_end
度。