javascript 读取 JSON 平铺地图编辑器文件并显示到画布

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15667588/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 01:36:54  来源:igfitidea点击:

Reading JSON Tiled map editor file and displaying to canvas

javascriptjsoncanvasmaptile

提问by Tom Burman

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

林跟随这教程能够被平铺的地图编辑器在我的JavaScript /帆布游戏创建负载JSON地图文件。

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!

据我所知,通过放入 console.logs 和 alerts,脚本运行得非常好!

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:

它是从我的主要 javascript 文件中调用的,它是这样的:

$(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

谢谢你的帮助汤姆

回答by markE

Tiled + Canvas

平铺+帆布

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

我查看了 Shane Riley在http://blog.hashrocket.com/posts/using-tiled-and-canvas-to-render-game-screens上的 Tiled+Canvas 博客文章。一个有趣的帖子!

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.

1) 您的 get_tileset 函数中有一个小错误。

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

2) 您需要将Shane 的所有演示文件指向位于本地计算机上文件。我只是将所有这些文件放在一个文件夹中(对我有用)。您将需要接触这些文件(详情如下):

  • mountain.html
  • mountain.json
  • mountain.tmx
  • mountain_landscape_23.png
  • render_scene.js
  • 山.html
  • 山.json
  • 山.tmx
  • Mountain_landscape_23.png
  • 渲染场景.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 functionor inline function, not a function call.

一个错误——在你的 get_tileset() 中,tileset.onload 需要一个命名函数内联函数,而不是函数调用。

// 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()    

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

在您的 $.getJSON 中包含一个错误捕获器,以便您了解失败的请求!

$.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:

在 Mountain.html 中:

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

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

在 render_scene.js 中(如果你从 Gist 下载)

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

In mountain.json:

在mountain.json 中:

"image":"mountain_landscape_23.png",

In mountain.tmx:

在 Mountain.tmx 中:

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

Mountain_landscape_23.png

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.

重要的!根据您设置开发环境的方式,您可能会遇到跨域安全错误并且浏览器将拒绝绘制您的磁贴。如果是这样,请将这个 png 文件放入像 photoshop 这样的编辑器中,并将其保存回您的开发域以消除 CORS 错误。