Estoy haciendo un pequeño juego HTML5 y, al cargar mis sprites al comienzo del mapa, hago un poco de procesamiento con GetImageData()/bucle sobre toda la imagen/PutImageData().Canvas horrible GetImageData()/PutImageData() el rendimiento en el móvil
Esto funciona fantásticamente genial en mi PC, sin embargo, en mis teléfonos celulares es tremendamente lento.
PC: 5-6 ms
iPhone 4: 300-600 ms
Android HTC Desire S: 2500-3000 ms
que he estado haciendo alguna evaluación comparativa muy básico, y ambos getImageData y PutImageData correr muy rápido, lo que está teniendo mucho es el bucle a través de los contenidos.
Ahora, I obviamente espero una desaceleración en el teléfono, pero 1000x suena un poco excesivo, y la carga tarda aproximadamente 4 minutos en mi HTC, por lo que no va a funcionar. Además, todo lo demás en el juego funciona a velocidad muy razonable (sobre todo porque la pantalla es ridículamente pequeña, pero aún así, funciona sorprendentemente bien para JS en un teléfono celular)
Lo que estoy haciendo en este procesamiento básicamente está "oscureciendo" el sprite a un cierto nivel. Simplemente recorro todos los píxeles y los multiplico por un valor < 1. Eso es todo.
Dado que esto es demasiado lento ... ¿Hay una forma mejor de hacer lo mismo, utilizando la funcionalidad Canvas (composición, opacidad, lo que sea), sin recorrer todos los píxeles uno por uno?
NOTA: Esta capa tiene unos 100% de píxeles transparentes y unos 100% de píxeles opacos. Ambos necesitan permanecer 100% opacos o 100% transparentes.
Cosas que he pensado que no funcionarían:
1) Pintando los sprites en un nuevo lienzo, con menor opacidad. Esto no funcionará porque necesito que los sprites permanezcan opacos, solo que más oscuros.
2) Pintar los sprites y pintar un rect negro semitransparente encima de ellos. Esto los hará más oscuros, pero también hará que mis píxeles transparentes ya no sean transparentes ...
¿Alguna idea?
Este es el código que estoy usando, por si acaso ves algo terriblemente estúpida en ella:
function DarkenCanvas(baseImage, ratio) {
var tmpCanvas = document.createElement("canvas");
tmpCanvas.width = baseImage.width;
tmpCanvas.height = baseImage.height;
var ctx = tmpCanvas.getContext("2d");
ctx.drawImage(baseImage, 0, 0);
var pixelData = ctx.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height);
var length = pixelData.data.length;
for (var i = 0; i < length; i+= 4) {
pixelData.data[i] = pixelData.data[i] * ratio;
pixelData.data[i + 1] = pixelData.data[i + 1] * ratio;
pixelData.data[i + 2] = pixelData.data[i + 2] * ratio;
}
ctx.putImageData(pixelData, 0, 0);
return tmpCanvas
}
EDIT: Este es un ejemplo de lo que estoy tratando de hacer con la imagen :
original: http://www.crystalgears.com/isoengine/sprites-ground.png
oscurecido: http://www.crystalgears.com/isoengine/sprites-ground_darkened.png
Gracias!
Daniel
¿por favor muéstranos las fotos del antes y después del efecto que intentas lograr? –
Acabo de agregar enlaces en la parte inferior de la pregunta. ¡Gracias! –
¿Estás tratando de oscurecer algunos sprites? Por amor de Dios, no use datos de imagen por píxel para eso. Simplemente dibuje sobre negro semitransparente (con un [[globalCompositeOperation'] diferente (http://www.tutorialspoint.com/html5/canvas_composition.htm) para preservar el alfa). – Phrogz