Labyrinthe

Bonjour à  tous,

Je suis actuellement en train de réaliser un petit jeu, dans un but éducatif.
Ce que j'aimerais faire c'est de pouvoir déplacer une bille dans un labyrinthe grâce à  l'inclinaison de l'iphone...
Le problème que j'ai pour l'instant, c'est que je ne sais pas comment faire pour détecter les murs du labyrinthe. Mon labyrinthe est une image en .png (transparent et noir pour les murs). J'aimerais savoir si c'est possible de lire la matrice de l'image??? si oui comment...  Ou aurait-il une autre solution. ???

Merci d'avance pour vos réponse....

Snoopy

Réponses

  • AliGatorAliGator Membre, Modérateur
    08:49 modifié #2
    Bonjour Snoopy,

    Tu veux faire concurrence à  l'appli iPhone Labyrinth3D ? ^^

    Il est éventuellement possible de lire la matrice de l'image, en récupérant les pixels de la représentaiton bitmap de l'image... Mais je ne suis pas sûr que ce soit la meilleure solution à  mon avis (il est plus intéressant en général de décorréler la vue et le modèle pour te permettre d'afficher ce que tu veux y compris si à  terme tu veux mettre de jolis graphismes & co), ça dépend de la granularité de ton labyrinthe également.

    La solution à  laquelle je pense pour lire le pixel à  la position (X,Y) dans ton image c'est d'utiliser CGBitmapContextCreate en lui passant un buffer d'octets dimentionné comme il faut et dessiner ton image dans ce BitmapContext, tu pourras alors accéder au buffer et donc aux valeurs des pixels directement.
    Tu as des pistes évoquées dans la FAQ Apple ici à  mon avis c'est un bon point de départ (sauf que dans ton cas autant utiliser un CGBitmapContext monochrome puisque ton image est N&B et que tu ne vas regarder que si c'est noir pour un mur ou blanc pour un trou, pas besoin d'utiliser ARGB et d'une image en couleur pour ton cas donc)
  • Snoopy_87Snoopy_87 Membre
    08:49 modifié #3
    Tout d'abord merci pour ta réponse AliGator,

    Euh... je crois que mon application pourra aller se cacher derrière Labyrinth3D. Même gratuite, j'imagine que personne n'en voudra  :)

    Bref revenons à  mes moutons... J'ai lu en travers entre hier et aujourd'hui la documentation de ses classes : CGContextRef, CGBitmapContext, CGImage... Mais j'ai pas tout compris, enfin il y a tellement de choses à  savoir que je ne sais pas par où commencer, je me suis vite embrouillé. Ce que j'avais oublié de préciser, c'est que je suis un débutant confirmé en programmation.

    Ce que j'ai pour l'instant c'est une image .png affiché sur l'écran de mon iphone. J'ai les transformé en CGImageRef et j'ai pu récupérer la largueur, hauteur.. enfin plein de choses pas trop intéressante. J'ai ensuite essayer de créer un CGContextRef avec la méthode que tu m'as proposé CGBitmapContextCreate, pour pouvoir dessiner ensuite mon image dedans. Mais lors de la simulation il me signale une erreur avec la méthode CGBitmapContextCreate. Il dit "unsuported paramètre combination". C'est surement dû à  mon buffer.

    La  première question que je me pose, c'est de quel type doit être mon buffer. J'ai vu que le buffer devait avoir au minimum la taille suivante : bytesPerRow*height, ce qui dans mon cas fait 460*1280, ce qu'il me semble énorme... n'aurais-je pas meilleur temps de lire la matrice de l'image directement.

    Bref si tu pourrai m'éclaircir encore un peu plus, je t'en remercierai

    Snoopy
  • AliGatorAliGator Membre, Modérateur
    08:49 modifié #4
    Heu 460*1280 oui c'est bien ça si tu utilises un espace colorimétrique de 4 composantes, comme ARGB (chaque pixel étant alors codé par 4 octets, un pour l'alpha et un pour le rouge, un pour le vert, un pour le bleu).
    Si ton image fait 460x320 en effet elle contient 460*320 pixels donc 460*320*4 octets si elle est en ARGB. Et tu pourras accéder directement à  chaque pixel en lisant les 4 octets se trouvant à  la position (x+y*320)*4, le premier de ces 4 octets représentant l'alpha, le 2e le rouge, le 3e le vert, le 4e le bleu. Donc ça te paraà®t peut-être beaucoup mais bon c'est le nombre d'octets que fait réellement ton image donc en même temps...

    Bon ceci dit, dans ton cas, tu n'as pas dit que tu avais une image N&B ? (d'ailleurs même si ton image d'origine n'est pas N&B tu peux créer un BitmapContext utilisant un Colorspace N&B et dessiner dessus ça va convertir) ? Du coup chaque pixel n'a besoin que d'un seul octet pour être représenté dans cet espace colorimétrique. Du coup ton buffer peut ne faire que 320*460 octets.

    Ensuite pour le warning que tu as, il dit bien ce qu'il sous-entend. Tu utilises pour CGBitmapContextCreate des paramètres incompatibles entre eux. Encore une fois, pense à  prendre l'habitude de faire une petite recherche Google (il y a plein d'entrées là  dessus) mais surtout lire les docs dédiées : tu trouveras dans le Quartz2D Programming Guide tout ce qu'il faut savoir sur les Graphic Contexts (entre autre ce que c'est au juste, ce que sont les BitmapGraphicContexts en particulier, comment les manipuler, ...) et même des codes d'exemple pour plein de cas et...Les combinaisons des paramètres colorSpaces/bpp/bpc... compatibles !
  • 08:49 modifié #5
    (Fait attention il essaie de t'effrayer pour que tu abandonnes  ;D )
  • Snoopy_87Snoopy_87 Membre
    08:49 modifié #6
    Merci merci...

    J'ai lu ce matin la documentation d'Apple... J'ai compris le principe. Mais apparemment ça l'air plus facile à  lire qu'à  réaliser.
    Ci-dessous j'ai essayé de créer un CGContextRef et malheureusement le compilateur me dit toujours la même erreur, soit unsupported parameter combination.
    Je ne vois vraiment pas où j'ai fait faux. Pourrais-tu m'aider ??

    Merci

    Snoopy


    <br /><br />-(void) createBitmapContext<br />{<br />&nbsp; &nbsp; // size of the screen<br />&nbsp; &nbsp; int pixelsWidth = 320;<br />&nbsp; &nbsp; int pixelsHigh = 460;<br />	<br />&nbsp; &nbsp; CGContextRef&nbsp; &nbsp; context = NULL;<br />&nbsp; &nbsp; void *&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; bitmapData;<br />&nbsp; &nbsp; int&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  bitmapByteCount;<br />&nbsp; &nbsp; int&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  bitmapBytesPerRow;<br />	<br />&nbsp; &nbsp; // compute the size of the buffer <br />&nbsp; &nbsp; bitmapBytesPerRow&nbsp;  = pixelsWidth ;<br />&nbsp; &nbsp; bitmapByteCount&nbsp; &nbsp;  = (bitmapBytesPerRow * pixelsHigh);<br />	<br />&nbsp; &nbsp; // malloc the space for the buffer<br />&nbsp; &nbsp; bitmapData = malloc( bitmapByteCount );<br />&nbsp; &nbsp; <br />	<br />&nbsp; &nbsp; if (bitmapData == NULL)<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;Memory not allocated!&quot;);<br />&nbsp; &nbsp; &nbsp; &nbsp; return;<br />&nbsp; &nbsp; }<br />	<br />&nbsp; &nbsp; // create a CGContextRef<br />&nbsp; &nbsp; context = CGBitmapContextCreate (bitmapData,<br />			&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pixelsWidth,<br />					&nbsp; &nbsp; 		&nbsp; pixelsHigh,<br />					&nbsp; &nbsp; 		&nbsp; 8,&nbsp; &nbsp; <br />					&nbsp;  		&nbsp; bitmapBytesPerRow,<br />					&nbsp;  		&nbsp; kCGColorSpaceModelMonochrome,<br />							&nbsp; kCGImageAlphaNone);<br />	 <br />&nbsp; &nbsp; // test if the CGContextRef has been created<br />&nbsp; &nbsp; if (context== NULL)<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; free (bitmapData);<br />&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;Context not createeeed hahahaa!&quot;);<br />&nbsp; &nbsp; &nbsp; &nbsp; return;<br />&nbsp; &nbsp; }<br />	<br />	<br />	// draw into the CGContextRef<br />	//...<br />}<br /><br /><br />
    
  • CéroceCéroce Membre, Modérateur
    08:49 modifié #7
    Ali t'a enduit d'erreur:  >:)
    Monochrome = 2 couleurs, en général: le noir et le blanc, soit un mode 1 bit/pixel.
    256 niveaux de gris : 1 octet/pixel.

    Or, le mode 1 bit/pixel n'est pas géré par Core Graphics. Voir ce document, dans la rubrique Supported Pixels Formats.
  • AliGatorAliGator Membre, Modérateur
    08:49 modifié #8
    Ah oui pardon abus de langage à  parler de monochrome N&B alors qu'implicitement côté format je pensais niveaux de gris, bien vu Céroce !
  • Snoopy_87Snoopy_87 Membre
    08:49 modifié #9
    Merci pour vos réponses,

    Je suis arrivé à  créer un CGContextRef et à  dessiner mon image à  l'intérieure, enfin....j'espère, en tout cas j'ai plus d'erreur. Le problème que je rencontre maintenant, c'est que je ne sais pas comment faire pour lire une valeur d'un pixel dans mon image. J'imagine que c'est grâce au buffer que j'ai mis en paramètre lors de la création du CGContextRef. Mais mon buffer est d'un type void*. J'ai essayé de mettre un int et ensuite d'afficher la valeur des pixels à  la console mais cela m'affiche tout le temps 0. Pouvez-vous m'éclaircir à  ce sujet ???

    Merci d'avance

    Snoopy

    Voici mon code :
    <br />-(void) createBitmapContext<br />{<br />&nbsp; &nbsp; CGImageRef imageRef = [imageLaby image].CGImage;<br />&nbsp; &nbsp; CGContextRef context = NULL;<br />	<br />&nbsp; &nbsp; int pixelsWidth = CGImageGetWidth(imageRef);<br />&nbsp; &nbsp; int pixelsHight = CGImageGetHeight(imageRef);<br />&nbsp; &nbsp; int bitmapByteCount;<br />&nbsp; &nbsp; int bitmapBytesPerRow;<br />	<br />&nbsp; &nbsp; void* bitmapData;	<br />	<br />&nbsp; &nbsp; // compute the size of the buffer <br />&nbsp; &nbsp; bitmapBytesPerRow&nbsp;  = pixelsWidth;<br />&nbsp; &nbsp; bitmapByteCount&nbsp; &nbsp;  = bitmapBytesPerRow * pixelsHight;<br />	<br />&nbsp; &nbsp; // malloc the space for the buffer<br />&nbsp; &nbsp; bitmapData = malloc(bitmapByteCount);<br />	<br />&nbsp; &nbsp; //create a colorSpace<br />&nbsp; &nbsp; CGColorSpaceRef spaceColorRef = CGColorSpaceCreateDeviceGray();<br />&nbsp; &nbsp; <br />	//<br />&nbsp; &nbsp;  if (bitmapData == NULL)<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;Memory not allocated!&quot;);<br />&nbsp; &nbsp; &nbsp; &nbsp; return;<br />&nbsp; &nbsp; }<br />	<br />&nbsp;  // create a CGContextRef<br />&nbsp; &nbsp; context = CGBitmapContextCreate (bitmapData,<br />							&nbsp; pixelsWidth,<br />					&nbsp; &nbsp; &nbsp; &nbsp; 	&nbsp; pixelsHight,<br />							 8,&nbsp; &nbsp; <br />							 bitmapBytesPerRow,<br />							 spaceColorRef,<br />							 kCGImageAlphaNone);<br />	<br />&nbsp; &nbsp;  // release the colorSpace<br />&nbsp; &nbsp;  CGColorSpaceRelease(spaceColorRef);<br />	<br />&nbsp; &nbsp;  // test if the CGContextRef has been created<br />&nbsp; &nbsp; if (context== NULL)<br />&nbsp; &nbsp; {<br />&nbsp; &nbsp; &nbsp; &nbsp; free (bitmapData);<br />&nbsp; &nbsp; &nbsp; &nbsp; NSLog(@&quot;Context not created!&quot;);<br />&nbsp; &nbsp; &nbsp; &nbsp; return;<br />&nbsp; &nbsp; }<br />			<br />&nbsp; &nbsp;  // draw into the CGContextRef<br />&nbsp; &nbsp; CGContextDrawImage(context, CGRectMake(0, 0, pixelsWidth, pixelsHight), imageRef);<br />}<br /><br />
    

     
  • CéroceCéroce Membre, Modérateur
    08:49 modifié #10
    void* est un pointeur générique, tu peux le convertir en ce que tu veux. Ici comme chaque pixel correspond à  un octet, utilise un [tt]UInt8*[/tt]:

    <br />UInt32	bitmapSize = width * height * sizeof(UInt8);<br />UInt8 *bitmapData = malloc(bitmapSize);<br />
    


    Pour la suite, la bitmap se lit de gauche à  droite et de haut en bas. C'est à  dire qu'à  l'adresse bitmapData, se trouve le pixel qui se situe en haut à  gauche, et qu'à  l'adresse bitmapData+bitmapSize-1 se trouve le pixel en bas à  droite.

  • Snoopy_87Snoopy_87 Membre
    08:49 modifié #11
    Merci à  tous pour vos réponses... Je suis enfin arrivé à  lire correctement les valeurs de mon image  :D


    Snoopy
Connectez-vous ou Inscrivez-vous pour répondre.