Question

I'm implementing a menu system for my game using canvas (for certain performance reasons I cannot use HTML/CSS to make the menus). I have the menu configured using JSON and menuComponent objects are created with their respective properties (x, y, width, height, imagePath, etc). I have a menu loader which then iterates over the component objects and calls the componentObjects' draw method (all images wait for their onload event to fire first, of course).

Anyway, I expect my images to be drawn in the order that their draw method is called so that they overlap in the correct order. The majority of the time this behaviour is correct but occasionally they will draw in the wrong order.

My question is - can I trust Canvas to draw images in the order the drawMethod is called for those images? Say I have image A which is, for example, 10MB and image B which is 10kb. If I call draw image A and then draw image B then is there a chance that image B will load first because it's a smaller image?

I was trying to be smart with my code (having nested components inside my component objects and recursively call draw methods) so it's possible there's some race conditions in my code, I just want to confirm the above behaviour is correct. If I add logic to force my objects to wait until a ready flag is set then it seems to work. But unfortunately that slows up my menus load time.

Was it helpful?

Solution

To put a formal answer to this post -

In the end I simplified my solution to use one menuLoader object which has an array of hashes for each image to be drawn (containing x, y, imagePath, ready flag). I call a create components method which builds up these hashes with the ready flag set to false by default. I set an onload event for each image to set its respective ready flag to true.

After create components has finished executing I use setInterval to spin until all flags have been set to true. Once this condition is met I iterate through my array of hashes again and call the draw method for each image.

OTHER TIPS

Man I've faced same problem and have been stucked with it for about three days. And I figured one interseting thing. Please look though this code snippet and supply me with your thoghts on it.

final ResourceManager rm = new ResourceManager(1000, 1000);
rm.loadImgResource(LandCardResources.INSTANCE.getMeadow(), "meadow", 0, 0);
rm.loadImgResource(LandCardResources.INSTANCE.getHellHorseKnight(), "knight", 150, 150);

Resource manager is an object representing BackBufferCanvas that holds all images in its context (like simple image sprite). Constructor is also responsible for adding this Backbuffer to RootPanel, so we can determine thats everything worked like we expected. After that I'm adding my main canvas to root trying to draw on it from backBufferCanvas using perfectly working ResourceManager instance.

canvas.setWidth(500 + "px");
canvas.setHeight(500 + "px");
canvas.setCoordinateSpaceWidth(500);
canvas.setCoordinateSpaceHeight(500);
RootPanel.get().add(canvas);
rm.drawImageFromMetaDb(ctx, 0, 0, 100, 100, 0, 0, 100, 100);
rm.drawImageFromMetaDb(ctx, 150, 150, 100, 100, 50, 50, 100, 100);

And it never works. But if I for example add Button to rootPanel with handler that is responsible for rm.drawImage..... It will work perfectly when clicking this Button. Can't really understand why this is happening as backBufferCanvas is attached before mainCanvas so logic must be already delayed.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top