首页 > 解决方案 > 删除画布中特定坐标的对象

问题描述

我想在点击时删除画布中已经生成的球并减少底部的计数器,但我的功能不起作用。这是我关于去除球部分的代码。是否可以使用 div 来获得相同的结果并方便移除球?谢谢你

    ball.onclick = function removeBalls(event) {


    var x = event.clientX;
    var y = event.clientY;

    ctx.clearRect(x, y, 100, 50);
    ctx.fillStyle = "#000000";
    ctx.font = "20px Arial";
    ctx.fillText("Balls Counter: " + balls.length - 1, 10, canvas.height - 10);

}

下面我附上我的完整代码

// GLOBAL VARIBLES

var gravity = 4;
var forceFactor = 0.3; //0.3 0.5
var mouseDown = false;
var balls = []; //hold all the balls
var mousePos = []; //hold the positions of the mouse
var ctx = canvas.getContext('2d');
var heightBrw = canvas.height = window.innerHeight;
var widthBrw = canvas.width = window.innerWidth;
var bounciness = 1; //0.9

window.onload = function gameCore() {

    function onMouseDown(event) {
        mouseDown = true;
        mousePos["downX"] = event.pageX;
        mousePos["downY"] = event.pageY;
    }

    canvas.onclick = function onMouseUp(event) {

        mouseDown = false;
        balls.push(new ball(mousePos["downX"], mousePos["downY"], (event.pageX - mousePos["downX"]) * forceFactor,
            (event.pageY - mousePos["downY"]) * forceFactor, 5 + (Math.random() * 10), bounciness, random_color()));
        ball
    }

    function onMouseMove(event) {
        mousePos['currentX'] = event.pageX;
        mousePos['currentY'] = event.pageY;
    }
    function resizeWindow(event) {
        canvas.height = window.innerHeight;
        canvas.width = window.innerWidth;
    }

    function reduceBounciness(event) {

        if (bounciness == 1) {
            for (var i = 0; i < balls.length; i++) {


                balls[i].b = bounciness = 0.9;
                document.getElementById("btn-bounciness").value = "⤽ Bounciness";

            }
        } else {
            for (var i = 0; i < balls.length; i++) {
                balls[i].b = bounciness = 1;
                document.getElementById("btn-bounciness").value = " ⤼ Bounciness";
            }
        }

        return bounciness;
    }

    function reduceSpeed(event) {
        for (var i = 0; i < balls.length; i++) {
            balls[i].vx = velocityX = 20 + c;
            balls[i].vy = velocityY = 20 + c;
        }
    }

    function speedUp(event) {
        for (var i = 0; i < balls.length; i++) {
            balls[i].vx = velocityX = 120 + c;
            balls[i].vy = velocityY = 120 + c;
        }
    }

    function stopGravity(event) {
        if (gravity == 4) {
            for (var i = 0; i < balls.length; i++) {
                balls[i].g = gravity = 0;
                balls[i].vx = velocityX = 0;
                balls[i].vy = velocityY = 0;
                document.getElementById("btn-gravity").value = "►";
            }
        } else {
            for (var i = 0; i < balls.length; i++) {
                balls[i].g = gravity = 4;
                balls[i].vx = velocityX = 100;
                balls[i].vy = velocityY = 100;
                document.getElementById("btn-gravity").value = "◾";
            }
        }


    }


    ball.onclick = function removeBalls(event) {


        var x = event.clientX;
        var y = event.clientY;

        ctx.clearRect(x, y, 100, 50);
        ctx.fillStyle = "#000000";
        ctx.font = "20px Arial";
        ctx.fillText("Balls Counter: " + balls.length - 1, 10, canvas.height - 10);

    }


    document.getElementById("btn-gravity").addEventListener("click", stopGravity);
    document.getElementById("btn-speed-up").addEventListener("click", speedUp);
    document.getElementById("btn-speed-down").addEventListener("click", reduceSpeed);
    document.getElementById("btn-bounciness").addEventListener("click", reduceBounciness);
    document.addEventListener("mousedown", onMouseDown);
    document.addEventListener("mousemove", onMouseMove);
    window.addEventListener('resize', resizeWindow);

}

// GRAPHICS CODE
function circle(x, y, r, c) { // x position, y position, r radius, c color 
    //draw a circle
    ctx.beginPath(); //approfondire
    ctx.arc(x, y, r, 0, Math.PI * 2, true);
    ctx.closePath();
    //fill
    ctx.fillStyle = c;
    ctx.fill();
    //stroke
    ctx.lineWidth = r * 0.1; //border of the ball radius * 0.1
    ctx.strokeStyle = "#000000"; //color of the border 
    ctx.stroke();
}
function random_color() {
    var letter = "0123456789ABCDEF".split(""); //exadecimal value for the colors
    var color = "#"; //all the exadecimal colors starts with #
    for (var i = 0; i < 6; i++) {
        color = color + letter[Math.round(Math.random() * 15)];
    }
    return color;
}
function selectDirection(fromx, fromy, tox, toy) {
    ctx.beginPath();
    ctx.moveTo(fromx, fromy);
    ctx.lineTo(tox, toy);
    ctx.moveTo(tox, toy);

}

//per velocità invariata rimuovere bounciness
function draw_ball() {
    this.vy = this.vy + gravity * 0.1; // v = a * t
    this.x = this.x + this.vx * 0.1; // s = v * t
    this.y = this.y + this.vy * 0.1;

    if (this.x + this.r > canvas.width) {
        this.x = canvas.width - this.r;
        this.vx = this.vx * -1 * this.b;
    }
    if (this.x - this.r < 0) {
        this.x = this.r;
        this.vx = this.vx * -1 * this.b;
    }
    if (this.y + this.r > canvas.height) {
        this.y = canvas.height - this.r;
        this.vy = this.vy * -1 * this.b;
    }
    if (this.y - this.r < 0) {
        this.y = this.r;
        this.vy = this.vy * 1 * this.b;
    }

    circle(this.x, this.y, this.r, this.c);
}
// OBJECTS
function ball(positionX, positionY, velosityX, velosityY, radius, bounciness, color, gravity) {
    this.x = positionX;
    this.y = positionY;
    this.vx = velosityX;
    this.vy = velosityY;
    this.r = radius;
    this.b = bounciness;
    this.c = color;
    this.g = gravity;
    this.draw = draw_ball;

}

// GAME LOOP
function game_loop() {

    ctx.clearRect(0, 0, canvas.width, canvas.height);

    if (mouseDown == true) {
        selectDirection(mousePos['downX'], mousePos['downY'], mousePos['currentX'], mousePos['currentY']);
    }
    for (var i = 0; i < balls.length; i++) {

        balls[i].draw();
    }

    ctx.fillStyle = "#000000";
    ctx.font = "20px Arial";
    ctx.fillText("Balls Counter: " + balls.length, 10, canvas.height - 10);
}

setInterval(game_loop, 10);
* { 
    margin: 0px; padding: 0px;
 }
html, body { 
    width: 100%; height: 100%;

 }
#canvas { 
    display: block;
    height: 95%;
    border: 2px solid black;
    width: 98%;
    margin-left: 1%;
   
 }


#btn-speed-up, #btn-speed-down, #btn-bounciness, #btn-gravity{
    padding: 0.4%;
    background-color: beige;
    text-align: center;
    font-size: 20px;
    font-weight: 700;
    float: right;
    margin-right: 1%;
    margin-top:0.5%;

} 
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Power Balls</title>
<link rel="stylesheet" type="text/css" href="css/style.css">

</head>

<body>
   
    <canvas id="canvas"></canvas>
  
    <input type="button" value="⤼ Bounciness" id="btn-bounciness"></input> 
    <input type="button" onclick="c+=10" value="+ Speed" id="btn-speed-up"></input> 

    <input type="button" value="◾" id="btn-gravity"></input> 
    <input type="button" onclick="c+= -10" value=" - Speed" id="btn-speed-down"></input> 
   
    
<script src="js/main.js"></script>
</body>

</html>

标签: javascript

解决方案


我看到两个问题:

  • ball.onclick不会被触发,因为ball它不是 DOM 对象。相反,您需要使用canvas.onclick. 检查用户是否点击了球或空白区域,以决定是删除还是创建球。
  • 删除球,ctx.clearRect是不够的。这将从当前绘制的帧中清除球,但对象仍保留在数组中balls,因此将在下一帧中再次通过 绘制balls[i].draw();。相反,您需要从数组中完全移除点击的球,例如使用splice.

否则,很好的演示!:)


推荐阅读