gpt4 book ai didi

javascript - 检测矩形的哪一侧与另一个矩形碰撞

转载 作者:行者123 更新时间:2023-12-05 00:34:25 27 4
gpt4 key购买 nike

我正在尝试使用带有 javascript 的 HTML5 Canvas 开发游戏,并且在没有使用两个对象的 (x,y) 坐标对其进行硬编码的情况下检测碰撞时遇到问题。在我基于研究的代码中,发现了检查两个对象是否发生碰撞的常用算法,即

Object1 = a moving player
Object2 = fixed (x,y) points. Non movable object

(object1.x < object2.x + object2.width && object1.x + object1.width > object2.x &&
object1.y < object2.y + object2.height && object1.y + object1.height > object2.y)

我尝试了它并用其他代码开发了它,它可以工作,它检测到碰撞。但是我遇到了碰撞问题,它适用于 left side 中的条件但是当 object1转到 top, bottom or right object2 的返回到 object2 的 left side .换句话说,如果 object1 到顶部/底部或右侧,它会回到左侧。任何形式的帮助将不胜感激。
function collide(object1, object2){

//object1 player
this.x = object1.x;
this.y = object1.y;
this.w = object1.w;
this.h = object1.h;

//object2 any object
this.x2 = object2.x;
this.y2 = object2.y;
this.w2 = object2.w;
this.h2 = object2.h;

//collisions
var isCorrect = false;
var side = 0;

if ((this.x < this.x2 + this.w2) && (this.x + this.w > this.x2)
&& (this.y < this.y2 + this.h2) && (this.h + this.y > this.y2)){
isCorrect = true;
}

if (this.x + this.w > this.x2){
//left check
side = 1;
}else if (this.x < this.x2 + this.w2){
//right check
side = 2;
}else if (this.y + this.h > this.y2){
//bottom check
side = 3;
}else if (this.y < this.y2 + this.h2){
//top check
side = 4;
}

if (isCorrect){
if ((this.x + this.w > this.x2) && side == 1){
playerObj.x -= 5;
}else if ((this.x < this.x2 + this.w2) && side == 2){
playerObj.x += 5;
}else if ((this.y + this.h > this.y2) && side == 3){
playerObj.y += 5;
}else if ((this.y < this.y2 + this.h2) && side == 4){
playerObj.y -= 5;
}
}
}

最佳答案

这个碰撞函数会告诉你 rect2 的哪一侧与 rect1 发生了碰撞:

当然,rect1 的另一侧与 rect2 相撞。

这个函数是一个 2-pass 测试:

  • Test1:检查 2 个矩形的中心是否足够接近碰撞
  • 测试2:如果是,检查相交深度以确定哪一侧最容易发生碰撞。

  • 碰撞函数
    function collide(r1,r2){
    var dx=(r1.x+r1.w/2)-(r2.x+r2.w/2);
    var dy=(r1.y+r1.h/2)-(r2.y+r2.h/2);
    var width=(r1.w+r2.w)/2;
    var height=(r1.h+r2.h)/2;
    var crossWidth=width*dy;
    var crossHeight=height*dx;
    var collision='none';
    //
    if(Math.abs(dx)<=width && Math.abs(dy)<=height){
    if(crossWidth>crossHeight){
    collision=(crossWidth>(-crossHeight))?'bottom':'left';
    }else{
    collision=(crossWidth>-(crossHeight))?'right':'top';
    }
    }
    return(collision);
    }

    这是示例代码和演示:

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");
    var cw=canvas.width;
    var ch=canvas.height;
    function reOffset(){
    var BB=canvas.getBoundingClientRect();
    offsetX=BB.left;
    offsetY=BB.top;
    }
    var offsetX,offsetY;
    reOffset();
    window.onscroll=function(e){ reOffset(); }

    var rects=[];
    var rect1={ x:100,y:100,w:85,h:85,fill:'red'}
    var rect2={ x:10,y:10,w:40,h:60,fill:'gold'}

    $("#canvas").mousemove(function(e){handleMouseMove(e);});

    draw();

    function collide(r1,r2){
    var dx=(r1.x+r1.w/2)-(r2.x+r2.w/2);
    var dy=(r1.y+r1.h/2)-(r2.y+r2.h/2);
    var width=(r1.w+r2.w)/2;
    var height=(r1.h+r2.h)/2;
    var crossWidth=width*dy;
    var crossHeight=height*dx;
    var collision='none';
    //
    if(Math.abs(dx)<=width && Math.abs(dy)<=height){
    if(crossWidth>crossHeight){
    collision=(crossWidth>(-crossHeight))?'bottom':'left';
    }else{
    collision=(crossWidth>-(crossHeight))?'right':'top';
    }
    }
    return(collision);
    }

    function draw(){
    ctx.clearRect(0,0,cw,ch);
    ctx.fillStyle=rect1.fill;
    ctx.fillRect(rect1.x,rect1.y,rect1.w,rect1.h);
    ctx.fillStyle=rect2.fill;
    ctx.fillRect(rect2.x,rect2.y,rect2.w,rect2.h);
    var side=collide(rect1,rect2);
    ctx.fillStyle='green'
    if(side=='top'){ ctx.fillRect(rect2.x,rect2.y,rect2.w,3); }
    if(side=='right'){ ctx.fillRect(rect2.x+rect2.w,rect2.y,3,rect2.h); }
    if(side=='bottom'){ ctx.fillRect(rect2.x,rect2.y+rect2.h,rect2.w,3); }
    if(side=='left'){ ctx.fillRect(rect2.x,rect2.y,3,rect2.h); }
    }

    function handleMouseMove(e){
    // tell the browser we're handling this event
    e.preventDefault();
    e.stopPropagation();

    mouseX=parseInt(e.clientX-offsetX);
    mouseY=parseInt(e.clientY-offsetY);

    rect2.x=mouseX;
    rect2.y=mouseY;

    draw();

    }
    body{ background-color: ivory; }
    #canvas{border:1px solid red;}
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <h4>Move the mouse to drag the gold rect<br>Any colliding side of gold rect will highlight</h4>
    <canvas id="canvas" width=300 height=300></canvas>

    关于javascript - 检测矩形的哪一侧与另一个矩形碰撞,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29861096/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com