JavaScript谷歌恐龙克隆游戏:Duck函数意外影响障碍元素问题排查
问题描述
我正在开发一款基于JavaScript的谷歌恐龙克隆小游戏,目前障碍块可从右向左在地面移动,玩家能跳跃躲避。我希望新增功能:障碍块要么处于地面(需跳跃躲避)要么处于空中(需下蹲躲避)。我已编写角色跳跃函数,运行正常;编写的下蹲函数虽能让sprite元素正常下蹲,但会同时导致obstacle元素反向移动(本该保持水平位置却向上“跳跃”)。该Duck函数应仅作用于sprite元素,却意外影响了obstacle,排查代码未发现原因,求解决思路。
现有代码
JavaScript
var sprite = document.querySelector('#sprite'); var jumpButton = document.querySelector('#jump'); var duckButton = document.querySelector('#duck'); function jump() { sprite.classList.add('jump'); setTimeout(function() { sprite.classList.remove('jump'); }, 750); } function duck() { sprite.classList.add('duck'); setTimeout(function() { sprite.classList.remove('duck'); }, 750); } jumpButton.addEventListener('click', jump); duckButton.addEventListener('click', duck);
CSS
* { margin: 0; padding: 0; } body { background-color: #373b47; font-family: Helvetica, sans-serif; } #container { margin: 30px auto 0 auto; height: 200px; width: 500px; border: 1px solid #ffffff; background-color: #0d003c; } #sprite { width: 50px; height: 50px; background-color: #2897bf; position: relative; top: 150px; } @keyframes jump { 0% { top: 150px; } 30% { top: 100px; } 70% { top: 110px; } 100% { top: 150px; } } @keyframes duck { 0% { height: 50px; top: 150px; } 50% { height: 25px; top: 175px; } 100% { height: 50px; top: 150px; } } .jump { animation: jump 1s; } .duck { animation: duck 1s; } #obstacle { width: 25px; height: 25px; background-color: #afafc2; position: relative; top: 125px; left: 475px; animation: move 1s infinite linear; } @keyframes move { 0% { left: 475px; } 100% { left: 0px; } }
HTML
<div id="container"> <div id="sprite"></div> <div id="obstacle"></div> </div> <div id="controls"> <button id="jump">Jump</button> <button id="duck">Duck</button> </div>
解决思路
问题核心是相对定位元素的文档流占位特性:
- sprite和obstacle都使用
position: relative,这类元素仍会占据原文档流空间。当sprite执行下蹲动画时,修改了height和top值,导致它在文档流中的占位高度变化,后续的obstacle元素会被向上挤压,出现“跳跃”的视觉效果。
三种可行修复方案:
方案一:改用绝对定位脱离文档流
这是游戏元素布局的常规方案,让角色和障碍物完全独立控制位置,不会互相影响。修改CSS:#container { position: relative; /* 新增,让内部绝对定位元素以容器为参照 */ } #sprite { position: absolute; top: 150px; left: 0; /* 固定初始水平位置 */ } #obstacle { position: absolute; top: 125px; left: 475px; }方案二:用transform缩放实现下蹲,不改变文档流占位
保持相对定位,但通过transform: scaleY()实现下蹲效果,这种方式不会修改元素的实际宽高和占位空间,因此不会影响obstacle:@keyframes duck { 0% { transform: scaleY(1); top: 150px; } 50% { transform: scaleY(0.5); top: 175px; /* 配合缩放调整top,保持角色底部贴地 */ } 100% { transform: scaleY(1); top: 150px; } }方案三:修正相对定位的布局依赖
如果坚持用相对定位,给sprite添加margin-bottom来抵消高度变化带来的影响,或者把obstacle也放在独立的容器中,但这种方式不如前两种简洁。
内容的提问来源于stack exchange,提问作者user646464
相关产品推荐
相关产品推荐

