Javascript 停止在画布中重复碰撞检测

发布于 2024-12-09 03:03:16 字数 1279 浏览 0 评论 0原文

我正在尝试在 javascript 和 html5 canvas 中做一些简单的碰撞。到目前为止,我的想法是:

  checkCollision = (function(){
        var l, i, ni,dis = 0;
        var ob1,ob2 = {};

        return function(){
            //collisions is the array holding all the objects
            l = collisions.length;
            i = 0;
            ni = 1;
            while(i<l){
                //grab the first object
                ob1 = collisions[i];

                while(ni<l){
                    //get the object to check against
                    ob2 = collisions[ni];
                    //find the distance between the two
                    dis = Math.sqrt(Math.pow((ob1.pos[0]-ob2.pos[0]),2)+Math.pow((ob1.pos[1]-ob2.pos[1]),2));
                    //rad is the radius
                    if(ob1.rad+ob2.rad >= dis){
                        console.log("collision")
                    }

                    //move forward second increment
                    ni++;
                }

                i++;
                //keep one place ahead
                ni=i+1;
            }
        };

    })();

我在没有任何帮助的情况下做到了这一点,但现在我想我的大脑太糊涂了,无法弄清楚最后一部分。每一帧都会发生碰撞,这是我不希望的。我只想让它在碰撞第一次发生时触发一次。我尝试为每个对象提供一个碰撞变量,如果已经发生碰撞,则该变量为 true,但效果不佳。有些会触发一次,有些会持续触发。 有人有任何指点吗?

I'm trying to do some simple collisions in javascript and html5 canvas. So far I have this:

  checkCollision = (function(){
        var l, i, ni,dis = 0;
        var ob1,ob2 = {};

        return function(){
            //collisions is the array holding all the objects
            l = collisions.length;
            i = 0;
            ni = 1;
            while(i<l){
                //grab the first object
                ob1 = collisions[i];

                while(ni<l){
                    //get the object to check against
                    ob2 = collisions[ni];
                    //find the distance between the two
                    dis = Math.sqrt(Math.pow((ob1.pos[0]-ob2.pos[0]),2)+Math.pow((ob1.pos[1]-ob2.pos[1]),2));
                    //rad is the radius
                    if(ob1.rad+ob2.rad >= dis){
                        console.log("collision")
                    }

                    //move forward second increment
                    ni++;
                }

                i++;
                //keep one place ahead
                ni=i+1;
            }
        };

    })();

I did it without any help of any kind, but now I guess my brain is too much mush to figure this last part out. The collision is happening every frame, which I don't want. I just want it to fire once when the collision first happens. I've tried by giving each object a collide variable that's true if there's already a collision but it's not working very well. Some it fires once and some it fires constantly.
Does anyone have any pointers?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你在看孤独的风景 2024-12-16 03:03:16

“每一帧都发生”是什么意思?该算法看起来不错,但碰撞似乎没有任何后果,它只是被记录下来。你想跳出循环吗?

一些评论与您的​​问题无关,但可能会使您的代码更具可读性和简洁性:

>   checkCollision = (function(){
>         var l, i, ni,dis = 0;
>         var ob1,ob2 = {};

我不知道为什么您初始化 disob2,它们是稍后赋值。使用这样的闭包意味着这些值将持续到后续调用,直到分配新值为止。真的需要关闭吗?对于这样的动画来说,这可能会影响性能。

>             ni = 1;
>             while(i<l){

您可以将 ni 放在 while 后面,如下所示:

        while(i < l){
            ni = i + 1;

并去掉最后一个 ni = i + 1。您还可以执行以下操作:

>             ob1 = collisions[i++];

并删除最后一个 i++;,并在分配给 ob2 时对 ni 执行相同操作。

执行上述操作减少了代码行数,因此更容易理解,例如

function checkCollision() {
    var ni, dis, ob1, ob2;
    //collisions is the array holding all the objects
    var l = collisions.length;
    var i = 0;

    while (i < l) {
        ni = i + 1;
        //grab the first object
        ob1 = collisions[i++];

        while (ni < l) {
            //get the object to check against
            ob2 = collisions[ni++];
            //find the distance between the two
            dis = Math.sqrt(Math.pow((ob1.pos[0] - ob2.pos[0]), 2) + 
                            Math.pow((ob1.pos[1] - ob2.pos[1]), 2));
            //rad is the radius
            if (ob1.rad + ob2.rad >= dis) {
                console.log("collision");

                // And what else?

            }
        }
    }
}

What do you mean by "happening every frame"? The algorithm seems ok, but there doesn't seem to be any conesquence from the collision, it is just logged. Do you want to break out of the loop?

Some comments that have nothing to do with your issue but might make your code a bit more readable and concise:

>   checkCollision = (function(){
>         var l, i, ni,dis = 0;
>         var ob1,ob2 = {};

I don't know why you initialise dis and ob2, they are assigned values later. Using a closure like this means that the values persist to subesquent calls until new values are assigned. Is the closure really needed? It may be a performance hit for animations like this.

>             ni = 1;
>             while(i<l){

You can put ni after the while, like this:

        while(i < l){
            ni = i + 1;

and get rid of the last ni = i + 1. You can also do:

>             ob1 = collisions[i++];

and get rid of the last i++;, an do the same for ni when assigning to ob2.

Doing the above reduces the number of lines of code so it is more digestable, e.g.

function checkCollision() {
    var ni, dis, ob1, ob2;
    //collisions is the array holding all the objects
    var l = collisions.length;
    var i = 0;

    while (i < l) {
        ni = i + 1;
        //grab the first object
        ob1 = collisions[i++];

        while (ni < l) {
            //get the object to check against
            ob2 = collisions[ni++];
            //find the distance between the two
            dis = Math.sqrt(Math.pow((ob1.pos[0] - ob2.pos[0]), 2) + 
                            Math.pow((ob1.pos[1] - ob2.pos[1]), 2));
            //rad is the radius
            if (ob1.rad + ob2.rad >= dis) {
                console.log("collision");

                // And what else?

            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文