EaselJS isometric map, problem in code, can identify

10
window.onload = function() {

var stage = new createjs.Stage("canvas");
var bmp;
var board;
var img;
var data;
var tileClone;
var x,y;
var mapWidth;
var mapHeight;

 img = new createjs.SpriteSheet({
    "images": ["images/tiles.png"],
    "frames": {
        "height": 48,
        "width": 48,
        "regX": 0,
        "regY": 0
    }
});

/*data = [
    [1,5,5,2],
    [8,0,0,6],
    [8,0,9,6],
    [4,7,7,3]
];*/

data = [
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 0, 1, 1, 1, 1, 1, 0],
    [0, 1, 0, 1, 1, 1, 1, 0],
    [0, 1, 1, 1, 1, 0, 1, 0],
    [0, 1, 1, 1, 1, 1, 1, 0],
    [0, 0, 0, 0, 0, 0, 0, 0]
];

board = new createjs.Container();
board.x = 0;
board.y = 0;
stage.addChild(board);

bmp = new createjs.Sprite(img);
for (i = 0; i < 2; i++) {
    for (j = 0; j < 2; j++) {
        tileClone = bmp.clone();
        tileClone.gotoAndStop(data[i][j]);
        tileClone.x  = (j-i);
        tileClone.y = (i+j); 
        tileClone.regX=65; 
        tileClone.regY = 32.5;
        board.addChild(tileClone);
    }
}
alert("sadas");  
stage.update();
};

Can you identify? nothing is drawn on the web

    
asked by anonymous 01.05.2014 / 22:06

1 answer

20

The main problem with your code is that your loops ( for commands) are not processing all map items, since you've limited them to 2 . In addition, positioning in x and y does not take into account the dimensions of each tile.

These corrected issues would look like this (note that I removed the change from the registration point - properties regX and regY - because they also affect this placement, as you were informed in a comment):

for (i = 0; i < data.length; i++) {
    for (j = 0; j < data[i].length; j++) {
        tileClone = bmp.clone();
        tileClone.gotoAndStop(data[i][j]);
        tileClone.x = j * tileClone.getBounds().width;
        tileClone.y = i * tileClone.getBounds().height;
        board.addChild(tileClone);
    }
}

You did not provide the image with your tilesheet, but in the title of your question you mention that it is a map in isometric projection , so your map should be something like this ( Clint Bellanger's Grass and Water

ThepreviouscodesimplypositionsthebricksintheCartesianplane,sotheresultwillnotbeisometric:

Note: this output is produced with the following data (just to get cooler), created using the Tiled Map Editor tool. a>.

data = [
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 4, 12, 12, 5, 0, 0, 0],
    [0, 15, 22, 22, 9, 0, 0, 0],
    [0, 7, 11, 22, 22, 12, 5, 0],
    [0, 0, 19, 14, 14, 14, 6, 0],
    [0, 0, 0, 0, 0, 0, 0, 0]
];

To really position the bricks to take advantage of the isometric map, you need to do a conversion from Cartesian coordinates to isometric coordinates. The principle of isometry simulation in a "normal" brick basically consists of rotating it 45 degrees and then flattening it vertically in order to decrease its height in half. The following image, reproduced this great tutorial on subject , illustrates how this works (in fact, having normal two-dimensional brick images is easy enough to build isometric maps in Photoshop or Gimp; #!)

HavingitstileCloneobjectalreadyproperlypositionedintheCartesiancoordinates,theconversiontoisometriccoordinatescanbeperformedbymeansofafunctionasfollows(seethetutorialIcitedabovefordetails):

function placeIsoTile(tileClone) { var isoX = tileClone.x - tileClone.y; var isoY = (tileClone.x + tileClone.y) / 2; tileClone.x = isoX; tileClone.y = isoY; }

In the case of the map I used as an example, it is also necessary to consider the bricks as having half the original size to eliminate the spaces between them. So the loop from above was changed. The final code ( also available in JSFiddle ) looks like this (the size of the bricks was changed to 64 because of the map I used example):

window.onload = function() {
    var stage = new createjs.Stage("canvas");
    var bmp;
    var board;
    var img;
    var data;
    var tileClone;
    var x,y;
    var mapWidth;
    var mapHeight;

     img = new createjs.SpriteSheet({
        "images": ["http://i.stack.imgur.com/ZlsL6.png"],
        "frames": {
            "height": 64,
            "width": 64,
            "regX": 0,
            "regY": 0
        }
    });

    data = [
        [0, 0, 0, 0, 0, 0, 0, 0],
        [0, 4, 12, 12, 5, 0, 0, 0],
        [0, 15, 22, 22, 9, 0, 0, 0],
        [0, 7, 11, 22, 22, 12, 5, 0],
        [0, 0, 19, 14, 14, 14, 6, 0],
        [0, 0, 0, 0, 0, 0, 0, 0]
    ];

    board = new createjs.Container();
    board.x = 0;
    board.y = 0;
    stage.addChild(board);

    bmp = new createjs.Sprite(img);
    for (i = 0; i < data.length; i++) {
        for (j = 0; j < data[i].length; j++) {
            tileClone = bmp.clone();
            tileClone.gotoAndStop(data[i][j]);

            // Abaixo, em x, note a adição da margem de 350 pixels à esquerda
            // Note também o posicionamento cartesiano considerando a metade das
            // dimensões originais dos tijolos
            tileClone.x = 350 + j * tileClone.getBounds().width / 2;
            tileClone.y = i * tileClone.getBounds().height / 2;
            board.addChild(tileClone);

            // Essa é a função que reposiciona o tijolo considerando a projeção isométrica
            placeIsoTile(tileClone);
        }
    }
    stage.update();
};

function placeIsoTile(tileClone) {
    var isoX = tileClone.x - tileClone.y;
    var isoY = (tileClone.x + tileClone.y) / 2;

    tileClone.x = isoX;
    tileClone.y = isoY;    
}

As in the isometric projection the X axis is drawn from the initial position diagonally to the left of the viewer, I include a margin of 350 pixels in the code just to make it easier to see. You'll have to predict something like this in your code (ie make sure the first brick on the last line is visible on the left side of the canvas).

In the tutorial I referenced above there are other important tips, especially on the order of drawing and moving objects in this projection.

Here is the final result below. :)

    
06.05.2014 / 22:50