Холст: не все объекты в массиве объектов прыгающего шара обнаруживаются

Я создал приложение spa/rest/crud, используя laravel 5.5, vuejs и vue-router. Теперь пришла в голову идея использовать компонент для целевой страницы и немного оживить его с помощью canvas. (Первоначально p5.js, но я отказался от этого на данный момент.) Пока все хорошо. Я получил компоненты Vue, работающие через Vue-Router, и для первой страницы я создал компонент с пользовательской директивой, которая передает элемент canvas в шаблоне его данные (в форме объекта ball)

Теперь, так как мне пришлось переключиться на Canvas, с которым я не очень знаком, я столкнулся с проблемой. В качестве теста я положил 4 шарика в массив. Но только 1 показывает. Теперь, когда я отключаю функцию clearRect. Они появляются беспорядочно. Мне пришлось использовать beginPath(), по-видимому, чтобы шарики не "тянулись". Но когда я делаю это, появляется только один. Может быть, это простая вещь, которую я пропускаю. Я опубликую часть, которая, как мне кажется, вызывает проблему ниже:

<script>            
export default {
    data: function(){
        return {

        }
    },
    directives: {
      bindCanvas: {

        inserted: function (el) {
            var ctx = el.getContext("2d");
            var Ball = function(x,y,r){
                this.position = {};
                this.position.x = x;
                this.position.y = y;
                //i could not use vectors so i came up with this solution
                this.velocity = {x:0,y:0};
                this.acceleration = {x:0,y:0};                  
                this.radius = r;
            };
            Ball.prototype.addForce = function(x,y){

                this.acceleration.x += x/1000;
                this.acceleration.y += y/1000;

            };
            Ball.prototype.move = function(){                   

                this.position.x += this.velocity.x;
                this.position.y += this.velocity.y;
                this.velocity.x += this.acceleration.x;
                this.velocity.y += this.acceleration.y;

                //reset acceleration to 0
                this.acceleration.x *= 0;
                this.acceleration.y *= 0;
            };
            Ball.prototype.display = function(){
                //here is the problem somewhere i think.
                ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
                ctx.beginPath();
                ctx.fillStyle = 'rgb(255,0,0)';
                ctx.arc(this.position.x,this.position.y,this.radius,0, Math.PI*2);
                ctx.fill();
            };

            Ball.prototype.checkBorders = function(){
                if(this.position.x > ctx.canvas.width-(this.radius/2)){
                    this.velocity.x = this.velocity.x *-1;
                } else if (this.position.x < 0){
                    this.velocity.x *= -1;
                }
                if (this.position.y > ctx.canvas.height-(this.radius/2)){
                    this.velocity.y *= -1;
                } else if(this.position.y < 0){
                    this.velocity.y *= -1;
                }
            };

            Ball.prototype.checkMaxSpeed = function(){
                if(this.velocity.x > 0.5){
                    this.velocity.x = 0.5;
                }
                if(this.velocity.x < -0.5){
                    this.velocity.x = -0.5;
                }
                if(this.velocity.y > 0.5){
                    this.velocity.y = 0.5;
                }
                if(this.velocity.y < -0.5){
                    this.velocity.y = -0.5;
                }
            };

            var arrayOfBalls = [];

            for(var i=0;i<=3;i++){
                arrayOfBalls.push(new Ball(Math.random()*100,Math.random()*100,Math.random()*100));
            }


            var animate = function(){


                for(var j = arrayOfBalls.length-1; j>= 0; j--){
                arrayOfBalls[j].checkBorders();
                arrayOfBalls[j].checkMaxSpeed();
                arrayOfBalls[j].addForce(Math.random(),Math.random());
                arrayOfBalls[j].addForce(0,0.00098);

                arrayOfBalls[j].display();
                arrayOfBalls[j].move();
                }
                window.requestAnimationFrame(animate);

            };
            animate();
        }
      }
    },


}

1 ответ

Решение

Как упоминалось в моем комментарии, проблема заключается в вызове clearRect() в функции display() для каждого шара. Обычно холст необходимо очищать только один раз в каждом кадре / цикле анимации, поэтому clearRect можно поместить в верхнюю часть функции анимации, как показано здесь...

var animate = function(){

    // Clear the canvas just once each animation frame here
    ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);

    for(var j = arrayOfBalls.length-1; j>= 0; j--) {
        arrayOfBalls[j].checkBorders();
        arrayOfBalls[j].checkMaxSpeed();
        arrayOfBalls[j].addForce(Math.random(),Math.random());
        arrayOfBalls[j].addForce(0,0.00098);

        arrayOfBalls[j].display();
        arrayOfBalls[j].move();
    }
    window.requestAnimationFrame(animate);
};
Другие вопросы по тегам