如何解决网页小游戏修改敌方动画时长出现的卡顿跳变问题
问题根因
修改CSS动画animation-duration时出现位置跳变,核心是浏览器在动画时长变更后会重新映射当前动画进度,而非基于现有位置接续执行。你之前延迟修改的方案未生效,主要是触发提速的判定逻辑每10ms就触发一次,重复修改了时长参数。
修复方案
方案1:迭代时修改时长(零跳变,改动最小)
只在敌方每轮移动完全结束、即将从屏幕右侧重新出现时修改时长,完全不会影响当前轮次的移动表现:
- 新增全局变量存储下一轮动画的时长,新增动画迭代事件监听:
// 初始值和CSS中设置的5s保持一致 let nextVillanDuration = 5; // 监听敌方动画每轮结束事件 ourVillanFig.addEventListener('animationiteration', () => { ourVillanFig.style.animationDuration = nextVillanDuration + 's'; });
- 替换你原来
setInterval里的提速逻辑,只更新下一轮时长即可:
// 新增锁变量,避免同一轮敌方重复触发提速 let hasSpeedIncreased = false; setInterval(function() { // ...保留原有其他逻辑不变 // 新增:敌方完全离开屏幕后重置锁 if (ourVillanFigXValue < -ourVillanFig.offsetWidth) { hasSpeedIncreased = false; } else if (obstacleBarCrossed && gameOverValueX < ourVillanFig.offsetWidth && !hasSpeedIncreased) { hasSpeedIncreased = true; // 最低速度限制为2s跑完一轮 if (nextVillanDuration > 2) { nextVillanDuration -= 0.1; } // 去掉你原来的延迟计算、setTimeout修改duration的逻辑 } }, 10);
方案2:中途实时提速(无感知修改)
如果需要在敌方移动中途就生效提速,可以用Web Animations API直接修改动画参数,保持当前位置不变:
else if (obstacleBarCrossed && gameOverValueX < ourVillanFig.offsetWidth && !hasSpeedIncreased) { hasSpeedIncreased = true; const anim = ourVillanFig.getAnimations()[0]; // 计算当前动画播放进度 const currentProgress = anim.currentTime / anim.effect.timing.duration; const newDuration = Math.max(2, parseFloat(getComputedStyle(ourVillanFig).animationDuration) - 0.1) * 1000; // 更新时长同时锁定当前进度,不会出现跳变 anim.effect.updateTiming({ duration: newDuration, currentTime: currentProgress * newDuration }); }
内容的提问来源于stack exchange,提问作者Yupma
相关产品推荐
相关产品推荐

