Javascript 使用HTML5画布将图像解析为tileset
我正在尝试将tileset图像(类型为.png)解析为数组。我有一个测试画布,我先用它来绘制,然后我从中提取图像信息。当我运行这段代码时,它抛出“uncaughttypeerror:Type error”。我能够记录this.mainTiles为空。有什么想法吗?我还不知道画布的所有细节,所以我被卡住了。谢谢你的帮助!(另外,您可以忽略结尾的最后一行,我只是用它来测试——但我想说明它不起作用) 编辑2:在markE的回答之后,这里是最新的更新。仍然觉得我缺少了一个关于.onload的基本属性Javascript 使用HTML5画布将图像解析为tileset,javascript,html,html5-canvas,Javascript,Html,Html5 Canvas,我正在尝试将tileset图像(类型为.png)解析为数组。我有一个测试画布,我先用它来绘制,然后我从中提取图像信息。当我运行这段代码时,它抛出“uncaughttypeerror:Type error”。我能够记录this.mainTiles为空。有什么想法吗?我还不知道画布的所有细节,所以我被卡住了。谢谢你的帮助!(另外,您可以忽略结尾的最后一行,我只是用它来测试——但我想说明它不起作用) 编辑2:在markE的回答之后,这里是最新的更新。仍然觉得我缺少了一个关于.onload的基本属性 f
function TileSet() {
this.Tiles = [];
this.tileHeight = 32;
this.tileWidth = 32;
this.tileCount = 4;
this.addSpriteSheet = function (spriteSheetLoc, name) {
var tileSheet = new Image();
tileSheet.onload = function() {
tempCanvas.width = tileSheet.width;
tempCanvas.height = tileSheet.height;
tempContext.drawImage(tileSheet, 0, 0);
for (var t=0;t<this.tileCount;t++) {
this.Tiles[t]=tempContext.getImageData(t*this.tileWidth,t*32,this.tileWidth,tileSheet.height);
dMode.Log(this.Tiles);
}
context.putImageData(this.Tiles[this.Tiles.length-1],0,0);
dMode.Log(this.Tiles);
}
tileSheet.src = spriteSheetLoc;
}
函数TileSet(){
this.Tiles=[];
这个.tileHeight=32;
此.tileWidth=32;
this.tileCount=4;
this.addSpriteSheet=函数(spriteSheetLoc,名称){
var tileSheet=新图像();
tileSheet.onload=函数(){
tempCanvas.width=tileSheet.width;
tempCanvas.height=tileSheet.height;
drawImage(tileSheet,0,0);
对于(var t=0;t,以下是如何将精灵表解析为一组单独的画布图像数据
我有一些工作代码,可以做你想做的事情
我没有你的“resources/tiles/tilea2.png”,所以我使用了我自己的“monstersArun.png”,这是一个10跨的64x64瓷砖精灵表
您可以修改此代码以适应精灵表布局(行x列和平铺大小)
代码如下:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var tileCount=10;
var tiles=new Array();
var tileWidth;
var t;
var img=new Image();
img.onload=function(){
canvas.width=img.width;
canvas.height=img.height;
tileWidth=img.width/tileCount;
ctx.drawImage(img,0,0);
for(var t=0;t<tileCount;t++){
tiles[t]=ctx.getImageData(t*tileWidth,0,tileWidth,img.height);
}
// just a test
// draw the last tiles[] into another canvas
var canvasTile=document.getElementById("canvasTile");
var ctxTile=canvasTile.getContext("2d");
canvasTile.width=tileWidth;
canvasTile.height=canvas.height;
ctxTile.putImageData(tiles[tiles.length-1],0,0);
}
img.src="monsterarun.png";
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas><br/>
<canvas id="canvasTile" width=64 height=64></canvas>
</body>
</html>
这会导致图像加载。加载需要时间,因此javascript会开始加载图像,但它也会立即进入下一行代码。因此,下面的代码会在图像可用之前尝试使用图像,这不好
因此,在处理其余代码之前,您应该给javascript一个完全加载图像的机会。您可以使用图像的onload方法来完成此操作,如下所示:
var tileSheet = new Image();
tileSheet.onload=function(){
// put ALL you code that depends on the image being fully loaded here
}
tileSheet.src = spriteSheetLoc;
请注意如何将tileSheet.src放在onload函数之后。实际上,javascript执行tileSheet.src,然后返回执行onload块中的所有代码
[再次编辑--完成代码]
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var tempCanvas = document.getElementById("tempCanvas");
var tempContext = tempCanvas.getContext("2d");
var canvas = document.getElementById("gameCanvas");
var context = canvas.getContext("2d");
// create a new TileSet
var Tiles = new TileSet();
// parse a spritesheet into tiles
//Tiles.addSpriteSheet("resources/tiles/tilea2.png","anyName");
Tiles.addSpriteSheet("houseIcon.png","anyName");
function TileSet() {
this.Tiles = [];
this.tileHeight = 32;
this.tileWidth = 32;
this.tileCount = 4;
this.addSpriteSheet = function (spriteSheetLoc, name) {
var me=this; // me==this==TileSet
var tileSheet = new Image();
tileSheet.onload = function() {
// calculate the rows/cols in the spritesheet
// tilesX=rows, tilesY=cols
var tilesX = tileSheet.width / me.tileWidth;
var tilesY = tileSheet.height / me.tileHeight;
// set the spritesheet canvas to spritesheet.png size
// then draw spritesheet.png into the canvas
tempCanvas.width = tileSheet.width;
tempCanvas.height = tileSheet.height;
tempContext.drawImage(tileSheet, 0, 0);
for(var i=0; i<tilesY; i++) {
for(var j=0; j<tilesX; j++) {
// Store the image data of each tile in the array.
me.Tiles.push(tempContext.getImageData(j*me.tileWidth, i*me.tileHeight, me.tileWidth, me.tileHeight));
}
}
// this is just a test
// display the last tile in a canvas
context.putImageData(me.Tiles[me.Tiles.length-1],0,0);
}
// load the spritesheet .png into tileSheet Image()
tileSheet.src = spriteSheetLoc;
}
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="tempCanvas" width=300 height=300></canvas><br/>
<canvas id="gameCanvas" width=300 height=300></canvas>
</body>
</html>
正文{背景色:象牙;}
画布{边框:1px纯红;}
$(函数(){
var tempCanvas=document.getElementById(“tempCanvas”);
var tempContext=tempCanvas.getContext(“2d”);
var canvas=document.getElementById(“gameCanvas”);
var context=canvas.getContext(“2d”);
//创建一个新的瓷砖集
var Tiles=新TileSet();
//将精灵表解析为平铺
//Tiles.addSpriteSheet(“resources/Tiles/tilea2.png”、“anyName”);
Tiles.addSpriteSheet(“houseIcon.png”、“anyName”);
函数TileSet(){
this.Tiles=[];
这个.tileHeight=32;
此.tileWidth=32;
this.tileCount=4;
this.addSpriteSheet=函数(spriteSheetLoc,名称){
var me=this;//me==this==TileSet
var tileSheet=新图像();
tileSheet.onload=函数(){
//计算精灵表中的行/列
//TILEXS=行,tilesY=列
var tilex=tileSheet.width/me.tileWidth;
var tilesY=tileSheet.height/me.tileHeight;
//将spritesheet画布设置为spritesheet.png大小
//然后将spritesheet.png绘制到画布中
tempCanvas.width=tileSheet.width;
tempCanvas.height=tileSheet.height;
drawImage(tileSheet,0,0);
对于(var i=0;i尝试分别用tempCanvas.width
和tempCanvas.height
替换tempContext.width
和tempCanvas.height
来替换tempContext.width
和tempContext.height
。我不相信上下文有宽度/高度。你能展示一下tempContext
是如何定义的吗?当然可以。请查看对代码的编辑。尝试替换temp。宽度
和tempContext.height
分别与tempCanvas.width
和tempCanvas.height
一起。我不相信上下文有宽度/高度。这就解决了问题!我没有意识到我应该直接使用画布来访问其宽度——我想我必须使用上下文。非常感谢。很高兴它起作用了!如果你不这样做的话记住,我会把我的评论作为一个答案,如果你接受我会很感激的。看起来它应该有效,但最好能解释一下OP的错误coded@Juan门德斯:谢谢你的鼓励,我通常更乐于助人……在我的回答中增加了OP的帮助:)这当然是一个更干净的解决方案,也是有意义的——但出于某种原因,它对我来说不起作用。很抱歉让你被问题淹没,我觉得这其中有一些基本的东西,我需要一劳永逸地了解一下.onload函数。我已经在原始帖子上发布了最新的迭代。@Taylor Hill,H这是处于工作状态的代码。请注意:在tileSheet.onload中,“this”指的是tileSheet图像()--而不是TileSet对象(这就是var me=this;)。您的TileSet对象依赖于要在对象外部定义的tempContext。相反,您需要在TileSet内部创建画布,如下所示:var myTempCanvas=document.createElement(“画布”);然后为myTempCanvas创建上下文。非常感谢您的帮助!我对这个社区的帮助感到惊讶。
tileSheet.src = spriteSheetLoc;
var tileSheet = new Image();
tileSheet.onload=function(){
// put ALL you code that depends on the image being fully loaded here
}
tileSheet.src = spriteSheetLoc;
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var tempCanvas = document.getElementById("tempCanvas");
var tempContext = tempCanvas.getContext("2d");
var canvas = document.getElementById("gameCanvas");
var context = canvas.getContext("2d");
// create a new TileSet
var Tiles = new TileSet();
// parse a spritesheet into tiles
//Tiles.addSpriteSheet("resources/tiles/tilea2.png","anyName");
Tiles.addSpriteSheet("houseIcon.png","anyName");
function TileSet() {
this.Tiles = [];
this.tileHeight = 32;
this.tileWidth = 32;
this.tileCount = 4;
this.addSpriteSheet = function (spriteSheetLoc, name) {
var me=this; // me==this==TileSet
var tileSheet = new Image();
tileSheet.onload = function() {
// calculate the rows/cols in the spritesheet
// tilesX=rows, tilesY=cols
var tilesX = tileSheet.width / me.tileWidth;
var tilesY = tileSheet.height / me.tileHeight;
// set the spritesheet canvas to spritesheet.png size
// then draw spritesheet.png into the canvas
tempCanvas.width = tileSheet.width;
tempCanvas.height = tileSheet.height;
tempContext.drawImage(tileSheet, 0, 0);
for(var i=0; i<tilesY; i++) {
for(var j=0; j<tilesX; j++) {
// Store the image data of each tile in the array.
me.Tiles.push(tempContext.getImageData(j*me.tileWidth, i*me.tileHeight, me.tileWidth, me.tileHeight));
}
}
// this is just a test
// display the last tile in a canvas
context.putImageData(me.Tiles[me.Tiles.length-1],0,0);
}
// load the spritesheet .png into tileSheet Image()
tileSheet.src = spriteSheetLoc;
}
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="tempCanvas" width=300 height=300></canvas><br/>
<canvas id="gameCanvas" width=300 height=300></canvas>
</body>
</html>