在画布中调整边缘处的弹跳框大小失败

问题描述 投票:0回答:1

我看到了这个视频,并尝试在画布中做同样的事情

这是代码(没有大小增量)

canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");

canvas.width = parseInt(window.innerWidth, 10);
canvas.height = parseInt(window.innerHeight, 10);

let x = 0;
let y = 0;
let size = 50;
let dx = 5;
let dy = 5;
let hue = 0;

function animate()
{
    x += dx;
    y += dy;

    hue = (hue + 10) % 360;

    if(x <= 0 || x >= canvas.width - size)
    {
        dx = -dx;
    }

    if(y <= 0 || y >= canvas.height - size)
    {
        dy = -dy;
    }

    ctx.fillStyle = `hsl(${hue}, 100%, 50%)`;
    ctx.fillRect(x, y, size, size);
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 1;
    ctx.strokeRect(x, y, size, size);

    window.requestAnimationFrame(animate);
}

animate();
<canvas id="canvas"></canvas>

它工作正常,但是当我添加增加部分时,正方形会卡在边缘并呈指数增长:

canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");

canvas.width = parseInt(window.innerWidth, 10);
canvas.height = parseInt(window.innerHeight, 10);

let x = 0;
let y = 0;
let size = 50;
let dx = 5;
let dy = 5;
let hue = 0;

function animate()
{
    x += dx;
    y += dy;

    hue = (hue + 10) % 360;

    if(x <= 0 || x >= canvas.width - size)
    {
        dx = -dx;
    size = Math.ceil(size * 1.10);
    }

    if(y <= 0 || y >= canvas.height - size)
    {
        dy = -dy;
    size = Math.ceil(size * 1.10);
    }

    ctx.fillStyle = `hsl(${hue}, 100%, 50%)`;
    ctx.fillRect(x, y, size, size);
    ctx.strokeStyle = 'black';
    ctx.lineWidth = 1;
    ctx.strokeRect(x, y, size, size);

    window.requestAnimationFrame(animate);
}

animate();
<canvas id="canvas"></canvas>

根据尺寸增量,它会卡在不同的边缘和不同的弹跳次数。

我认为我必须在边缘检测中评估更多东西,但我可以弄清楚。

javascript html5-canvas collision-detection
1个回答
0
投票

这是一个相当经典的问题。 您的代码的以下部分

x += dx;
y += dy;

无论如何,仅更新方块的位置。这意味着它既不考虑正方形的“未来”位置,也不考虑它的大小 - 随着时间的推移而增加。 修复方法非常简单:在更新方块在屏幕上的位置之前,检查方块是否会以当前的速度向外移动。如果是这样,请将其放置在边界边缘并反转速度。

canvas = document.getElementById("canvas"); ctx = canvas.getContext("2d"); canvas.width = parseInt(window.innerWidth, 10); canvas.height = parseInt(window.innerHeight, 10); let x = 0; let y = 0; let size = 50; let dx = 5; let dy = 5; let hue = 0; function animate() { if (dx < 0) { if (x + dx < 0) { x = 0; dx = -dx; size = Math.ceil(size * 1.10); } else { x += dx; } } else { if (x + size + dx > canvas.width) { x = canvas.width - size; dx = -dx; size = Math.ceil(size * 1.10); } else { x += dx; } } if (dy < 0) { if (y + dy < 0) { y = 0; dy = -dy; size = Math.ceil(size * 1.10); } else { y += dy; } } else { if (y + size + dy > canvas.height) { y = canvas.height - size; dy = -dy; size = Math.ceil(size * 1.10); } else { y += dy; } } hue = (hue + 10) % 360; ctx.fillStyle = `hsl(${hue}, 100%, 50%)`; ctx.fillRect(x, y, size, size); ctx.strokeStyle = 'black'; ctx.lineWidth = 1; ctx.strokeRect(x, y, size, size); window.requestAnimationFrame(animate); } animate();
<canvas id="canvas"></canvas>

© www.soinside.com 2019 - 2024. All rights reserved.