Détection de collision et fichier image (jpeg,png, etc)

tet2bricktet2brick Membre
15:33 modifié dans API AppKit #1
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,

Réponses

  • CeetixCeetix Membre
    15:33 modifié #2
    imaginons que ton sol soit une image (genre barre horizontale prenant tout l'ecran, donc 420 px de large) et qu'il soit placé tout en bas de ton ecran.
    Ton perso est lui aussi une image. En gros voici le principe:

    <br />if(monPerso.center.y &gt;= monSol.center.y)<br />{<br />monPerso.center = CGPointMake(monPerson.center.x,0);<br />}<br /><br />
    


    Je crois je ne suis pas sûr. teste le en bidouillant ^^
  • CéroceCéroce Membre, Modérateur
    15:33 modifié #3
    Oui, c'est possible.

    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.
  • tet2bricktet2brick Membre
    15:33 modifié #4
    Tout d'abord merci pour vos deux réponses ultra rapides.

    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.


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


    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 ;)
  • CéroceCéroce Membre, Modérateur
    février 2009 modifié #5
    dans 1235571288:

    Qu'entends tu par masque de sprite? (je débute vraiment :) )


    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.

    dans 1235571288:

    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?


    ça par exemple:
    http://cocos2d.org/
    La doc:
    http://www.sapusmedia.com/cocos2d-iphone-api-doc/index.html
  • AliGatorAliGator Membre, Modérateur
    15:33 modifié #6
    Hello !

    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 !
  • CeetixCeetix Membre
    15:33 modifié #7
    Oulala j'avais tout faux ou j'ai du mal comprendre le probleme lol ... Désolé  :-\\
  • CoharsCohars Membre
    janvier 2011 modifié #8
    Bonsoir,
    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.
  • CéroceCéroce Membre, Modérateur
    15:33 modifié #9
    dans 1294087159:

    Comment on créer le masque ?

    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.

    dans 1294087159:

    Et comment on repère la collision entre les deux masques ?

    Par un OU exclusif:
    <br />MasquePerso&nbsp; |&nbsp; MasqueDécor || XOR<br />-------------+--------------++-----<br />&nbsp; &nbsp;  0&nbsp; &nbsp; &nbsp;  |&nbsp; &nbsp; &nbsp; 0&nbsp; &nbsp; &nbsp;  ||&nbsp; 1<br />&nbsp; &nbsp;  0&nbsp; &nbsp; &nbsp;  |&nbsp; &nbsp; &nbsp; 1&nbsp; &nbsp; &nbsp;  ||&nbsp; 1<br />&nbsp; &nbsp;  1&nbsp; &nbsp; &nbsp;  |&nbsp; &nbsp; &nbsp; 0&nbsp; &nbsp; &nbsp;  ||&nbsp; 1<br />&nbsp; &nbsp;  1&nbsp; &nbsp; &nbsp;  |&nbsp; &nbsp; &nbsp; 1&nbsp; &nbsp; &nbsp;  ||&nbsp; 0&nbsp;  &lt;- Collision<br />
    


    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.

    dans 1294087159:

    EDIT : je viens de voir que j'étais dans la section mac, or ma question conczrne les iPhones. Désolé, je re-posterais demain.

    Peu importe, ça n'est pas spécifique au Mac non plus.
  • CoharsCohars Membre
    15:33 modifié #10
    dans 1294087159:

    EDIT : je viens de voir que j'étais dans la section mac, or ma question conczrne les iPhones. Désolé, je re-posterais demain.

    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 ?
    MasquePerso&nbsp; |&nbsp; MasqueDécor || XOR<br />-------------+--------------++-----<br />&nbsp; &nbsp;  0&nbsp; &nbsp; &nbsp;  |&nbsp; &nbsp; &nbsp; 0&nbsp; &nbsp; &nbsp;  ||&nbsp; 1<br />&nbsp; &nbsp;  0&nbsp; &nbsp; &nbsp;  |&nbsp; &nbsp; &nbsp; 1&nbsp; &nbsp; &nbsp;  ||&nbsp; 1<br />&nbsp; &nbsp;  1&nbsp; &nbsp; &nbsp;  |&nbsp; &nbsp; &nbsp; 0&nbsp; &nbsp; &nbsp;  ||&nbsp; 1<br />&nbsp; &nbsp;  1&nbsp; &nbsp; &nbsp;  |&nbsp; &nbsp; &nbsp; 1&nbsp; &nbsp; &nbsp;  ||&nbsp; 0&nbsp;  &lt;- Collision<br />
    


    1 c'est quand il  y a du noir j'imagine ? (et XOR ça veut dire quoi ??)

    Merci.
  • AliGatorAliGator Membre, Modérateur
    15:33 modifié #11
    dans 1294250993:

    Oui c'est vrai, je vais rester ici alors.
    Surtout que c'est une très mauvaise idée de faire du double post (de commencer un post dans une section, et de reposter le même message dans une autre section des forums ensuite), c'est contraire à  la charte et au bon usage des forums car ça éparpille les réponses. Si tu te rends compte que tu as posté un message au mauvais endroit " surtout s'il a déjà  eu des réponses entre temps " ne reposte pas le message ailleurs, mais demande plutôt juste à  un modérateur ou un administrateur de déplacer ton message dans la bonne section, tout simplement. Sinon c'est le bordel.

    dans 1294250993:
    1 c'est quand il  y a du noir j'imagine ? (et XOR ça veut dire quoi ??)
    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)
  • CéroceCéroce Membre, Modérateur
    15:33 modifié #12
    dans 1294250993:

    - Le masque on le "cache" derrière notre image c'est ça ?

    Le masque n'est pas affiché, il décrit uniquement où se trouve de la matière.

    dans 1294250993:

    1 c'est quand il  y a du noir j'imagine ?

    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.
  • CoharsCohars Membre
    15:33 modifié #13
    Il y a des... "moteurs graphiques" (je crois que c'est ça) en plus je crois.  Il y Box2D et Chipmunk. Je ne sais pas du tout comment ils fonctionnent, je vais aller voir sur le forum. Mais sur les quelques discussion que j'ai pu voir, ils disent que Box2D et Chipmunk sont "trop lourds", si c'est juste pour gérer les collisions. Mais je ne sais pas ce qu'ils proposent à  la place...

    EDIT : Box2D ça doit être un moteur physique plutôt.
Connectez-vous ou Inscrivez-vous pour répondre.