Multiple textures

Mar 26, 2013 at 11:23 AM
Hi, I'm very glad I found this engine. It is really nice and simple to use.
I want to use it for a browsergame my own, and I'm testing all aspects of the engine.
I tried to apply more sheets, each one qith a different texture, but something goes wrong and I didn't succeed. Can you see my code and point me to the error?
      // define a sheet with texture loaded from external image
      var sheet = new sheetengine.Sheet({x:0,y:40,z:40}, {alphaD:0,betaD:0,gammaD:0}, {w:80,h:80});
      var img = new Image();
      img.onload = function() {
        sheet.context.drawImage(img, 0,0); }

      // define a sheet with texture loaded from external image
      var sheet2 = new sheetengine.Sheet({x:40,y:0,z:40}, {alphaD:0,betaD:0,gammaD:90}, {w:80,h:80});
      var img2 = new Image();
      img2.onload = function() {
        sheet2.context.drawImage(img2, 0,0); }

      // define a sheet with texture loaded from external image
      var sheet3 = new sheetengine.Sheet({x:0,y:0,z:80}, {alphaD:90,betaD:0,gammaD:0}, {w:80,h:80});
      var img3 = new Image();
      img3.onload = function() {
        sheet3.context.drawImage(img3, 0,0); }

        // draw the scene
        sheetengine.calc.calculateChangedSheets();
        sheetengine.drawing.drawScene(true);
      };
      img.src = 'images/stonewall.png';
      img2.src = 'images/stonewall.png';
      img3.src = 'images/wood.png';
I did this test modifyng the texture test official page (as you can see from the first block).
Coordinator
Mar 26, 2013 at 2:33 PM
I suspect there is a syntax error in your code: I cannot see the opening block that is closed after calling the drawScene function.
Also, calling the calculateChangedSheets and drawScene must come after all the images have been loaded. Since images are loaded asynchronously, you will have to count the images somehow. Something like the following should do it:
var imageCount = 0;
function imageLoaded() {
  imageCount++;
  if (imageCount == 3) {
    // draw the scene
    sheetengine.calc.calculateChangedSheets();
    sheetengine.drawing.drawScene(true);
  }
}

img.onload = imageLoaded;
img2.onload = imageLoaded;
img3.onload = imageLoaded;

img.src = 'images/stonewall.png';
img2.src = 'images/stonewall.png';
img3.src = 'images/wood.png';
I wrote it from scratch, so it might be buggy, but I think you get the point.
Mar 26, 2013 at 3:13 PM
Thank you for the fast answer.

The code you wrote does not give errors, but the three sheets are not displayed.

I tried again from the example you made. One single sheet is displayed, two sheets, with different image, give no errors, but only the first one is displayed. Why?
      var canvasElement = document.getElementById('maincanvas');
      sheetengine.scene.init(canvasElement, {w:900,h:500});

      // define some basesheets
      for (var x=-1; x<=1; x++) {
        for (var y=-1; y<=1; y++) {
          var basesheet = new sheetengine.BaseSheet({x:x*200,y:y*200,z:0}, {alphaD:90,betaD:0,gammaD:0}, {w:200,h:200});
          basesheet.color = '#5D7E36';
        }
      }

      // define a sheet with texture loaded from external image
      var sheet = new sheetengine.Sheet({x:0,y:0,z:40}, {alphaD:0,betaD:0,gammaD:0}, {w:80,h:80});
      var img = new Image();
      img.onload = function() {
        sheet.context.drawImage(img, 0,0);
        
        // draw the scene
        sheetengine.calc.calculateChangedSheets();
        sheetengine.drawing.drawScene(true);
      };
      img.src = 'images/stonewall.png';
      
      // define a sheet with texture loaded from external image
      var sheet2 = new sheetengine.Sheet({x:40,y:40,z:40}, {alphaD:0,betaD:0,gammaD:90}, {w:80,h:80});
      var img2 = new Image();
      img2.onload = function() {
        sheet2.context.drawImage(img2, 0,0);
        
        // draw the scene
        sheetengine.calc.calculateChangedSheets();
        sheetengine.drawing.drawScene(true);
      };
      img2.src = 'images/wood.png';
Mar 26, 2013 at 3:19 PM
What I'm trying to achieve is to be able to represent a building with texturized sheets.
I can have different sheets, but with the same texture loaded. And in the single scene there would be a lot of sheets with different textures.
Coordinator
Mar 26, 2013 at 4:20 PM
There are two problems with your approach: firstly it draws the scene every time a new sheet is loaded which is unnecessary and very resource consuming. Secondly, once the sheets have been calculated and drawn you have to explicitely indicate if you have made changes to the canvas, by calling the canvasChanged() function of the sheet (in your example drawing on one of the sheets will always be called after the calculateChangedSheets and drawScene functions, so it is a problem here).
Instead, I would suggest to load all the images, and call these functions only once, only after all the images have been loaded. Here is a short code that demonstrates this (it is not particularly nice, my point is to demonstrate the idea):
      var canvasElement = document.getElementById('maincanvas');
      sheetengine.scene.init(canvasElement, {w:900,h:500});

      // define some basesheets
      for (var x=-1; x<=1; x++) {
        for (var y=-1; y<=1; y++) {
          var basesheet = new sheetengine.BaseSheet({x:x*200,y:y*200,z:0}, {alphaD:90,betaD:0,gammaD:0}, {w:200,h:200});
          basesheet.color = '#5D7E36';
        }
      }

      var imageCount = 0;
      var onLoaded = function(img, sheet) {
        sheet.context.drawImage(img, 0,0);
        imageCount++;
        if (imageCount == 3) {
          sheetengine.calc.calculateChangedSheets();
          sheetengine.drawing.drawScene(true);
        }
      }
    
      var sheet = new sheetengine.Sheet({x:0,y:0,z:40}, {alphaD:0,betaD:0,gammaD:0}, {w:80,h:80});
      var img = new Image();
      img.onload = function() { onLoaded(img, sheet); };
      img.src = 'images/myimage.png';

      var sheet2 = new sheetengine.Sheet({x:80,y:0,z:40}, {alphaD:0,betaD:0,gammaD:0}, {w:80,h:80});
      var img2 = new Image();
      img2.onload = function() { onLoaded(img2, sheet2); };
      img2.src = 'images/myimage2.png';

      var sheet3 = new sheetengine.Sheet({x:160,y:0,z:40}, {alphaD:0,betaD:0,gammaD:0}, {w:80,h:80});
      var img3 = new Image();
      img3.onload = function() { onLoaded(img3, sheet3); };
      img3.src = 'images/myimage3.png';
Mar 27, 2013 at 7:46 AM
Perfect! Thank you very much.
Your code worked very fine, here is my test block:
Image
Three sheets, two textures, one wall block.

I think Sheetengine will be my engine of choice.
Mar 27, 2013 at 3:25 PM
Edited Mar 27, 2013 at 3:52 PM
Sorry to bother you, but I have one more question.
In the example above, there are two images: wall.png and roof.png.
There are also three sheets, the two walls and the roof.
With the code you wrote, I define two different image objects, and load twice the same image file, wall.png.

I tried to use a previous loaded image on a new sheet, but it doesn't work. It is right?

Image
In the example above I tried to use the same image on two sheets but it doesn't work.
Coordinator
Mar 27, 2013 at 4:16 PM
You will need to restructure the code then. Simply pre-load all your images, and when everything is set, start creating sheets and drawing the scene.

Something like this (here I have 3 sheets and 2 images):
      var imageCount = 0;
      var onLoaded = function() {
        imageCount++;
        if (imageCount == 2)
          imagesReady();
      }

      var imagesReady = function() {
        var sheet = new sheetengine.Sheet({x:0,y:0,z:40}, {alphaD:0,betaD:0,gammaD:0}, {w:80,h:80});
        sheet.context.drawImage(img, 0,0);
        var sheet2 = new sheetengine.Sheet({x:80,y:0,z:40}, {alphaD:0,betaD:0,gammaD:0}, {w:80,h:80});
        sheet2.context.drawImage(img2, 0,0);
        var sheet3 = new sheetengine.Sheet({x:160,y:0,z:40}, {alphaD:0,betaD:0,gammaD:0}, {w:80,h:80});
        sheet3.context.drawImage(img2, 0,0);

        sheetengine.calc.calculateChangedSheets();
        sheetengine.drawing.drawScene(true);
      }
    
      var img = new Image();
      img.onload = onLoaded;
      img.src = 'images/myimage.png';

      var img2 = new Image();
      img2.onload = onLoaded;
      img2.src = 'images/myimage2.png';
So load all your images, and when everything is loaded call a function that defines all the sheets, calculates them, and draws the scene. I haven't tested the above, but it should be clear nevertheless.
Mar 28, 2013 at 6:49 AM
Thank you again.
I already thought about a similar solution. I'll try soon to envelope all this notions in a solution to show you.
Mar 29, 2013 at 1:03 PM
I wanted to thank you again about the support.
Here below a first test on isometric 3D map (16x16 blocks).
Image
Coordinator
Apr 2, 2013 at 5:52 PM
I don't see the image :( Could you upload it once more, I'm very curious :)
Apr 2, 2013 at 7:28 PM
Edited Apr 3, 2013 at 6:09 AM
Sorry, I upload it again:
Image

And mixing a little the heights and tiles:
Image

I used a different kind of premade textures, only to check ...
Dec 14, 2013 at 11:30 PM
Really fantastic spasquini did you do this block by block or did you build some kind of level building tool to do this?