Détection de collision et fichier image (jpeg,png, etc)
tet2brick
Membre
Bonjour à tous,
Voila je débute en programmation Mac, j'ai un petit projet de jeu basique pour me donner un but, je me demandais juste s'il était possible de créer un système de détection de collision (donc par exemple définir le sol pour un personnage, ou les murs qu'il ne peut franchir) en me basant sur un fichier image externe (jpg, png ou autre format)
Fichier qui serait uniquement en noir et blanc, ou tout ce qui serait noir serait du "dur", infranchissable, le reste serait l'air pur et délicat que... hum, je m'égare.
Je ne demande pas spécialement la méthode toute faite, mais juste si c'est possible et peut être quelques pistes, histoire que je ne prenne pas une direction inutile et que je puisse voir les autres possibilités si ça n'est pas applicable.
Merci d'avance,
Voila je débute en programmation Mac, j'ai un petit projet de jeu basique pour me donner un but, je me demandais juste s'il était possible de créer un système de détection de collision (donc par exemple définir le sol pour un personnage, ou les murs qu'il ne peut franchir) en me basant sur un fichier image externe (jpg, png ou autre format)
Fichier qui serait uniquement en noir et blanc, ou tout ce qui serait noir serait du "dur", infranchissable, le reste serait l'air pur et délicat que... hum, je m'égare.
Je ne demande pas spécialement la méthode toute faite, mais juste si c'est possible et peut être quelques pistes, histoire que je ne prenne pas une direction inutile et que je puisse voir les autres possibilités si ça n'est pas applicable.
Merci d'avance,
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Ton perso est lui aussi une image. En gros voici le principe:
Je crois je ne suis pas sûr. teste le en bidouillant ^^
Déjà , pour dégrossir le tout, tu dois regarder si les rectangles des deux sprites sont confondus. Si ce n'est pas le cas -> pas de collision -> fin.
Sinon, il faut continuer la détection, au pixel près:
- prends l'intersection (bitmap) des deux masques des sprites.
- fais un OU Exclusif entre les deux -> Si tu obtiens un seul zéro, tu as une collision. (je pars du principe qu'un 1 dans le masque signifie qu'il y a de la matière sur ce pixel).
P.S.: Cocoa n'est pas idéale pour les jeux.
Petite précision, le but serait de pouvoir générer des "niveaux" complet sur base d'un jpeg, pour pouvoir en générer de nombreux à la volée (voir des aléatoires) donc pas de sprite pour le décor, juste une image noir/blanc complète.
Qu'entends tu par masque de sprite? (je débute vraiment )
Cocoa n'est pas idéal pour les jeux, mais dans le cas du dévelopement d'un jeu sur iphone, il existe d'autres possibilités?
Merci encore
Revenons sur ce qu'est un masque:
Par exemple, un JPEG, ne peut pas avoir de parties transparentes. Mais ce que tu peux faire, c'est utiliser une autre image, en niveaux de gris, qui va définir l'opacité de chaque pixel. Cette deuxième image est le masque.
Pour un fichier PNG, c'est différent, parce qu'il peut posséder une couche rouge, une couche verte, une couche bleu, et une couche alpha. La couche alpha est le masque, mais dans ce cas, il fait partie intégrante de l'image.
Note que dans ces deux cas, on va sûrement utiliser un masque avec 8 bits/pixels, qui permettent de lisser joliment les bords du sprite.
Mais pour la détection de collision, un masque 1 bit/pixel est suffisant. Si ce n'est toujours pas clair, je développerai.
ça par exemple:
http://cocos2d.org/
La doc:
http://www.sapusmedia.com/cocos2d-iphone-api-doc/index.html
En fait je crois qu'il avait déjà l'idée du masque 1bit/pixel, puisqu'il parle d'une image N&B à utiliser pour ses niveaux, un pixel noir indiquant un élément "solide" (mur) et un blanc indiquant de l'air dans lequel le personnage peut circuler. C'est cette image qu'on appellera le "masque" représentant le niveau.
Petite remarque au passage, ne prend pas du JPEG qui, utilisant une transformée de Fourrier pour réaliser la compression de l'image (c'est ce qui fait que les JPEG sont si légers), introduit en contrepartie des artefacts qui font que les bordures (transitions du noir au blanc en l'occurrence) seront pas strictes mais progressives : autour de ces contours si tu zoomes tu verras que les pixels alentours ne seront pas tout noir ou tout blanc... Préférer du PNG ou du GIF à la limite...
---
Si on veut juste faire de la détection pour savoir un un point (représentant ton "joueur") est ou non sur un mur, pour justement faire la détection de collision, c'est pas trop dur : on regarde si le pixel de notre masque à l'endroit où est notre "joueur" est noir ou blanc. S'il est noir, on est dans un mur, sinon c'est bon.
Maintenant, si ton "joueur" n'est pas juste un point, mais qu'on veut plutôt considérer tout le joueur (représenté par un cercle ou un rectangle par exemple pour faire simple) là c'est autre chose. On peut penser à juste tester les 4 coins du rectangle englobant de notre joueur. Ca peut être un bon début, déjà : si l'un des 4 est dans un mur (le pixel correspondant dans le masque de ton niveau est noir), on est sûr qu'on est dans un mur. Mais si jamais manque de bol il y a un mur moins épais que le joueur et que ce dernier est "à cheval" sur ce mur... le point bas gauche et bas droit de ton personnage seront "dans le vide" (pixel correspondant dans le masque blanc) mais s'il y aura un "mur" entre ces deux points, tu ne le "verras" pas dans ce cas de figure.
Alors après ça dépend de ton jeu :
- si c'est un truc genre à la Lode Runner (ah souvenirs souvenirs, sur mon vieil Apple ][e loool) ça peut le faire car ton niveau est alors découpé en une sorte de "grille" et ton personnage se déplace de "case en case" sur cette "grille" de jeu, mais a lui-même la taille d'une "case". Dans ce cas cela revient à tester si la "case" vers laquelle ton personnage se dirige est un mur ou pas, et de même s'il aura un "mur" (enfin un sol en l'occurence) sous ses pieds.
- si c'est pas découpé sous forme d'une grille mais un genre jeu de plateforme, il faudra sans doute faire un test plus fin, tester chaque pixel représentant ton personnage (ou son rectangle englobant selon la précision de collision que tu veux) pour vérifier qu'aucun des pixels de ce perso ne touche un mur... après si tu teste à chaque micro-déplacement du personnage, donc à chaque fois que tu le décales d'un pixel, ça risque d'être un peu beaucoup aussi, va falloir optimiser
- de plus il faut faire gaffe par exemple si tu dessines une "côte" dans ton niveau de ton jeu, et pas un sol horizontal... il faudra que ton personnage puisse "monter la côte" quand tu vas dessus, sans être obligé de le faire sauter tout le temps... Or si tu fais une bête détection de collision pixel par pixel ça va pas suffire car tu vas voir qu'il y a un bout de mur (car le sol "monte") dans cette direction... alors qu'il faudrait pas empêcher ton personnage d'y aller pour autant, par contre faudra penser à le faire "monter" tout seul de quelques pixels (pour suivre la "côte") tout de même...
Bref, pas si simple comme problématique !
je ressort cette vieille discussion car c'est tout à fait ce que je recherche, donc ça évite de créer un nouveau sujet.
C'est surtout les masques qui m'intéressent ! (au passage, j'utilise Cocos2D, et je suis un débutant aussi).
J'ai compris le principe, mais je ne vois pas trop comment on l'applique. Et je me pose des questions un peu... "bêtes".
Comment on créer le masque ?
Et comment on repère la collision entre les deux masques ?
PS : pour le moment j'utilise CGRectIntersect, c'est bien pour s'entrainer à manipuler d'autres choses sans trop s'attarder sur les collisions, mais là , il est temps que je m'attarde un peu plus sur les collision, parce que avec des rectangles, c'est vraiment pas propres !!
Merci.
Et bonne année.
EDIT : je viens de voir que j'étais dans la section mac, or ma question conczrne les iPhones. Désolé, je re-posterais demain.
Avec un logiciel graphique, type Photoshop. Il s'agit de prendre l'image de départ et de dessiner en noir où se trouve de la matière.
Par un OU exclusif:
Mais tu n'as pas besoin de le coder toi-même, je suis certain que Cocos2D implémente un tel mécanisme, c'est une des bases d'un moteur 2D.
Peu importe, ça n'est pas spécifique au Mac non plus.
Peu importe, ça n'est pas spécifique au Mac non plus.
[/quote]
Oui c'est vrai, je vais rester ici alors.
Deux dernière question après je m'attaque à la doc de Cocos2D (je préfère avec des petites bases avant de lire les doc anglaise...).
- Le masque on le "cache" derrière notre image c'est ça ?
1 c'est quand il y a du noir j'imagine ? (et XOR ça veut dire quoi ??)
Merci.
Oui, et XOR ça veut dire "OU Exclusif" (eXclusive OR), c'est de la logique combinatoire classique (si tu connais pas ça tu pourras trouver des cours sur le net à la limite mais c'est assez simple)
Le masque n'est pas affiché, il décrit uniquement où se trouve de la matière.
Non, c'est quand il y a de la matière. Sur l'éditeur graphique, l'absence de matière peut très bien être affichée en noir, c'est à toi de choisir. Tu peux aussi considérer que 0 correspond à la présence de matière (dans ce cas, il faudra reprendre la "table de vérité").
Non t'avons expliqué le concept, c'est à toi d'adapter ça en code.
Par exemple, disons que le masque utilise un octet par pixel. L'absence de matière est signifiée par une valeur de 0, toute autre valeur signifiant la présence de matière. Pour un pixel:
BOOL collision = (pixelMasqueDecor > 0) && (pixelMasquePerso > 0)
J'ai introduit la logique combinatoire parce qu'elle permet de gagner des instructions au niveau du microprocesseur et d'aller 4x plus vite.
P.S.: J'ai jeté un oe“il à Cocos2D, et il n'y a pas l'air d'avoir de détection de collision... étrange.
EDIT : Box2D ça doit être un moteur physique plutôt.