ebook img

C++ APPRENDRE ET PROGRAMMER PDF

29 Pages·2012·0.93 MB·French
by  
Save to my drive
Quick download
Download
Most books are stored in the elastic cloud where traffic is expensive. For this reason, we have a limit on daily download.

Preview C++ APPRENDRE ET PROGRAMMER

"C++ APPRENDRE ET PROGRAMMER" Sélection de Bonnes Feuilles -> extrait du Chap 5 : "Manipulation d’une matrice et classes" Août 2012 139 Miseenplaceduprojet Cechapitrevaêtrel’occasiondedévelopperlejeudulabyrinthe,unprogramme unpetitpeuplusévoluéparrapportàcequenousavonsfaitjusqu’ici.Nous utiliseronsencesenslabibliothèquegraphiqueOpenGL. CettebibliothèqueaétéprésentéeauchapitreGraphiquededonnées. Lejeudulabyrintheconsisteàdéplacerunbonhommedansunniveau "labyrinthique",unpeuàlamanièred’unPacman,le"fossile"dujeuvidéo.Des ennemisdonnerontdufilàretordreaujoueurafind’éviterquecelanedevienneun parcoursdesanté.Deplus,lesdéplacementsdecesennemisserontcontrôléspar uneintelligenceartificielled’unecomplexitéextrême,procheduhasard,cequi 5 apporterauncôté"imprévisible"audéroulementdujeu. Leniveaudujeuseravu"dedessus",endeuxdimensions.Lejoueurpourrafaire évoluersonpersonnagedansleniveauenlecontrôlantàl’aidedesflèches directionnellesdesonclavier.Partantd’unpointA,ilessaieraderejoindreun pointBtoutenévitantlesennemissanguinairesrodantauxalentours. Noussouhaitonsquelacréationdesniveauxdejeusoitfacilementréalisable.Notre objectifestd’offriràquiconquelapossibilitédes’endonneràcœurjoiepour "designer"sespropresniveauxetyplacerstratégiquementdesennemis.Deplus,la tailledesniveauxneserapasfixée,cequipermettradecréerdesplateauxdetoutes sortes:petits,grands,carrés,rectangulaires,etc. 5.1 Mise en place du projet Configuration pour OpenGL CréezunnouveauprojetvidedetypeApplicationConsoleWin32.Nommez-le LabyrinthedansunenouvellesolutionégalementappeléeLabyrinthe.Créez-yun nouveaufichiersourcevierge,main.cppparexemple.Incluezlesfichiersd’en-tête habituelsetcréezunefonctionmainvide.EnemployantGLUT,configurezleprojet pourqu’ilpuisseaccueillircettebibliothèque. Pourconfigurerleprojet,reportez-vousauchapitreGraphiquededonnées.Par ailleurs,unrécapitulatifcomplet,expliquantcommentconfigurerunprojetVisual C++pourlesbibliothèquesOpenGLetGLUT,estconsultabledansl’annexe ConfigurerunprojetpourGLUTetOpenGL. Vérifiezquelefichierd’en-têteglut.hestbieninclusdepuisvotrefichiersource. #include "GL/glut.h" 140 Chapitre5-Manipulationd’unematriceetclasses Mise en place des données principales Lapremièredonnéequenouspouvonsdéclarerestlatailleduniveau.Nousaurons forcémentbesoindunombredecolonnesetdelignesdelagrilleduniveaupour pouvoirlegérer.Déclarezdeuxvaleursentièresglobales. int NbColonnes, NbLignes; // Taille du niveau Danslafonctionprincipaleduprogramme,commençonsparaffecterdesvaleurs auxtroisvariablesglobalespournepasleslaissernoninitialisées(lesaffectations multiplesdugenreTailleX=TailleY=0sontpossibles).CréonslafenêtreOpenGLet définissonslafonctionLabyAffichageentantquefonctiond’affichage,etLabyRedimen tantquefonctionderedimensionnement. Reportez-vousauchapitreGraphiquededonnéespoursavoircommentutiliser GLUTetcréerunefenêtreOpenGL. Listing 5-1:Fonctionprincipaleduprogramme void main(void) { NbColonnes=NbLignes=0; // Initialisation de la taille /* Gestion de graphique */ // Position de la fenêtre glutInitWindowPosition(10, 10); // Taille de la fenêtre glutInitWindowSize(500, 500); // Mode d'affichage glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE); // Création de la fenêtre glutCreateWindow("Labyrinthe"); // Fonction d'affichage glutDisplayFunc(LabyAffichage); // Fonction de redimentionnement glutReshapeFunc(LabyRedim); glutMainLoop(); } Bienentendu,nousdevonsdéfinircesdeuxfonctionsd’événementsdansnotre programme.Lafonctiond’affichagenedoitposséderaucunparamètre.C’estlàque touteslesinstructionsd’affichageserontappelées.Nouseffaceronstoutd’abord l’écrandejeuafindepouvoircommencerledessinsurunsupportvierge,en spécifiantlacouleurdefondenblanc.L’instructionglMatrixMode(quenousne détailleronspasdanscechapitre)permetdespécifierlamatriceactiveenvuede 141 Miseenplaceduprojet disposerlesélémentssurlascènelorsdudessin.Aprèslesinstructionsd’affichage, l’appelàglFlushpermetdeterminerledessindelascène. Listing 5-2:Fonctiond’affichage void LabyAffichage(); void LabyAffichage() { // Définit la couleur de fond glClearColor(1.0, 1.0, 1.0, 1.0); // Efface l'écran glClear(GL_COLOR_BUFFER_BIT); // Définit la matrice de modélisation active glMatrixMode(GL_MODELVIEW); 5 /* Instructions d'affichage ici */ glFlush(); // Achève l'affichage } Lesfonctionnalitésplusavancéesd’OpenGL,commelamanipulationdesmatrices demodélisation,sonttraitéesauchapitreInitiationàla3Dtempsréel:OpenGL. Lafonctionderedimensionnementdemandeenparamètredeuxvaleursentières correspondantàlatailledelafenêtre(largeur/hauteur).L’instructiongluOrtho2D permetdespécifierl’échelledudessin.Lepremiercouple(0.0,NbColonnes)permet dedéfinirlescoordonnéesmaximaleshorizontalement(gauche/droite)et(NbLignes, 0.0)lescoordonnéesextrêmesverticalement(bas/haut,etnonhaut/bas!).Ainsi l’appelàgluOrtho2D(0.0,NbColonnes,NbLignes,0.0)spécifielepixeldecoordonnées (0,0)commeétantlecoinsupérieurgauchedelafenêtreetlepixel(NbColonnes, NbLignes)lecoininférieurdroit. Listing 5-3:Fonctionderedimensionnement void LabyRedim(int x, int y); void LabyRedim(int x, int y) { glViewport(0, 0, x, y); glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, (double)NbColonnes, (double)NbLignes, 0.0); } 142 Chapitre5-Manipulationd’unematriceetclasses 5.2 Gérer le niveau : les matrices Lesniveauxdejeudanslesquelslejoueurévolueraserontdeslabyrinthes,endeux dimensionset"vusdedessus"commedansPacmanouBomberman.Dansnotre programme,nousstockeronscesinformationsdansuntableau,nonpasàuneseule dimensioncommeceluiquinousaserviàstockerNélèves(tableau"ligne"),maisà deuxdimensions(ilcontiendradoncdeslignesetdescolonnes). PoursavoircommentstockerNélèvesdansuntableauàunedimension,reportez- vousauchapitreInterfacedesaisie. Pourtracerlesniveaux,nouspourrionsdéfinirlestableaux"directementdansle code",c’est-à-dire"endur"commeonleditenjargondeprogrammation.L’ennuide cettesolutionprovientdumanqueinhérentd’évolutivitéetdesouplessedu programme.Ellenouscontraindraitàmodifierlecodeduprogrammeetdoncàle recompileravecVisual,s’ildevenaitnécessairedemodifierlaconceptionoulataille d’unniveau.Unjoueurnepourraitpas,dèslors,créersespropresniveauxdejeu. Unesolutionbeaucouppluspratique,etévolutive,estdestockerlesdonnéesd’un programmedansdesfichiersexternes.Dansn’importequeljeuvidéo,lesanimations despersonnagesnesontpasconservéesendurdansleprogramme.Ellessont stockéesdansdesfichiersexternesspéciaux,éditésàl’aidedelogicielsd’animation (3DStudio,Maya…).Demêmepourlestextures(lesimagesplaquéessurles polygonesd’unescène3D)sontgénéralementstockéesdansdesfichiersimagede type.bmp,.jpgouencore.tga. Stocker les niveaux Figure5-1: Fichierniveau.txt Pournotrepart,nousallonsstockerlesniveauxdenotrejeudansdesfichierstexte facilementéditablesàl’aideden’importequeléditeurdetexte,telleBloc-notes. 143 Gérerleniveau :lesmatrices OuvronsdoncleBloc-notesdeWindowsetcréonsunnouveaufichiertexteque nousnommeronsniveau.txt.Nousallonsdevoiràprésent"dessiner"leniveaudejeu sousformed’unegrilledecaractères.Choisissonsparexemplelecaractère0pour spécifierunmur,etlecaractère1uneallée(ouuncouloir).Formonscettegrilleen composantunassemblageastucieuxde0etde1.Voiciunexempledepetitniveau labyrinthiqueréalisable: SauvegardonscefichierdansledossierduprojetLabyrinthe\Labyrinthe,àcôtédu fichiersourcedecedernier. Figure5-2: Enregistrement dufichierniveau. txt 5 Bienqu’étantstockédanscefichiertexte,lecontenuduniveaudejeudevraêtre récupérédansnotreprogramme.Letypededonnéesquenousallonsutiliserpour stockerunegrilledeceformatestuntableauàdeuxdimensions:unedimension pourlescolonnes,etunedimensionpourleslignes.Mathématiquement,celase nommeunematrice.Nousallonsvoircommentalloueruntableaudecetype. Defaçonstatique,untableauàdeuxdimensionsde4×5contenantdesbooléens s’allouedelafaçonsuivante: bool tableau_statique[4][5]; Cependant,dansnotrecas,neconnaissantpaslatailleduniveauàl’avance,nous devonspasserparuneallocationdynamique.Avantdepouvoirallouercette matrice,nousdevonsconnaîtresesdimensions.Ilseraitpossibledelesdéterminer enlisantunepremièrefoislecontenudufichier,puisenlelisantunedeuxièmefois pourremplirletableau.Maisilestplussimpleetplusrapided’écrirelatailledela matricedirectementdanslefichieroùeststockéleniveau.Spécifionstoutd’abord sonnombredecolonnes,puissonnombredelignes. 144 Chapitre5-Manipulationd’unematriceetclasses Figure5-3: Ajoutdelataille delagrilledansle fichierduniveau Allouer un tableau à deux dimensions Untableauàunedimensionestdéfiniparunpointeurpointantsurlapremière cellule.Alloueruntableaud’entiersàl’aidedel’instructionint*tab=newint[N] auraitpoureffetdecréerNcellulespouvantaccueillirchacuneunentier. Untableauàdeuxdimensionsestenréalitéuntableaudetableaux,cequi correspondàundoublepointeur.Lamarcheàsuivrepouralloueruntableaude C×Lentiersestdoncd’alloueruntableaudeCcellules.Chaquecellulepeut accueillirunpointeur(simple)surunentier.Ilfautensuitealloueruntableaude LentierspourchacunedecesCcellules.Leschémasuivantreprésenteune allocationàdeuxdimensions: Figure5-4: Schématisation d’uneallocation dynamiqued’un tableauàdeux dimensions Doublepointeur Commençonspardéclarerengloballedoublepointeurpermettantd’identifierla matriceduniveau.Undoublepointeursedéclareàl’aidededeuxétoiles.Dela mêmemanière,untriplepointeursedéclareavectroisétoiles.Étantdonnéque l’informationcontenuedansunfichiertexteestdutexte,choisissonsunematricede caractères(typechar)pourstockerlesdonnéesduniveau.Celasimplifieralalecture. char** Matrice; // Matrice contenant le niveau 145 Gérerleniveau :lesmatrices InitialisonscedoublepointeuràlavaleurNULL(ilnepointesurrien)audébutdela fonctionmain(vouspouveztoutàfaitl’initialiserdirectementlorsdesadéclaration). Matrice = NULL; // Initialisation du double pointeur CréonsunefonctionOuvrirNiveauquipermettradechargerunniveau.Elleprendra commeparamètreunechaînedecaractèrescorrespondantaunomdufichier contenantleniveauàcharger.L’appeldecettefonctionseradelaforme OuvrirNiveau("niveau.txt").Unechaînedecaractèresétantuntableau,etuntableau étantdéfiniparunpointeursurlapremièrecellule,unparamètrechaînede caractèresestdutypechar*. void OuvrirNiveau(char* nom_fichier); 5 void OuvrirNiveau(char* nom_fichier) // Définition { // Instruction d'ouverture du niveau } Tableauenparamètre Passeruntableau(parexempled’entiers)enparamètreàunefonctionse réalisevialasyntaxeint*nom.Ilestégalementpossibled’utiliserlasyntaxe intnom[].Ainsilesdeuxdéclarationssuivantessontéquivalentes: void fonction1(int* tableau); // Ces deux déclarations void fonction2(int tableau[]); // sont identiques Àl’intérieurdenotrefonction,nousallonsallouerlamatriceMatriceavantdelirele fichierniveau.txtpourchargerlesinformationscontenues.Pourallouercette matrice,nousdevonsconnaîtresatailleNbColonnes×NbLignes.Dansunpremier temps,fixonscesvaleurs. NbColonnes = 10; NbLignes = 8; Allocationdynamique Maintenantquelatailledelamatriceestfixée,nouspouvonsallouercettedernière. Commenousl’avonsmentionnéprécédemment,uneallocationdynamiqueàdeux dimensionsnécessitedeuxétapes: j alloueruntableaudeNbColonnespointeurssurchar: // Allocation du tableau du niveau Matrice = new char*[NbColonnes]; 146 Chapitre5-Manipulationd’unematriceetclasses j alloueruntableaudeNbLignescellules(detypechar)parpointeur: for(int i=0; i< NbColonnes; i++) Matrice[i] = new char[NbLignes]; Ilestpréférabled’initialiserlesvaleurscontenuesdanscettematriceàdesvaleurs pardéfautcommelecaractère0,caractérisantunmur.Lasyntaxepouraccéderaux cellulesd’untableauàunedimensionreposesurdescrochets.Icil’instruction Matrice[3]donneaccèsautableaucaractérisantlaquatrièmelignedelamatrice.La syntaxepouraccéderaucaractèrestockéàlaquatrièmelignedeladeuxième colonneestMatrice[1][3].Delamêmefaçon,accéderauxcellulesd’untableauàtrois dimensions,dansunjeudeRubik’sCubeparexemple,seferaitainsi:Rubiks[x][y][z]. Pourparcourirlamatriceentièrement,c’est-à-direpourinitialiserchacunedeses cellules,nousallonsfaireappelàunedoubleboucle.Nousdevonspassertoutesles colonnesenrevue,etpourchacunedecescolonnes,parcourirlesNbLigneslignes. Notezqu’ilestégalementpossibledefairel’inverse(c’est-à-direparcourird’abord leslignespuislescolonnes),celanechangerienici. // Initialisation des valeurs du tableau for(int i=0; i<NbColonnes; i++) for(int j=0; j<NbLignes; j++) Matrice[i][j] = '0'; Boucleenbloc Ilestpossibledeprogrammercettedoubleboucleenspécifiantlesblocsde cettefaçon: for(int i=0; i<NbColonnes; i++) { for(int j=0; j<NbLignes; j++) { Matrice[i][j] = ’0’; } } Maiscelan’estpasnécessaire.Eneffet,laboucleparcourantleslignes comptecommeuneseuleinstructionauxyeuxdelapremièreboucle traitantlescolonnes. Libérer la mémoire d’une matrice Quiditallocationditdésallocation!Sinousnerespectonspasceprincipede réservationetdelibérationdemémoire,nousnousexposonsàune"fuitede 147 Gérerleniveau :lesmatrices mémoire".PréparonsunefonctionLibererMemoirechargéedesupprimerletableau Matrice. Listing 5-4:Déclarationetcorpsdelafonctiondedésallocation void LibererMemoire(); /* … */ void LibererMemoire() // Définition { /* Instructions de libération de mémoire */ } 5 Unedésallocationconsisteenuneallocationinverse.Unematriceestcomposée d’unelignedepointeurs,chacund’entreeuxétantallouéd’unecolonne.Ilfautdonc toutd’abordlibérerlamémoireoccupéeparlesNbColonnescolonnesàl’aided’une boucle.Dansundeuxièmetemps,lalibérationdelalignedeNbLignespointeurs permetdesupprimerlatotalitédesdonnéesdelamatrice. Listing 5-5:Libérationdelamémoireallouéeparunematrice void LibererMemoire() { // Vérifie que Matrice a bien été allouée if(Matrice != NULL) { for(int i=0; i<NbColonnes; i++) // Libération des colonnes delete [] Matrice[i]; // Libération de la ligne de pointeurs delete [] Matrice; } } Testeravantdedésallouer Avantdelibérerdelamémoireallouéedynamiquementetaccessibleparun pointeur,mieuxvauttesterquecepointeurpointeeffectivementsurune casemémoireexistante.Cartenterdelibérerdelamémoiren’existantpas aurapoureffetdefaireplanterleprogramme.C’estpourquoiavant d’appelerlesinstructionsdelete,nousavonstestéaupréalablequela matriceabienétéallouéeencomparantledoublepointeurMatriceavecla valeurNULL. Unebonnequestionàseposeràprésentest:quanddoit-onappelercettefonction delibérationdemémoire?Lalibérationdedonnéesallouéesdynamiquementdoit

Description:
une intelligence artificielle d'une complexité extrême, proche du hasard, ce qui apportera un côté "imprévisible" au déroulement du jeu. Le niveau du
See more

The list of books you might like

Most books are stored in the elastic cloud where traffic is expensive. For this reason, we have a limit on daily download.