0

I hope someone can tell me what I'm doing wrong here.

I'm trying to draw an image on canvas.

The images are part of a texture atlas (created with texturePacker) so there is a sprite sheet and an accompanying JSON file:

animals.png Sprite Sheet

{"frames": {

"cat.png":
{
    "frame": {"x":2,"y":2,"w":128,"h":128},
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128},
    "sourceSize": {"w":128,"h":128}
},
"hedgehog.png":
{
    "frame": {"x":132,"y":2,"w":128,"h":128},
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128},
    "sourceSize": {"w":128,"h":128}
},
"tiger.png":
{
    "frame": {"x":262,"y":2,"w":128,"h":128},
    "rotated": false,
    "trimmed": false,
    "spriteSourceSize": {"x":0,"y":0,"w":128,"h":128},
    "sourceSize": {"w":128,"h":128}
}},
"meta": {
    "app": "https://www.codeandweb.com/texturepacker",
    "version": "1.0",
    "image": "animals.png",
    "format": "RGBA8888",
    "size": {"w":392,"h":132},
    "scale": "1",
    "smartupdate": "$TexturePacker:SmartUpdate:9a29ce0a7220e3ca27b8044b48608e8d:06a75246a1a4b65f2beacae47a5e81d7:b00d48b51f56eb7c81e25100fcce2828$"
}
}

The texture atlas is preloaded by a file named assets.js, a utility created to preload game assets. I thought the file was a little too large to post here.

When I try to paint a preloaded image on canvas with either ctx.drawImage() or ctx.createPattern() I get an error:

TypeError: CanvasRenderingContext2D.createPattern: Argument 1 could not be converted to any of:

 HTMLImageElement, SVGImageElement, HTMLCanvasElement, HTMLVideoElement, ImageBitmap.

I am supposed to be able to access the individual images on the sprite sheet in the following way:

`let anyImage = assets["anImage.png"]

So, my code is thus:

import { assets } from "../lib/assets.js";
import { makeCanvas } from "../lib/makeCanvas.js";

// load the files
assets
  .load(["../images/animals.json", "../images/animals.png"])
  .then(() => setUp());

function setUp() {
  let canvas = makeCanvas();
  let ctx = canvas.ctx;

  //Load an image to test that everything works
  let catImage = new Image();
  console.log(catImage);
  catImage.addEventListener("load", loadHandler, false);
  catImage.src = "../images/cat.png";

  // try to use preloaded image fails with Type error
  //ctx.drawImage(assets["tiger.png"], 0, 0);

  // try another way of using preloaded image
  // also fails with the same Type error
  let tiger = assets["tiger.png"];
  console.log(tiger);
  let pattern = ctx.createPattern(tiger, "no-repeat");
  ctx.fillStyle = pattern;
  ctx.rect(0, 0, 64, 64);
  ctx.fill();

  //The loadHandler to draw the catIamage
  function loadHandler() {
    ctx.drawImage(catImage, 128, 128);
  }

}

Note: I haven't included the assets.js or makeCanvas.js code because I believe they are working correctly. But the source code can be found here: assets.js

From console.log(tiger) I get the following:

Object { frame: {…}, rotated: false, trimmed: false, spriteSourceSize: {…}, sourceSize: {…}, source: img }
​
frame: Object { x: 262, y: 2, w: 128, … }
​
rotated: false
​
source: <img src="../images/animals.png">
​
sourceSize: Object { w: 128, h: 128 }
​
spriteSourceSize: Object { x: 0, y: 0, w: 128, … }
​
trimmed: false
​
<prototype>: Object { … }

Can anyone see what I am doing wrong here? It appears that everything is loaded as it should be, but I just don't seem to be able to use the assets.

Thanks in advance, it's really appreciated.

Fishbite
  • 144
  • 12
  • could you add `console.log(typeof tiger);` right before the call to ctx.createPattern(tiger, ...) and let us know what is it? the problem seems to be that it is from a type not supported by the method – germanio Jul 03 '21 at 14:04
  • @germanio `console.log(typeof tiger);` returns `object` – Fishbite Jul 03 '21 at 17:12
  • how about instantiating one of those expected classes (`HTMLImageElement, SVGImageElement, HTMLCanvasElement, HTMLVideoElement, ImageBitmap`) from `tiger` and using it as the argument 1? – germanio Jul 05 '21 at 15:21
  • ok I think I found something to try: the documentation in assets.js says you can access _the asset_ with its path as the key, which in your case is: `../images/animals.png`, not `tiger.png`. Check this: https://github.com/Fishbite/AdvancedGaming/blob/master/sprites/lib/assets.js#L119 – germanio Jul 05 '21 at 17:18
  • it seems no matter how I write this: `let tiger = assets["tiger.png"]; ` let tiger = assets["../images/tiger.png"];` I get the same error. If I omit the quotes from the path I get an `Expecting expression, but got "." ` I'm continuing work on this from the ground up and will post something as soon as I figure it out. I think I am missing a link in the chain to be able to use this format: `let tiger = assets["tiger.png"];` – Fishbite Jul 07 '21 at 09:54
  • it seems you need to access it with the original image name: `../images/animals.png` – germanio Jul 12 '21 at 16:00
  • I've done a bit more reading after picking up Rex van der Spuy's book __Advanced Game Design with HTML5 and JavaScript__ and yes, if you are using individual preloaded images you can access the asset with its path as the key, as you previously said. However, we are trying to access an image from a texture atlas, so "tiger.png" in ```assets["tiger.png"]``` refers to the texture atlas frame id, not an image. It's quite difficult to replicate what Rex has done because there are so many levels of abstraction and inheritance e.g. ```let hedgehog = new Sprite(assets["hedgehog.png"], 0, 0);``` – Fishbite Jul 17 '21 at 14:09
  • ...where the above ```new Sprite()``` is created from a Sprite constructor class which itself extends another ```class``` ```DisplayObject``` which is responsible for a sprite's properties and the sprite's children if it has any. I haven't answered my original question yet, so I may add more to my original post in the hope that I can shed some light on the matter. Interestingly enough, the ```Sprite class``` uses the very ```drawImage()``` method I was trying to use myself! – Fishbite Jul 17 '21 at 14:29

0 Answers0