|  | @@ -14,15 +14,6 @@ const game = {
 | 
	
		
			
				|  |  |    sprite: {}, // [Not directly used] Holds cached reference to media.
 | 
	
		
			
				|  |  |    audio: {}, // Holds cached reference to media - game.audio.<name>.play() plays that audio once.
 | 
	
		
			
				|  |  |    lang: {}, // Holds language dictionary in a key-value format - game.lang.<key> returns <value>.
 | 
	
		
			
				|  |  | -  loadedCur: 0, // [Not directly used] CURRENT number of cached media (on current state)
 | 
	
		
			
				|  |  | -  loadedMax: 0, // [Not directly used] EXPECTED number of cached media (on current state)
 | 
	
		
			
				|  |  | -  loadManager: {
 | 
	
		
			
				|  |  | -    // [Not directly used] <mediaCategory> : [ <isLoading?> , <#CurrentlyCached> ]
 | 
	
		
			
				|  |  | -    lang: [false, 0],
 | 
	
		
			
				|  |  | -    audio: [false, 0],
 | 
	
		
			
				|  |  | -    image: [false, 0],
 | 
	
		
			
				|  |  | -    sprite: [false, 0],
 | 
	
		
			
				|  |  | -  },
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    /** 
 | 
	
		
			
				|  |  |     * Handles game states. <br>
 | 
	
	
		
			
				|  | @@ -43,6 +34,9 @@ const game = {
 | 
	
		
			
				|  |  |      list: [],
 | 
	
		
			
				|  |  |      // [Not directly used]
 | 
	
		
			
				|  |  |      name: undefined,
 | 
	
		
			
				|  |  | +    // progressBar
 | 
	
		
			
				|  |  | +    progressBar: undefined,
 | 
	
		
			
				|  |  | +    progressBarLabel: undefined,
 | 
	
		
			
				|  |  |      /**
 | 
	
		
			
				|  |  |       * Create new state. <br>
 | 
	
		
			
				|  |  |       *
 | 
	
	
		
			
				|  | @@ -85,16 +79,23 @@ const game = {
 | 
	
		
			
				|  |  |            colors.blueBg,
 | 
	
		
			
				|  |  |            1
 | 
	
		
			
				|  |  |          );
 | 
	
		
			
				|  |  | -        self.progressBar = game.add.geom.rect(
 | 
	
		
			
				|  |  | +        game.state.progressBar = game.add.geom.rect(
 | 
	
		
			
				|  |  |            context.canvas.width / 2,
 | 
	
		
			
				|  |  |            context.canvas.height / 2,
 | 
	
		
			
				|  |  | -          20,
 | 
	
		
			
				|  |  | -          20,
 | 
	
		
			
				|  |  | +          40,
 | 
	
		
			
				|  |  | +          40,
 | 
	
		
			
				|  |  |            undefined,
 | 
	
		
			
				|  |  |            0,
 | 
	
		
			
				|  |  | -          colors.white
 | 
	
		
			
				|  |  | +          colors.blueBgOff
 | 
	
		
			
				|  |  | +        );
 | 
	
		
			
				|  |  | +        game.state.progressBar.anchor(0.5, 0.5);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        game.state.progressBarLabel = game.add.text(
 | 
	
		
			
				|  |  | +          context.canvas.width / 2,
 | 
	
		
			
				|  |  | +          context.canvas.height / 2 + 100,
 | 
	
		
			
				|  |  | +          '0/0',
 | 
	
		
			
				|  |  | +          textStyles.h2_blue
 | 
	
		
			
				|  |  |          );
 | 
	
		
			
				|  |  | -        self.progressBar.anchor(0.5, 0.5);
 | 
	
		
			
				|  |  |          // Calls state's preload() to load the state's media
 | 
	
		
			
				|  |  |          self.preload();
 | 
	
		
			
				|  |  |        } else {
 | 
	
	
		
			
				|  | @@ -123,6 +124,87 @@ const game = {
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  |    },
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  loadHandler: {
 | 
	
		
			
				|  |  | +    cur: 0, // [Not directly used] CURRENT number of cached media (on current state)
 | 
	
		
			
				|  |  | +    max: 0, // [Not directly used] EXPECTED number of cached media (on current state)
 | 
	
		
			
				|  |  | +    // [Not directly used] media type and status information
 | 
	
		
			
				|  |  | +    type: {
 | 
	
		
			
				|  |  | +      lang: { isLoading: false, cached: 0, length: 0 },
 | 
	
		
			
				|  |  | +      audio: { isLoading: false, cached: 0, length: 0 },
 | 
	
		
			
				|  |  | +      image: { isLoading: false, cached: 0, length: 0 },
 | 
	
		
			
				|  |  | +      sprite: { isLoading: false, cached: 0, length: 0 },
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    /** [Not directly used] Removes the urls that are already in the cache.
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param {string[]} unfilteredUrls array of urls
 | 
	
		
			
				|  |  | +     * @param {object} mediaCategory media category
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @returns {string[]} array of uncached urls
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    getUncachedUrlsOnly: function (unfilteredUrls, mediaCategory) {
 | 
	
		
			
				|  |  | +      const uncachedUrls = [];
 | 
	
		
			
				|  |  | +      unfilteredUrls.forEach((url) => {
 | 
	
		
			
				|  |  | +        if (mediaCategory[url[0]] === undefined) uncachedUrls.push(url);
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  | +      return uncachedUrls;
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    /** [Not directly used] Informs ONE media file was loaded to cache. <br>
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * After ALL FILES of the SAME CATEGORY are cached, calls game.load.cachedAllInOneMediaType()
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * @param {String} mediaType media category (to update the cached files from that category)
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    cachedOneFile: function (mediaType) {
 | 
	
		
			
				|  |  | +      const length = game.loadHandler.type[mediaType].length;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      // Update progress bar on loading screen
 | 
	
		
			
				|  |  | +      if (length - 1 !== 0) {
 | 
	
		
			
				|  |  | +        // if (game.state..progressBarLabel?.name) {
 | 
	
		
			
				|  |  | +        //   game.state..progressBarLabel.name = `${game.loadHandler.cur + 1}/${
 | 
	
		
			
				|  |  | +        //     game.loadHandler.max
 | 
	
		
			
				|  |  | +        //   }`;
 | 
	
		
			
				|  |  | +        // }
 | 
	
		
			
				|  |  | +        game.state.progressBar.width =
 | 
	
		
			
				|  |  | +          (500 / game.loadHandler.max) * game.loadHandler.cur;
 | 
	
		
			
				|  |  | +        game.render.all();
 | 
	
		
			
				|  |  | +        game.loadHandler.cur++;
 | 
	
		
			
				|  |  | +        // console.log(game.loadHandler.cur, game.loadHandler.max);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      // If reached last index of current media array
 | 
	
		
			
				|  |  | +      if (game.loadHandler.type[mediaType].cached >= length - 1) {
 | 
	
		
			
				|  |  | +        // Resets load manager
 | 
	
		
			
				|  |  | +        game.loadHandler.type[mediaType].isLoading = false;
 | 
	
		
			
				|  |  | +        game.loadHandler.type[mediaType].cached = 0;
 | 
	
		
			
				|  |  | +        game.loadHandler.type[mediaType].length = 0;
 | 
	
		
			
				|  |  | +        // Informs
 | 
	
		
			
				|  |  | +        game.loadHandler.cachedAllInOneMediaType();
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  | +        // Updates
 | 
	
		
			
				|  |  | +        game.loadHandler.type[mediaType].cached++;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +    /** [Not directly used] Informs ALL MEDIA files from the SAME CATEGORY are cached. <br>
 | 
	
		
			
				|  |  | +     *
 | 
	
		
			
				|  |  | +     * After ALL CATEGORIES of media are cached, calls create() via game.state. <br>
 | 
	
		
			
				|  |  | +     * ATTENTION: Do not call create() directly.
 | 
	
		
			
				|  |  | +     */
 | 
	
		
			
				|  |  | +    cachedAllInOneMediaType: function () {
 | 
	
		
			
				|  |  | +      // Checks if finished loading ALL media categories
 | 
	
		
			
				|  |  | +      let endPreload = true;
 | 
	
		
			
				|  |  | +      for (let key in game.loadHandler.type) {
 | 
	
		
			
				|  |  | +        if (game.loadHandler.type[key].isLoading) {
 | 
	
		
			
				|  |  | +          endPreload = false;
 | 
	
		
			
				|  |  | +          break;
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      // If flag doesnt change, all media is cached
 | 
	
		
			
				|  |  | +      if (endPreload) {
 | 
	
		
			
				|  |  | +        game.loadHandler.cur = 0;
 | 
	
		
			
				|  |  | +        game.loadHandler.max = 0;
 | 
	
		
			
				|  |  | +        game.state.create();
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    },
 | 
	
		
			
				|  |  | +  },
 | 
	
		
			
				|  |  |    /**
 | 
	
		
			
				|  |  |     * Loads media files to cache. <br>
 | 
	
		
			
				|  |  |     *
 | 
	
	
		
			
				|  | @@ -141,26 +223,31 @@ const game = {
 | 
	
		
			
				|  |  |       * @param {string} url url for the selected language
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      lang: function (url) {
 | 
	
		
			
				|  |  | -      game.loadManager.lang[0] = true;
 | 
	
		
			
				|  |  | -      game.loadManager.lang[1] = 0;
 | 
	
		
			
				|  |  | +      game.loadHandler.type.lang.isLoading = true;
 | 
	
		
			
				|  |  | +      game.loadHandler.type.lang.cached = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |        game.lang = {}; // Clear previously loaded language
 | 
	
		
			
				|  |  | -      const init = { mode: 'same-origin' };
 | 
	
		
			
				|  |  | -      fetch(url, init)
 | 
	
		
			
				|  |  | -        .then((response) => {
 | 
	
		
			
				|  |  | -          return response.text();
 | 
	
		
			
				|  |  | -        })
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      fetch(url, { mode: 'same-origin' })
 | 
	
		
			
				|  |  | +        .then((response) => response.text())
 | 
	
		
			
				|  |  |          .then((text) => {
 | 
	
		
			
				|  |  | -          let msg = text.split('\n');
 | 
	
		
			
				|  |  | -          game.loadedMax += msg.length - 1;
 | 
	
		
			
				|  |  | -          msg.forEach((cur) => {
 | 
	
		
			
				|  |  | +          const lines = text.split('\n');
 | 
	
		
			
				|  |  | +          game.loadHandler.type.lang.length = lines.length;
 | 
	
		
			
				|  |  | +          game.loadHandler.max += lines.length;
 | 
	
		
			
				|  |  | +          lines.forEach((line) => {
 | 
	
		
			
				|  |  |              try {
 | 
	
		
			
				|  |  | -              let msg = cur.split('=');
 | 
	
		
			
				|  |  | +              const msg = line.split('=');
 | 
	
		
			
				|  |  | +              if (msg.length !== 2)
 | 
	
		
			
				|  |  | +                throw Error('Game error: sintax error in i18y file');
 | 
	
		
			
				|  |  |                game.lang[msg[0].trim()] = msg[1].trim();
 | 
	
		
			
				|  |  | -            } catch (Error) {
 | 
	
		
			
				|  |  | -              if (isDebugMode) console.log('Sintax error fixed');
 | 
	
		
			
				|  |  | +            } catch (error) {
 | 
	
		
			
				|  |  | +              console.error(error.message);
 | 
	
		
			
				|  |  |              }
 | 
	
		
			
				|  |  | -            game.load.finishedOneMediaElement(msg.length - 1, 'lang');
 | 
	
		
			
				|  |  | +            game.loadHandler.cachedOneFile('lang');
 | 
	
		
			
				|  |  |            });
 | 
	
		
			
				|  |  | +        })
 | 
	
		
			
				|  |  | +        .catch((error) => {
 | 
	
		
			
				|  |  | +          console.error(error);
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  |      /**
 | 
	
	
		
			
				|  | @@ -170,20 +257,27 @@ const game = {
 | 
	
		
			
				|  |  |       * @param {string[]} urls audio urls for the current state
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      audio: function (urls) {
 | 
	
		
			
				|  |  | -      game.loadManager.audio[0] = true;
 | 
	
		
			
				|  |  | -      game.loadManager.audio[1] = 0;
 | 
	
		
			
				|  |  | -      urls = this.getUncachedUrls(urls, game.audio);
 | 
	
		
			
				|  |  | +      game.loadHandler.type.audio.isLoading = true;
 | 
	
		
			
				|  |  | +      game.loadHandler.type.audio.cached = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      urls = game.loadHandler.getUncachedUrlsOnly(urls, game.audio);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      game.loadHandler.type.audio.length = urls.length;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |        if (urls.length == 0) {
 | 
	
		
			
				|  |  | -        game.load.finishedOneMediaElement(0, 'audio');
 | 
	
		
			
				|  |  | +        game.loadHandler.cachedOneFile('audio');
 | 
	
		
			
				|  |  |        } else {
 | 
	
		
			
				|  |  | -        game.loadedMax += urls.length - 1;
 | 
	
		
			
				|  |  | -        const init = { mode: 'same-origin' };
 | 
	
		
			
				|  |  | -        urls.forEach((cur) => {
 | 
	
		
			
				|  |  | -          fetch(cur[1][1], init)
 | 
	
		
			
				|  |  | +        game.loadHandler.max += urls.length;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        urls.forEach((url) => {
 | 
	
		
			
				|  |  | +          fetch(url[1][1], { mode: 'same-origin' })
 | 
	
		
			
				|  |  |              .then((response) => response.blob())
 | 
	
		
			
				|  |  | -            .then((myBlob) => {
 | 
	
		
			
				|  |  | -              game.audio[cur[0]] = new Audio(URL.createObjectURL(myBlob));
 | 
	
		
			
				|  |  | -              game.load.finishedOneMediaElement(urls.length - 1, 'audio');
 | 
	
		
			
				|  |  | +            .then((data) => {
 | 
	
		
			
				|  |  | +              game.audio[url[0]] = new Audio(URL.createObjectURL(data));
 | 
	
		
			
				|  |  | +              game.loadHandler.cachedOneFile('audio');
 | 
	
		
			
				|  |  | +            })
 | 
	
		
			
				|  |  | +            .catch((error) => {
 | 
	
		
			
				|  |  | +              console.error(error);
 | 
	
		
			
				|  |  |              });
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  |        }
 | 
	
	
		
			
				|  | @@ -195,20 +289,31 @@ const game = {
 | 
	
		
			
				|  |  |       * @param {string[]} urls image urls for the current state
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      image: function (urls) {
 | 
	
		
			
				|  |  | -      game.loadManager.image[0] = true;
 | 
	
		
			
				|  |  | -      game.loadManager.image[1] = 0;
 | 
	
		
			
				|  |  | -      urls = this.getUncachedUrls(urls, game.image);
 | 
	
		
			
				|  |  | +      game.loadHandler.type.image.isLoading = true;
 | 
	
		
			
				|  |  | +      game.loadHandler.type.image.cached = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      urls = game.loadHandler.getUncachedUrlsOnly(urls, game.image);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      game.loadHandler.type.image.length = urls.length;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |        if (urls.length == 0) {
 | 
	
		
			
				|  |  | -        game.load.finishedOneMediaElement(0, 'image');
 | 
	
		
			
				|  |  | +        game.loadHandler.cachedOneFile('image');
 | 
	
		
			
				|  |  |        } else {
 | 
	
		
			
				|  |  | -        game.loadedMax += urls.length - 1;
 | 
	
		
			
				|  |  | -        urls.forEach((cur) => {
 | 
	
		
			
				|  |  | +        game.loadHandler.max += urls.length;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        urls.forEach((url) => {
 | 
	
		
			
				|  |  |            const img = new Image();
 | 
	
		
			
				|  |  |            img.onload = () => {
 | 
	
		
			
				|  |  | -            game.image[cur[0]] = img;
 | 
	
		
			
				|  |  | -            game.load.finishedOneMediaElement(urls.length - 1, 'image');
 | 
	
		
			
				|  |  | +            game.image[url[0]] = img;
 | 
	
		
			
				|  |  | +            game.loadHandler.cachedOneFile('image');
 | 
	
		
			
				|  |  | +          };
 | 
	
		
			
				|  |  | +          img.onerror = () => {
 | 
	
		
			
				|  |  | +            console.error('Game error: image not found');
 | 
	
		
			
				|  |  | +            game.image[url[0]] = img;
 | 
	
		
			
				|  |  | +            img.src = fallbackImgUrl;
 | 
	
		
			
				|  |  | +            game.loadHandler.cachedOneFile('image');
 | 
	
		
			
				|  |  |            };
 | 
	
		
			
				|  |  | -          img.src = cur[1];
 | 
	
		
			
				|  |  | +          img.src = url[1];
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      },
 | 
	
	
		
			
				|  | @@ -219,83 +324,40 @@ const game = {
 | 
	
		
			
				|  |  |       * @param {string[]} urls spritesheet urls for the current state
 | 
	
		
			
				|  |  |       */
 | 
	
		
			
				|  |  |      sprite: function (urls) {
 | 
	
		
			
				|  |  | -      game.loadManager.sprite[0] = true;
 | 
	
		
			
				|  |  | -      game.loadManager.sprite[1] = 0;
 | 
	
		
			
				|  |  | -      urls = this.getUncachedUrls(urls, game.sprite);
 | 
	
		
			
				|  |  | +      game.loadHandler.type.sprite.isLoading = true;
 | 
	
		
			
				|  |  | +      game.loadHandler.type.sprite.cached = 0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      urls = game.loadHandler.getUncachedUrlsOnly(urls, game.sprite);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +      game.loadHandler.type.sprite.length = urls.length;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |        if (urls.length == 0) {
 | 
	
		
			
				|  |  | -        game.load.finishedOneMediaElement(0, 'sprite');
 | 
	
		
			
				|  |  | +        game.loadHandler.cachedOneFile('sprite');
 | 
	
		
			
				|  |  |        } else {
 | 
	
		
			
				|  |  | -        game.loadedMax += urls.length - 1;
 | 
	
		
			
				|  |  | -        urls.forEach((cur) => {
 | 
	
		
			
				|  |  | -          const img = new Image();
 | 
	
		
			
				|  |  | -          img.onload = () => {
 | 
	
		
			
				|  |  | -            game.sprite[cur[0]] = img;
 | 
	
		
			
				|  |  | -            game.load.finishedOneMediaElement(urls.length - 1, 'sprite');
 | 
	
		
			
				|  |  | -          };
 | 
	
		
			
				|  |  | -          img.src = cur[1];
 | 
	
		
			
				|  |  | -          img.frames = cur[2];
 | 
	
		
			
				|  |  | +        game.loadHandler.max += urls.length;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        urls.forEach((url) => {
 | 
	
		
			
				|  |  | +          try {
 | 
	
		
			
				|  |  | +            const img = new Image();
 | 
	
		
			
				|  |  | +            img.onload = () => {
 | 
	
		
			
				|  |  | +              game.sprite[url[0]] = img;
 | 
	
		
			
				|  |  | +              game.loadHandler.cachedOneFile('sprite');
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +            img.onerror = () => {
 | 
	
		
			
				|  |  | +              console.error('Game error: sprite not found');
 | 
	
		
			
				|  |  | +              game.sprite[url[0]] = img;
 | 
	
		
			
				|  |  | +              img.src = fallbackImgUrl;
 | 
	
		
			
				|  |  | +              img.frames = 1;
 | 
	
		
			
				|  |  | +              game.loadHandler.cachedOneFile('sprite');
 | 
	
		
			
				|  |  | +            };
 | 
	
		
			
				|  |  | +            img.src = url[1];
 | 
	
		
			
				|  |  | +            img.frames = url[2];
 | 
	
		
			
				|  |  | +          } catch (error) {
 | 
	
		
			
				|  |  | +            console.error(error);
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  |          });
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      },
 | 
	
		
			
				|  |  | -    /** [Not directly used] Removes the urls that are already in the cache.
 | 
	
		
			
				|  |  | -     *
 | 
	
		
			
				|  |  | -     * @param {string[]} urls array of urls
 | 
	
		
			
				|  |  | -     * @param {object} media media category
 | 
	
		
			
				|  |  | -     *
 | 
	
		
			
				|  |  | -     * @returns {string[]} array of uncached urls
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    getUncachedUrls: function (urls, media) {
 | 
	
		
			
				|  |  | -      const newUrls = [];
 | 
	
		
			
				|  |  | -      urls.forEach((cur) => {
 | 
	
		
			
				|  |  | -        if (media[cur[0]] == undefined) newUrls.push(cur);
 | 
	
		
			
				|  |  | -      });
 | 
	
		
			
				|  |  | -      return newUrls;
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    /** [Not directly used] Informs ONE media file was loaded to cache. <br>
 | 
	
		
			
				|  |  | -     *
 | 
	
		
			
				|  |  | -     * After ALL FILES of the SAME CATEGORY are cached, calls game.load.finishedOneMediaType()
 | 
	
		
			
				|  |  | -     *
 | 
	
		
			
				|  |  | -     * @param {number} lastIndex last index of the media array (to check if is finished)
 | 
	
		
			
				|  |  | -     * @param {String} mediaType media category (to update the cached files from that category)
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    finishedOneMediaElement: function (lastIndex, mediaType) {
 | 
	
		
			
				|  |  | -      // Updates progress bar
 | 
	
		
			
				|  |  | -      if (lastIndex != 0) {
 | 
	
		
			
				|  |  | -        self.progressBar.width = (200 / game.loadedMax) * game.loadedCur;
 | 
	
		
			
				|  |  | -        game.render.all();
 | 
	
		
			
				|  |  | -        game.loadedCur++;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      // If reached last index of current media array
 | 
	
		
			
				|  |  | -      if (lastIndex == game.loadManager[mediaType][1]) {
 | 
	
		
			
				|  |  | -        // Resets load manager
 | 
	
		
			
				|  |  | -        game.loadManager[mediaType][0] = false;
 | 
	
		
			
				|  |  | -        game.loadManager[mediaType][1] = 0;
 | 
	
		
			
				|  |  | -        // Informs
 | 
	
		
			
				|  |  | -        game.load.finishedOneMediaType();
 | 
	
		
			
				|  |  | -      } else {
 | 
	
		
			
				|  |  | -        // Updates
 | 
	
		
			
				|  |  | -        game.loadManager[mediaType][1]++;
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  | -    /** [Not directly used] Informs ALL MEDIA files from the SAME CATEGORY are cached. <br>
 | 
	
		
			
				|  |  | -     *
 | 
	
		
			
				|  |  | -     * After ALL CATEGORIES of media are cached, calls create() via game.state. <br>
 | 
	
		
			
				|  |  | -     * ATTENTION: Do not call create() directly.
 | 
	
		
			
				|  |  | -     */
 | 
	
		
			
				|  |  | -    finishedOneMediaType: function () {
 | 
	
		
			
				|  |  | -      // Checks if finished loading ALL media categories
 | 
	
		
			
				|  |  | -      let endPreload = true;
 | 
	
		
			
				|  |  | -      for (let key in game.loadManager) {
 | 
	
		
			
				|  |  | -        if (game.loadManager[key][0] == true) {
 | 
	
		
			
				|  |  | -          endPreload = false;
 | 
	
		
			
				|  |  | -          break;
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -      // If flag doesnt change, all media is cached
 | 
	
		
			
				|  |  | -      if (endPreload) {
 | 
	
		
			
				|  |  | -        game.state.create();
 | 
	
		
			
				|  |  | -      }
 | 
	
		
			
				|  |  | -    },
 | 
	
		
			
				|  |  |    },
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |    /**
 | 
	
	
		
			
				|  | @@ -432,9 +494,9 @@ const game = {
 | 
	
		
			
				|  |  |          y == undefined ||
 | 
	
		
			
				|  |  |          text == undefined ||
 | 
	
		
			
				|  |  |          style == undefined
 | 
	
		
			
				|  |  | -      )
 | 
	
		
			
				|  |  | +      ) {
 | 
	
		
			
				|  |  |          console.error('Game error: missing parameters.');
 | 
	
		
			
				|  |  | -      else {
 | 
	
		
			
				|  |  | +      } else {
 | 
	
		
			
				|  |  |          const med = {
 | 
	
		
			
				|  |  |            typeOfMedia: 'text',
 | 
	
		
			
				|  |  |            name: text,
 |