почему моя анимация с html5 canvas такая мерцающая?

1

Я хочу сохранить анимацию так, как есть, моя проблема связана с мерцанием анимации.

если по какой-то причине мой вопрос нуждается в более подробных подробностях, пожалуйста, позвольте мне сейчас, и я объясню более подробно.

var text = 'got it';
    document.getElementById('mycanvas').style.backgroundColor = 'lightgray';
    var ctx = document.getElementById('mycanvas');
    var c = ctx.getContext('2d');

    function ball(x, y, zx, zy, rotation,goldx,goldy) {
    this.x = x;
    this.y = y;

    this.zx = zx;
    this.zy = zy;
    this.rotation = rotation;
    this.goldx = goldx;
    this.goldy = goldy;
    this.draw = function() {


    c.beginPath();
    c.setTransform(1, 0, 0, 1, 0, 0);
       c.translate(0, 0.01);
        c.rotate(this.rotation);
    c.fillStyle = 'black';


    c.font="10px corsive";
    c.fillText("$100", this.x, this.y + 10);
    c.strokeStyle = "gray"

    c.rect(this.x, this.y, 24,14);
    c.fillStyle = 'rgba(0, 128, 0, 0.49)';
    c.fill();
    c.stroke();
    c.closePath();

    }

    var X = Math.floor(Math.random() *10);
    this.draw1 = function() {
    c.beginPath();
    c.arc(this.goldx, this.goldy, 5, Math.PI*2,false);

    c.fillStyle = 'gold';
    c.fill();
    c.stroke();
    }

    this.update = function() {
    var b = Math.random() * 500;
    if(this.y  > 510 || this.x > 510 || this.x  < -30) {ballArray.splice(i,1)}

    this.x += this.zx;
    this.y += this.zy;



    if(ballArray.length < 99) {ballArray.push(new ball(this.x,20,this.zx,this.zy, this.rotation))}

    if(x > 350) { this.rotation += 0.00009} else {this.rotation -= 0.00009};
    this.draw();

    if(this.goldy  > 510 || this.goldx > 510 || this.goldx  < 0) {goldArray.splice(j,1)}
    if(goldArray.length < 49) {goldArray.push(new ball(0,0,0,0,0,goldx,goldy))}
    this.goldy += 1;
     

    this.draw1();
     }
     
    }
    var goldArray = [];

    for (j = 0; j < 50; j++){
    var goldx = Math.random() * 500;
    var goldy = Math.random() * 500;
    goldArray.push(new ball(0,0,0,0,0,goldx,goldy));
    }
    var ballArray = [];

    for(i= 0; i < 100; i++) {
    var x = Math.random() * 500;
    var y = Math.random() * 500;
    var zx = Math.random() - 0.5;
    var zy = 1;
    var rotation = 0;
    ballArray.push(new ball(y,x,zx,zy,rotation,goldx,goldy));
    }

    function animate() {
    requestAnimationFrame(animate);
    c.clearRect(0,0,500, 500);
     for(j = 0; j< goldArray.length; j++) {
     goldArray[j].update();
     }
    for(i = 0; i < ballArray.length; i++) {
    ballArray[i].update();

     }

    }

    animate();
<canvas id="mycanvas" width="500" height="500" style="border: 1px solid black"></canvas>
Теги:
animation
html5-canvas

2 ответа

0
Лучший ответ

Сплав массива вызывает пропуски объектов

Ваша анимация щелкает по множеству причин.

Основной из них - это то, как вы удаляете мяч или золото. Вы вызываете функцию update из цикла for.

for(i = 0; i < balls.length; i++){
    balls[i].update();
}

Затем в функции обновления вы проверяете, находится ли мяч вне пределов. Если вы удаляете его из массива

if(this.y > 510) { //  example not your code
     balls.splice(i,1);
}

Но вы игнорируете тот факт, что вы только что переместили все шары над этим в массив вниз по одному индексу. Когда функция обновления возвращает шар в i, была удалена, а следующая над ним теперь находится в точке i. Затем цикл увеличивает i и вы рисуете следующий мяч, пропуская мяч.

Пропущенный мяч не отображает эту рамку и, таким образом, вы получаете мерцание. То же самое с золотом.

Быстрая починка

Есть и другие проблемы (многие), и для исправления потребуется полная переписывание.

Вы можете просто сбросить мяч и золото, а не удалить его и создать другое.

Где у вас есть

if(this.y  > 510 || this.x > 510 || this.x  < -30) { ballArray.splice(i,1) }

измените его на

if(this.y  > 510 || this.x > 510 || this.x  < -30) {
     this.x = Math.random() * 500;
     this.y = Math.random() * 500;
     this.zx = Math.random() - 0.5;
     this.zy = 1;
     this.rotation = 0;         
}

и удалите строку

if(ballArray.length < 99) {ballArray.push(new ball(this.x,20,this.zx,this.zy, this.rotation))}

Сделайте то же самое для золота.

это подготовит вас к следующей проблеме.

Некоторые кодовые заметки.

У вас все еще будут проблемы, потому что у вас есть золото и мяч как один объект, представляющий как мяч, так и золото для каждого шара и то же самое для каждого золота.

Вам нужен шар и золото как отдельные предметы, так что золото не рисует мяч, а наоборот.

У тебя должно быть

 function Gold(){ 
     this.draw(){ // draw code
     this.update() { // update code
     ...
 }
 function Ball(){ /* code */
     this.draw(){ // draw code
     this.update() { // update code
     ...
 }

И создайте каждый

 ballArray.push(new Ball( stuff));
 goldArray.push(new Gold( stuff));

Также вам нужно объявить все переменные, которые вы не сделали для i, j которые, таким образом, попадают в глобальную область действия и скоро вернутся к вам.

Всякий раз, когда вы используете переменную, она ДОЛЖНА иметь в некотором месте внутри функции объявление.

например

 function animate(){
     var i;
     var j;
     ... rest of code.

Ох и еще...

но сейчас я оставлю его.

  • 0
    спасибо большое, отличная помощь blindman67
0

Я не уверен, что это помогает с холстом, но с анимацией css, если вы добавляете преобразование: translatez (0) в родительский контейнер, он позволяет объявление об ускорении аппаратного обеспечения может остановить мерцание сложных программ с использованием преобразования или матрицы

  • 0
    Это старый хак, который, я сомневаюсь, применим даже больше, но, кроме того, содержание холста отображается независимо и всегда аппаратно ускоряется (если доступно и флажки установлены правильно)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню