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!
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.