除非是全局的,否则不会呈现Javascript图像
我正在尝试使用JS渲染来自sprite工作表的图像。奇怪的是,除非进行渲染的对象是全局对象,否则它不会工作(请参见代码和注释)。FF和Chrome的行为都是相同的除非是全局的,否则不会呈现Javascript图像,javascript,canvas,Javascript,Canvas,我正在尝试使用JS渲染来自sprite工作表的图像。奇怪的是,除非进行渲染的对象是全局对象,否则它不会工作(请参见代码和注释)。FF和Chrome的行为都是相同的 resetGame()在页面加载时执行 var TILE_SIZE = 24; function CharacterImage(imageSource) { var tile_x = 0; var tile_y = 0; var img = new Image(); img.src = imageS
resetGame()
在页面加载时执行
var TILE_SIZE = 24;
function CharacterImage(imageSource)
{
var tile_x = 0;
var tile_y = 0;
var img = new Image();
img.src = imageSource;
this.render = function(ctx, x, y)
{
ctx.drawImage(img, tile_x, tile_y, TILE_SIZE, TILE_SIZE,
x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE);
}
}
function Hero(canvas, image)
{
var ctx = canvas.getContext("2d");
var img = image;
this.render = function()
{
var x = 1;
var y = 1;
img.render(ctx, x, y);
}
}
// If the heroImage is constructed here, instead of within the function below,
// the image is rendered as expected.
var heroImage = new CharacterImage("img/sf2-characters.png");
function resetGame()
{
var heroCanvas = document.getElementById("heroLayer");
// On the otherhand, if the object is constructed here, instead of
// globally, the rendering doesn't work.
var heroImage = new CharacterImage("img/sf2-characters.png");
var hero = new Hero(heroCanvas, heroImage);
hero.render();
}
等等,我想我知道发生了什么。加载映像需要时间,因此您应该以某种方式将事件绑定到映像的加载。可以这样做,例如:
var TILE_SIZE = 24;
function CharacterImage(imageSource)
{
var tile_x = 0;
var tile_y = 0;
var img = new Image();
img.src = imageSource;
this.render = function(ctx, x, y)
{
ctx.drawImage(img, tile_x, tile_y, TILE_SIZE, TILE_SIZE,
x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE);
}
// Set up a "load" event for the img
this.loaded = function(callback) {
img.addEventListener('load', callback);
}
}
function resetGame()
{
var heroCanvas = document.getElementById("heroLayer");
var heroImage = new CharacterImage("img/sf2-characters.png");
var hero;
// Initiate the "load" event
heroImage.loaded(function() {
hero = new Hero(heroCanvas, heroImage);
hero.render();
};
}
不过,您可能需要的是某种预加载程序“class”/事件,它在您实际继续渲染之前跟踪正在加载的所有内容。它可能看起来像这样
var TILE\u SIZE=60;
函数精灵(图像源)
{
this.img=新图像();
this.img.src=图像源;
this.position={x:0,y:0};
}
Sprite.prototype={
isLoaded:函数(){
返回此.img.complete;
},
onLoad:函数(回调){
if(typeof callback!=“function”)返回;
if(this.isLoaded()){
回调();
}
否则{
this.img.removeEventListener('load',callback);
this.img.addEventListener('load',callback);
}
},
moveBy:函数(x,y){
此.position.x+=x;
此.position.y+=y;
},
渲染:函数(ctx){
如果(!this.isLoaded())返回;
ctx.drawImage(this.img,this.position.x*平铺尺寸,this.position.y*平铺尺寸,平铺尺寸,平铺尺寸);
}
};
函数SpriteList()
{
this.list={};
}
SpriteList.prototype={
isLoaded:函数(){
for(此.list中的变量i){
如果(!this.list[i].isload()){
返回false;
}
}
返回true;
},
_onLoadFunc:null,
onLoad:函数(回调){
这是。_onLoadFunc=回调;
这个.onImageLoaded();
},
onImageLoaded:函数(){
if(this.isLoaded()&&typeof this.\u onLoadFunc==“函数”){
这是。_onLoadFunc();
}
},
添加:函数(名称、精灵){
this.list[name]=sprite;
sprite.onLoad(this.onImageLoaded.bind(this));
},
get:函数(名称){
返回此.列表[名称];
}
};
var sprites=新的SpriteList();
精灵。添加(“玩家”,新精灵(“http://www.fillmurray.com/200/200"));
精灵。添加(“敌人”,新精灵(“http://www.fillmurray.com/100/100"));
雪碧。添加(“拾取”,新雪碧(“http://www.fillmurray.com/60/60"));
精灵。获取(“拾取”)。移动(1,2);
精灵。获取(“敌人”)。移动(2,0);
sprites.onLoad(函数(){
document.getElementById(“加载”).innerHTML=“加载!”;
var c=document.getElementById(“ctx”);
var ctx=c.getContext(“2d”);
精灵。获取(“玩家”)。渲染(ctx);
精灵。获取(“敌人”)。渲染(ctx);
精灵。获取(“拾取”)。渲染(ctx);
});代码>
正在加载。。。
你在哪里调用resetGame()
?在页面加载时,就像他在问题中说的,“不工作”是什么意思?你收到错误信息了吗,什么都没发生,什么?谢谢。这看起来很有希望。我正在做游戏的另一部分,所以一旦我有机会尝试你的建议,我会选择这个作为答案,如果它奏效的话。