Bataille Navale OpenGL

Salut à tous!

Voilà, j’ai commencé à programmer en C il y a quelques mois, vers la fin de l’année à l’IUT grâce aux cours de C en informatique industrielle, ce qui m’a donné l’occasion d’apprendre et de m’initier à ce langage si connu.
Ayant déjà fait pas mal de programmation en basic, j’ai vite progressé en C, et quelques semaines après avoir débuté j’ai pu m’intéresser à des trucs… plus intéressants que ce qu’on faisait.

On avait un TP de bataille navale à réaliser, en mode texte très basique.
Pendant les vacances de Pâques j’ai lu de la doc sur la librairie Glut OpenGL (on m’a dit que c’était la plus simple pour débuter), des cours d’universités sur cette même librairie, ce qui m’a permis de voir que finalement utiliser et adapter cette librairie à un petit jeu de bataille navale n’était pas si compliqué. La preuve avec mon niveau de débutant j’y suis arrivé sans trop de complications.

J’ai pu coder une version « utilisable » de mon jeu en deux semaines.
Cette version a un peu évolué depuis (un peu car depuis j’y ai peu travaillé). Le jeu est 100% au point, le seul truc qui manque, c’est l’IA. Pour le moment on peut juste jouer contre un autre joueur réel. C’est déjà pas mal non? :stuck_out_tongue:

Si je poste ici, c’est parce que je veux savoir si mon programme est bien codé. Car quand je le lis, je trouve que c’est pas trop propre, et j’ai l’impression d’être le seul à comprendre mon code bordélique. Je sais pas non plus si l’architecture du code et des fonctions est claire. Enfin.
Si un codeur ou deux ici avaient l’aimabilité de jeter un coup d’oeil à mon modeste code pour me donner son avis, j’aimerai beaucoup :stuck_out_tongue:

D’abord, voici les fichiers exécutables:
version Windows
version Linux (installez la librairie Glut avant d’exécuter)
Pour déplacer le curseur on utilise les flèches directionnelles, pour faire une rotation de 90° du curseur quand on place un bateau c’est ENTREE, et pour placer un bateau, et faire feu (haha) c’est ESPACE (parce que c’est une grosse touche sur laquelle on peut se défouler).

Ensuite le code source:
projet Visual C++ 6.0 (Windows)
projet Kdevelop (Linux)
Si vous n’avez pas Kdevelop, aucun souci, vous pouvez compiler le programme avec n’importe quel compilateur, vous pouvez utiliser gcc en ligne de commande sur le fichier bn.c tout simplement (passer les paramètres -lglut -lGL -lGLU -L/usr/X11R6/lib au compilateur).

Le fichier loadppm.c a été codé par un professeur d’université, Eric Bittar, et ça m’a permi de charger une image de fond dans mon jeu.
La page concernée où j’ai réucpéré loadppm.c: ICI

Si vous avez des questions de trucs que vous vous demandez « mais à quoi ça sert??? Pourquoi il a mis ça ici??? » je pourrais sûrement vous répondre :stuck_out_tongue: et vous faire part du raisonement loufoque qui a produit votre intérrogation :stuck_out_tongue:

Voici le topic que j’avais créé pour résoudre certains problèmes que j’avais rencontrés:
http://www.cafzone.net/ipb/lofiversion/index.php/t25498.html

Voila, donc si quelqu’un pouvait me dire ce qu’il pense de la structure du code, et tout, ce que je pourrais améliorer, ça peut m’intéresser B)
Je débute donc j’ai pas mal à apprendre.

#include "loadppm.c"     // c'est pas moi qui ai écrit loadppm.c !

AH !!!
Vade retro includas !!!

quelle horeur, sur ça marche, mais imagine tu commence un projet plus gros et tu include à chaque fois le fichier c, le linker va t’envoyer petre car il trouvera plusieurs fois le même symbole (en l’occurence une fonction). De manière générale, on évite de faire un #include sur un fichier contenant du code, on met que des déclarations.

Le truc plus propre et clean à faire :

[code]#ifndef LOADPPM
#define LOADPPM

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include <GL/glut.h>

typedef struct {
   int sizeX, sizeY;
   GLubyte *data;
} PPMImage;

static PPMImage *LoadPPM(const char *filename);

#endif /* LOADPPM */[/code]
ça dans un LoadPPM.h, et dans ton projet

#include "LoadPPM.h"

ça va être plus contraignant car il va falloir compiler bn.c ainsi que LoadPPM.c, mais ça sera bénéfique d’avoirs ces fichiers séparés en module (réutilisation plus facile dans l’avenir par exemple).

===================================================

gluBuild2DMipmaps(GL_TEXTURE_2D, 3, image->sizeX, image->sizeY, GL_RGB, GL_UNSIGNED_BYTE, image->data);

Là c’est plus « conceptuel », sachant que tu affiches ta texture fixement en arrière plan les mipmaps ne sont pas vraiment nécéssaires, pas besoin de versions réduites de la texture :]. J’utiliserai plutôt la fonction basique d’OpenGL : glTexImage2D.

===================================================

Le dernier truc que j’ai repéré, c’est trop plein de chiffres, on sait pas forcément à
quoi ça correspond, au hasard :

if (touche == 13) { if (orientation == 1){ orientation =0;} else {orientation = 1;} }

Dans 2 mois je suis pas sur que tu te rappelles ce que vaut 0 ou 1 pour l’orientation ou bien ce qu’est la touche 13 (à part peut-être la treizième touche :stuck_out_tongue: ). Mon truc à moi, c’est faire plein de #define dans tous les sens, et de les placer dans un bon gros header. En partant de ça on pourrait penser à quelquechose du genre

#define ORIENTATION_VER &nbsp; &nbsp; 0 &nbsp;/* Valeurs au pif */ #define ORIENTATION_HOR &nbsp; &nbsp;1

Ce qui en remplaçant dans ton code source rendrait la chose plus lisible.

===============================================

Bon voilà c’est ce que j’ai vu un peu au hasard car je me suis pas plongé à fond dedans, car c’est vrai que c’est un peu bordélique ^^; (non je montrerai pas mes sources qui sont bien pires). Sinon je pense pas que j’aurais organisé le programme comme toi, mais moi j’ai rien fait ^^;.

Dernier pti truc (ui chui chiant), dans le même ordre d’idée que le « dans 2 mois », essaye de commenter l’appel des fonctions, même si souvent le nom de l’argument est explicite, par exemple on se doute bien que des arguments x,y sont des positions, mais position du centre ou d’un coin (et quel coin?)? (pour un rectangle j’entend). Je sais pas si je suis assez clair… tant pis on est dimanche ^^

Sinon je me suis fait battre par moi même à la bataille navale et je suis profondemment vexé.

Pour rajouter deux petits détails, plutôt qu’une liste de #define, on peut utiliser enum dans certains cas, ça évite de numéroter à la main ce qui empêche les erreur et permet de modifier l’ordre sans problème.

[code]#define UP 1
#define DOWN 2
#define LEFT 3
#define RIGHT 4

peut être remplacé par

enum {
UP = 1,
DOWN,
LEFT,
RIGHT
};[/code]

Et aussi, lorsque tu définis une chaîne de caractères, tu n’es pas obligé de spécifier la taille du tableau, le compilateur peut le faire pour toi :

Pas la peine d’écrire explicitement hello[12].

[quote]Dans 2 mois je suis pas sur que tu te rappelles ce que vaut 0 ou 1 pour l’orientation ou bien ce qu’est la touche 13 (à part peut-être la treizième touche laugh.gif ). Mon truc à moi, c’est faire plein de #define dans tous les sens, et de les placer dans un bon gros header. En partant de ça on pourrait penser à quelquechose du genre[/quote]Oui c’est vrai que c’est mieux, je vais faire des #define pour toutes ces valeurs biscornues.

Sinon il faut aussi effectivement que j’ajoute pas mal de commentaires, mais ça je compte m’y mettre.

[quote]Sinon je me suis fait battre par moi même à la bataille navale et je suis profondemment vexé.[/quote]Ca ne m’étais encore jamais arrivé :stuck_out_tongue:

Faudra que je me penche sur la modif pour loadppm.c
Etant donné qu’il me faudra compiler deux fichiers .c, comment on fait avec VC++6? J’ajoute juste les deux fichiers au projet? Et aussi, en ligne de commande avec gcc? (ça pourra m’être utile).

Merci pour tes conseils en tout cas!

EDIT: désolé tu as posté pendant que je répondais Drealmer

[quote]Et aussi, lorsque tu définis une chaîne de caractères, tu n’es pas obligé de spécifier la taille du tableau, le compilateur peut le faire pour toi[/quote]Ah ben c’est intéressant )a, je savais pas j’avais jamais testé, aussi je m’embêtais à changer à chaque fois comme un débile dès que j’ajoutais une lettre :stuck_out_tongue:

Ah oui des enum ça existe aussi ça, j’oublie souvent de l’utiliser :]

pour la compilation sous GCC :

gcc -c LoadPPM.c gcc -c bn.c gcc LoadPPM.o bn.o -o out
Je zappe les options du compilo mais je pense que t’as pigé l’esprit, et VC6 se dépatouille comme un grand pour te produire l’exe final quand tu rajoutes le fichier dans ton projet

[quote name=‹ bluelambda › date=’ 21 Aug 2005, 20:13’]Sinon il faut aussi effectivement que j’ajoute pas mal de commentaires, mais ça je compte m’y mettre.
[right][post=« 388083 »]<{POST_SNAPBACK}>[/post][/right][/quote]
Ben pourquoi ? Moi je trouve ça bien dosé niveau commentaires. Trop de commentaires, c’est pire que pas de commentaires du tout :stuck_out_tongue: Il faut documenter tout ce qui permet de comprendre la structure du code, et ne pas mettre de commentaires là où c’est trivial.

Exemple de mauvais commentaire (riez pas, j’ai déjà vu) :

x = x + 5; // on ajoute 5 à x

Oui faut pas exagérer non plus :stuck_out_tongue:
Mais je viens de relire un peu et quelques passages manquent vraiement de commentaires, je ne sais plus trop moi même pourquoi j’ai fait comme ça. Bref il manque quelques explications.

Ensuite il y a tout ce que j’ai fait au brouillon, à l’occas si j’ai le temps je le ferai à l’ordi, ça permet de mieux comprendre le déroulement du programme et les choix que j’ai faits.