dilongzuyj 2024-02-05 16:54 采纳率: 75%
浏览 2
已结题

js检测碰撞失效的问题

我遇到一个js触发碰撞失效的问题,疑似问题出现在onroad =(20 - rx <= 30 && 20 - rx > -30 && y - ry <= 30 && y - ry < -30);if(ter.style.left - 20 <= 30){

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
#abo {
  background-color:#65C4FF;
  width:1000px;
  height:500px;
}
#ball {
  background-color:#F1B;
  border-radius:30px;
  width:30px;
  height:30px;
  position:absolute;
  left:20px;
  top:200px;
}
</style>
</head>
<body>
<div id="abo">
<div id="ball"></div>
</div>
<script>
var run;
var ball = document.getElementById("ball");
var area = document.getElementById("abo");
var dy = 1;
var y = 0;
var ditu =
[
[1,1,1],
[1,0,1],
[1,1,1],
[1,1,1],
[1,1,1],
[1,1,0],
[1,1,1],
[1,1,1],
[1,1,1],
[0,1,1],
[1,1,1],
[1,1,1],
[1,1,1]
];
var canJump = true;
var roads = [];
var onroad = false;
var ter;
document.documentElement.addEventListener("click", function(){
  if(canJump){
     dy = -1.5;
  }
});
function go(){
  console.clear();
  ter.style.left = `${parseFloat(ter.style.left)- 1}px`;
  if(ter.style.left - 20 <= 30){
    clearInterval(run);
    let r = confirm("你胜利了,是否退出游戏");
    if(r){
      close();
    }else{
      tru();
    }
  }
  roads.forEach(gtg =>{
    let rx = parseFloat(gtg.style.left);
    let ry = parseFloat(gtg.style.top);
    onroad =(20 - rx <= 30 && 20 - rx > -30 && y - ry <= 30 && y - ry < -30);
    if(rx <= 0){
      gtg.style.display = "none";
    }else if(x >= 1000){
      gtg.style.display = "none";
    }else{
      gtg.style.display = "block";
    }
    gtg.style.left = `${rx - 1}px`;
  });
  if(y < 500){
    if(!(onroad)){
      y += dy;
    }
  }else{
    y = 500;
    clearInterval(run);
    let r = confirm("你失败了,是否退出游戏");
    if(r){
      close();
    }else{
      tru();
    }
  }
  ball.style.top = `${y}px`;
  if(dy < 1){
    canJump = false;
    dy += 0.01;
  }else{
    dy = 1
    setTimeout(function(){canJump = true}, 205);
  }
}
function tru(){
  roads.forEach(gthi =>{
    gthi.remove();
  });
  roads = [];
  if(ter != undefined){
    ter.remove();
  }
  ditu.forEach((gth, ine) =>{
    gth.forEach((gthe, index) =>{
      if(gthe >= 1){
        let div = document.createElement("div");
        div.setAttribute("style", `background-color:#FFDE;width:30px;height:30px;position:absolute;top:${(index + 1)* 50 + index * 30 + 125}px;left:${ine * 30 + 20}px;`);
        area.appendChild(div);
        roads.push(div);
      }
    });
    if(ine == ditu.length - 1){
      let div = document.createElement("div");
      div.setAttribute("style", `background-color:#FF7;width:30px;height:500px;position:absolute;top:0px;left:${ine * 30 + 50}px;`);
      area.appendChild(div);
      ter = div;
      div.setAttribute("id", "terminal");
    }
  });
  x = 20;
  y = 250;
  run = setInterval(go, 1);
}
tru();
</script>
</body>
</html>

  • 写回答

3条回答 默认 最新

  • 专家-赤兔[在线] 全栈领域优质创作者 2024-02-05 16:58
    关注

    引自免费微信小程序:皆我百晓生

    针对您提供的JavaScript代码,问题可能出在碰撞检测的条件判断上。在go函数中有两处地方涉及碰撞检测:

    1. 疑似问题一

      onroad = (20 - rx <= 30 && 20 - rx > -30 && y - ry <= 30 && y - ry < -30);
      

      这段代码试图检测小球(id为"ball")是否与道路元素发生碰撞。从逻辑上看,这段代码存在矛盾:(y - ry <= 30 && y - ry < -30) 这个条件不可能同时满足。应当改为 (y - ry >= -30 && y - ry <= 30) 才能正确检测到两者之间的重叠。

      修改后的碰撞检测条件应为:

      onroad = (20 - rx <= 30 && 20 - rx >= -30 && y - ry >= -30 && y - ry <= 30);
      
    2. 疑似问题二

      if(ter.style.left - 20 <= 30){
        // 游戏胜利逻辑
      }
      

      这段代码用于检测小球是否到达终点("terminal"),但是它计算的是终点位置减去20像素,这可能不是你想要的效果。根据上下文,应该直接比较小球和终点的位置关系。然而,由于没有提供小球的实时位置变量,这里我们假设x是小球的left值,则正确的检测应该是类似这样的形式:

      if(x + ball.offsetWidth / 2 >= ter.offsetLeft) {
        // 游戏胜利逻辑
      }
      

    考虑到代码的整体结构,请结合上述修改,调整你的碰撞检测部分:

    function go(){
      // ...其他不变的代码...
      
      // 碰撞检测修正
      onroad = (x + ball.offsetWidth / 2 >= rx - 15 && x + ball.offsetWidth / 2 <= rx + 15 && y + ball.offsetHeight / 2 >= ry - 15 && y + ball.offsetHeight / 2 <= ry + 15);
    
      // ...其他不变的代码...
    
      // 判断是否到达终点修正
      if(x + ball.offsetWidth / 2 >= ter.offsetLeft) {
        clearInterval(run);
        let r = confirm("你胜利了,是否退出游戏");
        if(r){
          close();
        }else{
          tru();
        }
      }
    
      // ...其他不变的代码...
    }
    

    请注意,上面的修正中我使用了小球宽度和高度的一半来确保碰撞检测区域覆盖整个圆形小球,并且假设了小球中心点进行碰撞检测。如果实际情况并非如此,请按需调整坐标计算方式。此外,我还假设了x变量代表小球当前的left值。如果有误,请按照实际的小球位置变量替换。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 2月13日
  • 已采纳回答 2月5日
  • 创建了问题 2月5日

悬赏问题

  • ¥15 poi合并多个word成一个新word,原word中横版没了.
  • ¥15 【火车头采集器】搜狐娱乐这种列表页网址,怎么采集?
  • ¥15 求MCSCANX 帮助
  • ¥15 机器学习训练相关模型
  • ¥15 Todesk 远程写代码 anaconda jupyter python3
  • ¥15 我的R语言提示去除连锁不平衡时clump_data报错,图片以下所示,卡了好几天了,苦恼不知道如何解决,有人帮我看看怎么解决吗?
  • ¥15 在获取boss直聘的聊天的时候只能获取到前40条聊天数据
  • ¥20 关于URL获取的参数,无法执行二选一查询
  • ¥15 液位控制,当液位超过高限时常开触点59闭合,直到液位低于低限时,断开
  • ¥15 marlin编译错误,如何解决?