需要碰撞检测的 Javascript 和 Canvas “引擎”

发布于 2024-11-09 01:39:38 字数 7932 浏览 0 评论 0原文

所以,我有一个小小的“移动和填充”引擎,目前它非常原始。

每隔一段时间(基于计时器)另一个像素(5x5)就会出现在屏幕上 - 如果您与该像素相交,我想触发一个事件。 (公平地说,该像素(5x5)需要大得多:/)。

所以,这是我的 JSFiddle(供各位小提琴手使用): http://jsfiddle.net/neuroflux/q9APG/

是我的画布 JavaScript:

var canvas, ctx;
var pixX = 0; //positions
var pixY = 0;
var endX = 0;
var endY = 0;
var youX = 5; //sizes
var youY = 5;
var dis = 1; //timings
var p = 0;

window.onload = function() {
    init();
}

function init() {
    canvas = document.getElementById('main');
    ctx = canvas.getContext('2d');
    setInterval(loop,40);
    var pixTimer = Math.floor((Math.random() * 1000) * 10) + 1;
    setInterval(addPixel, pixTimer);
    document.addEventListener('keydown',function(e) {
        runMove(e);
    });
}

function addPixel() {
    pX = Math.floor(Math.random() * 800) + 1;
    pY = Math.floor(Math.random() * 600) + 1;
    p++;
}

function loop() {
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.fillRect(pixX,pixY,youX,youY);
    ctx.fillText(pixX + ':' + pixY, 5, 500);
    if (p > 0) {
        for (var a = 0; a <= p; a++) {
            ctx.fillRect(pX,pY,5,5);
        }
    }
}

function runMove(e) {
    var canvas = document.getElementById('main');
    ky = e.keyCode;
    switch(ky) {
        case 37:
            endX = endX - dis;
            if (pixX == endX) {

            } else {
                if (pixX >= 0 && pixX < canvas.width) {
                    moveleft = setInterval(ml,10);
                    function ml() { pixX--; }
                } else {
                    pixX = 0;
                }
            }
            return false;
        case 38:
            endY = endY - dis;
            if (pixY == endY) {

            } else {
                if (pixY >= 0 && pixY < canvas.height) {
                    moveup = setInterval(mu,10);
                    function mu() { pixY--; }
                }
            }
            return false;
        case 39:
            endX = endX + dis;
            if (pixX == endX) {

            } else {
                if (pixX >= 0 && pixX < canvas.width) {
                    moveright = setInterval(mr,10);
                    function mr() { pixX++; }
                }
            }
            return false;
        case 40:
            endY = endY + dis;
            if (pixY == endY) {

            } else {
                if (pixY >= 0 && pixY < canvas.height) {
                    movedown = setInterval(md,10);
                    function md() { pixY++; }
                }
            }
            return false;
        case 80:
            growing = setInterval(grow,100);
            clearInterval(shrinking);
            function grow() {
                youX = youX + dis;
                youY = youY + dis;
            }
            return false;
        case 73:
            clearInterval(shrinking);
            clearInterval(growing);
            return false;
        case 79:
            shrinking = setInterval(shrink,100);
            clearInterval(growing);
            function shrink() {
                youX = youX - dis;
                youY = youY - dis;
            }
            return false;
        default:
            return false;
    }
}

这 已经尝试过这个,但遇到了问题:((什么都不会触发): JSFiddle: http://jsfiddle.net/neuroflux/uF5kj/

画布代码:

    var canvas, ctx;
        var pixX = 0; //positions
        var pixY = 0;
        var endX = 0;
        var endY = 0;
        var youX = 5; //sizes
        var youY = 5;
        var dis = 1; //timings
        var p = 0;
        var pixel = new Array();

        window.onload = function() {
            init();
        }

        function init() {
            canvas = document.getElementById('main');
            ctx = canvas.getContext('2d');
            setInterval(loop,40);
            var pixTimer = Math.floor((Math.random() * 1000) * 10) + 1;
            setInterval(addPixel, pixTimer);
            document.addEventListener('keydown',function(e) {
                runMove(e);
            });
        }

        function addPixel() {
            pX = Math.floor(Math.random() * 800) + 1;
            pY = Math.floor(Math.random() * 600) + 1;
            p++;
        }

        function loop() {
            ctx.clearRect(0,0,canvas.width,canvas.height);
            var bgImg = new Image();
            bgImg.src = 'bg.png';
                ctx.drawImage(bgImg,0,0,800,600);
            ctx.fillRect(pixX,pixY,youX,youY);
            ctx.fillText(pixX + ':' + pixY, 5, 500);
            if (p > 0) {
                for (var a = 0; a <= p; a++) {
                    pixel[a] = ctx.fillRect(pX,pY,5,5);
                }
            }
        }

        function checkIntersections() {
            for (var x = 0; x < pixel.length; x++) {
                    if (pixX == pixel[x].x) { alert(0) }
            }
        }

        function runMove(e) {
            var canvas = document.getElementById('main');
            ky = e.keyCode;
            switch(ky) {
                case 37:
                    endX = endX - dis;
                    if (pixX == endX) {

                    } else {
                        if (pixX >= 0 && pixX < canvas.width) {
                            moveleft = setInterval(ml,10);
                            function ml() { pixX--; }
                        } else {
                            pixX = 0;
                        }
                    }
                    return false;
                case 38:
                    endY = endY - dis;
                    if (pixY == endY) {

                    } else {
                        if (pixY >= 0 && pixY < canvas.height) {
                            moveup = setInterval(mu,10);
                            function mu() { pixY--; }
                        }
                    }
                    checkIntersections();
                    return false;
                case 39:
                    endX = endX + dis;
                    if (pixX == endX) {

                    } else {
                        if (pixX >= 0 && pixX < canvas.width) {
                            moveright = setInterval(mr,10);
                            function mr() { pixX++; }
                        }
                    }
                    checkIntersections();
                    return false;
                case 40:
                    endY = endY + dis;
                    if (pixY == endY) {

                    } else {
                        if (pixY >= 0 && pixY < canvas.height) {
                            movedown = setInterval(md,10);
                            function md() { pixY++; }
                        }
                    }
                    checkIntersections();
                    return false;
                case 80:
                    growing = setInterval(grow,100);
                    clearInterval(shrinking);
                    function grow() {
                        youX = youX + dis;
                        youY = youY + dis;
                    }
                    checkIntersections();
                    return false;
                case 73:
                    clearInterval(shrinking);
                    clearInterval(growing);
                    return false;
                case 79:
                    shrinking = setInterval(shrink,100);
                    clearInterval(growing);
                    function shrink() {
                        youX = youX - dis;
                        youY = youY - dis;
                    }
                    return false;
                default:
                    return false;
            }
        }

So, I have a little "move around and stuff" engine, which is very primative at the moment.

Every so often (timer based) another pixel (5x5) will appear on the screen - if you intersect with that pixel, I would like to fire an event. (To be fair, that pixel (5x5) needs to be a hella-lot bigger :/ ).

So, here is my JSFiddle (for you fiddlers):
http://jsfiddle.net/neuroflux/q9APG/

And here is my javascript for the canvas:

var canvas, ctx;
var pixX = 0; //positions
var pixY = 0;
var endX = 0;
var endY = 0;
var youX = 5; //sizes
var youY = 5;
var dis = 1; //timings
var p = 0;

window.onload = function() {
    init();
}

function init() {
    canvas = document.getElementById('main');
    ctx = canvas.getContext('2d');
    setInterval(loop,40);
    var pixTimer = Math.floor((Math.random() * 1000) * 10) + 1;
    setInterval(addPixel, pixTimer);
    document.addEventListener('keydown',function(e) {
        runMove(e);
    });
}

function addPixel() {
    pX = Math.floor(Math.random() * 800) + 1;
    pY = Math.floor(Math.random() * 600) + 1;
    p++;
}

function loop() {
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.fillRect(pixX,pixY,youX,youY);
    ctx.fillText(pixX + ':' + pixY, 5, 500);
    if (p > 0) {
        for (var a = 0; a <= p; a++) {
            ctx.fillRect(pX,pY,5,5);
        }
    }
}

function runMove(e) {
    var canvas = document.getElementById('main');
    ky = e.keyCode;
    switch(ky) {
        case 37:
            endX = endX - dis;
            if (pixX == endX) {

            } else {
                if (pixX >= 0 && pixX < canvas.width) {
                    moveleft = setInterval(ml,10);
                    function ml() { pixX--; }
                } else {
                    pixX = 0;
                }
            }
            return false;
        case 38:
            endY = endY - dis;
            if (pixY == endY) {

            } else {
                if (pixY >= 0 && pixY < canvas.height) {
                    moveup = setInterval(mu,10);
                    function mu() { pixY--; }
                }
            }
            return false;
        case 39:
            endX = endX + dis;
            if (pixX == endX) {

            } else {
                if (pixX >= 0 && pixX < canvas.width) {
                    moveright = setInterval(mr,10);
                    function mr() { pixX++; }
                }
            }
            return false;
        case 40:
            endY = endY + dis;
            if (pixY == endY) {

            } else {
                if (pixY >= 0 && pixY < canvas.height) {
                    movedown = setInterval(md,10);
                    function md() { pixY++; }
                }
            }
            return false;
        case 80:
            growing = setInterval(grow,100);
            clearInterval(shrinking);
            function grow() {
                youX = youX + dis;
                youY = youY + dis;
            }
            return false;
        case 73:
            clearInterval(shrinking);
            clearInterval(growing);
            return false;
        case 79:
            shrinking = setInterval(shrink,100);
            clearInterval(growing);
            function shrink() {
                youX = youX - dis;
                youY = youY - dis;
            }
            return false;
        default:
            return false;
    }
}

I have already tried this, but got issues :( (nothing would fire):
JSFiddle: http://jsfiddle.net/neuroflux/uF5kj/

Canvas Code:

    var canvas, ctx;
        var pixX = 0; //positions
        var pixY = 0;
        var endX = 0;
        var endY = 0;
        var youX = 5; //sizes
        var youY = 5;
        var dis = 1; //timings
        var p = 0;
        var pixel = new Array();

        window.onload = function() {
            init();
        }

        function init() {
            canvas = document.getElementById('main');
            ctx = canvas.getContext('2d');
            setInterval(loop,40);
            var pixTimer = Math.floor((Math.random() * 1000) * 10) + 1;
            setInterval(addPixel, pixTimer);
            document.addEventListener('keydown',function(e) {
                runMove(e);
            });
        }

        function addPixel() {
            pX = Math.floor(Math.random() * 800) + 1;
            pY = Math.floor(Math.random() * 600) + 1;
            p++;
        }

        function loop() {
            ctx.clearRect(0,0,canvas.width,canvas.height);
            var bgImg = new Image();
            bgImg.src = 'bg.png';
                ctx.drawImage(bgImg,0,0,800,600);
            ctx.fillRect(pixX,pixY,youX,youY);
            ctx.fillText(pixX + ':' + pixY, 5, 500);
            if (p > 0) {
                for (var a = 0; a <= p; a++) {
                    pixel[a] = ctx.fillRect(pX,pY,5,5);
                }
            }
        }

        function checkIntersections() {
            for (var x = 0; x < pixel.length; x++) {
                    if (pixX == pixel[x].x) { alert(0) }
            }
        }

        function runMove(e) {
            var canvas = document.getElementById('main');
            ky = e.keyCode;
            switch(ky) {
                case 37:
                    endX = endX - dis;
                    if (pixX == endX) {

                    } else {
                        if (pixX >= 0 && pixX < canvas.width) {
                            moveleft = setInterval(ml,10);
                            function ml() { pixX--; }
                        } else {
                            pixX = 0;
                        }
                    }
                    return false;
                case 38:
                    endY = endY - dis;
                    if (pixY == endY) {

                    } else {
                        if (pixY >= 0 && pixY < canvas.height) {
                            moveup = setInterval(mu,10);
                            function mu() { pixY--; }
                        }
                    }
                    checkIntersections();
                    return false;
                case 39:
                    endX = endX + dis;
                    if (pixX == endX) {

                    } else {
                        if (pixX >= 0 && pixX < canvas.width) {
                            moveright = setInterval(mr,10);
                            function mr() { pixX++; }
                        }
                    }
                    checkIntersections();
                    return false;
                case 40:
                    endY = endY + dis;
                    if (pixY == endY) {

                    } else {
                        if (pixY >= 0 && pixY < canvas.height) {
                            movedown = setInterval(md,10);
                            function md() { pixY++; }
                        }
                    }
                    checkIntersections();
                    return false;
                case 80:
                    growing = setInterval(grow,100);
                    clearInterval(shrinking);
                    function grow() {
                        youX = youX + dis;
                        youY = youY + dis;
                    }
                    checkIntersections();
                    return false;
                case 73:
                    clearInterval(shrinking);
                    clearInterval(growing);
                    return false;
                case 79:
                    shrinking = setInterval(shrink,100);
                    clearInterval(growing);
                    function shrink() {
                        youX = youX - dis;
                        youY = youY - dis;
                    }
                    return false;
                default:
                    return false;
            }
        }

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

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

发布评论

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

评论(2

陈年往事 2024-11-16 01:39:39

您最好使用圆圈,因为可以更轻松地计算距离(固定半径)。假设您将半径设置为 10,那么如果距离 20 它们在彼此内部,即存在碰撞。

// Pythagoras theorem to calculate distance between 2 points
function does_collide(x1, y1, x2, y2) {
    return Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)) < 20;
}

每次,计算用户/物体之间的距离:

if(does_collide(pixX, pixY, pX, pY)) {
    ctx.fillText('collison!@', 0, 10);
    collison = true;
} else {
    collison = false;
}

在任何时候,collison变量都可以用来检查是否存在碰撞。

您可以使用以下方法绘制一个圆圈:

ctx.beginPath();
ctx.arc(x, y, r, 0, 2 * Math.PI);
ctx.fill();

http://jsfiddle.net/q9APG/4/

You'd be better off with circles, since the distance can more easily be calculated (fixed radius). Say you set radius to 10, then if distance < 20 they are inside each other, i.e. there is collison.

// Pythagoras theorem to calculate distance between 2 points
function does_collide(x1, y1, x2, y2) {
    return Math.sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1)) < 20;
}

Each time, calculate distance between user / object:

if(does_collide(pixX, pixY, pX, pY)) {
    ctx.fillText('collison!@', 0, 10);
    collison = true;
} else {
    collison = false;
}

At any time, the collison variable can be used for checking whether there is collison.

You can draw a circle using:

ctx.beginPath();
ctx.arc(x, y, r, 0, 2 * Math.PI);
ctx.fill();

http://jsfiddle.net/q9APG/4/

狂之美人 2024-11-16 01:39:38

等等,所以您想要的只是一个查看两个矩形是否相交的函数?

这是为您提供的防弹功能:

// returns true if there is any overlap
// params: x,y,w,h of two rectangles
function intersects(x1, y1, w1, h1, x2, y2, w2, h2) {
  if (w2 !== Infinity && w1 !== Infinity) {
    w2 += x2;
    w1 += x1;
    if (isNaN(w1) || isNaN(w2) || x2 > w1 || x1 > w2) return false;
  }
  if (y2 !== Infinity && h1 !== Infinity) {
    h2 += y2;
    h1 += y1;
    if (isNaN(h1) || isNaN(y2) || y2 > h1 || y1 > h2) return false;
  }
  return true;
}

Wait, so all you want is a function to see if two rectangles intersect?

Here's a bulletproof function for you:

// returns true if there is any overlap
// params: x,y,w,h of two rectangles
function intersects(x1, y1, w1, h1, x2, y2, w2, h2) {
  if (w2 !== Infinity && w1 !== Infinity) {
    w2 += x2;
    w1 += x1;
    if (isNaN(w1) || isNaN(w2) || x2 > w1 || x1 > w2) return false;
  }
  if (y2 !== Infinity && h1 !== Infinity) {
    h2 += y2;
    h1 += y1;
    if (isNaN(h1) || isNaN(y2) || y2 > h1 || y1 > h2) return false;
  }
  return true;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文