2016-02-22 4 views
1

Я создаю небольшую игру html5 с холстом.HTML5: getImageData с onmousemove замедляет мое приложение в Firefox

В холсте есть много отображаемых спрайтов, и один из них автоматически перемещается слева направо. Остальные - статика.

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

Но getImageData делает медленным аномально движущийся спрайт в Firefox.

Так каково решение, чтобы избежать этого замедления?

Вот мой код:

function getSelectedObject(array_objects) 
{ 
    //Clear the temporary canvas : 
    tmpcx.clearRect(0, 0, tmpc.width, tmpc.height); 

    /*Search the right sprite object :*/ 
    for(var i = array_objects.length-1; i >= 0; i--) 
    { 
     array_objects[i].draw(tmpcx); 

     imageData = tmpcx.getImageData(mouse_x, mouse_y, 1, 1); 

     component = imageData.data; 

     if(component[3] > 0) 
     { 
      //Return the sprite object found : 
      return array_objects[i]; 
     } 

     else 
     { 
      tmpcx.clearRect(0, 0, tmpc.width, tmpc.height); 
     } 
    } 

    return false; 
} 


canvas.onmousemove = function(event) 
{ 

selectedObject = getSelectedObject(array_objects); 

} 
+0

Так каково решение, чтобы избежать этого замедления? – totoaussi

+0

Непонятно, что вы пытаетесь * выполнить * здесь. Вам нужен движущийся спрайт на холсте, который отслеживает положение мыши? –

+0

Перемещение спрайта - это просто проверить эффективность приложения: если движущийся спрайт замедляется, это означает, что приложение имеет плохую производительность. Обычно движущийся спрайт не должен замедляться. – totoaussi

ответ

2

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

Я ссылаюсь на функцию под названием checkBoundingBoxisOver - не уверен, что вы могли бы написать эту функцию, но я не могу сейчас - кроме того, я даже не знаю, что такое ваши array_objects !!!

Я думаю, что это было просто, нужно х, у, ширина, высота спрайта сделать предварительную проверку, если спрайт может даже, возможно, под мышкой, прежде чем делать дорогой рисовать

function getSelectedObject(array_objects) { 
    //Clear the temporary canvas : 
    tmpcx.clearRect(0, 0, tmpc.width, tmpc.height); 
    var sprite; 
    /*Search the right sprite object :*/ 
    for (var i = array_objects.length - 1; i >= 0; i--) { 

     sprite = array_objects[i]; 

     if (checkBoundingBoxisOver(sprite, mouse_x, mouse_y)) { 

      sprite.draw(tmpcx); 
      imageData = tmpcx.getImageData(mouse_x, mouse_y, 1, 1); 
      component = imageData.data; 
      if (component[3] > 0) { 
       return sprite; 
      } 
     } 
    } 
    return false; 
} 
+0

Большое спасибо, я попробую! Проверяя, прежде всего, если рамка ограничения закончилась, прежде чем проверять пиксель альфа - отличная идея! – totoaussi

+0

Спасибо, он работает лучше. – totoaussi

2

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

getImageData чрезвычайно медленна для Firefox даже при чтении всего одного пикселя.

Мое решение назвать getImageData только один раз и сохранить результат в переменной ImageData

var imageData = self.context.getImageData(0,0,image.width, image.height); 

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

var pixelRed = this.imageData.data[(y* imageWidth * 4) + (x * 4)] == 0; 

х и у самообъясняющие и так как пиксели 4 значения байтов (красный, зеленый, синий, альфа) Мне нужно умножьте индекс массива на 4. Для меня это очень быстро.

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

Смежные вопросы