29,635
社区成员
![](https://csdnimg.cn/release/cmsfe/public/img/topic.427195d5.png)
![](https://csdnimg.cn/release/cmsfe/public/img/me.40a70ab0.png)
![](https://csdnimg.cn/release/cmsfe/public/img/task.87b52881.png)
![](https://csdnimg.cn/release/cmsfe/public/img/share-circle.3e0b7822.png)
如题,碰撞检测的问题
在调试时用console.log发现最后一直是true
所以掉不下来
awa,能帮我康康错在哪儿吗
<!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,0,1],
[1,0,1],
[1,0,1],
[1,0,0],
[1,1,1],
[1,1,1],
[1,1,1],
[0,1,1],
[0,1,1],
[0,1,1],
[0,1,1],
[0,1,1],
[1,0,1],
[1,1,1],
[1,1,1],
[1,1,1],
[1,1,0],
[1,1,0],
[1,1,0],
[1,1,0],
[0,1,0],
[0,0,0],
[0,0,1],
[0,1,0],
[1,0,0],
[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 orset = [];
var ter;
document.documentElement.addEventListener("click", function(){
if(canJump){
dy = -1.5;
}
});
function go(){
if(dy < 1){
canJump = false;
dy += 0.01;
}else{
dy = 1;
setTimeout(function(){canJump = true;}, 205);
}
ter.style.left = `${ter.offsetLeft - 1}px`;
if(ter.offsetLeft >= 1000){
ter.style.visibility = "hidden";
}else{
ter.style.visibility = "visible";
}
if(ter.offsetLeft - 20 <= 30){
clearInterval(run);
let r = confirm("你胜利了,是否退出游戏");
if(r){
close();
}else{
tru();
}
}
roads.forEach(gtg =>{
let rx = gtg.offsetLeft;
let ry = gtg.offsetTop;
orset.push(rx - 20 >= -30 && 20 - rx >= -30 && ry - y >= 30 && ry - y >= -30);
if(rx >= 1000){
gtg.style.visibility = "hidden";
}else if(rx <= 0){
gtg.remove();
}else{
gtg.style.visibility = "visible";
}
gtg.style.left = `${rx - 1}px`;
});
console.clear();
console.log(orset);
orset.forEach(gtg =>{
if(gtg){
onroad = true;
}
});
orset = [];
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`;
}
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>
看了一下你的代码,我注意到你的碰撞检测逻辑中似乎存在一些问题。具体来说,在处理orset数组的部分,你的逻辑是检查球是否与任何障碍物在同一水平线上(通过rx - 20 >= -30 && 20 - rx >= -30判断横向位置),并且判断球和障碍物的纵向位置关系(通过ry - y >= 30 && ry - y >= -30),但这里的条件判断似乎有误。
首先,对于ry - y >= 30 && ry - y >= -30这个条件,它的意思应该是判断球和障碍物的垂直距离是否在一定范围内,但是写成这样实际上是一个恒真的判断(因为ry - y >= -30总是为真),这可能是导致你的onroad变量总是为true的原因之一。
正确的碰撞检测逻辑应该考虑球和障碍物的相对位置和大小,通常是判断两者的矩形边界是否重叠。你的球和障碍物都是正方形,可以用更简单的方式来判断。
这里是一些具体的建议来修正你的代码:
碰撞检测条件:你需要检查球的底部是否触碰到障碍物的顶部,并且球的横向位置与障碍物有重叠。考虑到球和障碍物的大小,这个条件应该是类似于rx - ballWidth <= ballX && ballX <= rx + roadWidth && ballBottomY <= ry && ry - ballBottomY <= ballHeight的形式,其中ballWidth、ballHeight是球的尺寸,roadWidth是道路的宽度,ballX和ballBottomY分别是球的横坐标和底部的纵坐标。
重构碰撞检测逻辑:你的orset.push(...)中的条件需要重写,以正确反映球和障碍物之间的空间关系。
调整动画逻辑:动画的实现似乎也有一些问题,比如ter.style.left的调整应该基于当前位置和一定的速度或位移值,而不是简单地每次减去1。
下面是对你的go函数部分碰撞检测逻辑的一个简化示例,以帮助你理解如何修正:
javascript
Copy code
// 假设每个障碍物也是30x30像素
const roadWidth = 30; // 障碍物的宽度
const ballWidth = 30; // 球的宽度
const ballHeight = 30; // 球的高度
roads.forEach(gtg => {
let rx = gtg.offsetLeft;
let ry = gtg.offsetTop;
// 检查球是否在障碍物上方并且横向位置有重叠
let ballBottomY = y + ballHeight; // 球底部的Y坐标
if (rx - ballWidth < x && x < rx + roadWidth && ballBottomY > ry && ballBottomY - ry < ballHeight) {
onroad = true;
}
// 更新障碍物位置逻辑...
});
请注意,上述代码中的变量x和y代表球的左上角坐标,你需要根据实际情况调整这些值和条件判断。此外,这只是一个基础示例,实际的碰撞检测逻辑可能需要根据你的游戏规则进行更详细的调整。
go()函数里面的if条件
if(y < 500){
if(!onroad){
y += dy;
}
}
!onload是不是要改成onload
我想这个是游戏网页