0

I am trying to make a point and click adventure video game on HTML Canvas for G4C. I have an array full of images. I want to convert it into a single parameter so that I can do something like image[1] and when that happens, the selected image array element will appear as the background on the canvas. The parameter is inside a function call.

So how do I convert my array into a single parameter, more specifically the image parameter, when calling a particular function that has multiple parameters in it?

The code must be in Vanilla JavaScript.

CSS

#gameCanvas {
    width: 960px;
    height: 640px;
    border: 5px solid rgba(52,52,52,1.00);
    background-color: rgba(241,213,179,1.00);
}

Vanilla JavaScript

/**Array of Images**/
var imgArray = [
    "gameImages/titleScreen.png",
    "gameImages/titleScreen1.png",
    "gameImages/titleScreenBW.png",
    "gameImages/startScreen.png",
    "gameImages/startScreenBW.png",
    "gameImages/forestTrail.png",
    "gameImages/forestTrailBW.png",
    "gameImages/jewleryOnLog.png",
    "gameImages/jewleryOnLogBW.png",
    "gameImages/sunlitWaterFall.png",
    "gameImages/sunlitWaterFalBW.png",
    "gameImages/sunlitWaterFall.png",
    "gameImages/sunsetStarySky.png",
    "gameImages/sunsetStarySkyBW.pn",
    "gameImages/campSunset.png",
    "gameImages/campSunsetBW.png",
    "gameImages/LoveHeart.png",
    "gameImages/LoveHeartBW.png",
    "gameImages/nightSky2BW.png",
    "gameImages/nightSky2.png",
    "gameImages/nightSkyAnimate.gif"
];

function drawImageProp(ctx, image, x, y, w, h, offsetX, offsetY) {

//Function Code for resizing images to fit canvas proportions...

ctx.drawImage(image, cx, cy, cw, ch, x, y, w, h);

}


drawImageProp(ctx, image, 0, 0, width, height); //I want to change image to get the array image element

/**Right now, the image parameter on Adobe Dreamweaver displays the error "'image' is not defined. [no-undef]"
**/

I tried drawImageProp.apply(null, imgArray); and other apply methods although I am unable to find use for that since I am not making all array elements into parameters.

I tried a for (){} loop with: for (var i = 0; i < imgArray.length; i++) { imgArray.element = image; } but I am unable to determine if it works due to a lack of knowledge.

If there is an improvement for this code or better ways to insert images as backgrounds into HTML Canvas to use as a part of drawing or displaying scenes/events in a point and click adventure video game, please give a well explained answer. It would be much appreciated.

3
  • Theres q couple more steps, as tthe canvas draw function does not load the image for you, you have to assign the URL to an Image object and wait for it to load, then draw it. You are also not including any actual variable named image, so its obviously undefined. I think the gap of knowledge might be slightly too large to fill in on the fly here... Best to read the documentation and examples on MDN: developer.mozilla.org/en-US/docs/Web/API/Canvas_API Commented Apr 6, 2020 at 2:42
  • Well if I were to assign the image parameter as a variable, would I need var image = new Image();? Also, do you have any references or sources for your critique? Commented Apr 6, 2020 at 2:49
  • I have added my answer, it rudimentary but its a start to give you an idea of the problems you need to solve (loading the images mostly). Commented Apr 6, 2020 at 3:05

1 Answer 1

1

I have modified your code a bit to show how you could resolve it. The crux of the problem is that you:

  • Need Image elements to draw into a canvas, not the URL to them.
  • Need to await loading all the Images before you can draw them

// First we have to convert all our images to Image objects and await them loading. This is not efficient to do all at once (slow), but for clarity I will do it like this for now.
var imgArray = [
    "gameImages/titleScreen.png",
    "gameImages/titleScreen1.png",
    "gameImages/titleScreenBW.png",
    "gameImages/startScreen.png",
    "gameImages/startScreenBW.png",
    "gameImages/forestTrail.png",
    "gameImages/forestTrailBW.png",
    "gameImages/jewleryOnLog.png",
    "gameImages/jewleryOnLogBW.png",
    "gameImages/sunlitWaterFall.png",
    "gameImages/sunlitWaterFalBW.png",
    "gameImages/sunlitWaterFall.png",
    "gameImages/sunsetStarySky.png",
    "gameImages/sunsetStarySkyBW.pn",
    "gameImages/campSunset.png",
    "gameImages/campSunsetBW.png",
    "gameImages/LoveHeart.png",
    "gameImages/LoveHeartBW.png",
    "gameImages/nightSky2BW.png",
    "gameImages/nightSky2.png",
    "gameImages/nightSkyAnimate.gif"
].map(sourceUrl => {
   
   // We will map every URL to an Image object and tell it to only say its ready (aka 'resolved') once we receive a load event.
   
   return new Promise((resolve, reject) => {
    
    const img = new Image;
    
    img.addEventListener( 'load', e => resolve( img ) );
    img.addEventListener( 'error', reject );
    img.src = sourceUrl;
    
   });
   
});

function drawImageProp(ctx, image, x, y, w, h, offsetX, offsetY) {

  ctx.drawImage(image, cx, cy, cw, ch, x, y, w, h);

}

// Now we will tell the browser to only execute the following after all imags are loaded:
// NOTE: If only one Image has an error, the code WILL fail.
// Failsafes for this are another batch of issues you need to resolve.

Promise.all( imgArray ).then( allImages => {
  
  // allImages will contain an array of Image elements that you can now 
  // pass to a canvas to draw one by one. Not sure what you want to accomplish here, 
  // but the following should at least not error out.
  
  allImages.forEach(image => {
  
    drawImageProp(ctx, image, 0, 0, width, height);
    
  });
  
}, error => {
  
  console.log( 'An image has thrown an error while loading, aborted everything', error );

});

Hope this helps you on your way!

Sign up to request clarification or add additional context in comments.

9 Comments

Thank you for the response. I am getting an error for the promise value. It states, " 'Promise' is not defined' [no-undef]" which seems to be the main issue for this new piece of code which blocks the images from loading. Are there solutions for this error?
Promise should be defined as a global object... Try window.Promise? I really dont know why that wouldnt work - it should just exist as its now a commonplace core web technology that enables all asynchronous operations at this point...What browser are you testing this in?
I am testing in Chrome and FireFox.
What is reporting the ‘no undef’? Because Promise should just exist. Heres the docs on it: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… - just type ‘Promise’ in tour browsers console, it should just be there.
In Firefox debug console, I am getting: "XML Parsing Error: syntax error Location: 127.0.0.1:50220/previewapp/localurl Line Number 1, Column 1:" even though I have <!doctype html> .
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.