在画布 Javascript 中随机扩展圆圈

时间:2021-02-22 16:09:02

标签: javascript canvas

我是新来的,我是编码新手。目前在做游戏项目。到目前为止,我的代码会生成随机圆圈,用户必须单击才能使其消失。我想让它一旦出现圆圈就开始扩大,在某个点之后它会反转,直到圆圈消失。用户必须在 消失之前单击圆圈。在 randomize 函数中,我尝试使用一些 if 语句,但没有用。只有单击已绘制的圆圈之一,圆圈才会扩展。任何帮助,将不胜感激。代码如下:

<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
      <style type="text/css">
      #canvas{
              display:inline;
              margins:auto;}
      </style>


    <canvas id="canvas" height="500" width="700" ></canvas>
    <script type="text/javascript">
    
    var canvas = document.getElementById('canvas');
    var ctx = canvas.getContext('2d');
    
    var circles = [];
    function drawCanvas() {
        ctx.fillStyle = 'lightblue';
        ctx.fillRect(0, 0, canvas.width, canvas.height);
        for (var a = 0; a < circles.length; a++) {
            drawCircle(circles[a].x, circles[a].y, circles[a].r);
        }
    }
    function drawCircle(x, y, radius){
        ctx.beginPath();
        ctx.arc(x, y, radius, 0, 2 * Math.PI);
        ctx.closePath();
        ctx.fillStyle = color;
        ctx.fill();
    }
    function clickCircle(xmus, ymus){
        for (var i = 0; i < circles.length; i++) {            
            var distance = Math.sqrt(
                Math.pow(xmus - circles[i].x, 2)
                + 
                Math.pow(ymus - circles[i].y, 2)
            );
           console.log(distance);
           if(distance < circles[i].r){   
               //Remove the circle from our array
                circles.splice(i, 1); //This removes 1 element from our circles array at index i
               //Then redraw our canvas from the beginning
               drawCanvas();
            }
        }
    }
    
    canvas.addEventListener('click', (event) => {
        const rect = canvas.getBoundingClientRect();
        const x = event.clientX - rect.left;
        const y = event.clientY - rect.top;
        clickCircle(x,y);
    });
    
    function randomize(){
        var radius = Math.floor(Math.random()*25)+10;

        for (var j = 0; j < circles.length; j++){  
        if(circles[j].r < 50){
            circles[j].r += 2;}

        else if (circles[j].r == 50 || circles[j].r > 50){
            circles[j].r -= 2;
        }}
        var x = Math.floor(Math.random()*600)+50;
        var y = Math.floor(Math.random()*400)+50;
        circles.push({
            x: x,
            y: y,
            r: radius
        });
        drawCircle(x,y,radius);
    }
    
    var interval = setInterval(randomize, 1000);


</script>
</body>
</html>

1 个答案:

答案 0 :(得分:0)

  1. 您的 randomize 函数仅绘制最新的圆圈,而不绘制任何其他圆圈。将 drawCircle(x,y,radius) 替换为 drawCanvas() 以重新绘制每个循环中所有较早的圆圈。

  2. 正如评论中指出的那样,您的 if 条件将圆扩大到半径 50,然后在下一个循环中将其缩小到 48,因此它们都卡在 48 和 50 之间交替. 更改您的逻辑,例如让每个圆都有一个 growth 属性,当半径达到 50 时该属性变为负数。

  3. 您目前无法移除半径为零的圆。

  4. 您不应该在该数组的循环中间splice 数组 - 它会更改索引并跳过一些圆圈。而是使用 filter 删除不需要的。

您的 randomize 函数将被重写如下:

function randomize(){
        var radius = Math.floor(Math.random()*25)+10;

        for (var j = 0; j < circles.length; j++){  
            circles[j].r += circles[j].growth;
            if (circles[j].r > 50 && circles[j].growth > 0) {
                circles[j].growth = -circles[j].growth;
            } 
        }

        // keep only those that still have positive radius:
        circles = circles.filter(circle => circle.r > 0);

        var x = Math.floor(Math.random()*600)+50;
        var y = Math.floor(Math.random()*400)+50;
        circles.push({
            x: x,
            y: y,
            r: radius,
            growth: +2
        });
        drawCanvas();
    }

对于更高级的游戏,您可能需要一个单独的计时器,使用 requestAnimationFrame 来更新画布,方法是在代码末尾添加如下内容:

function step() {
    drawCanvas();
    window.requestAnimationFrame(step);
}
step();

这样可以避免每次更改屏幕中的任何内容时都必须调用 drawCanvas。显示刷新时,画布将自动重绘。