Reading JSON Tiled map editor file and displaying to canvas
Asked Answered
I

2

6

Im following this this tutorial to be able to load json map files created by tiled map editor in my javascript/canvas game.

ive got to the point where i have implemented my own kind of version, and am getting no errors in firebug in console or net etc.

And as far as i can see, by putting in console.logs and alerts, the script is running absolutely fine!

The problem is the canvas stays blank! when it should have a tilemap now on it.

Here is my version of the tutorial implemented in my game:

function Level() {
var c;
var data;
var layers = [];

this.get_map = function(name,ctx){
    c = ctx;
    $.getJSON('maps/'+ name + '.json', function(json){
    get_tileset(json);
    });
};

function get_tileset(json) {
    data = json;
    this.tileset = $("<img />", { src: json.tilesets[0].image })[0];
    this.tileset.onload = renderLayers(this);
}

function renderLayers(layers){
    layers = $.isArray(layers) ? layers : data.layers;
    layers.forEach(renderLayer);
}

function renderLayer (layer){
    if (layer.type !== "tilelayer" || !layer.opacity) {
        alert("Not a tileLayer");
    }
    var s = c.canvas.cloneNode(),
            size = data.tileWidth;
    s = s.getContext("2d");

    if (layers.length < data.layers.length) {
        layer.data.forEach(function(tile_idx, i) {
            if (!tile_idx) { return; }
            var img_x, img_y, s_x, s_y,
                tile = data.tilesets[0];
            tile_idx--;
            img_x = (tile_idx % (tile.imagewidth / size)) * size;
            img_y = ~~(tile_idx / (tile.imagewidth / size)) * size;
            s_x = (i % layer.width) * size;
            s_y = ~~(i / layer.width) * size;
            s.drawImage(this.tileset, img_x, img_y, size, size,
                s_x, s_y, size, size);
        });

        layers.push(s.canvas.toDataURL());
        c.drawImage(s.canvas, 0, 0);
    }
    else {
        layers.forEach(function(src) {
            var i = $("<img />", { src: src })[0];
            c.drawImage(i, 0, 0);
        });
    }

}

}

and it is called from my main javascript file which is this:

$(document).ready(function(){

var canvas = document.getElementById("TBG");
var ctx = canvas.getContext("2d");

var ui = new Gui();
var level = new Level();

//----------Login/Register Gui --------------
$('#TBG').hide();
$('#load-new').hide();
$('#reg').hide();
$('#login').hide();

//if login_but is clicked do ui.login function
$('#login_but').click(ui.login);
//if reg_but is clicked do ui.register function
$('#reg_but').click(ui.register);

$('#new_but').click(function(){
    game_settings("new");
});

$('#load_but').click(function(){
    game_settings("load");
});

//if login_sumbit button is clicked do ui.login_ajax function
$("#login_submit").click(ui.login_ajax);

$("#reg_submit").click(ui.register_ajax);

$("#welcome").on("click", "#logout_but", ui.logout);

//________________________

//Initialisation of game

function game_settings(state){
    if(state == "load"){
        ui.load_game();
        //do ajax call to load user last save
        level.get_map("level_01",ctx);
    }
    else{
        //set beginning params


        //Change screens
        ui.new_game();
        alert("new game");
    }
}

// End Loop ------------------------------------------------------





});

I don't suppose you lovely people could spot why the tile-map isn't being printed to my canvas?

Thanks for any help Tom

Imaimage answered 27/3, 2013 at 19:20 Comment(3)
Are you sure you have good json data coming in? Try adding .done and .fail functions to your $.getJSON and then do debugging there to be sure you're getting valid data.Iceland
yeah the JSON data is fine i believe. i done a console log after it was brought into the function and also when it was passed and the data was fineImaimage
Does anyone have any ideas about this?? i cant seem to find out why its not drawing! argghhhh hahaImaimage
I
9

Tiled + Canvas

I looked at the Tiled+Canvas blog post on http://blog.hashrocket.com/posts/using-tiled-and-canvas-to-render-game-screens by Shane Riley. An interesting post!

Good News…I grabbed his code from his demo and I have his code working locally on my development computer.

In going through the process and in looking at your code, I think you can get your code to work by taking care of 2 issues:

1) You have a small bug in your get_tileset function.

2) You need to point all of Shane’s demo files towards files located on your local computer. I just put all these files together in a single folder (worked for me). You will need to touch these files (details below):

  • mountain.html
  • mountain.json
  • mountain.tmx
  • mountain_landscape_23.png
  • render_scene.js

Here are the details. These worked for me and they should work for you. But if not, let me know and I can post my complete code.

A Bug -- In your get_tileset(), the tileset.onload is expecting a named function or inline function, not a function call.

// not this.tileset.onload=renderLayers(this)
this.tileset.onload=renderLayers;    

// change the signature of renderLayers 
// (you have “layers” in scope for visibility in this function so this s/b ok)
// So: not function renderLayers(layers)
function renderLayers()    

Please include an error catcher in your $.getJSON so you get visibility on failed requests!

$.getJSON('maps/'+ name + '.json', function(json){
        get_tileset(json);
}).fail( alert(“I think you should know that something has gone horribly wrong!”);  );

Here are the changes required to localize your files.

In mountain.html:

    <script src="render_scene.js" type="text/javascript"></script>

In render_scene.js (if you downloaded from the Gist)

load: function(name) {
  return $.ajax({
    url: "mountain.json",
    dataType: "text json"
  }).done($.proxy(this.loadTileset, this));
}

In mountain.json:

"image":"mountain_landscape_23.png",

In mountain.tmx:

<image source="mountain_landscape_23.png" width="512" height="512"/>

Mountain_landscape_23.png

Important! Depending on how you’ve got your development environment set up, you might get a cross-domain-security-error and the browser will refuse to draw your tiles. If so, take this png file into an editor like photoshop and save it back out to your dev domain to nullify the CORS error.

Iceland answered 29/3, 2013 at 4:23 Comment(0)
A
0

Heh, about 10yrs late but if you change

        size = data.tileWidth;

to

        size = data.tilewidth;

it works perfectly.

Attainder answered 12/12, 2023 at 3:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.