dimanche 22 mai 2011

The physic engine adventure

[This is just a tech crazy talk between myself and everyone wondering why I didn't post progress on the game since a few days]

Hello everyone,

Since a few day I had a great but sad idea in mind. Why should I use my home brew collision engine while there is plenty very good one out there. Using one of them would save me plenty time relying on a good, working, performent, tested engine :D

Well, so I took my litle keyboard, wear my geek mode on, and start learning, coding, failling, learning again to code again and fail again.

So what's the result.... hem well. I tried multiple engines, and the problem is: they don't do what I want. I want a per pixel collision detection, most engine works with boxing items in shaped (what my engine does with rectangle shape as first step too). But then converting a pixel art into a shape is hell, not safe and time consuming.

Most simple games (ie: angry birds) don't care about this convertion hell has they have sprites that basically doesn't mutate a lot (not shape change). But in our game, even the most simple alien can have a shape change (take the U-Interceptor for instance) on every tile of the sprite sheet.

The need of updating the shape become huge. Even if it's still possible to compute all possibles shapes since the begining, every engine I tried just burn and explode as soon as we start updating the world object shape.

Some workarounds may be found, like switching between a collection of world object for one single game actor, activating and desactivating them on the fly, as well as synching there positions, rotations etc, but this would be time consuming.

Anyway...

This was just to makes things better, but it screw them a lot. So as far as I see it, until I have time to look more deeper into real working physics engine, I guess my home brew collision detection will do the trick.

Of course I can still optimize it a bit, using test points for bullets, changing the order of per pixel check according to some rules etc, or even implement a shape - intersection algo and make my own shape-collision engine.

But yhea, too much work for just this game, let's focus a bit more on funny stuffs first :D I miss a game test :D

7 commentaires:

  1. PS: This shape updating issue would be solve with a 3D game, as a mesh can mutate and mesh collision works fine. I understand now why 2D games are based on 3D engine. But between meshes and sprites for this game, I made my choice :D <3 Sprites xD

    RépondreSupprimer
  2. http://sylvainhb.blogspot.com/search/label/collisions

    Si je peux me permettre un élément: dans un shoot, le plus important sera de faire en sorte que le jeu reste jouable. Une collision "pixel-perfect" peut parfois aller à l'encontre du gameplay avec le coin d'un tir qui touche le coin du vaisseau mais qui l'explose quand-même.

    RépondreSupprimer
  3. Si j'avais du réaliser moi-même le jeu sur DS, en fait, je serais parti sur une animation modulaire (séparer les "barres" du U du reste du vaisseau, notamment) de façon à ce que chaque sous-sprite puisse avoir sa zone de collision propre, et donc un déplacement sans changement de forme.

    Du coup, j'en aurais profité pour faire de la boule au centre le "point faible" du vaisseau.

    RépondreSupprimer
  4. J'ai aussi constaté à l'expérience qu'avoir une bonne gestion de "qui doit tester les collisions avec qui" peut fortement réduire le "stress" sur les algorithmes. P.ex. dans notre shoot, si les vaisseaux ennemis peuvent s'ignorer les uns les autres (au moins la plupart du temps), c'est bien mieux. Idem si les tirs (du héros et des ennemis) peuvent ignorer les autres tirs. On retombe alors sur une charge de calcul linéaire qui réduit comme peau de chagrin le besoin d'algorithmes sophistiqués tels que les quad-trees, etc.

    Cf. http://sylvainhb.blogspot.com/2009/06/les-collisions.html

    RépondreSupprimer
  5. "http://sylvainhb.blogspot.com/search/label/collisions" --> superbe lecture :D Je vois que l'on à affronté beaucoup de problèmes similaire :D Ton abandon des test points est-il définitifs?

    "Si je peux me permettre un élément: dans un shoot, le plus important sera de faire en sorte que le jeu reste jouable. Une collision "pixel-perfect" peut parfois aller à l'encontre du gameplay avec le coin d'un tir qui touche le coin du vaisseau mais qui l'explose quand-même"

    Hem interressante remarque, il faut que je garde ça en tête.

    "Du coup, j'en aurais profité pour faire de la boule au centre le "point faible" du vaisseau."

    En faite j'ai déjà fais des test (Vers Decembre 2010 quand j'ai commencer ce moteur) pour résoudre ce genre de cas particulier.

    Ma première approche était bien des "MultiSprite" actors composé de plusieurs sprites ayant des comportements différent et des liens entres eux. J'ai vite abandonné cet méthode qui sera parfaite pour un rpg ou un platfomer (personage pouvant porter différents type d'équipement, expressions, etc) mais qui dans le cas d'un jeu plus simple n'avait pas d'interêt. Il me reste du code under progress quelque part à ce propos;

    La solution que j'ai appliqué pour ce cas de figure dans mes tests à l'époque est de basé la collision pixel par pixel non pas sur les données couleurs du sprite lui même mais sur un autre sprite servant de mask de collision, mais je n'ai pas été beaucoup plus loin dans cette idée pour l'instant.

    Bon celà étant je n'ai pas encore la solution parfaite.


    "J'ai aussi constaté à l'expérience qu'avoir une bonne gestion de "qui doit tester les collisions avec qui"

    J'ai aussi eu cette idée. J'y ai même ajouté la possibilité d'une pré-condition vérifiée avant la collision.

    Voici grosso modo à quoi ressemble la définition d'une de mes collisions:

    When().CollideWith().If((m, p) => m.Life > 0).Run( ..DoSomething..);

    Bien sur cette version est un cas absurde sans contexte car les monstres peuvent très bien setter un flag pour être sortit de l'algo de collision lorsque cette condition est respectée, ceci n'est valable que si l'on désire qu'un autre type de collision ait lieu sur ces même monstre avec d'autres objet que les playership.

    Enfin je bosse toujours dessus et tes post m'ont remis les idées au clair :) Merci beaucoup, ça fait du bien de voir que ce genre de problèmes n'arrivent pas qu'à moi :p

    Je pense que pour le moment je vais laisser toutes ces idées cogiter une petite semaine en veille dans ma tête, m'éloigner un peu du sujet pour avoir une meilleur vue.

    RépondreSupprimer
  6. Bon forcement blogger n'aime pas les > et les < donc à détruit mon code de collision

    When<Monster>().CollideWith<PlayerShip>().If((m, p) => m.Life > 0).Run((m, p) => p.CollideWithMonster(m));

    RépondreSupprimer
  7. Ouaip, pas de complexe à avoir: la gestion des collisions est un des points-clé dans un moteur de jeu. Un moteur de rendu qui dépote, en général, n'importe quel codeur parvient à l'écrire, à l'heure actuelle. Mais un système de collisions suffisament souple pour s'accomoder des impératifs du gameplay, c'est une autre histoire.

    Pour ce qui est des testpoints, ils sont définitivement abandonnés au profit de hitboxes dans le cadre de mes jeux sur DS. En fait, ils sont relégués au rôle mineur de "collecteur d'information en cas de collision", mais ne sont plus les éléments déclencheurs de ces collision. La raison majeure est qu'ils correspondent à une simplification extrème du problème des collisions (genre, le champignon sauteur sera toujours placé au centre d'une plate-forme de 32 pixels de large). Si un monstre se retrouve "en terrain inconnu", il risque d'avoir un comportement totalement incongru.

    RépondreSupprimer