2009-12-24 7 views
2

[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).

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-

Répondre

0

Je n'ai pas essayé SVG animation (pour l'instant); mais Canvas est étonnamment bon; surtout si vous faites des calques.

En résumé, créez un objet canvas pour chaque calque et effacez/redessinez chaque objet séparément. Vous pouvez également faire un blitting rapide entre une toile hors écran et celles qui sont affichées.

Je sais, en théorie SVG devrait être beaucoup plus rapide; mais comme vous l'avez remarqué, l'analyse syntaxique DOM vous tue. avec Canvas, il n'y a pas besoin de ça.

+0

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

+0

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

0

Bon, commençons par le commencement:

Dude - qui est le bit le plus impressionnant de SVG j'ai jamais vu. Merci de partager cela.

Il a fonctionné parfaitement bien sur mon système, jusqu'à ce que j'ai détruit tout un tas de roches à la fois. Que faire si vous remplacez l'animation dynamique de frag par une animation SVG pré-faite? Est-ce que cela améliore les performances?

+0

C'est une bonne idée. Je ne suis pas certain si cela va accélérer, mais ça vaut vraiment la peine d'essayer. – pdkl95

Questions connexes