检测两个物体(墙壁)的碰撞是多么好的做法。是的,不仅仅是检测,而是进一步位移,使物体不会相互进入。也就是说,当它们碰撞时,它们会相互抵靠,但不会进入。
class WallObj {
constructor(obj) {//x, y, w, h, bern ,thru) {
this.x = obj.x
this.y = obj.y
this.w = obj.w
this.h = obj.h
this.bern = obj.bern
this.thru = obj.thru
this.hide = obj.hide
this.id = obj.id
}
collusionWall(startPosition, endPosition) {
var xS = startPosition[0]
var x = endPosition[0]
if (xS - x > 0)
if (x)
// if wall behind point
if (this.x < startPosition[0])
return endPosition
else if (this.x + this.w < x)
return endPosition
return endPosition
// return [this.x, endPosition[1]]
}
}
最佳答案
一个简单的方法是检查 x 和 y :
let ctx = mycan.getContext("2d");
let objects = [];
class player
{
constructor()
{
this.position = {x:50,y:50};
this.color = "blue";
this.size = 32;
this.stop= false;
this.prevpos=this.position;
window.addEventListener("keydown",(e)=>{
if(this.stop) this.position=this.prevpos;
else this.displacement(e);
});
}
displacement(e)
{
this.prevpos = this.position;
this.position.x+=(e.key=="ArrowRight");
this.position.x-=(e.key=="ArrowLeft");
this.position.y+=(e.key=="ArrowDown");
this.position.y-=(e.key=="ArrowUp");
}
draw()
{
ctx.fillStyle = this.color; ctx.fillRect(this.position.x,this.position.y,this.size,this.size);
}
};
class wall
{
constructor(posx,posy)
{
this.position = {x:posx,y:posy};
this.color = "red";
this.size = 32;
}
draw(){
ctx.fillStyle = this.color;
ctx.fillRect(this.position.x,this.position.y,this.size,this.size);
}
};
for(let i = 0; i<mycan.width;i+=32)
{
objects.push(new wall(i,0));
objects.push(new wall(i,mycan.height-32));
}
for(let j = 0; j<mycan.height;j+=32)
{
objects.push(new wall(0,j));
objects.push(new wall(mycan.width-32,j));
}
let playr=new player;
let collision = (colider)=>{
let colx = false;
let coly = false;
/*******************************************************
here we check if the top left point from our current
wall object is inferior to the top left point of our
player and if the top rignt point of the wall object is
superior to the player top left point.
we need to repeat this for the player top right point
(so we compare the player top right point is superior
to the wall top left point and inferior to the wall
top right point)
then we repeat this for y
*******************************************************/
for(let object of objects)
{
colx = (
(
(object.position.x<=colider.position.x) &&
(
(object.position.x+object.size)>=
(colider.position.x)
)
)||(
(
(colider.position.x+colider.size)>=object.position.x) &&
(
(colider.position.x+object.size)<=(object.position.x+object.size)
)
)
)
coly = (
(
(object.position.y<=colider.position.y) &&
(
(object.position.y+object.size)>=
(colider.position.y)
)
)||(
(
(colider.position.y+colider.size)>=object.position.y) &&
(
(colider.position.y+object.size)<=(object.position.y+object.size)
)
)
)
if(colx&&coly) return true;
}
return false;
};
setInterval(()=>{
ctx.clearRect(0,0,mycan.width,mycan.height);
playr.stop = collision(playr);
playr.draw();
for(let obj of objects)
obj.draw();
},1000/30);
<canvas id="mycan" width=400 height=250></canvas>
更好的方法是将你的 2d 世界分割成多个区域,在这些区域中,可以碰撞的物体的密度或多或少重要(四叉树)。
像这样:
更简单的方法是查看碰撞对象是否在球体中(这意味着墙壁发生球体碰撞并且很难表示为正方形),但我们可以说玩家是一个球体并且检查是否有东西进入了他的半径。
https://studiofreya.com/3d-math-and-physics/sphere-vs-aabb-collision-detection-test/
关于javascript - 与物体(墙壁)碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64554583/