Now I have a simple code without a main game loop. I'm rendering the sprites on the canvas using the Loader constructor and its image.onload function (because without image.onload I won't see any sprites) Now I want to animate on of my sprites and for that I need to create a draw loop. Unfortunately, this is where my knowledge ends. I tried creating render function and just copy pasting my ship.drawimage(boat, boatPosX, boatPosY, 50, 50);
methods what so ever, but it's not working because I need image.onload function which is inside Loader
. And I can't put Loader constructor to my render()
function because then var background = new Loader("ground.png");
var boat = new Loader("ship.png");
can't access the constructor variable to init new object.
So at this point I'm pretty lost how I should refactor my code better?
Here is the full code:
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var mapArray = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 2, 2, 0],
[0, 0, 1, 1, 1, 0, 0, 2, 0, 0],
[0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
var StyleSheet = function(image, width, height) {
this.image = image;
this.width = width;
this.height = height;
this.draw = function(image, sx, sy, swidth, sheight, x, y, width, height) {
context.drawImage(image, sx, sy, swidth, sheight,x, y, width, height);
}
this.drawimage = function(image, x, y, width, height) {
context.drawImage(image, x, y, width, height);
}
}
/* Initial Sprite Position */
var boatPosX = 230;
var boatPosY = 200;
var Loader = function(src) {
this.image = new Image();
this.image.src = src;
this.image.onload = function() {
var sprite = new StyleSheet(background, 36, 36);
var ship = new StyleSheet(boat, 90, 100);
for (let i = 0; i < mapArray.length; i++) {
for (let j = 0; j < mapArray[i].length; j++) {
if (mapArray[i][j] == 0) {
sprite.draw(background, 190, 230, 26, 26, i * sprite.width, j * sprite.height, sprite.width, sprite.height);
}
if (mapArray[i][j] == 1) {
sprite.draw(background, 30, 30, 26, 26, i * sprite.width, j * sprite.height, sprite.width, sprite.height);
}
if (mapArray[i][j] == 2) {
sprite.draw(background, 200, 20, 26, 26, i * sprite.width, j * sprite.height, sprite.width, sprite.height);
}
}
}
ship.drawimage(boat, boatPosX, boatPosY, 50, 50);
}
return this.image;
}
function render() {
}
setInterval(render, 10);
/* Sprite controls */
function move(e) {
if (e.keyCode == 39) {
boatPosX += 2;
console.log("works");
}
if (e.keyCode == 37) {
boatPosX -= 2;
}
}
document.onkeydown = move;
var background = new Loader("ground.png");
var boat = new Loader("ship.png");
console.log(background);
UPDATE:
So following my old questions, I decided to do some changes to my code so that I would be allowed to call requestAnimationFrame
for my onload
function and draw the sprite on the canvas constantly. For that I separated Loader constructor and my method onload
by putting onload
into a new function and assigning that function to Loader
prototype. Then I do var background = new Loader("ground.png");
and background.render();
but I get Uncaught TypeError: background.render is not a function
error. Not sure what I'm doing wrong?
var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
var mapArray = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 2, 2, 0],
[0, 0, 1, 1, 1, 0, 0, 2, 0, 0],
[0, 0, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
var StyleSheet = function(image, width, height) {
this.image = image;
this.width = width;
this.height = height;
this.draw = function(image, sx, sy, swidth, sheight, x, y, width, height) {
context.drawImage(image, sx, sy, swidth, sheight,x, y, width, height);
}
this.drawimage = function(image, x, y, width, height) {
context.drawImage(image, x, y, width, height);
}
}
/* Initial Sprite Position */
var boatPosX = 230;
var boatPosY = 200;
var Loader = function(src) {
this.image = new Image();
this.image.src = src;
return this.image;
}
Loader.prototype.render = function() {
this.image.onload = function() {
var sprite = new StyleSheet(background, 36, 36);
var ship = new StyleSheet(boat, 90, 100);
for (let i = 0; i < mapArray.length; i++) {
for (let j = 0; j < mapArray[i].length; j++) {
if (mapArray[i][j] == 0) {
sprite.draw(background, 190, 230, 26, 26, i * sprite.width, j * sprite.height, sprite.width, sprite.height);
}
if (mapArray[i][j] == 1) {
sprite.draw(background, 30, 30, 26, 26, i * sprite.width, j * sprite.height, sprite.width, sprite.height);
}
if (mapArray[i][j] == 2) {
sprite.draw(background, 200, 20, 26, 26, i * sprite.width, j * sprite.height, sprite.width, sprite.height);
}
}
}
ship.drawimage(boat, boatPosX, boatPosY, 50, 50);
}
}
/* Sprite controls */
function move(e) {
if (e.keyCode == 39) {
boatPosX += 2;
console.log("works");
}
if (e.keyCode == 37) {
boatPosX -= 2;
}
}
document.onkeydown = move;
var background = new Loader("ground.png");
var boat = new Loader("ship.png");
background.render();
console.log(background);
Codepen example: https://codepen.io/Limpuls/pen/dejVpR