Javascript,CanvasRenderingContext2D.drawImage无法识别图像数据

时间:2017-04-20 12:39:40

标签: javascript jquery html

function IMGLoader()
{
	this.imageBuffer = [];
}
IMGLoader.prototype.load = function(src)
{
	var temp = new Image();
	temp.src = src;
	this.imageBuffer.push(temp);
	
}

所以我一直试图将一些图像作为网格渲染到画布上。当我开始调试我的代码时,我能够摆脱除了一个错误之外的所有错误。这又迫使我重写并尝试了几种方法。我对javascript很新,对jquery不太了解。

出现的问题是,我加载的图像不会渲染到画布。在调用drawImage之前,我试图确保它们已被加载。我还检查了“spr”instanceof Image,它有时是。最终它是一个图像,当我从核心调用它时,在IMGLoader加载它们之后:见上文

我花了8个多小时试图解决这个问题,我试图用相同的错误参数阅读其他问题。但它没有多大帮助。

如果你能发现我的错误请这样做。

// Object calling function...
function GameObject(x, y, w, h)
{
	this.x = x;
	this.y = y;
	this.w = w;
	this.h = h;
	this.img = null;
}
GameObject.prototype.draw = function(ctx)
{
	//alert("Attempt draw...");
	//alert(this.img instanceof Image);
	//var context = document.getElementById("mainCanvas").getContext("2d");
	this.img.onload = function (){

		ctx.drawImage(this.img, this.x, this.y, this.w, this.h);
	};
	this.img.onerror = function() {
		alert("Image is not loaded!");
	};
}
GameObject.prototype.loadIMG = function(spr)
{
	
	this.img = spr;
	//alert(this.img instanceof Image);
}


//child class that inherits
//####################################################
Player.prototype = Object.create(GameObject.prototype);
Player.prototype.constructor = Player;
function Player (x, y, w, h)
{
	

	GameObject.call(this,[x, y, w, h]);
	this.moveQueue = [];
}
Player.prototype.update = function ()
{
	if (this.moveQueue.length > 0)
	{
		var move = moveQueue.pop();
		this.x = move[0];
		this.y = move[1];
	}
}


// Primary controller code
//##############################
function Game()
{	
	this.cvs = null;
	this.ctx = null;	
	this.eventhandler = null;
	this.tileMap = null;
	this.imgLoader = null;
	this.gameObjects = [];	
}

Game.prototype.setup = function()
{
	// Loading graphics window and renderer
	this.cvs = document.getElementById("mainCanvas");
	//this.cvs.width = document.body.clientWidth;
	//this.cvs.height = document.body.clientHeight;
	this.ctx = this.cvs.getContext("2d");
	
	this.eventhandler = new EventHandler();
	this.tileMap = new TileMap();
	this.imgLoader = new IMGLoader();
	
	this.eventhandler.setup(this.cvs);
	
	
	this.imgLoader.load("./assets/floortile001.png");
	this.imgLoader.load("./assets/player.png");
	
	var floorTiles = [this.imgLoader.imageBuffer[0]];
	this.tileMap.setup(2, 2, 128, floorTiles);
	
	
	var playerSprite = this.imgLoader.imageBuffer[1];
	
	this.gameObjects.push(new Player(128, 128, 96, 96));
	this.gameObjects[0].loadIMG(playerSprite); 

}
Game.prototype.handleEvents = function()
{
	if (this.eventhandler.hasClickedLeft)
	{
		var start = [this.player.x, this.player.y];
		var end = this.tileMap.boundCoordinates(this.eventhandler.x, this.eventhandler.y);
		this.player.moveQueue = algorithms.pathfinding(start, end, this.tileMap);
	}
}
Game.prototype.update = function()
{
	for (var i = 0; i < this.gameObjects.length; i++)
		this.gameObjects[i].update();
}
Game.prototype.render = function()
{
	this.ctx.clearRect(0, 0, this.cvs.width, this.cvs.height);
	this.ctx.fillStyle = "#000000";
	this.ctx.fillRect(0, 0, this.cvs.width, this.cvs.height);
	this.tileMap.draw(this.ctx);
	for (var i = 0; i < this.gameObjects.length; i++)
		this.gameObjects[i].draw(this.ctx);
}
Game.prototype.run = function()
{
	var self = this;
	setInterval(function()
	{
		self.handleEvents();
		self.update();
		self.render();
	}, 1000/30);
}
<!DOCTYPE html>
<meta charset="UTF-8">
<html>
<head>
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js" type="text/javascript"></script>
	
	<script type="text/javascript" src="js/priorityqueue.js"></script>
	<script type="text/javascript" src="js/algorithms.js"></script>
	<script type="text/javascript" src="js/gameobject.js"></script>
	<script type="text/javascript" src="js/tile.js"></script>
	<script type="text/javascript" src="js/tilemap.js"></script>
	<script type="text/javascript" src="js/player.js"></script>
	<script type="text/javascript" src="js/imgloader.js"></script>
	<script type="text/javascript" src="js/core.js"></script>
	<script type="text/javascript" src="js/eventhandler.js"></script>
</head>

<body>
	<canvas id="mainCanvas" width="800px" height="800px"></canvas>
</body>
</html>
<script type="text/javascript">
$(document).ready(function () {
	var game = new Game();
	game.setup();
	game.run();
});
</script>

1 个答案:

答案 0 :(得分:1)

您的问题可能是,在这些行中

this.img.onload = function (){
  ctx.drawImage(this.img, this.x, this.y, this.w, this.h);
};

回调中的this不会引用与外部相同的this

一种可能的解决方案是使用箭头函数,它保留上下文:

this.img.onload = () => {
  ctx.drawImage(this.img, this.x, this.y, this.w, this.h);
};

另一种选择是使用另一个变量来保存上下文:

var self = this;
this.img.onload = function (){
  ctx.drawImage(self.img, self.x, self.y, self.w, self.h);
};