Javascript 嘿,我想用canvas和js制作这个小程序,它可以检测圆之间的碰撞
我正在学习如何使用JS在画布上进行渲染,我正在尝试制作一个简单的碰撞检测程序,该程序可以使碰撞中涉及到的cricles变成某种颜色。目前为止它有点起作用,也就是说它不起作用:D我只看到随机的圆圈有时变成绿色,而不是那些实际上正在碰撞的圆圈 所以我想把这个贴在这里,让你们看看,看看你们能找到什么。提前谢谢 我相信问题出在“碰撞”函数中,但我不太清楚它是什么 顺便说一句,我也愿意就这段代码的改进提出建议 这是html和cssJavascript 嘿,我想用canvas和js制作这个小程序,它可以检测圆之间的碰撞,javascript,canvas,collision,Javascript,Canvas,Collision,我正在学习如何使用JS在画布上进行渲染,我正在尝试制作一个简单的碰撞检测程序,该程序可以使碰撞中涉及到的cricles变成某种颜色。目前为止它有点起作用,也就是说它不起作用:D我只看到随机的圆圈有时变成绿色,而不是那些实际上正在碰撞的圆圈 所以我想把这个贴在这里,让你们看看,看看你们能找到什么。提前谢谢 我相信问题出在“碰撞”函数中,但我不太清楚它是什么 顺便说一句,我也愿意就这段代码的改进提出建议 这是html和css <html lang="es"> <head&g
<html lang="es">
<head>
<link rel="stylesheet" href="index.css">
<meta charset="utf-8">
<title>bubbles</title>
</head>
<body>
<p id="fpsIndicator"></p>
<canvas id="cnv"></canvas>
</body>
<footer>
<script src="Circle.js"></script>
<script src="index.js"></script>
</footer>
</html>
这是主JS文件和Circle类
let fpsInd = document.getElementById("fpsIndicator");
let canvas = document.getElementById("cnv");
let ctx = canvas.getContext("2d");
let frames = 0;
let fps = 0;
let lastCallTime;
let bubbles = 35;
let arrBubbles = [];
const RADIAE = 50;
const COLLISION_COLOR = "green";
adjustCanvas();
window.addEventListener("resize", adjustCanvas);
for(let i = 0; i < bubbles; i++){
let x = randomInteger(RADIAE, canvas.width-RADIAE);
let y = randomInteger(RADIAE, canvas.height-RADIAE);
if(i == 0){
arrBubbles.push(new Circle(x, y, RADIAE, "blue"));
continue;
}
for(let j = 0; j < arrBubbles.length; j++){
let d = distance(x, y, arrBubbles[j].x, arrBubbles[j].y);
if(d <= RADIAE*2){
x = randomInteger(RADIAE, canvas.width-RADIAE);
y = randomInteger(RADIAE, canvas.height-RADIAE);
j = -1;
}
}
arrBubbles.push(new Circle(x, y, RADIAE, "blue"));
}
loop();
function loop(){
frames++;
getFPS();
if(frames % 3 == 0)
fpsInd.innerHTML = "FPS: "+fps;
ctx.clearRect(0,0,window.innerWidth, window.innerHeight);
arrBubbles.forEach( (item)=> {
item.draw(ctx);
item.move(canvas.width, canvas.height);
});
collisions();
requestAnimationFrame(loop);
}
function collisions(){
for(let i = 0; i < arrBubbles.length; i++){
let first = arrBubbles[i];
for(let p = 0; p < arrBubbles.length; p++){
let second = arrBubbles[p];
let d = distance(first.x, first.y, second.x, second.y);
if(d <= first.radius + second.radius){
second.color = COLLISION_COLOR;
first.color = COLLISION_COLOR;
}
else {
second.color = "blue";
first.color = "blue";
}
}
}
}
function distance(x1, y1, x2, y2){
let distX = x2-x1;
let distY = y2-y1;
return Math.sqrt(distX*distX + distY*distY);
}
function randomInteger(min, max){
return Math.floor(Math.random() * (max-min+1) + min);
}
function adjustCanvas(){
canvas.setAttribute("width", window.innerWidth);
canvas.setAttribute("height", window.innerHeight);
}
function getFPS(){
let delta;
if(!lastCallTime){
lastCallTime = Date.now();
fps = 0;
return;
}
delta = (Date.now() - lastCallTime) / 1000;
lastCallTime = Date.now();
fps = Math.floor(1/delta);
}
让fpsInd=document.getElementById(“fpsinder”);
让canvas=document.getElementById(“cnv”);
设ctx=canvas.getContext(“2d”);
设帧=0;
设fps=0;
让我们在最后的时间;
让气泡=35;
设arrbuses=[];
常数半径=50;
const COLLISION_COLOR=“绿色”;
调整画布();
addEventListener(“调整大小”,调整画布);
for(设i=0;i 如果(d=canvasW-this.radius | | this.x-1=canvasH-this.radius | | | this.y-1)到目前为止做得很好。你已经正确设置了游戏/动画的所有基础知识。你是对的-唯一真正的问题是碰撞
函数。看看那里发生了什么
它选择一个圆圈,首先称它为,
,然后在屏幕上每隔一个圆圈称一个圆圈
- 如果它们相交,则会将两种颜色更改为碰撞颜色
- 如果它们不相交,则会将两种颜色更改回默认颜色
现在再看一遍,想想如果第一个>代码>圆检查第一个与它真正相撞的圆的碰撞。那么在那个循环中发生的最后一件事就是检查它与其他圆(不与它碰撞)的碰撞,并将所有颜色恢复到默认值。
基本上,您需要重新思考如何创建这两个循环的逻辑。例如,我建议添加一个布尔标志(例如,冲突
)这可以在内部循环完成后进行检查-甚至可以将其添加为圆
实例的属性。因此,如果首先
与内部循环中的某个对象发生碰撞,则首先设置。碰撞=真
。在Circle draw()函数中,可以基于此属性设置颜色
幸运的是,按照这些循环的设置方式,它实际上覆盖了另一个bug。你没有考虑到第二个
圆何时与第一个
圆是同一个对象(它与自身的距离始终为零,因此应该始终变为绿色…但上面的bug总是将其转回)。您可以通过在内部循环中添加这样的检查来说明这一点:
if(第一!==second)
或if(i!==p)
等等。非常感谢!!facepalm我怎么会错过这个,呵呵,我去给圆添加了.colling属性。我已经更改了绘制和碰撞功能,但仍然不好,现在所有的圆都是用碰撞颜色永久绘制的。这是新代码:
function collisions(){
let p, quitLooping;
let first, second, d;
for(let i = 0; i < arrBubbles.length; i++){
first = arrBubbles[i];
p = 0;
quitLooping = false;
while(p < arrBubbles.length && !quitLooping){
second = arrBubbles[p];
d = distance(first.x, first.y, second.x, second.y);
if( i !== p)
if(d <= first.radius + second.radius){
first.colliding = true;
quitLooping = true;
}
else
first.colliding = false;
p++;
}
}
}
draw(ctx){
(this.colliding) ? ctx.strokeStyle = COLLISION_COLOR : ctx.strokeStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, 2*Math.PI);
ctx.stroke();
}
函数冲突(){
设p,退出循环;
让第一,第二,d;
for(设i=0;i 如果(d该死的…nvm问题解决了,我忘记了if语句上的括号…无论如何,非常感谢tlong314!!!
class Circle{
constructor(x, y, radius, color){
this.x = x;
this.y = y;
this.radius = radius;
this.color = color;
this.velocity = {
X: randomInteger(1, 3),
Y: randomInteger(1, 3)
}
}
move(canvasW, canvasH){
if(this.x+1 >= canvasW-this.radius || this.x-1 <= this.radius)
this.velocity.X = -this.velocity.X;
if(this.y+1 >= canvasH-this.radius || this.y-1 <= this.radius)
this.velocity.Y = -this.velocity.Y;
this.x += this.velocity.X;
this.y += this.velocity.Y;
}
draw(ctx){
ctx.strokeStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, 2*Math.PI);
ctx.stroke();
}
}
function collisions(){
let p, quitLooping;
let first, second, d;
for(let i = 0; i < arrBubbles.length; i++){
first = arrBubbles[i];
p = 0;
quitLooping = false;
while(p < arrBubbles.length && !quitLooping){
second = arrBubbles[p];
d = distance(first.x, first.y, second.x, second.y);
if( i !== p)
if(d <= first.radius + second.radius){
first.colliding = true;
quitLooping = true;
}
else
first.colliding = false;
p++;
}
}
}
draw(ctx){
(this.colliding) ? ctx.strokeStyle = COLLISION_COLOR : ctx.strokeStyle = this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, this.radius, 0, 2*Math.PI);
ctx.stroke();
}