Page 1 of 2

Event listener when loading is done

Posted: 06 June 2020, 23:03
by Tisaac
Hi !

Is there any function or event listener we can use to trigger function once all the assets are loaded and the page is displayed ?
I would like to do some animation when entering the page, but if I launch it during the setup, it's already finished before the page actually render...

Re: Event listener when loading is done

Posted: 08 June 2020, 01:01
by Tisaac
I've "retro-enginered" the code of BGA and there are no call to any function once load is finished :(
However, I've found a workaroud by observing style change on loader_mask :

Code: Select all

			
			var target = document.getElementById('loader_mask');
			var observer = new MutationObserver(function(mutations) {
				if(target.style.display == 'none')
					_this.onLoaderOff();
			});
			observer.observe(target, { attributes : true, attributeFilter : ['style'] });

Re: Event listener when loading is done

Posted: 08 June 2020, 09:36
by sourisdudesert
hi

I really don't know if this is a good idea to add some animation each time you reload a game page. For turn based players, are you sure you want to have an animation before playing each move? It's also going to be triggered during games replay, and for spectators, which I don't know if appropriate.

At now there is no function in the framework because we never met the case where it could have been useful.

Re: Event listener when loading is done

Posted: 08 June 2020, 10:10
by Tisaac
When I enter the Santorini game, I want to make some animation to zoom on the 3D board to really feels like you are entering the game.
The animation last < 2s and it's only a zoom so you can already think about what you are going to do (and you can even click during the animation).
We will see what the alpha testers think about it, but I understand that it is not the common behavior for most games.

Re: Event listener when loading is done

Posted: 08 June 2020, 10:18
by sourisdudesert
Just tested it: this is REALLY beautiful. Love it.

Re: Event listener when loading is done

Posted: 08 June 2020, 10:32
by Tisaac
Glad you like it :D

I've also noticed from the source code that a function "onChangePreference" exists. Is this called when a player change its preferences without reloading the page ?

Re: Event listener when loading is done

Posted: 08 June 2020, 10:37
by sourisdudesert
Yes. However, I should warn you about everything that is undocumented: something that is undocumented may change without any warnings, and this may break your code. So if you really want to use something that is undocumented, you should make sure to detect first if the feature is still there, and make sure the game is still working even if it is not there.

Re: Event listener when loading is done

Posted: 08 June 2020, 11:53
by Draasill
Hi,

hijacking this thread about the preferences.

I understand very well that an undocumented method is not a good idea to use.

But ATM, i'm using something like :

Code: Select all

			dojo.connect(
				$('preference_control_100'),
				'onchange',
				this,
				'myMethod'
			)
I stole the code from the "frenchtarot" game.

IMO this is worst, depending on the UI of BGA.

Since there are preferences with "needReload" and some without, it's sad not being able to connect to pref change :)

Re: Event listener when loading is done

Posted: 11 June 2020, 13:48
by Draasill
Hoping that it may help others, or that this kind of "polyfill" would be natively in the framework one day, here is how I listen to preferences changes, or set them programmatically :

Code: Select all


		// Set a preference value
		// (actually change the select in preference_control_NNN)
		setPreferenceValue: function(number, newValue) {
			var optionSel = 'option[value="' + newValue + '"]'
			dojo
				.query(
					'#preference_control_' +
						number +
						' > ' +
						optionSel +
						', #preference_fontrol_' +
						number +
						' > ' +
						optionSel
				)
				.attr('selected', true)
			// Trigger the onchange event
			var select = $('preference_control_' + number)
			// IE does things differently
			if (dojo.isIE) {
				select.fireEvent('onchange')
			} else {
				// Not IE
				var event = document.createEvent('HTMLEvents')
				event.initEvent('change', false, true)
				select.dispatchEvent(event)
			}
		},

		// Listen for "change" events on preference_control_NNN select,
		// then call this.onPreferenceChange
		initPreferencesObserver: function() {
			dojo.query('.preference_control').on(
				'change',
				dojo.hitch(this, function(e) {
					var match = e.target.id.match(/^preference_control_(\d+)$/)
					if (!match) {
						// Not a "game" preference control
						return
					}
					var pref = match[1]
					var newValue = e.target.value
					// Change this.prefs
					this.prefs[pref].value = newValue
					// Call "onPreferenceChange"
					this.onPreferenceChange(pref, newValue)
				})
			)
		},
Then you just have to use "onPreferenceChange" to listen, or "setPreferenceValue" to update one (while keeping the select boxes in sync).

Code: Select all


		// Called when a preference is set
		onPreferenceChange: function(pref, value) {
			switch (pref) {
				case '100':
					this.doSomeThing()
					break
				case '102':
					this.doAnotherThing()
					break
			}
		},
Thanks to @woodruff for the hack in the tarot code :)

Re: Event listener when loading is done

Posted: 05 July 2020, 12:38
by quietmint
sourisdudesert wrote: 08 June 2020, 09:36 At now there is no function in the framework because we never met the case where it could have been useful.
We do need this! In many games there is an automatic countdown timer that triggers an action after a few seconds (e.g., both Coup and Santorini have this). The countdown timer should not start until the game UI is completely loaded. If loading is slow, then automatic action may happen before the player can stop it.

I propose the following as a better method. This overrides BGA framework setLoader hook, and calls your own hook onLoadingComplete() when the progress gets to 100%.

Code: Select all

define(["dojo", "dojo/_base/declare", "ebg/core/gamegui", "ebg/counter", "ebg/stock", "ebg/scrollmap"], function (dojo, declare) {

  // Dojo ShrinkSafe does not support named function expressions
  // To use this.inherited(), define the function here (not inside "return")

  var isLoadingComplete = false;
  function override_setLoader(value, max) {
    // [Undocumented] Called by BGA framework when loading progress changes
    // Call our onLoadingComplete() function once when done
    this.inherited(override_setLoader, arguments);
    if (!isLoadingComplete && value >= 100) {
      isLoadingComplete = true;
      this.onLoadingComplete();
    }
  }

  return declare("bgagame.yourgame", ebg.core.gamegui, {
    /*
     * [Undocumented] Override BGA framework functions
     */
    setLoader: override_setLoader,
    
    onLoadingComplete: function() {
      // your code here
    },
    
    ...
[code]