Problème C++ : tableaux et classes

Fermé
Petitcolas Jonathan - 24 mai 2005 à 21:16
 prout-man - 15 sept. 2008 à 15:35
Bonjour,

Je suis actuellement en train de programmer un petit jeu genre Sokoban en C++. J'ai pour cela crée différentes classes : une pour les caisses, une pour les murs, etc... Elles fonctionnent toutes très bien et le premier niveau est jouable parfaitement.

Mais alors, où est le problème ??? J'y arrive... :-)

J'aimerais que mon jeu ait plus qu'un niveau. Et donc, je me demandais s'il était possible de créer dynamiquement un tableau et d'y mettre des objets de mes classes, pour construire le niveau. J'ai donc fureté à droite à gauche sur le Net, et j'ai vu qu'il fallait utiliser le mot-clé [i]new[/i]. Soit... C'est que je fais. Mais, j'ai un problème lors de l'appel à une fonction de l'une de mes classes. Voici les parties du code correspondantes (pour la classe [i] soko [/i] par exemple, avec un constructeur admettant en argument deux char) :

// Déclaration du pointeur
soko* Sokoban;

// Création d'un élément dans le tableau
soko *Sokoban = new soko( 7, 9 );

// Utilisation d'une fonction
Sokoban[1].Move(1,0);

Voilà. Et, lorsque je lance le programme et que j'appuie sur une flèche, le programme quitte automatiquement. Si la ligne est enlevée, tout marche bien...

Merci pour tous les gentils programmeurs (et programmeuses) qui m'aideront !

16 réponses

Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
25 mai 2005 à 08:49
une question, pourquoi commence tu par Sokoban[1] ?
je ne suis pas très fortiche en pointeur/tableau, mais il me semble que la tu declare un tableau à un element.
essai Sokoban[0].Move(1,0); ou Sokoban->Move(1,0);
En général si ça compile et que le programme plante, c'est que ça viens d'un problème d'allocation mémoire, ou de depassement tableau.
Moi, pour ne pas m'enmerder avec les new, je ferai :
soko Sokoban[Nombre_de_niveau];
qui normalement fonctionne.
Une question : tu utilise quoi pour le mode graphique?
Bonne chance.
1
Luffy =) Messages postés 365 Date d'inscription mercredi 20 avril 2005 Statut Membre Dernière intervention 19 mai 2006 109
27 mai 2005 à 16:34
yep =) désolé pour le retard... en tout cas, bienvenue parmi nous !!!

alors, c'est normal que ça ne marche pas. cette ligne est correcte :
box* Box = NULL 
tu déclares un pointeur vers un objet ou un tableau d'objets. ensuite quand tu fais :
 Box = new box(14,10);
Box = new box(14,8);
Box = new box(15,9);
tu crées 3 instances de ta classe box sur le même espace mémoire, c'est-à-dire qu'à chaque nouvelle ligne, ton objet est "effacé" et recréé.

si tu veux créer un tableau de box, il faut t'y prendre comme ça :
box *Box=NULL;
Box = new box[3];
et là tu auras trois instances de box. pour y accéder, il faudra faire :
box[0]->Methode(parametre);
box[1]->Methode(parametre);
box[2]->Methode(parametre);
et les paramètres pour le constructeur me diras-tu ???? ben en fait je sais pas trop si c'est possible de passer les paramètres à 3 instances lors de la création. Tout du moins, ce que tu peux faire c'est un accesseur à tes variables membres, c'est-à-dire une méthode qui modifiera tes valeurs. soit tu fais une fonction qui s'appelle SetMachin(int a,int b) ou "Machin" est le nom de ta ou tes variables, soit tu fais une fonction Init(int a, int b) qui corresponderait à l'initialisation de ton objet. Dans tout les cas, quelle que soit le nom de ta fonction, elle te permettrait d'initialiser les valeurs des variables de ta classe.

++
1
Luffy =) Messages postés 365 Date d'inscription mercredi 20 avril 2005 Statut Membre Dernière intervention 19 mai 2006 109
24 mai 2005 à 22:12
salut !

en fait quand tu utilises l'opérateur "new" pour instancier une classe, il faut utiliser "->" à la place du "." habituel pour appeler tes fonctions.

et ça devrait compiler ! on peut y jouer nous à ton jeu ?! je veux y jouer !!!!
0
Petitcolas Jonathan
25 mai 2005 à 06:50
OK. Merci. Je vais essayer ça ce soir ou demain (histoire que j'ai un peu de temps)... Quoi qu'il en soit, je serais ravi de t'envoyer une version du jeu, une fois celui-ci terminé. Car, en effet, pour l'instant, les bases fonctionnent... Mais c'est tout.

Il reste encore un peu de son à ajouter, et les autres niveaux à faire.
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Petitcolas Jonathan
25 mai 2005 à 06:59
Allez ! J'ai pas pu résister à l'envie d'essayer avant de partir bosser... :-)

Cependant, il me dit qu'il y a un problème :

[i] type 'soko' doesn't have an overloaded member 'operator ->'
left of '->Move' must point to class/struct/union

[/i]

Voilà... D'où cela vient-il ? Car, c'est bien une classe... Ou alors, j'ai mal compris. J'ai écrit :

[i] Sokoban[1]->Move(1,0); [/i]

Thanks !
0
Petitcolas Jonathan
25 mai 2005 à 21:11
Hélas, ça ne marche toujours pas : il me met la même erreur...

Je programme actuellement avec la librairie SDL. J'ai un petit peu essayé avec DirectX, mais je me suis arrêté à l'importation de Meshes 3D... En effet, j'ai ensuite découvert la facilité de SDL et d'OpenGL... Donc, mon choix est fait ! Du moins pour l'instant... :)

Sinon, je veux utiliser des tableaux dynamiques pour une raison très simple : il faut que la taille de ceux-ci changent en fonction du niveau : chacun ne possèdent pas le même nombre de murs, etc...

Je vais continuer mes recherches persos sur le Net pour tenter de trouver une réponse à ce problème... Après tout, rien n'est impossible !
0
Petitcolas Jonathan
25 mai 2005 à 21:58
Ca y est ! J'ai enfin réussi ! En fait, voici la syntaxe à adopter :

// Déclaration du tableau

wall *Wall;

// Ajout d'éléments

Wall = new wall(1,1);

La persévérance porte toujours ses fruits ! Plus rien ne m'arrête à présent pour terminer ce petit jeu... Enfin... Si, quand même... En effet, pour pousser mes caisses, je me sers d'une fonction qui est dans la classe box.

Voici la partie du code correspondante :

case SDLK_DOWN:
{
for( i=0 ; i<sizeof(Box) ; i++)
{
Box[i].MoveUD();
}

Sokoban->Move(0, 2);
break;
}

Le problème est cependant que cette boucle ne teste que la dernière caisse Box[sizeof(Box)] que j'ai déclarée... Est-ce une erreur d'index ? Ou faut-il que je revois entièrement mon code, qui marchait pourtant très bien lors des essais sans les tableaux dynamiques ?

Tant que j'y suis, un grand merci à tous les programmeurs qui me sont venus en aide ! Je vous mettrais dans les crédits... :-)
0
Luffy =) Messages postés 365 Date d'inscription mercredi 20 avril 2005 Statut Membre Dernière intervention 19 mai 2006 109
25 mai 2005 à 23:50
Salut =)

t'as entendu Char Snipeur ?! on va être dans les crédits !!!!

allez, pour la peine, je vais essayer de résoudre ton problème... mdr =)

à mon avis il vient du sizeof() que tu utilises dans ta boucle for(). car quand on veut la taille d'une variable, on ne met pas de parenthèses. tu peux aller voir là pour la syntaxe exacte :
http://www.lri.fr/~aze/page_c/aide_c/sizeof.html

mais je pense qu'il y aura un autre problème, c'est que sizeof te renvoies la taille en octets de ta variable, et non le nombre d'éléments de ton tableau. ce qui veut dire que soit tu fait un :

sizeof Box / sizeof(ClasseBox)

si tout tes objets Box font la même taille, soit tu incrémentes un compteur pour toujours avoir le nombre de box dans ton tableau. perso je préfère fonctionner de la dernière manière, qui est plus propre et plus sûre.

bon courage =)
0
Petitcolas Jonathan
26 mai 2005 à 06:58
OK... Je vais essayer ça... Allez ! La dernière difficulté à surmonter avant la création des niveaux ! Ca devient bon !

Je vous tiens au courant de l'avancée du projet...
0
Sethpolma Messages postés 66 Date d'inscription mercredi 25 juin 2003 Statut Membre Dernière intervention 8 mars 2007 15
26 mai 2005 à 21:44
Un petit changement de nom : je me suis inscrit finalement à ce site, qui a l'air pas mal du tout...

Donc, me voilà avec (encore...) mon éternel problème... :-)

J'ai essayé avec le nombre de caisses directement, pour faire un truc du style : for( char i = 0 ; i < 3 ; i++ ) et hélas, cela ne fonctionne pas. A mon avis (après quelques essais), je pense que l'erreur concerne l'appel au contenu de mes tableaux... Ou alors, à leurs remplissages.

box* Box = NULL

Box = new box(14,10);
Box = new box(14,8);
Box = new box(15,9);

Voilà pour le remplissage. Le constructeur demande deux paramètres indiquant les coordonnées de la case où la caisse doit être affichée.

Quant à la recherche du contenu, elle est au dessus... J'ai même essayé de supprimer la boucle, et de me contenter de faire un Box[0].MoveUD(); en vain...

Help ! I need somebody ! Help ! :)

Parce que, c'est bien intéressant les cours sur les pointeurs, mais au bout d'une heure de recherches sur Internet, il y en a un peu marre... Il faudrait quand même que j'investisse dans un bon bouquin de C++...
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
27 mai 2005 à 16:44
Lors de ton enchainement de tes 3 new box, tu ne suprimerai pas les précédent? Comment le compilateur sait qu'il doit incrémenté le tableau ou le remplacer?
si tu met un constructeur par defaut ("box::box(void){}")
et que tu fait Box=new box[Nbcaisse] ça ne fonctionnerai pas?
en tout cas chez moi ça fonctionne. je précise Nbcaisse est un int pas un const int : donc il peut varier selon les niveau
0
Sethpolma Messages postés 66 Date d'inscription mercredi 25 juin 2003 Statut Membre Dernière intervention 8 mars 2007 15
27 mai 2005 à 19:57
Miracle ! Ca marche ! Maintenant, il ne me reste plus qu'à réorganiser le tout... Car, quelques petits problèmes d'affichage viennent perturber le tout ! Les caisses se déplacent, mais elles deviennent invisibles. Pas très pratique pour jouer... Donc, encore de folles heures de débuggage pour moi !

Quoi qu'il en soit, merci beaucoup à vous deux, Luffy et Char Sniper ! Comme convenu, je penserai à vous dans les crédits... :) Et vous signalerai l'avancement du projet...
0
Sethpolma Messages postés 66 Date d'inscription mercredi 25 juin 2003 Statut Membre Dernière intervention 8 mars 2007 15
29 mai 2005 à 11:43
Non ! Encore un problème ! Maintenant, tout à l'air de marcher, mise à part la vérification du niveau (si toutes les caisses sont sur les emplacements). Je ne pense pas que le problème vienne de ma fonction, car sur plusieurs niveaux (quatre pour l'instant), elle marche parfaitement.

Mais, c'est lors du changement de niveau : la fonction semble ne plus marcher.

Voici les portions de code correspondantes :

// Fonction de vérification

for( i=0 ; i<nbBox ; i++ )
{
Goal[i].Check();

if( Goal[i].ReadOK() == false )
{
win = false;
}
}

// Création des emplacements GOALS

Goal = new goal[nbBox];

Goal[0] = goal(14,5);
Goal[1] = goal(18,9);
Goal[2] = goal(14,13);

// Suppression lors du changement de niveau

delete [] Goal;

Je ne sais pas d'où vient le problème... Ca doit venir du fait qu'il garde en mémoire les autres goals... Mais il y a delete pourtant... Donc, je m'en remets à nouveau à vous !
0
Char Snipeur Messages postés 9696 Date d'inscription vendredi 23 avril 2004 Statut Contributeur Dernière intervention 3 octobre 2023 1 297
30 mai 2005 à 11:20
c'est quoi le pb exactement?
ça pourrai pas venir du win qui n'est pas reinitialisé?
0
bon c'est cool d'avoir des problemes et de tomber sur des gents simpa qui t'aide a les resoudre mais si tu trouve la reponse est le simpatique reflex de la donnée, que l'on ne reste pas juste sur tes questions! quand on sait c'est cool d'aider les autres
0
c koi ton site
j'en é besoin
0