Ich tue ein kleines HTML5-Spiel und während des Ladens meiner Sprites am Anfang der Karte, tue ich einige Verarbeitung mit GetImageData() / Schleife über alle das Bild / PutImageData().
Auf meinem PC funktioniert das fantastisch, aber auf meinen Handys ist es furchtbar langsam.
PC: 5-6 ms
iPhone 4: 300-600 ms
Android HTC Desire S: 2500-3000 ms
Ich habe einige SEHR grundlegende Benchmarking, und beide GetImageData und PutImageData laufen sehr schnell, was lange dauert, ist die Schleife durch den Inhalt.
Nun, ich natürlich erwarten eine Verlangsamung auf dem Telefon, aber 1000x klingt ein bisschen übertrieben, und das Laden dauert etwa 4 Minuten auf meinem HTC, so dass das nicht funktionieren wird. Auch alles andere im Spiel funktioniert mit sehr angemessener Geschwindigkeit (vor allem, weil der Bildschirm lächerlich kleiner ist, aber immer noch, es funktioniert überraschend gut für JS auf einem Handy)
Was ich in dieser Verarbeitung tue, ist im Grunde "Verdunkelung" das Sprite zu einem bestimmten Grad. Ich einfach Schleife durch alle Pixel, und multiplizieren sie mit einem Wert < 1. Das ist alles.
Da dies zu langsam ist... Gibt es einen besseren Weg, dasselbe zu tun, mit der Canvas-Funktionalität, (Compositing, Deckkraft, was auch immer), ohne Schleife durch alle Pixel einer nach dem anderen?
HINWEIS: Diese Ebene hat einige 100% transparente Pixel und einige 100% undurchsichtige Pixel. Beide müssen entweder 100 % undurchsichtig oder 100 % transparent bleiben.
Ich habe mir Dinge ausgedacht, die nicht funktionieren würden:
1) Malen der Sprites in einer neuen Leinwand, mit geringerer Deckkraft. Dies wird nicht funktionieren, weil ich die Sprites zu bleiben undurchsichtig, nur dunkler brauchen.
2) Malen der Sprites und ein halbtransparentes schwarzes Rechteck über sie malen. Dies wird sie dunkler machen, aber es wird auch meine transparenten Pixel nicht mehr transparent machen...
Irgendwelche Ideen?
Dies ist der Code, den ich verwende, nur für den Fall, dass Sie darin etwas furchtbar Idiotisches sehen:
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 : Dies ist ein Beispiel für das, was ich mit dem Bild zu tun versuche:
Original: http://www.crystalgears.com/isoengine/sprites-ground.png
Verdunkelt: http://www.crystalgears.com/isoengine/sprites-ground_darkened.png
Danke!
Daniel