Pixel Perfect Détection de Collision en HTML5 Canvas
Je veux vérifier une collision entre deux Sprites en HTML5 canvas. Pour le bien de la discussion, supposons que les deux sprites sont IMG objets et une collision signifie que le canal alpha n'est pas 0. Maintenant, tous les deux sprites peuvent avoir une rotation autour du centre de l'objet, mais aucune autre transformation dans le cas où cela rend tout plus facile.
Maintenant la solution la plus évidente, je suis venu avec serait celui-ci:
- calculer la matrice de transformation pour les deux
- figure une estimation approximative de la zone où le code de test (comme le décalage de + calculé de l'espace supplémentaire pour la rotation)
- pour tous les pixels de l'intersection de rectangle, de transformer les coordonnées et test de l'image à la position calculée (arrondi au plus proche voisin) pour le canal alpha. Alors abandonner sur le premier coup.
Le problème que je vois c'est que a) il n'existe pas de matrice de classes en JavaScript qui signifie que je dois le faire en JavaScript qui pourrait être assez lent, j'ai tester les collisions à chaque image, ce qui rend ce assez cher. En outre, j'ai pour répliquer quelque chose que j'ai déjà à faire sur le dessin (ou de ce canevas ne pour moi, la définition des matrices).
Je me demande si je suis absent quelque chose ici, et si il y a une solution plus facile pour la détection de collision.
OriginalL'auteur Armin Ronacher | 2010-04-30
Vous devez vous connecter pour publier un commentaire.
Eh bien, vous pourriez faire un nouveau contexte de rendu, le terrain, l'un tourné à fond blanc masque à elle, de définir la composition de l'opération de
lighter
et de la parcelle à l'autre tourné masque sur le dessus à l'offset donné.Maintenant, si il y a un non-pixel blanc à gauche, il y a un hit. Si vous souhaitez toujours avoir à
getImageData
et tamiser à travers les pixels pour le savoir. Vous pourriez être en mesure de réduire la charge de travail un peu à l'échelle de la résultante de l'image vers le bas (en s'appuyant sur l'anti-aliasing pour garder quelques pixels non-blancs), mais je pense qu'il est probablement va être assez lente.Ouais, je pense que, de façon réaliste, vous allez être pré-calculées à l'aide de tableaux de collision. Si vous avez de l'espace, vous pouvez stocker un " hit/no hit bit pour chaque combinaison d'un sprite, sprite b, la rotation relative, relative-x-normalisé-à-rotation et relative-y-normalisé-à-rotation. En fonction du nombre de sprites que vous avez et combien d'étapes de rotation ou mouvement, cela pourrait devenir assez grand.
Un compromis serait de stocker les pré-rotation des masques de chaque sprite dans un tableau JavaScript (en Nombre, en vous donnant 32 bits/pixels de facilement
&&
-mesure des données, ou comme un personnage dans un Sring, vous donnant 16 bits) et&&
chaque ligne de l'intersection sprite masques ensemble.Ou, renoncer à des pixels et de commencer à regarder par exemple. les chemins d'accès.
OriginalL'auteur bobince
Je ne suis pas un codeur javascript mais j'imagine que la même optimisation des astuces fonctionnent aussi bien pour Javascript comme ils le font pour le C++.
Il suffit de tourner les coins du sprite à la place de chaque pixel. Effectivement vous serait de faire quelque chose comme logiciel de mappage de texture. Vous pourriez travailler la position x,y d'un pixel à l'aide de diverses gradient de l'information. Rechercher le logiciel de mappage de texture pour plus d'info.
Si vous quadtree décomposé le sprite dans "hit" et "non-hit" zones alors vous pouvez effectivement vérifier pour voir si un quad arbre de décomposition est tous les "non-hit", "touché" ou "contact" (c'est à dire contient des hits et de la non-hit pixels. Les 2 premières sont triviales pour passer à travers. Dans le dernier cas, vous devez aller à la prochaine niveau de décomposition et répéter le test. De cette façon, vous ne vérifiez les pixels vous aurez besoin de trop et pour les grandes zones de "non-hit" et "hit" vous n'avez pas à faire un tel ensemble complexe de contrôles.
De toute façon c'est juste un couple de pensées.
OriginalL'auteur Goz
Même problème, une solution de rechange. J'ai d'abord utiliser getImageData de données pour trouver un polygone qui entoure le sprite. Attention ici parce que l'application fonctionne avec des images avec un fond transparent qui ont un seul objet solide. Comme un navire. La prochaine étape est Ramer Douglas Peucker Algorithme de réduire le nombre de sommets du polygone. Je reçois enfin un polygone de très peu de sommets facile et pas cher à faire tourner et de vérifier les collisions avec les autres polygones pour chaque sprite.
http://jsfiddle.net/rnrlabs/9dxSg/
OriginalL'auteur rnrneverdies