Problème C++ : tableaux et classes

Petitcolas Jonathan -  
 prout-man -
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 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
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   Statut Membre Dernière intervention   110
 
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   Statut Membre Dernière intervention   110
 
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
 
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
 
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
 
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
 
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   Statut Membre Dernière intervention   110
 
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
 
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   Statut Membre Dernière intervention   15
 
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 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
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   Statut Membre Dernière intervention   15
 
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   Statut Membre Dernière intervention   15
 
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 9813 Date d'inscription   Statut Contributeur Dernière intervention   1 299
 
c'est quoi le pb exactement?
ça pourrai pas venir du win qui n'est pas reinitialisé?
0
salut
 
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
prout-man
 
c koi ton site
j'en é besoin
0