为多个用户同步正在进行的轮盘游戏动画



我目前正在开发一个财富之轮,它通过node.js和websockets同步到每个连接的设备。然而,我想在轮子已经旋转的情况下,当用户加入时,切断动画的开始,这样它只会显示动画的最后几秒,而不会改变它的放松。

jQuery动画是由一个简单的步骤动画组成的,该动画使轮子旋转。我已经尝试更改步骤的"fx"对象的参数,如fx.startfx.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秒应该被切断。

在任何时间点捕捉缓和动画旋转

  • 线性动画t01,或从0.N1.0(如果玩家在10秒中的第6秒加入,则为0.6($({t: t}).animate({t: 1},
  • 放松在任何给定的"现在"时间点,使用自定义宽松函数将当前0.0-1.0时间范围(t_now值(转换为相应的宽松e_now
  • 将缓和e_now结果乘以所需结束度数

不要使用"swing"使用"linear",让我们使用自定义宽松功能来控制宽松和时间(您可以在网上找到许多宽松片段(。假设我们喜欢easeInOutSine:

const easeInOutSine = t => -(Math.cos(Math.PI * t) - 1) / 2;

示例

例如,4个人,一个旋转轮子,另一个后的2、4.5和8.7秒加入表演

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度。

最新更新