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

如何重置Div至初始位置?足球游戏球复位失败问题排查

问题描述

开发一款足球游戏时遇到以下问题:球的div初始位于开球线位置,点击射门后会向鼠标点击位置移动,但射门完成后无法复位到初始位置。我在JS文件加载时用getBoundingClientRect()获取了球的初始位置,编写了restoreBallPositions方法,试图通过延迟设置top和left属性回到保存的ballRect位置,但该方法完全无效,不清楚原因。

代码片段

JavaScript 代码

const ball = document.getElementById('ball');
const ballRect = ball.getBoundingClientRect();
console.log(ballRect);

function goal() {
  var score = getScore();
  increaseDifficulty(score)
  document.getElementById("score").innerHTML = score + 1;
  var b = getShotCordinates();
  moveBall(b[0], b[1]);
  restoreBallPositions();
}

function save() {
  resetScore();
  resetDifficulty();
  restoreBallPositions();
}

function resetScore() {
  document.getElementById("score").innerHTML = 0;
}

function getScore() {
  return parseInt(document.getElementById("score").innerHTML);
}

function increaseDifficulty(score) {
  switch (score) {
    case 5:
      document.getElementById("goalkeeper").style.animation = "protect 8s infinite";
      break;
    case 10:
      document.getElementById("goalkeeper").style.animation = "protect 6s infinite";
      break;
    case 15:
      document.getElementById("goalkeeper").style.animation = "protect 4s infinite";
      break;
    case 20:
      document.getElementById("goalkeeper").style.animation = "protect 3s infinite";
      break;
    case 25:
      document.getElementById("goalkeeper").style.animation = "protect 2s infinite";
      break;
    case 30:
      document.getElementById("goalkeeper").style.animation = "protect 1s infinite";
      break;
    default:
  }
}

function resetDifficulty() {
  document.getElementById("goalkeeper").style.animation = "protect 10s infinite";
}

function moveBall(x, y) {
  var x = x - 150;
  var y = y - 450;
  document.getElementById("ball").style.transform = "translate(" + x + "px," + y + "px)";
  document.getElementById("ball").style.transition = "0.2s";
}

function getShotCordinates() {
  var e = window.event;
  var Cordinates = [e.clientX, e.clientY];
  console.log(Cordinates[0] + " - " + Cordinates[1])
  return Cordinates;
}

function restoreBallPositions() {
  setTimeout(function() {
    ball.style.top = ballRect.y;
    ball.style.top = ballRect.x;
  }, 2000);
}

HTML 代码

<HTML lang="en">
<HEAD>
  <title>Soccor Game</title>
  <link rel='stylesheet' href='css/styles.css'>
</HEAD>
<BODY>
  <div id="canvas" class="field" onload="savePositions()">
    <div id="goals" class="goals" onclick="goal()"></div>
    <div id="goalkeeper" onclick="save()"></div>

    <div id="kick-off">
      <div id="ball" class="ball"></div>
    </div>

    <div id="score-container">
      <div id="counter">
        <h1 class="counter-text">Score</h1>
        <h1 class="counter-score" id="score">0</h1>
      </div>
    </div>
  </div>
  <script src='js/script.js'></script>
</BODY>
</html>
问题分析与修复方案

核心问题点

  1. 复位逻辑语法错误:restoreBallPositions里连续两次设置ball.style.top,完全遗漏了left属性的设置;而且ballRect.y和ballRect.x是纯数值,没有添加单位px,浏览器无法识别该样式值。
  2. 移动方式不匹配:moveBall方法是通过transform: translate()来移动球的,这种方式不会改变元素的top/left属性,反而会覆盖定位的位置。所以用设置top/left的方式无法抵消transform的位移效果。

修复后的restoreBallPositions方法

直接清除球的transform样式,就能让它回到父元素#kick-off定位的初始位置,这是最简单有效的方式:

function restoreBallPositions() {
  setTimeout(function() {
    ball.style.transform = 'none';
  }, 2000);
}

额外优化建议

  • getShotCordinates依赖window.event,兼容性较差,改为接收事件参数更稳妥:
function getShotCordinates(e) {
  var coordinates = [e.clientX, e.clientY];
  console.log(coordinates[0] + " - " + coordinates[1])
  return coordinates;
}
// 调用时传入事件
function goal(e) {
  // ...其他代码
  var b = getShotCordinates(e);
  // ...其他代码
}
// HTML里修改点击事件
<div id="goals" class="goals" onclick="goal(event)"></div>

内容的提问来源于stack exchange,提问作者GrahamNorton

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 16:55:27