Reputation: 1
function IMGLoader()
{
this.imageBuffer = [];
}
IMGLoader.prototype.load = function(src)
{
var temp = new Image();
temp.src = src;
this.imageBuffer.push(temp);
}
So I've been trying to render some images as a grid to the canvas. When I started debugging my code, I was able to get rid of all but one error. Which in turn forced me to rewrite and try several approaches. I am very new to javascript, and do not know much about jquery.
The problem that occurs, is that the images that I load does not render to the canvas. I tried to make sure they were loaded, before calling drawImage. I also checked if "spr" instanceof Image, where it sometimes is. Where it is definitively an image is when I call it from the core, after IMGLoader have loaded them: see above
I've spend more than 8 hours trying to resolve this issue, I've tried to read other questions with the same error argument. However it didn't help much.
If you can spot my mistake do so please.
// 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>
Upvotes: 0
Views: 108
Reputation: 74036
Your problem is probably, that in these lines
this.img.onload = function (){
ctx.drawImage(this.img, this.x, this.y, this.w, this.h);
};
the this
inside the callback does not refer to the same this
as outside.
One possible solution would be to use arrow functions, which preserve the context:
this.img.onload = () => {
ctx.drawImage(this.img, this.x, this.y, this.w, this.h);
};
Another option would be to have another variable to save the context:
var self = this;
this.img.onload = function (){
ctx.drawImage(self.img, self.x, self.y, self.w, self.h);
};
Upvotes: 2