javascript - 简单的 HTML/JS 碰撞检测不起作用
问题描述
第一次发帖,如果我的礼节不好,我很抱歉。我正在尝试设置一个简单的 HTML/JavaScript 页面,在具有一维运动的两个 2D 对象之间进行碰撞检测,但我不知道为什么它没有做任何事情。
包含所有商品的代码片段:
var field = document.getElementById("battlefield");
var allies = document.getElementsByClassName("ally");
var enemies = document.getElementsByClassName("enemy");
var fighters = document.getElementsByClassName("fighter");
var c1speed = 3; //Speed of fighters
function spawna1() { //spawns a blue fighter
node = document.createElement("div");
node.classList.add("fighter", "ally", "c1");
field.appendChild(node);
}
spawna1();
function spawne1() { //spawns a red fighter
node = document.createElement("div");
node.classList.add("fighter", "enemy", "e1");
field.appendChild(node);
}
spawne1();
var movea = setInterval(function() {
for (i = 0; i < allies.length; i++) { //Move blue
allies[i].style.left = (allies[i].offsetLeft + c1speed) + "px";
if (allies[i].offsetLeft > window.innerWidth + 200) {
allies[i].remove();
}
}
for (i = 0; i < enemies.length; i++) { //Move red
enemies[i].style.left = (enemies[i].offsetLeft - c1speed) + "px";
if (enemies[i].offsetLeft < -200) {
enemies[i].remove();
}
}
for (i = 0; i < fighters.length; i++) { //Collision detection, theoretically
for (j = i + 1; j < fighters.length; j++) {
if (fighters[i].offsetLeft < fighters[j].offsetLeft + fighters[j].width || //If i=red and j=blue
fighters[i].offsetLeft + fighters[i].width > fighters[j].offsetLeft) { //or if i=blue and j=red
fighters[i].remove(); //Remove the fighters when they collide
fighters[j].remove();
}
}
}
}, 20);
html,
body,
#page-container {
margin: 0;
padding: 0;
overflow-x: hidden;
}
#page-container {
width: 100%;
height: 100%;
display: block;
position: absolute;
background-color: #c5c5c5;
}
#game {
width: 100%;
height: 100%;
min-height: 100%;
display: block;
z-index: 99;
}
#battlefield {
width: 100%;
height: 67%;
}
#lower {
width: 100%;
height: 33%;
background-color: #000000;
}
.ally {
position: absolute;
left: 0px;
bottom: 33%;
background-color: blue;
width: 3em;
height: 3em;
}
.enemy {
position: absolute;
left: 600px;
bottom: 33%;
background-color: red;
width: 3em;
height: 3em;
}
<div id="page-container">
<div id="game">
<div id="battlefield">
</div>
<div id="lower">
<button onclick="spawna1();spawne1()">SPAWN MORE</button>
</div>
</div>
</div>
蓝色的“战斗机”应该向右移动,而红色的“战斗机”向左移动。碰撞时,它们都应该消失。这是我所拥有的基础知识(我强烈建议运行代码段):
var fighters = document.getElementsByClassName("fighter");
function spawna1() {
node = document.createElement("div");
node.classList.add("fighter", "ally", "c1");
field.appendChild(node);
}
spawna1();
function spawne1() {
node = document.createElement("div");
node.classList.add("fighter", "enemy", "e1");
field.appendChild(node);
}
spawne1();
var movea = setInterval(function() {
for (i = 0; i < fighters.length; i++) { //Hit detection formula
for (j = i + 1; j < fighters.length; j++) {
if (fighters[i].offsetLeft < fighters[j].offsetLeft + fighters[j].width ||
fighters[i].offsetLeft + fighters[i].width > fighters[j].offsetLeft) {
fighters[i].remove(); //remove fighters on collide
fighters[j].remove();
}
}
}
}, 20);
我非常感谢您的时间和耐心。感谢:D
解决方案
我想出了一个解决方案!
由于蓝色和红色对象在被调用时分别被分配了一个ally
和enemy
类spawn()
,我只需要更改碰撞检测以allies[i]
检查enemies[j]
. 这是片段:
var field = document.getElementById("battlefield");
var allies = document.getElementsByClassName("ally");
var enemies = document.getElementsByClassName("enemy");
var fighters = document.getElementsByClassName("fighter");
var c10 = document.getElementById("c10");
var c1o = 1;
var c1 = {
"a": 1,
"d": 1,
"s": 3,
"o": 1,
"si": 1500,
"os": c1o
};
var ce1 = {
"a": 1,
"d": 1,
"s": 3,
"o": 1,
"si": 1500,
"os": c1o
};
function spawna1() {
var spawna1int = setTimeout(function() {
node = document.createElement("div");
node.classList.add("fighter", "ally", "c1");
field.appendChild(node);
spawna1();
}, (c1.si / c1.o));
}
spawna1();
function spawne1() {
var spawna1int = setTimeout(function() {
node = document.createElement("div");
node.classList.add("fighter", "enemy", "c1");
field.appendChild(node);
spawne1();
}, (ce1.si / ce1.o));
}
spawne1();
var movea = setInterval(function() {
for (i = 0; i < allies.length; i++) { //Move A1
allies[i].style.left = (allies[i].offsetLeft + c1.s) + "px";
if (allies[i].offsetLeft > window.innerWidth + 200) {
allies[i].remove(); //Remove when off screen
}
}
for (i = 0; i < enemies.length; i++) { //Move E1
enemies[i].style.left = (enemies[i].offsetLeft - ce1.s) + "px";
if (enemies[i].offsetLeft < -200) {
enemies[i].remove(); //Remove when off screen
}
}
for (i = 0; i < allies.length; i++) { //Hit detection, I hope
for (j = 0; j < enemies.length; j++) {
if (allies[i].offsetLeft < enemies[j].offsetLeft + enemies[j].offsetWidth &&
allies[i].offsetLeft + allies[i].offsetWidth > enemies[j].offsetLeft) {
//What should happen when they collide???
if (allies[i].classList[1] == enemies[j].classList[1]) { //Friendly fire off
return;
}
if (eval(allies[i].classList[2]).a > eval(enemies[j].classList[2]).d) { //if I attack is higher than J defense, kill J
enemies[j].remove();
}
if (eval(enemies[j].classList[2]).a > eval(enemies[j].classList[2]).d) { //if J attack is higher than I defense, kill I
allies[i].remove();
}
if (eval(enemies[j].classList[2]).a == eval(enemies[j].classList[2]).a &&
eval(enemies[j].classList[2]).d == eval(enemies[j].classList[2]).d) { //if I and J are equal, kill both
allies[i].remove();
enemies[j].remove();
}
}
}
}
}, 20);
html,
body,
#page-container {
margin: 0;
padding: 0;
overflow-x: hidden;
}
#page-container {
width: 100%;
height: 100%;
display: block;
position: absolute;
background-color: #c5c5c5;
}
#game {
width: 100%;
height: 100%;
min-height: 100%;
display: block;
z-index: 99;
}
#battlefield {
width: 100%;
height: 67%;
}
#lower {
width: 100%;
height: 33%;
background-color: #000000;
}
.ally {
position: absolute;
left: -150px;
bottom: 33%;
background-color: blue;
}
.enemy {
position: absolute;
left: 600px;
bottom: 33%;
background-color: red;
}
.c1 {
width: 2em;
height: 2.5em;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Welcome to Valhalla!</title>
<meta name="author" content="beanamonster">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" type="text/css" href="halla.css">
</head>
<body>
<div id="page-container">
<div id="game">
<div id="battlefield">
</div>
<div id="lower">
</div>
</div>
</div>
<script src="halla.js"></script>
</body>
</html>
我在一夜之间添加了很多,所以这可能不再有意义了。但本质上,我们将红色对象分配给一个类,将蓝色对象分配一个不同的类。循环for
通过蓝调,而嵌套for
根据各自的类检查红调。
推荐阅读
- android - Android:如何从小米手环 4 获取健身数据?
- aws-api-gateway - Github Webhook 到与 SQS 集成的 AWS API Gateway 错误?
- javascript - 从 GTM 自定义 JS 变量中的 URL 返回文本
- google-sheets - 应用 VlLOOKUP 直到谷歌表格中的最后一个非空行
- c - 在程序中,扩大了形状的大小是成功的,但是改变颜色效果不好
- xampp - xampp 不工作,我几乎尝试了所有事情
- php - 页面在使用 Laravel 5.6 的 cpanel 中不起作用
- php - 在这里使用 Laravel Eloquent 时遇到问题
- android - REST 最佳实践为访客和身份验证获取 /articles?
- python - rect 与 rect 列表的碰撞