Chargement des images avec PIXI JS
#1
Bonjour,

Alors voilà, j'utilise le "Framework js" Pixi pour faire un jeu. Un truc simple, du moins pour l'instant.


Le problème est le chargement des images qui se fait de manière asynchrone.
Si j'instancie deux classes qui font appel au loader il me sort une erreur: Cannot add resources while the loader is running.
Je ne vois pas comment faire celà proprement pour l'instant.
Peut être un loader général qui mettrai en queue le chargement de l'asset + le callback en attendant que le précédent soit chargé?
Je vous colle une de mes classe concernée par ce problème:


Code :
class ChanceChoice {
   constructor(app, pixi) {
       this.app = app;
       this.loader = pixi.loader;
       this.container = new PIXI.Container();
       this.container.x = pixi.renderer.width *0.02;
       this.container.y = pixi.renderer.height *0.02;
       this.container.width = pixi.renderer.width *0.8;
       pixi.stage.addChild(this.container);
       
       this.assetsFunc = [];
   }
   
   loadAsset(name) {

       var load = this.loader
           .add({
               name: name,
               url: "/assets/" + name + ".png"
           }).load(function () {
               if (!(name in this.assetsFunc)) {
                   return;
               }
               var nbFuncs = this.assetsFunc[name].length;
               while (nbFuncs--) {
                   this.assetsFunc[name][i]();
                   this.assetsFunc[name].splice(i,1);
               }
               
           }.bind(this));
   }
   
   setChances(chances) {
       for (var i=0, j=chances.length; i<j; i++) {
           if (!(chances[i].img in this.loader.resources)) {
               var res = this.loadAsset(chances[i].img);
           }
           
           this.showChance(chances[i].id, chances[i].img, i);

       }
   }
   
   showChance(id, imgPath, nb) {
       if (!("texture" in this.loader.resources[imgPath])) {
           if (!(imgPath in this.assetsFunc)) {
               this.assetsFunc[imgPath] = [];
           }
           this.assetsFunc[imgPath].push(this.addChance(id, imgPath, nb));
           return;
       }
       this.addChance(id, imgPath, nb)();
       return true;
   }
   
   addChance(id, imgPath, nb) {
       var func = function() {
               let elmt = new PIXI.Sprite(this.loader.resources[imgPath].texture);
               elmt.x = (elmt.width + 10) * nb;
               elmt.y = 100;
               elmt.id = id;
               elmt.interactive = true;
               elmt.buttonMode = true;
               elmt.on('pointerdown', function(evt) {
                   this.sendChoice(evt.target.id);
               }.bind(this));
               this.container.addChild(elmt);
           }.bind(this);
           
           return func;
   }
   
   sendChoice(id) {
       this.app.xhr.open("GET", "/test.json");
       this.app.xhr.send();
   }
}
Répondre
#2
(12-18-2017, 10:51 PM)Konqueror a écrit : Peut être un loader général qui mettrai en queue le chargement de l'asset + le callback en attendant que le précédent soit chargé?

c'est ce qui semble être la réponse des forums anglophones
[WIP]projet Rivages
[WIP]projet Arthur (comme si ça suffisait pas d'un...)
Répondre
#3
Je suis potentiellement hors-sujet, mais si la question est de faire du pré-chargement d'images ou d'assets en général, il existe le <link rel="preload" as="image" href="..."/> dans le header de la page (à voir de preload/prefetch/prerender lequel est le plus adapté au cas présent). Cela permet de laisser le navigateur faire sa popote tout seul pour savoir quelle ressource charger en priorité et quand, sans dépendre d'aucun bibliothèque de code.
Répondre
#4
Ter Rowan, Alors le système de queue en fait n'est pas réalisable car, de ce que j'ai compris, je ne peux pas relancer un "add()" une fois qu'on a lancé le "load()".
Enfin je pense que l'on peux, mais je doit attendre que le load soit terminé.

Je suis parti sur une autre methode du coup:

Code :
loadImgs(imgs, callback) {
       var uncached = {};
       for (var prop in imgs) {
           if (!(prop in this.pixi.loader.resources)) {
               uncached[prop] = imgs[prop];
           }
       }

       if (Object.keys(uncached).length === 0 && uncached.constructor === Object) {
           callback();
       }

       for (var subprop in uncached) {
           this.pixi.loader
           .add({
               name: subprop,
               url: uncached[subprop]
           });
       }
       this.pixi.loader.once("complete", function (loader, resources) {
           callback();
       }).load();
   }

Alors ça fonctionne bien, le callback à passer étant le lancement de l'app.
Le problème est que je doit charger les images au démarrage, ce qui va m'obliger à préparer et envoyer les noms et path des images à charger.

Xenos, j'ai pas précisé mais il y aura des appels xhr et le problème reste le même que celui de la prépa des images coté serveur
Répondre
#5
A voir sinon, mais t'as aussi les service workers (assez délicat à manipuler, comme tout ce qui touche à ces optimisations de pré-cache): https://developer.mozilla.org/en-US/docs...ce_Workers et (dans ton cas) la partie cache https://developer.mozilla.org/en-US/docs/Web/API/Cache
J'avais un peu mis les mains dedans, puis finalement, j'ai laissé tomber vu que ce n'est pas capital pour mes minis-jeux (le but était d'éviter de recharger le jeu à chaque partie, mais bof, finalement, c'est pas lourd à l'exécution, et cela me permet de compter les parties jouées). Mais je crois que tu peux envoyer dans le cache du navigateur un ou plusieurs assets. Ca vaut le coup de regarder (ça prend une trentaine de lignes à coder, donc, ca sera surtout de la formation et de la réflexion plus que de l'alignement de code).

Bon, après, ça reste encore peut-être hors-sujet de base, mais c'est toujours cool de voir ces APIs natives et leurs possibilités 2
Répondre
#6
Alors j'ai lu en diagonale tes liens, je m'explique.
Pour avoir déjà fait une app dans le style RPG en vanilla, on se retrouve plus à devoir travailler sur le moteur de jeu que sur le jeu lui même (Je suis pas sur d'être clair dans mon explication :p).

Je suis seul pour l'instant, c'est pourquoi j'utilise PixiJS afin qu'il m'absorbe ces couches (compatibilité entre les navigateurs, helpers, ...).
Je pense que pixi l'utilise, mais je n'irai pas vérifier!

Je donnerai plus de détails sur mon jeu quand ça sera plus stable niveau technos utilisées, car là je vous balance des phrases sans contexte, c'est compliqué pour vous. Je teste pour l'instant.

Vous avez un chan IRC ou un Discord pour le site?
Répondre


Sujets apparemment similaires...
Sujet Auteur Réponses Affichages Dernier message
  Vectoriser des images et travailler des images vectorielles L'Omniscient 8 2 329 06-01-2016, 02:35 PM
Dernier message: @lucard
  Problème avec mon uploader d'images kersam 5 2 458 03-06-2009, 02:11 AM
Dernier message: Sylvain



Utilisateur(s) parcourant ce sujet : 1 visiteur(s)