You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 20:41:05