Mouseover to view animation (note: mild color cycling)
A year and some ago, I published an extension that allows to use custom logos for HTML5 games made with GameMaker: Studio. Since some functionality has been added since then, I made an updated version with more options.
Setting up
The process of setting up the extension is much as with the original (see linked post), but with a few changes:
First, the extension' JS code is expanded a little,
var inst = { }; function ImageLoadBar_hook(ctx, width, height, total, current, image) { function getv(s) { if (window.gml_Script_gmcallback_imgloadbar) { return window.gml_Script_gmcallback_imgloadbar(inst, null, s, current, total, width, height, image ? image.width : 0, image ? image.height : 0) } else return undefined; } function getf(s, d) { var r = getv(s); return typeof(r) == "number" ? r : d; } function getw(s, d) { var r = getv(s); return r && r.constructor == Array ? r : d; } function getc(s, d) { var r = getv(s); if (typeof(r) == "number") { r = r.toString(16); while (r.length < 6) r = "0" + r; return "#" + r; } else if (typeof(r) == "string") { return r; } else return d; } // get parameters: var backgroundColor = getc("background_color", "#FFFFFF"); var barBackgroundColor = getc("bar_background_color", "#FFFFFF"); var barForegroundColor = getc("bar_foreground_color", "#242238"); var barBorderColor = getc("bar_border_color", "#242238"); var barWidth = getf("bar_width", Math.round(width * 0.6)); var barHeight = getf("bar_height", 20); var barBorderWidth = getf("bar_border_width", 2); var barOffset = getf("bar_offset", 10); // background: ctx.fillStyle = backgroundColor; ctx.fillRect(0, 0, width, height); // image: var totalHeight, barTop; if (image != null) { var rect = getw("image_rect"); if (!rect) rect = [0, 0, image.width, image.height]; totalHeight = rect[3] + barOffset + barHeight; var image_y = (height - totalHeight) >> 1; ctx.drawImage(image, rect[0], rect[1], rect[2], rect[3], (width - rect[2]) >> 1, image_y, rect[2], rect[3]); barTop = image_y + rect[3] + barOffset; } else barTop = (height - barHeight) >> 1; // bar border: var barLeft = (width - barWidth) >> 1; ctx.fillStyle = barBorderColor; ctx.fillRect(barLeft, barTop, barWidth, barHeight); // var barInnerLeft = barLeft + barBorderWidth; var barInnerTop = barTop + barBorderWidth; var barInnerWidth = barWidth - barBorderWidth * 2; var barInnerHeight = barHeight - barBorderWidth * 2; // bar background: ctx.fillStyle = barBackgroundColor; ctx.fillRect(barInnerLeft, barInnerTop, barInnerWidth, barInnerHeight); // bar foreground: var barLoadedWidth = Math.round(barInnerWidth * current / total); ctx.fillStyle = barForegroundColor; ctx.fillRect(barInnerLeft, barInnerTop, barLoadedWidth, barInnerHeight); }
The interesting part here is window.gml_Script_gmcallback_imgloadbar,
Scripts prefixed with gmcallback_ are not obfuscated when compiling to HTML5.
This is originally intended for use with clickable_add function, but is also handy for any other situations where you want a particular script exposed, including this one.
And, since the game' code is fully loaded before the loading bar extension fires, this allows to execute non-game-specific GML code before the game even starts.
So, the next step would be to define a gmcallback_imgloadbar script that would contain something like the following:
/// gmcallback_imgloadbar(context, current, total, width, height, img_width, img_height) var r; var pc = argument1; // progress current var pt = argument2; // progress total var cw = argument3; // canvas width var ch = argument4; // canvas height var iw = argument5; // image width var ih = argument6; // image height switch (argument0) { case "image_rect": // ([left, top, width, height] in pixels) r[0] = (current_time div 500) mod 4 * (iw div 4); r[1] = 0; r[2] = iw div 4; r[3] = ih; return r; case "background_color": return c_white; case "bar_background_color": return c_white; case "bar_foreground_color": return $242238; case "bar_border_color": return $242238; case "bar_width": return round(cw * 0.6); // (px) case "bar_height": return 20; // (px) case "bar_border_width": return 2; // (px) case "bar_offset": return 10; // (px from image) } return undefined;
The script receives the name of requested parameter as the first argument, and returns the value for it. This allows to both configure parameters without editing the extension, and to have them change dynamically.
Here, as an example, the image' sub-coordinates are adjusted based on current_time, as result animating the loading screen' logo at rate of 2 frames/second if you've imported a 4-frame strip for it.
Pre-assembled example and extension are available for download via itch.io:
Alternatively, mirrors for both the extension and the example are hosted on this site too.
Have fun!
How do you make the Background image to be fullscreen and not to scroll?
For scrolling, you’ll want to give your body element an “overflow: hidden” style or keep the game at least one pixel smaller than width/height.
Supposedly the best way to have a full-screen loading bar at the moment is to change size+position of the game canvas, you can get a reference to it using “ctx.canvas”
I realize this post is nearly 7 years old, but this extension is still extremely useful in 2024.
However, there’s one thing about it that needs attention. When loading HTML5 in a container that’s less than 100 percent of the full size, the loading bar and graphic logo appear off-center. This is because the initial size is the canvas size. But depending on the room size, this can create a very jarring display.
The solution is to modify the width and height values passed to ImageLoadBar_hook() with the dimensions of the wrapper div by inserting the following snippet at line 28:
if (parent.document.getElementById(‘html5’) != null) {
// container width/height:
width = parent.document.getElementById(“html5”).offsetWidth;
height = parent.document.getElementById(“html5”).offsetHeight;
}
In my case, the wrapper div has an ID of “html5”. With this snippet in place, the logo graphic and loading bar are always centered within the given window.
Here’s a live example:
https://treeguardians.net/looking-ahead/lesson-5/woodlands-food-web
In any event, I want to thank YellowAfterLife for his tremendous contributions to the GameMaker community. :-)
Just what I needed! Thank you for this!
Hello, it is a good extension, but is it possible to center the loading image? What I am trying to do is to put only an animated gif ( without a bar), but there is a problem. I use your other extension – HDPI support (btw. it’s great and you should be proud of it) and unfortunately, those two extensions aren’t compatible. The loading bar or image is not centered on the screen :( Any idea how to fix this bug?
There’s an option in global game settings to center the canvas; you may reposition the canvas yourself via `ctx.canvas.style.left = value + “px”` (and `.top`).
Where should that code go that you say friend?
https://gyazo.com/2a92f2f940e68fcc9a0805ce0bb7a623.png
I put the code last but it doesn’t work :(
This is how he currently looks and he did not manage to center well
https://i.gyazo.com/c4d2f4da110aff8e4f7c339ba9325422.png
Thanks
Your first room’s size should match the game portal’s requested dimensions – that’s how GM decides on progress bar screen size.
How could I know that friend my room is 1280×720 the first now where I am testing is here: https: //qa.po.ki/#
I know you made the extension for them so I asked you :)
Cheers!
Should I buy a $ 149 web GMS2 program on the market to use this cool feature?
I’m afraid that’s a question that only you could answer with certainty
Hi,
What does line 4 do exactly? What is it checking for? Is it only checking if the given function exists, and that’s it?
Thanks
Indeed – it verifies that your project contains a “gmcallback_imgloadbar” script before calling it.
“Scripts prefixed with gmcallback_ are not obfuscated when compiling to HTML5.” Wow. That’s a feature they could have done with documenting better, on the page about writing javascript extensions for example! I never thought I had any reason to look at ‘clickable_add’ – who would have thought that was the only page of the manual to document a vital GameMaker feature that isn’t exclusively relevant to that function?
Pingback: A summary of my GameMaker assets
Awesome extension, man, thank you very much for the time you spent working on it and for share it for free. You should publish it into YoYo’s marketplace.