I’m trying to draw a grid with random images assigned to each square. I’m having trouble with the draw sequence and potentially closure issues with the Javascript variables. Any help is appreciated.
var tileSize = 30;
var drawCanvasImage = function(ctx,tile,x,y) {
return function() {
ctx.drawImage(tile,x,y);
console.log("x = " + x + "/ y = " + y);
}
}
function textures(ctx) {
var grass = new Image();
var sea = new Image();
var woods = new Image();
for (var i=0; i<=10; i++) {
for (var j=0; j<=20; j++) {
rand = Math.floor(Math.random()*3 + 1);
x = i * tileSize;
y = j * tileSize;
if (rand == 1) {
grass.onload = drawCanvasImage(ctx,grass,x,y);
} else if (rand == 2) {
sea.onload = drawCanvasImage(ctx,sea,x,y);
} else {
woods.onload = drawCanvasImage(ctx,woods,x,y);
}
}
}
grass.src = "textures/grass.png";
sea.src = "textures/sea.png";
woods.src = "textures/woods.png";
}
//function called by the onload event in the html body tag
function draw() {
var ctx = document.getElementById("grid").getContext('2d');
grid(ctx); //a function to draw the background grid - works fine
textures(ctx);
}
The current result is three drawn tiles, all at the position of x = 300 (equivalent to the i loop of 10 * the tileSize of 30) and a random y position.
After following a lead and accounting for (maybe?) closure issues by creating the variable drawCanvasImage, I at least got those three tiles to draw.
—-Edit—-
Working Code – Revision 2:
function randomArray() {
for (var i=0; i<=(xValue/tileSize); i++) {
terrainArray[i] = [];
for (var j=0; j<=(yValue/tileSize); j++) {
rand = Math.floor(Math.random()*4 + 1);
if (rand == 1) {
terrainArray[i][j] = 3;
} else if (rand == 2) {
terrainArray[i][j] = 2;
} else if (rand == 3) {
terrainArray[i][j] = 1;
} else {
terrainArray[i][j] = 0;
}
}
}
}
var drawTerrain = function(ctx,tile,landUseValue) {
return function() {
for (var i=0; i<=(xValue/tileSize); i++) {
for (var j=0; j<=(yValue/tileSize); j++) {
if (terrainArray[i][j] == landUseValue) {
ctx.drawImage(tile,i*tileSize,j*tileSize);
}
}
}
}
}
function textures(ctx) {
var grass = new Image();
var sea = new Image();
var woods = new Image();
var desert = new Image();
grass.onload = drawTerrain(ctx,grass,3);
sea.onload = drawTerrain(ctx,sea,0);
woods.onload = drawTerrain(ctx,woods,2);
desert.onload = drawTerrain(ctx,desert,1);
grass.src = "textures/grass.png";
sea.src = "textures/sea.png";
woods.src = "textures/woods.png";
desert.src = "textures/desert.png";
}
You’re rewriting the
onloads of the three images in every iteratiom. So, it will only execute the last-addedonloadf or every image.Suggestion: run your drawing method only after the thred are loaded(and them just call
drawCanvasImageevery iteration without an.onload=)Even better:store the randoms in an array, have each image independantly walk through the array on load and add copies of only itself wherever applicable .
Improvement to rev 2
To make it even more flexible, you could use an array to store the images, and then use
length. This way, if you want to add another image, all you have to do is modify the array.So now, all you have to do is call
terrain(ctx)when you want to load all the images. And, whenever you want to add an image to the list of images, just add it to the array up top. You won’t have to dig deeper and modify the random values and whatnot.