Ben een beetje aan het experimenteren met het <canvas> element in HTML5 om een spelletje te maken. Op zich werkt het allemaal best aardig maar een ding lukt me niet goed: het 'voorladen' (preloaden) van de afbeeldingen. Heb meerder stukjes code daarvoor gezien (en al heel wat gegoogled) maar op de een of andere manier heeft het geen resultaat. Daarom bij deze de code en wat uitleg. Iemand een idee hoe dit welk fatsoenlijk werkend te krijgen? Wat er nu gebeurt is dat er bij de eerste keer laden sommige plaatjes niet worden getekend en pas bij een refresh (F5) alles goed is.
Voorzover ik het heb begrepen hebben HTMLImage-elementen een event onload() dat wordt aangeroepen wanneer de afbeelding geladen is. In mijn script moeten drie afbeeldingen geladen worden. Als het goed is zou na elke geladen afbeelding de functie loaded moeten worden aangeroepem waar een tellertje wordt verhoogd. Als er voldoende afbeeldingen geladen zijn wordt een callback functie aangroepen en kan het programma verder gaan met het gebruiken van de afbeeldingen.
Om te testen of de functies worden aangroepen heb ik een alert geplaatst en in FireFox komen er zoals verwacht drie berichten in beeld. Ook de callback functie wordt bereikt want dat is de enige manier om resetLevel() te bereiken en die functie wordt uitgevoerd.
De functie van tileObj() is om de geladen afbeelding op een eigen canvas te plaatsen zodat die kleine canvas dan weer op de grote kan worden getekend. Het voordeel daarvan is dat er niet steeds opnieuw verkleind hoeft te worden (de plaatjes zijn groter dan de tiles).
--knip--
mapTiles = new Array();
function tileObj(img){
this.canvas = document.createElement("canvas");
this.ctx = this.canvas.getContext("2d");
this.ctx.drawImage(img,0,0,32,32);
}
function tileLoader(srcArray,callback){
this.numLoaded = 0;
this.sources = srcArray;
this.loaded = function(img){
this.numLoaded ++;
mapTiles.push(new tileObj(img));
alert("Loaded " + this.numLoaded + " image(s).");
if(this.numLoaded == this.sources.length){
callback();
}
}
this.startLoading = function(){
for(i in this.sources){
img = new Image();
img.src = this.sources[i];
img.onload = this.loaded(img);
}
}
}
function loadPlayerTiles(){
playerTileSet = new Image();
playerTileSet.src = "charset_knight1_trans.png";
playerTileSet.onload = function(){
context.drawImage(playerTileSet,0,0);
resetLevel();
}
}
window.onload = function(){
canvas = document.getElementById("myDrawing");
context = canvas.getContext("2d");
thisTileLoader = new tileLoader(new Array("floor_small.png","wall_small.jpg","crate_small.jpg"),loadPlayerTiles);
thisTileLoader.startLoading();
}
--knip--