[modifier] soupir ... la "protection anti-spam" ici ne me laisse pas publier les liens, donc je suppose que ce sont des URI à la place [/ edit] [edit2] ok, BROKEN forms de l'URI qui peut dépasser l'expression rationnelle ... [/ edit2]Gestion efficace des entités SVG en temps réel avec javascript
Je vais commencer par dire que je suis totalement nouveau à SVG, et un peu nouveau à Javascript, étant venu d'un contexte de bas niveau C. Sur un coup de tête, cependant, j'ai décidé de m'essayer à l'écriture d'un jeu en temps réel en utilisant toutes ces nouvelles technologies web amusantes.
Je suis entièrement préparé pour la réponse à être "Le Web ne peut pas encore faire cela, désolé!" Cela peut simplement être trop de débit de données pour un navigateur. J'ai donc écrit les débuts d'un clone d'astéroïdes. C'est ce que j'ai écrit. C'est un document SVG mince, avec le jeu entier étant généré dynamiquement en tant qu'entités ligne/polygone SVG à partir de javascript. À ma grande surprise, cela a fonctionné. J'ai été en mesure d'obtenir principalement animation lisse de Firefox 3.5 (pas testé sur autre chose).
- original, as-needed allocation version
- (javascript) http - public.codenazi.fastmail.fm/asteroids_dynamic.js~~V~~singular~~3rd
Cela fait des variations de ce à chaque fois un rocher, il a frappé:
// on startup
svg_ns = 'http://www.w3.org/2000/svg';
container = svgdoc.getElementById('rocks');
// each time a rock breaks, times ~20
x = svgdoc.createElementNS(svg_ns, "polygon");
x.setAttribute(...various things...);
container.appendChild(x);
Malheureusement, ce n'est pas assez lisse. Il traîne tout le temps. Il y a des saccades et des ruptures dans le flux, même sur ma boîte 3GHz moderne. Plusieurs amis que je l'ai montré se sont immédiatement plaints du bégaiement. J'ai passé la dernière semaine à lire comment optimiser javascript, ce qui a légèrement aidé, mais je pense que toutes les insertions/suppressions que je fais au DOM pour presque chaque action dans le Jeu. J'ai examiné divers schémas de pré-allocation, et je ne veux pas vraiment de gestionnaire de mémoire compliqué si cela ne va pas vraiment aider.
Ce qui a beaucoup été mentionné dans mes recherches, ce sont les discussions sur le «refusion» et le «repeindre». Si je comprends bien, toute insertion/suppression sur le DOM provoquera une sorte de re-parse de l'arbre entier, ce qui est lent. La solution commune consistait à collecter d'abord les sous-noeuds et à ne faire qu'un seul insert dans le document réel. Ce modèle ne fonctionne pas vraiment avec un jeu comme celui-ci, cependant. En tant que test, j'ai en quelque sorte combiné les deux idées: pré-allouer si possible, et insérer dans les groupes lorsque cela est possible. Donc, dans cette version, chaque astéroïde est remplacé par un groupe SVG, et l'astéroïde, ses effets d'explosion et son score pop-up sont créés en une seule fois. De cette façon, les allocations et les insertions ne se produisent que lorsque des astéroïdes sont créés (non détruits). Pour garder ces effets cachés jusqu'à ce qu'ils soient nécessaires, je définis l'attribut "display: hidden".
- nouvelle version de groupe préalloué: http - public.codenazi.fastmail.fm/asteroids_prealloc.svg
- (javascript): http - public.codenazi.fastmail.fm/asteroids_prealloc.js
Quand les roches sont créé, cela se produit à la place:
g = svgdoc.createElementNS(svg_ns, "g");
// make the rock itself
rock = svgdoc.createElementNS(svg_ns, "polygon");
rock.setAttribute(...various things...);
g.appendChild(rock);
// make the destroy effect (repeated many times)
frag = svgdoc.createElementNS(svg_ns, "line");
frag.setAttribute(...various things...);
frag.style.display = 'none';
g.appendChild(frag);
// actually add it
container.appendChild(g);
// then, sometime later when a hit is detected
rock.style.display = 'none';
frag.style.display = 'block';
Je pense que ce SAVIEZ le rendre un peu plus lisse! Mais ... il a également baissé le framerate de manière significative. Je dois garder la trace de plus d'éléments à la fois, et certains tests ont montré que le fait de tout emballer dans un autre élément rend le rendu du SVG plus lent aussi.
Donc, ma question est la suivante: est-ce encore possible? Puis-je obtenir une animation SVG raisonnablement fluide comme celle-ci sur firefox? Ou firefox va-t-il intrinsèquement avoir des stalles/bègues? Si c'est possible, existe-t-il une technique de gestion de la mémoire/des éléments qui peut allouer/insérer des éléments SVG d'une meilleure manière que je le suis actuellement?
Je genre de soupçonne que la réponse sera juste coller avec la première méthode plus facile avec moins d'éléments et d'attendre pour l'avenir lorsque les navigateurs sont mieux ... -sigh-
Je me doute que c'est la bonne solution, mais pour l'instant je vais envisager d'utiliser Canvas pour abandonner. La moitié du but était d'essayer de s'appuyer sur le SVG, donc la toile défait le but. – pdkl95
Waaaaay mise à jour tardive, mais j'ai le sens re-mis en œuvre l'ensemble du jeu en utilisant Canvas, et il fonctionne beaucoup mieux que vous avez dit. La différence de douceur est stupéfiante. Je suppose que je vais devoir attendre que SVG rattrape ... – pdkl95