IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Projets Discussion :

OpenAWars - Advance wars like


Sujet :

Projets

  1. #121
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par fearyourself Voir le message
    Je ne vois pas trop de soucis avec cette solution. Je pense que ca peut fonctionner, regarde avec un profiler si vraiment ce bout de code est sur le chemin critique.

    Jc
    Meuh! C'est Angle_blond qui me stresse pour un rien, comme ci j'avais fait une grosse erreur. Sinon, après avoir regardé mon morceau de code ... personnellement je n'ai rien à me reprocher. Donc j'attends son retour pour savoir ce qui cloche :p
    De plus, ce n'est pas sur un chemin critique ... et je n'ai pas remarqué de baisse de performance (genre une attente de 10 secondes )
    Donc, c'est juste par curiosité (et à cause de sa remarque) que je demande ce qui cloche :p

    ----------

    Sinon ... revenons sur mon "avancement",

    Nous voici au tout début de la refonte de la base du jeu. Le but est donc de refaire toute l'interface entre le jeu en lui même et la bibliothèque graphique. Plus précisément, je vais faire en sorte que changer de bibliothèque graphique soit plus que simple et surtout que cela ne modifie en rien le code du jeu.
    Pour ce faire, je vais crée classe virtuelle pure définissant les fonctions devant être réimplémentées par la classe utilisant la bibliothèque.
    La petite particularité que je tiens à rajouter, c'est que la classe doit avoir une visibilité tout aussi importante qu'une bibliothèque externe. Cela veut dire, que malgré un héritage, il n'y aura pas d'instance de la classe. Pour ce faire, j'utilise une classe statique dans laquelle on appelera la classe d'interface (j'aurais aussi pu utilisé un Singleton ...).
    Pour indication, j'ai fait un pseudo diagramme UML (voir pièce jointe). Je n'avais pas de logiciel spécialisé, alors j'ai fait le tout avec OpenOffice (je ne sais plus grand chose de l'UML ... donc c'est peut être légèrement faux).

    Voici la liste des types que j'utilise actuellement:
    SDL_Rect
    SDL_Colour
    SDL_Surface
    SDL_Event
    SDL_VideoInfo
    Voici la liste des fonctions:
    SDL_Init()
    SDL_Quit()

    SDL_ShowCursor()
    SDL_WM_SetCaption()
    SDL_VideoModeOK()
    SDL_GetVideoInfo()
    SDL_SetVideoMode()

    SDL_PumpEvents()
    SDL_GetKeyState()
    SDL_SetEventFilter()

    SDL_FillRect()
    SDL_BlitSurface()
    SDL_CreateRGBSurface()
    SDL_CreateRGBSurfaceFrom()
    SDL_FreeSurface()
    SDL_DisplayFormat()
    SDL_SetColorKey()
    SDL_SetAlpha()
    SDL_UpdateRect()
    SDL_LockSurface()
    SDL_UnlockSurface()

    SDL_Delay()
    SDL_GetTicks()

    IMG_Load
    IMG_GetError()

    TTF_OpenFont()
    TTF_RenderText_Solid()
    TTF_GetError()
    Et la liste des macros / définition supplémentaires:
    SDL_QUERY
    SDL_ENABLE
    SDL_DISABLE
    SDL_MUSTLOCK
    SDL_LIL_ENDIAN
    SDL_BYTEORDER
    SDL_QUIT
    SDL_DOUBLEBUF
    SDL_ANYFORMAT
    SDL_HWSURFACE
    SDL_FULLSCREEN
    SDL_GL_DOUBLEBUFFER
    SDL_OPENGL
    Pour les types, je redéfini mes types génériques (Colour , Rect, Surface). Lors de l'appel aux fonctions de NEngine, j'utiliserai mes types, et si besoin, ceux ci seront convertis par la couche implémentant la bibliothèque graphique.
    Je profite d'une petite retouche de mes (mon) types déjà implémentés: Vec2.
    Je lui ai défini deux nouveau noms:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    typedef Vec2<int> ISize2;
    typedef Vec2<unsigned int> USize2;
    Et ses membres peuvent être appelé de deux manières différentes grace à un 'union':
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    union
    {
    	T x;				/*!< The value on the x axis */
    	T width;
    };
    union
    {
    	T y;				/*!< The value on the y axis */
    	T height;
    };
    Cela peut, d'après moi, rendre le code plus lisible, lorsque j'utilise le Vec2 pour définir des tailles (par exemple, taille de la fenêtre nouvellement créée)

    La grande question était: comment faire en sorte que nous ayons un seul type visible dans l'application, mais que celui ci est différent pour chaque bibliothèque. A cause de ce problème (et de la solution que j'ai choisi) on ne va pas pouvoir utiliser deux bibliothèques en même temps.
    Voici un exemple de la solution que j'ai pris pour le type de la fenêtre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    typedef unsigned int Uint32;
     
    #ifdef SDL_ENGINE
    	#include <SDL/SDL.h>
     
    	typedef SDL_Surface* Window;
    #elif SFML_ENGINE
    	typedef sf::RenderWindow Window;
    #elif GLUT_ENGINE
    	typedef int Window;	// In GLUT, there is no access to the Window. So int is the type (to check error)
    #endif
    Comme ceci, selon la bibliothèque utiliser, le type va être différent. Par contre, l'utilisateur aura accès à ces types, mais ne pourra pas en faire grand chose. Ce sont les fonctions des implémentations des bibliothèques qui auront à utiliser ces types et non l'utilisateur (sinon, ce dernier n'aura pas de code indépendant de la bibliothèque).
    (Je continue à être perplexe sur ce code ... )

    Maintenant, le code de NE / NEngine / NESDL:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    class NE
    {
    private:
    	static NEngine* pEngine;
     
    public:
    	static bool init(void);
    	static void stop(void);
    	static NEngine* get(void);
    };
     
    NEngine* NE::pEngine = NULL;
     
    bool NE::init(void)
    {
    	if ( NE::pEngine != NULL )
    	{
    		LError << "The native engine is already defined";
    		return false;
    	}
     
    	try
    	{
    		NE::pEngine = new NESDL();
    	}
    	catch (ConstructionFailedException& cfe)
    	{
    		LError << cfe.what();
    		return false;
    	}
     
    	return true;
    }
     
    void NE :: stop(void)
    {
    	delete NE::pEngine;
    	NE::pEngine = NULL;
    }
     
    NEngine* NE :: get(void)
    {
    	assert(NE::pEngine);
    	return NE::pEngine;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    class NEngine
    {
    private:
     
    public:
    	virtual ~NEngine() {}
     
    	virtual Window createWindow(const USize2& winSize, const unsigned short bpp, const bool isFullscreen, const bool isOpenGL)=0;
    	virtual USize2 getWindowSize(const Window win)=0;
    	virtual int getBitsPerPixel(const Window win)=0;
    	virtual void destroyWindow(Window win)=0;
     
    	virtual bool isCursorVisible(void)const=0;
    	virtual void setCursorVisible(const bool mustShowCursor)const=0;
    	virtual void setCaption(const std::string& windowName, const std::string& iconName)const=0;
     
    	virtual bool needWindowClosure(void)const=0;
    };
    Pour le code de NESDL, on retrouvera exactement ce qui avait dans mon ancienne classe Window (qui a été enlevé entre temps).
    J'ai commencé à intégré ce nouveau code dans l'application, et pour le moment, je peux dire que cela va. Même si le design n'est peut être pas si bien que cela.

    Demain, j'implémenterai le reste de l'interface.
    Images attachées Images attachées  
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  2. #122
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Bonjour LittleWhite

    Pour indication, j'ai fait un pseudo diagramme UML (voir pièce jointe). Je n'avais pas de logiciel spécialisé, alors j'ai fait le tout avec OpenOffice (je ne sais plus grand chose de l'UML ... donc c'est peut être légèrement faux).
    Ce n'est pas important de faire de l'UML stricte, le principal étant d'être claire et précis (vaut mieux des bons diagrammes que de l'UML mal fait... perso, je fais des "vilains" mixtes avec yEd)


    Sinon ... revenons sur mon "avancement"
    Le vif du sujet...

    Je me fais la réflexion suivante : si tu avais travaillé sur la conception dès le départ, en partant d'une feuille blanche, tu te serais probablement posé la question suivante : "Quelle est la responsabilité de mon moteur de rendu ? Et donc, quelles sont les fonctionnalités que je veux exposer dans mon interface ?"
    Là, en faisant du refactoring, tu te poses la question suivante : "Quelles sont les fonctionnalités actuelles ?" Et j'ai l'impression que du coup, tu as beaucoup trop de fonctionnalités pour ton moteur. Et que tu exposes de types ou des fonctionnalités que l'utilisateur ne pourrait pas utiliser (tu le dis toi même), ce qui est un peu inutile (pourquoi ajouter une fonction createWindow qui retourne une Window si l'utilisateur ne peut rien en faire ? = détail d'implémentation)

    Dans le premier cas, tu te serais probablement dis : "la responsabilité de mon moteur est d'afficher mes tiles et mes objets". Et tu aurais probablement exposer les fonctionnalités suivantes :
    - créer une map de dimensions (W, H)
    - affecter le type de tile TILE_TYPE à la position (x, y) (que le moteur de rendu se débrouille avec le gestionnaire de ressources pour savoir l'image à afficher pour TILE_TYPE !)
    - ajouter/déplacer/supprimer un objet OBJECT_TYPE à la position (x, y) (qui peut représenter un véhicule, un bâtiment, une explosion, etc.)
    Et c'est tout

    Je simplifie un peu, pour une première analyse. Il est probable, en poussant l'analyse que l'on pourrait ajouter d'autres fonctionnalités (en particulier init() et quit())


    L'idée sur laquelle je veux insister est que tu n'as peut être (je précise "peut être", ce n'est que mon avis) pas besoin que NEngine fournisse des fonctionnalités comme charger une image, dessiner un rectangle, etc. A mon avis, ce ne sont que des détails d'implémentation.



    En complément, pour bien faire les choses et bien séparer les responsabilités, il faudrait en plus un gestionnaire de ressources (lire une map, lire des images), un gestionnaire de ta map (un conteneur pour la map de tiles et un conteneur pour la liste des objets) et un moteur de rendu qui affiche la map. Chaque gestionnaire serait constitué de plusieurs classes, par contre chaque gestionnaire serait indépendant l'un de l'autre et serait couplé à ton moteur de jeu.

    PS : pourquoi 2 classes distinctes NE et NEngine ? Et pourquoi faire de NEngine un pointeur alors que cette classe doit nécessairement être initialisé durant toute la vie du programme et que NULL n'est pas une valeur acceptable ?


    Bon courage (et désolé de te casser les pieds )

  3. #123
    Membre éprouvé
    Avatar de Ange_blond
    Homme Profil pro
    Ingénieur développement en 3D temps réel
    Inscrit en
    Mars 2007
    Messages
    902
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur développement en 3D temps réel
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2007
    Messages : 902
    Points : 1 179
    Points
    1 179
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    Meuh! C'est Angle_blond qui me stresse pour un rien, comme ci j'avais fait une grosse erreur. Sinon, après avoir regardé mon morceau de code ... personnellement je n'ai rien à me reprocher. Donc j'attends son retour pour savoir ce qui cloche :p
    Désolé
    Je voulais pas te stresser

    J'avais juste trouvé que c'était pas optimal de repeter un bloc de code plusieurs fois avec d'enorme similitudes. Dans ce genre de cas personellement je privilegie un truc parfois un poil moins lisible mais qui m'évite de faire des oublis lorsque je modife un bloc mais oublie qu'il y en a d'autres derriere...

    M'enfin chacun son truc hein
    "le langage C permet de tout faire, y compris se tirer dans le pied. Le langage C++ permet de tout faire, y compris se tirer dans le pied - et réutiliser la balle"

  4. #124
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Le vif du sujet...

    Je me fais la réflexion suivante : si tu avais travaillé sur la conception dès le départ, en partant d'une feuille blanche, tu te serais probablement posé la question suivante : "Quelle est la responsabilité de mon moteur de rendu ? Et donc, quelles sont les fonctionnalités que je veux exposer dans mon interface ?"
    Là, en faisant du refactoring, tu te poses la question suivante : "Quelles sont les fonctionnalités actuelles ?" Et j'ai l'impression que du coup, tu as beaucoup trop de fonctionnalités pour ton moteur. Et que tu exposes de types ou des fonctionnalités que l'utilisateur ne pourrait pas utiliser (tu le dis toi même), ce qui est un peu inutile (pourquoi ajouter une fonction createWindow qui retourne une Window si l'utilisateur ne peut rien en faire ? = détail d'implémentation)

    Dans le premier cas, tu te serais probablement dis : "la responsabilité de mon moteur est d'afficher mes tiles et mes objets". Et tu aurais probablement exposer les fonctionnalités suivantes :
    - créer une map de dimensions (W, H)
    - affecter le type de tile TILE_TYPE à la position (x, y) (que le moteur de rendu se débrouille avec le gestionnaire de ressources pour savoir l'image à afficher pour TILE_TYPE !)
    - ajouter/déplacer/supprimer un objet OBJECT_TYPE à la position (x, y) (qui peut représenter un véhicule, un bâtiment, une explosion, etc.)
    Et c'est tout

    Je simplifie un peu, pour une première analyse. Il est probable, en poussant l'analyse que l'on pourrait ajouter d'autres fonctionnalités (en particulier init() et quit())


    L'idée sur laquelle je veux insister est que tu n'as peut être (je précise "peut être", ce n'est que mon avis) pas besoin que NEngine fournisse des fonctionnalités comme charger une image, dessiner un rectangle, etc. A mon avis, ce ne sont que des détails d'implémentation.



    En complément, pour bien faire les choses et bien séparer les responsabilités, il faudrait en plus un gestionnaire de ressources (lire une map, lire des images), un gestionnaire de ta map (un conteneur pour la map de tiles et un conteneur pour la liste des objets) et un moteur de rendu qui affiche la map. Chaque gestionnaire serait constitué de plusieurs classes, par contre chaque gestionnaire serait indépendant l'un de l'autre et serait couplé à ton moteur de jeu.

    PS : pourquoi 2 classes distinctes NE et NEngine ? Et pourquoi faire de NEngine un pointeur alors que cette classe doit nécessairement être initialisé durant toute la vie du programme et que NULL n'est pas une valeur acceptable ?


    Bon courage (et désolé de te casser les pieds )
    Hum,

    Meuh! (Tout d'abord)
    Je ne sais vraiment pas ... j'imagine, un manque d'expérience. Pour moi, le NEngine doit savoir charger des fichiers, après peut être que je vais faire en sorte que le chargement des fichiers ne soit jamais visible dans l'application ... c'est un point que je n'avais pas trop pensé.
    Après vous avoir lu, il semblerait que je laisse trop de visibilité tout le temps, et que mes classes ne font pas vraiment ce qu'elles devraient faire.
    Pour l'instant, je ne pense pas encore être parti dans une mauvaise direction avec mon NEngine. Mais je vais réflechir avec cette histoire de Window que je laisse trop de possibilité ... ... effectivement, l'utilisateur n'a pas besoin de Window ...

    Je garde un pointeur sur NEngine, car pour faire jouer l'héritage de NEngine sur NESDL ...
    Encore une fois, vous me posez le doute ... j'ai l'impression d'être parti tout de travers avec tout ce programme ...
    C'était surtout car au début du design de NEngine, j'allais faire en sorte que l'on puisse changer à la volé la bibliothèque ... et que puis je me suis rendu compte que c'était pas possible ...
    Espérons que demain j'apporte enfin un truc correct

    -------

    Sinon, au niveau des mises à jour:

    Première chose que j'ai fait, c'est de faire en sorte que le nouveau type Window ne cache plus un pointeur.
    Cela donne la déclaration suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #ifdef SDL_ENGINE
    	#include <SDL/SDL.h>
     
    	typedef SDL_Surface Window;
    	typedef SDL_Surface Surface;
    #elif SFML_ENGINE
    	#include <SFML/Graphics.hpp>
     
    	typedef sf::RenderWindow Window;
    #elif GLUT_ENGINE
    	typedef int Window;	// In GLUT, there is no access to the Window. So int is the type (to check error)
    #endif
    Et on comprendra facilement que les fonction suivante utilisent maintenant un pointeur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    virtual Window* createWindow(const USize2& winSize, const unsigned short bpp, const bool isFullscreen, const bool isOpenGL)=0;
    virtual USize2 getWindowSize(const Window* const pWin)=0;
    virtual int getBitsPerPixel(const Window* const pWin)=0;
    virtual void destroyWindow(Window* const pWin)=0;
    Le deuxième point sur lequel j'ai travaillé, avant de continuer de mettre la pagaille dans mon code, est la documentation. Effectivement, hier en intégrant une première implémentation du NEngine, je n'ai absolument pas documenté mon travail.

    Maintenant, je peux continuer mon travail autour du NEngine. Après le fenêtrage, il faut que je m'occupe du dessin à l'écran. En fait, cela sera en grande partie juste un déplacement des fonctions du Renderer dans le NEngine (du coup, le Renderer va partir).
    Première fonction, celle pour nettoyer l'écran, rien de particulier. J'en profite même pour rajouter une petite fonctionnalité permettant d'effacer l'écran avec une couleur passé en paramètre.

    Pour les autres fonctions de dessins, il va falloir un peu modifier le design existant. Il n'aurait jamais vraiment du avoir de lien avec la SDL. Effectivement, les classes Sprite et AnimatedSprite utilisent directement des éléments donnés par la SDL.
    Du coup, au lieu d'avoir un pointeur sur une SDL_Surface, nous avons un pointeur sur une Surface (définie dans le morceau de code ci-dessus). A la place des SDL_Rect, j'utilise mes propres Rect:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    struct Rect
    {
    	IVec2 position;
    	USize2 size;
     
    	Rect(const IVec2& position, const USize2& size):position(position),size(size) {}
    };
    Lorsque j'ai besoin de la taille d'une surface, j'utilise de nouvelles fonctions introduitent dans le NEngine:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    virtual USize2 getSurfaceSize(const Surface* const pSurface)=0;
    Si vous vous rappelez bien, le Renderer de base connais l'existance des types de l'application ... ce qui n'est pas une bonne chose, car cela rend le Renderer très lié avec le reste de l'application. Pour enlever ce lien (car il serai dommage d'avoir des références sur Sprite et AnimatedSprite dans le NEngine) je défini des fonctions draw, dans ces deux classes.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    bool Sprite :: draw(Window* const pWin, const IVec2& position)
    {
    	assert(pWin);
     
    	return NE::get()->drawSurface(pWin, position, this->pSurface);
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    bool AnimatedSprite :: draw(Window* const pWin, const IVec2& position, const unsigned int time)
    {
    	assert(pWin);
     
    	Rect srcRect = this->getSrcRect(time);
     
    	return NE::get()->drawSurface(pWin,position,this->pSurface,srcRect);
    }
    Bien sur, en complément, il y a dans le NEngine:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    virtual bool drawSurface(Window* const pWin, const IVec2& position, Surface* const pSurface)=0;
    virtual bool drawSurface(Window* const pWin, const IVec2& position, Surface* const pSurface, const Rect& srcRect)=0;
    Une fois que toutes les référence au Renderer sont enlevé (ou remplacer par la Window, lors du passage en paramètre d'une fonction), le travail autour de l'affichage est fini (et cela fonctionne ).

    Note: La version Linux ne compilera pas !
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  5. #125
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    le NEngine doit savoir charger des fichiers
    Oui, mais...
    - tu donnes plusieurs responsabilités à ton NEngine (rendu et gestion des ressources) : maintenance du code plus complexe, plus de risque d'erreur, ajout de fonctionnalités plus difficile, etc.
    - la gestion des ressources n'est pas simplement de lire un fichier mais également savoir quand libérer les ressources, etc. Là, tu ne gère pas.
    - un autre point important (à mon avis) pour toi, qui est étudiant : tu dois te créer une bibliothèque de codes que tu pourras réutiliser plus tard, dans la vie professionnelle. Plus tu crées de code générique, plus tu auras de ressources pour plus tard.

    Personnellement, je crée ce genre de gestionnaire (ou moteur de rendu, ou toute brique logiciel qui peut être autonome) en créant un nouveau projet et j'utilise le main.cpp pour implémenter mes tests unitaires. J'implémente ensuite dans un sous répertoire les différentes classes de mon module. Et pour terminer, je créer mon programme et j'importe les différents modules à utiliser. Je suis sur ainsi que chaque module est indépendant des autres.


    Petites remarques sur le code du dernier post :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    virtual Window* createWindow(bla bla);
    
    bool Sprite :: draw(Window* const pWin, const IVec2& position)
    {
    	assert(pWin);
     
    	return NE::get()->drawSurface(pWin, position, this->pSurface);
    }
    
    virtual bool drawSurface(Window* const pWin, bla bla);
    Si je comprend bien l'idée, pour dessiner, il faut demander a NEngine un pointeur vers la window... qui sera renvoyé à NEngine pour dessiner
    Ça serait pas plus simple de laisser la windows comme paramètre interne de NEngine ?

  6. #126
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Oui, mais...
    - tu donnes plusieurs responsabilités à ton NEngine (rendu et gestion des ressources) : maintenance du code plus complexe, plus de risque d'erreur, ajout de fonctionnalités plus difficile, etc.
    - la gestion des ressources n'est pas simplement de lire un fichier mais également savoir quand libérer les ressources, etc. Là, tu ne gère pas.
    - un autre point important (à mon avis) pour toi, qui est étudiant : tu dois te créer une bibliothèque de codes que tu pourras réutiliser plus tard, dans la vie professionnelle. Plus tu crées de code générique, plus tu auras de ressources pour plus tard.

    Personnellement, je crée ce genre de gestionnaire (ou moteur de rendu, ou toute brique logiciel qui peut être autonome) en créant un nouveau projet et j'utilise le main.cpp pour implémenter mes tests unitaires. J'implémente ensuite dans un sous répertoire les différentes classes de mon module. Et pour terminer, je créer mon programme et j'importe les différents modules à utiliser. Je suis sur ainsi que chaque module est indépendant des autres.
    Je suis entièrement d'accord avec vous ... mais je n'ai pas de bonne idée actuellement.
    En ce moment, je fais en sorte de répondre a vos remarques (+ celle de Mat.M) qui est de faire un moteur plus générique -> le NEngine.
    Par contre, le NEngine n'est pas exactement comme vous le décrivez. Effectivement, celui ci c'est comment lire un fichier, mais personne n'a dit qu'il devait savoir quand le lire / et quand le libérer. Mon SpriteManager / FontManager (bon ok, celui ci va changer ) resteront en place et s'occuperont des ressources.
    Actuellement (certes ce n'est pas encore écrit) le NEngine n'aura qu'une fonction readFile() qui retournera un Surface* et c'est tout. La gestion n'entrera pas ici.
    Ce que je veux dire, pour le moment (et cela semble faux, mais je n'ai pas de meilleur design) c'est que le NEngine n'est qu'une classe qui contient toute les fonctions d'interface aux bibliothèques graphiques. Je veux dire que par là, elle ne fait que dire: "oui, si vous voulez implémenter une nouvelle bibliothèque (que ce soit SFML / GLUT / Qt), et bah vous n'avez juste a hérité la classe NEngine, et plop c'est fait et ça marche"
    Après, vous me dites que le design ne va pas ... ou n'est pas réutilisable ... bah je suis extrèmement perdu ... car ... jusqu'à présent ... presque aucun de mes codes n'a été réutilisé (ce n'est pas que ce n'est pas ce que je cherche ... mais c'est juste que je change de philosophie tout les deux jours).

    Ah! et pour la libération des ressources ... oui effectivement il n'y a pas de gestion, mais en même temps, le NEngine est un "Work in Progress" ... donc ... pour l'instant je ne vois même pas ou une telle gestion pourrait s'intégrer. Et puis comme je l'ai dit, le NEngine aura certes une fonction FreeSurface() mais rien de plus (donc on voit bien qu'il n'y a pas de gestion de ressources ... mais juste une fonction qui permet de libérer la ressource.
    Après, je suis un peu perplexe, vous me parlez de réutilisabilité de code, mais hier, il m'a semblé que vous disiez que mon code était trop générique, et que le votre me sembler restreindre l'utilisateur à faire un script (soit un code avec peu de choix). Mais ... pensez vous qu'un code plus restreint est plus réutilisable?
    Sinon, je suis dans la globalité d'accord avec vous ... mais je reste tout de même vraiment perplexe (surtout avec la réutilisabilité du code).

    Citation Envoyé par gbdivers Voir le message
    Petites remarques sur le code du dernier post :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    virtual Window* createWindow(bla bla);
    
    bool Sprite :: draw(Window* const pWin, const IVec2& position)
    {
    	assert(pWin);
     
    	return NE::get()->drawSurface(pWin, position, this->pSurface);
    }
    
    virtual bool drawSurface(Window* const pWin, bla bla);
    Si je comprend bien l'idée, pour dessiner, il faut demander a NEngine un pointeur vers la window... qui sera renvoyé à NEngine pour dessiner
    Ça serait pas plus simple de laisser la windows comme paramètre interne de NEngine ?
    \o/ C'est exactement ce que j'ai fais aujourd'hui
    Voir mon rapport du jour:

    Je dois dire que cette fois, je suis dans une très grande reflexion sur comment faire la base de mon programme.
    J'aimerai bien enlever ce besoin de Window qui se répand sur tout le code, mais si je le fais, je réduit la généricité de mon code ... et du coup, celui-ci devient moins évolutif.
    Le deuxième exemple du même genre, est basé sur la gestion du curseur (celui du système d'exploitation). Effectivement, il est loin d'être nécessaire de laisser les fonctions suivantes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    bool isCursorVisible(void)const;
    void setCursorVisible(const bool mustShowCursor)const;
    Mais cela veut aussi dire que si un jour je reprends ce moteur, je vais devoir changer la base même de celui-ci.

    Bon, je prends une décision (et j'essaie de ne pas revenir dessus). Le NEngine, aura bel et bien la gestion de multiple fenêtre, mais ceci sera masqué par NE, qui fera en sorte d'en concerver qu'une seule. L'application n'aura jamais accès à celle-ci.
    Il est de même pour le NEngine. L'application ne jouera plus avec directement.
    Du coup, coté NEngine nous avons actuellement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    class NEngine
    {
    private:
     
    public:
    	virtual ~NEngine() {}
     
    	// Windowing
    	virtual Window* createWindow(const USize2& winSize, const unsigned short bpp, const bool isFullscreen, const std::string& windowName, const std::string& windowIcon ="", const bool showCursor = false)=0;
    	virtual USize2 getWindowSize(const Window* const pWin)=0;
    	virtual int getBitsPerPixel(const Window* const pWin)=0;
    	virtual void destroyWindow(Window* const pWin)=0;
     
    	virtual bool needWindowClosure(void)const=0;
     
    	// Drawing
    	virtual USize2 getSurfaceSize(const Surface* const pSurface)=0;
     
    	virtual bool clearScreen(Window* const pWin, const Colour& colour)=0;
     
    	virtual bool drawRect(Window* const pWin, const Rect& tile, const Colour& colour)const=0;
    	virtual bool drawSurface(Window* const pWin, const IVec2& position, Surface* const pSurface)=0;
    	virtual bool drawSurface(Window* const pWin, const IVec2& position, Surface* const pSurface, const Colour& mask)=0;
    	// virtual bool drawSurface(Window* const pWin, const Rect& destRect, Surface* const pSurface)=0;
    	virtual bool drawSurface(Window* const pWin, const IVec2& position, Surface* const pSurface, const Rect& srcRect)=0;
    	virtual bool drawSurface(Window* const pWin, const IVec2& position, Surface* const pSurface, const Rect& srcRect, const Colour& mask)=0;
     
    	virtual bool updateScreen(Window* const pWin)=0;
    };
    Et visible par l'application:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    class NE
    {
    private:
    	static NEngine* pEngine;		/*!< Engine to use by the program */
    	static Window* pWin;			/*!< Window for the application */
     
    public:
    	static bool init(const USize2& winSize, const unsigned short bpp, const bool isFullscreen, const std::string& windowName, const std::string& windowIcon="");
    	static void stop(void);
     
    	static USize2 getWindowSize(void);
    	static int getWindowBPP(void);
     
    	static bool needWindowClosure(void);
     
    	static USize2 getSurfaceSize(const Surface* const pSurface);
     
    	static bool clearScreen(const Colour& colour);
     
    	static bool drawRect(const Rect& tile, const Colour& colour);
    	static bool drawSurface(const IVec2& position, Surface* const pSurface);
    	static bool drawSurface(const IVec2& position, Surface* const pSurface, const Colour& mask);
    	static bool drawSurface(const IVec2& position, Surface* const pSurface, const Rect& srcRect);
    	static bool drawSurface(const IVec2& position, Surface* const pSurface, const Rect& srcRect, const Colour& mask);
     
    	static bool updateScreen(void);
    };
    Note: En mettant à jour la doc doxygen, celui-ci m'a signalé une erreur qui aurait pu planté la compilation avec d'autre bibliothèque (non SDL)
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  7. #127
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Bon progrés, cela faisait un moment que je n'avais pas suivi ton avancement. Par contre, je me demande si tu ne vas trop te perdre dans ta refonte. N'en fais-tu pas un peu trop pour l'utilité de ton jeu ?

    En gros, si je comprends bien, tu es en train de faire une grosse refonte de ton moteur de jeu et non seulement un refactoring du jeu. Tu veux donc en tirer un moteur à part entière ?

    Ca c'est un boulot énorme et je te souhaite bien du courage. Mais je me demande l'utlité de la distinction que tu fais entre NEngine et NE, tu peux m'expliquer ta distinction ?

    Et quelle était l'erreur de Doxygen ?

    Jc

  8. #128
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Je suis entièrement d'accord avec vous ... mais je n'ai pas de bonne idée actuellement.
    C'est moi que tu vouvoies


    Plusieurs remarques (encore ) :

    1. Toutes les idées que je te donne ne sont pas forcement à implémenter tout de suite. Mais comme on parle de la partie conception, il faut quand même prévoir pour éviter de devoir refactoriser après.
    Prenons par exemple le gestionnaire de ressources. Il est évidement que ce n'est pas le bon moment pour ajouter ce type de nouvelle fonctionnalité, surtout que tu n'as pas encore réfléchit aux stratégies de gestion des ressources. Mais si tu laisses le NEngine s'occuper de la gestion des ressources, tu devras le modifier quand tu implémenteras un vrai gestionnaire. Et tu devras modifier plusieurs classes, avec les risques d'erreurs, de régression et de recherches du code à refactoriser. Si tu transfères tout de suite les fonctions de gestion de ressources dans une classe dédiée, tu gagneras du temps lorsque tu voudras refactoriser.

    2.
    c'est que le NEngine n'est qu'une classe qui contient toute les fonctions d'interface aux bibliothèques graphiques
    Oui, c'est le but
    L'idéal serait que par exemple, si tu utilises plusieurs lib dans plusieurs modules, les dépendances soient minimales (par exemple, si tu as un module GUI, un module son, un module ressources et un modules réseau et que tu utilises SDL, Fmod, libxml et boost::asio, chaque module ne devrait être lié qu'a une seule lib chacun)

    Le problème dans ton code actuel est que tu masques la dépendance à la SDL mais... la dépendance existe quand même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    typedef SDL_Surface Window;
    typedef SDL_Surface Surface;
    Si tu utilises le type Window dans ton code, tu écriras peut être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Surface* s = nengine->readFile(...);
    int width = s->w; // ok
    Ensuite, si tu changes de lib graphique, tu auras par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef QPaintDevice Surface;
    ...
    Surface* s = nengine->readFile(...);
    int width = s->w; // erreur, w n'existe pas dans QPaintDevice !
    Résultat, tu n'as pas supprimé la dépendance à la SDL


    3.
    Après, vous me dites que le design ne va pas ... ou n'est pas réutilisable ... bah je suis extrèmement perdu ... car ... jusqu'à présent ... presque aucun de mes codes n'a été réutilisé (ce n'est pas que ce n'est pas ce que je cherche ... mais c'est juste que je change de philosophie tout les deux jours).
    C'est bien le problème. Et c'est surement indicateur d'un problème de conception


    4.
    Après, je suis un peu perplexe, vous me parlez de réutilisabilité de code, mais hier, il m'a semblé que vous disiez que mon code était trop générique, et que le votre me sembler restreindre l'utilisateur à faire un script (soit un code avec peu de choix). Mais ... pensez vous qu'un code plus restreint est plus réutilisable?
    Il faut que le code soit générique au maximum pour être réutilisé mais chaque élément doit avoir une responsabilité unique. Dans le cas contraire, quand tu modifieras une des reponsabilités, tu devras tout modifier (non respect du OCP)

    Par exemple, la resposabilité "dessiner l'écran de jeu" de NEngine peut être diviser en plusieurs responsabilités : "dessiner du texte", "dessiner une image", etc.


    5. Tu utilises beaucoup de static dans NEngine... tu caches de variables globales qui en ont pas l'air de cette façon. Et c'est pas bien


    6. Est-il indispensable de créer 2 classes pour les sprites (AnimatedSprite et Sprite). Ne peut on pas considérer que Sprite est un AnimatedSprite avec 1 seule image ?

    Mon conseil : mets à plat sur une feuille de papier la structure de l'application, en indiquant bien les responsabilités de chaque classe/module et les connections entre elles. Et lit le blog d'Emmanuel


    Je vais te faire quelques graphismes pour illustrer mon propos.


    EDIT :
    Par contre, je me demande si tu ne vas trop te perdre dans ta refonte. N'en fais-tu pas un peu trop pour l'utilité de ton jeu ?
    J'entre autant dans les détails parce que je pars du principe que son objectif est avant tout d'acquérir plus d'expérience dans la création de jeu. Sinon, ça ne serait peut être pas "utile" pour le jeu à court terme

  9. #129
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par fearyourself
    Ca c'est un boulot énorme et je te souhaite bien du courage. Mais je me demande l'utlité de la distinction que tu fais entre NEngine et NE, tu peux m'expliquer ta distinction ?
    NEngine décrit une interface pour guider l'implementation de bibliothèques différentes.
    NE est une manière de cacher le tout afin de rendre un accès global dans tout le Jeu à NEngine (et en le simplifiant) (on va surement revenir dessus)

    Citation Envoyé par gbdivers Voir le message
    C'est moi que tu vouvoies
    Oui :p


    Citation Envoyé par gbdivers Voir le message
    2.

    Oui, c'est le but
    L'idéal serait que par exemple, si tu utilises plusieurs lib dans plusieurs modules, les dépendances soient minimales (par exemple, si tu as un module GUI, un module son, un module ressources et un modules réseau et que tu utilises SDL, Fmod, libxml et boost::asio, chaque module ne devrait être lié qu'a une seule lib chacun)

    Le problème dans ton code actuel est que tu masques la dépendance à la SDL mais... la dépendance existe quand même :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    typedef SDL_Surface Window;
    typedef SDL_Surface Surface;
    Si tu utilises le type Window dans ton code, tu écriras peut être :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Surface* s = nengine->readFile(...);
    int width = s->w; // ok
    Ensuite, si tu changes de lib graphique, tu auras par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef QPaintDevice Surface;
    ...
    Surface* s = nengine->readFile(...);
    int width = s->w; // erreur, w n'existe pas dans QPaintDevice !
    Résultat, tu n'as pas supprimé la dépendance à la SDL
    Alors je ne sais pas comment faire.
    J'ai des bibliothèques qui chacune, redéfinissent un type pour les fenêtres, et un type pour les surfaces (Sprite / Image).
    Donc oui, certes je ne cache pas qu'à un moment ou a un autre, j'utilise des SDL_Surface ou autre, mais d'un coté, cela est dans le choix du créateur de l'application qui utilise le NEngine, car:
    • Je ne peux pas cacher le type, car celui ci est nécessaire à l'utilisateur (et j'imagine que la seule solution, c'est d'utiliser des classes Window et Sprite, qui utilisent les types que j'ai défini, non ?)
    • Si l'utilisateur veut ne pas faire de multi plateforme / multi bibliothèques, bah il peut toujours utiliser le type comme bon lui semble

    Donc oui, c'est mal ... je ne cache pas efficacement le type. Par contre, je lui donne toutes les fonctions qu'il faut pour l'utiliser de manière multiplateforme. Que me proposez vous, de propre, qui demande peu de changement lorsque je dois implémenté une nouvelle bibliothèque (car refaire une classe Window pour chaque bibliothèque, n'est ce pas un peu trop lourd?)

    Citation Envoyé par gbdivers Voir le message
    3.

    C'est bien le problème. Et c'est surement indicateur d'un problème de conception
    Effectivement (je ne le cache pas), et c'est ce que j'essaie d'amélioré avec votre aide (c'est un vous de pluriel :p) ...

    Citation Envoyé par gbdivers Voir le message
    4.

    Il faut que le code soit générique au maximum pour être réutilisé mais chaque élément doit avoir une responsabilité unique. Dans le cas contraire, quand tu modifieras une des reponsabilités, tu devras tout modifier (non respect du OCP)

    Par exemple, la resposabilité "dessiner l'écran de jeu" de NEngine peut être diviser en plusieurs responsabilités : "dessiner du texte", "dessiner une image", etc.
    En même temps, le NEngine ne dessine pas l'écran ... mais dessine une Surface ... donc je ne vois pas le problème ... je suis dans la forme canonique (si je puis dire)

    Citation Envoyé par gbdivers Voir le message
    5. Tu utilises beaucoup de static dans NEngine... tu caches de variables globales qui en ont pas l'air de cette façon. Et c'est pas bien
    Ouep ... bah je ne vois pas encore comment faire ... pour que en même temps je me débarrasse de ce passage de paramètre à travers tout le programme pour avoir la fenêtre. D'un autre coté, j'essaie d'éviter le Singleton (je vais lire l'article cette après midi)

    Citation Envoyé par gbdivers Voir le message
    6. Est-il indispensable de créer 2 classes pour les sprites (AnimatedSprite et Sprite). Ne peut on pas considérer que Sprite est un AnimatedSprite avec 1 seule image ?
    Oui et non. Mais une seule classe serait de donner trop d'importance à cette classe (responsabilité unique?). (Il faut que je lise l'article aussi (je vais le faire)).
    Y a un Sprite, et y a un Sprite qui change selon le temps (soit un héritage, comme je l'ai fait ...) Donnez moi des arguments (favorables et défavorables) et je verrai si je dois changer

    Citation Envoyé par gbdivers Voir le message
    Mon conseil : mets à plat sur une feuille de papier la structure de l'application, en indiquant bien les responsabilités de chaque classe/module et les connections entre elles. Et lit le blog d'Emmanuel
    Ouep, je bloque peut être un peu sur cette partie

    Citation Envoyé par gbdivers Voir le message
    J'entre autant dans les détails parce que je pars du principe que son objectif est avant tout d'acquérir plus d'expérience dans la création de jeu. Sinon, ça ne serait peut être pas "utile" pour le jeu à court terme
    J'essaie de créer un jeu video d'abord Après, j'essaie de le faire pas trop mal. Là je me rends compte que l'on se penche plus sur la création d'un moteur, que du jeu en lui même (et oui, malheureusement fearyourself, je vais perdre encore un peu de temps là dessus )
    Je cherche à avoir un Design assez niquel (mais si en programmation tout n'est ni blanc ni noir) ... et que par la discussion je chercher à connaitre le pour et le contre de chaque solution. Pour l'instant, le design avec le NEngine n'est pas trop mauvais (pour moi), juste son utilisation dans le NE qui est très barbare.
    Après, une note que j'aimerais bien travailler avec le NEngine, c'est la séparation en petits modules (Window / Draw / Sound / Event) ... mais là je peine encore un peu.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  10. #130
    Expert éminent sénior

    Avatar de fearyourself
    Homme Profil pro
    Ingénieur Informaticien Senior
    Inscrit en
    Décembre 2005
    Messages
    5 121
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : Ingénieur Informaticien Senior
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2005
    Messages : 5 121
    Points : 11 877
    Points
    11 877
    Par défaut
    Je ne questionne pas le bon fondement de cette discussion, ni de son utilité. C'est un peu la discussion que nous avons eu sur mon projet : veux-tu faire un moteur générique ou un jeu ? Ensuite dans le "faire un jeu", veux-tu le faire avec un moteur spécifique que tu pourras réutiliser que très peu ou assez générique pour ce que tu veux ?

    Je pense, personnellement, qu'il vaut mieux faire une première version de ton jeu avec ton moteur comme il est, et ensuite voir, une fois le projet fini, ce qui était moins bon et ce qui était super.

    Ne perd pas de temps maintenant sur ce genre de détail et avance dans le jeu sans forcément prendre trop de raccourcis mais il vaut mieux un truc qui fonctionne que pleins de choses sur du papier.

    Si on prend mon moteur comme exemple, clairement il est improvisé et clairement il y a des choses qui bougent car je n'ai pas pensé à ce détail ou à celui-là. Mais, lorsque j'aurai fini la première version, je peux le reprendre, tirer les conclusions nécessaires et en faire une refonte compléte. Moi, je vise un moteur générique pour des raisons personnelles, mais toi tu faisais un jeu bien défini, alors pourquoi, pour ce projet, t'embêter avec ces détails ?

    Moi, je le faisais comme projet du soir/weekend pour délirer un peu et pas trop prendre la tête dessus, c'est pour me reposer et m'amuser, et toi ?

    C'est sur ces points que tu me perds un peu, je pense et potentiellement, tu te perds un peu,
    Jc

  11. #131
    Membre habitué Avatar de CriPpLe
    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    157
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 157
    Points : 125
    Points
    125
    Par défaut
    De toute façon même si t'essayes de faire un moteur générique pour ce jeu, pour le prochaine jeu que tu voudras faire tu auras tellement appris qu'au final tu partiras sur un nouveau moteur tout beaux en reprenant que certaines choses de l'anciens.

  12. #132
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Je pense, personnellement, qu'il vaut mieux faire une première version de ton jeu avec ton moteur comme il est, et ensuite voir, une fois le projet fini, ce qui était moins bon et ce qui était super.

    ...
    Tu as peut être raison. Peut être que je regarde trop en détail la conception (j'aime bien la conception et du coup j'aime prendre du temps pour travailler ce point dès le départ).
    Il n'est peut être pas nécessaire de travailler autant la conception pour ce type de projet (mais je trouve dommage que LittleWhite, qui est étudiant, n'en profite pas pour se perfectionner en conception en utilisant ses projets perso)

    De toute façon même si t'essayes de faire un moteur générique pour ce jeu, pour le prochaine jeu que tu voudras faire tu auras tellement appris qu'au final tu partiras sur un nouveau moteur tout beaux en reprenant que certaines choses de l'anciens.
    Ça c'est fort probable.
    L'idée de la généricité n'est pas forcement de créer un moteur de jeu complet qui sera directement réutilisable. Mais plus d'avoir des collections de classes qui le seront.
    Si par la suite on te demande de créer un programme quelconque et que tu as qu'un mois pour le faire, tu pourras reprendre tes classes XXX, YYY et ZZZ (qui finalement, seront pas si mal et seront suffisante pour cette application) et te concentrer sur ce qui est spécifique.

    Il y a des grands classiques que l'on retrouve dans de nombreuses applications : un gestionnaire de configuration, un gestionnaire de ressources, un conteneur de type vector mais en 2D, etc.

  13. #133
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    * explose de rire
    (C'est nerveux )

    Pardon ... mais c'est surtout que j'ai réfléchi à cette "satané" conception toute l'après midi, et je suis sur d'être loin d'un bon truc ....

    Pour réponse à toutes vos questions (du moins j'essaie) ...:

    Je fais ce jeu pour le plaisir, aucune contrainte, aucune obligation, c'est un jeu que j'ai commencé en fin de vacances d'été, et que je continue dès que j'ai un peu de temps libre (ce qui recommence à me manquer à cause de l'université )

    Je suis étudiant, certes, mais je suis étudiant en programmation de jeux vidéos. je tiens à le préciser car cela change un peu la donne sur le mot "étudiant". Pourquoi cela change la donne? Simplement car j'ai un cours qui apprends a crée un jeu video: "Advances Games Software Development" et qui celui-ci utilise la SDL pour la GP2X (comme console à contrainte) et que dans celui-ci, le plan est:
    1. Préparation du projet (faut au moins compilé le Hello World sur la GP2X n'est ce pas )
    2. Ouverture de la fenêtre
    3. Affichage Sprite
    4. Gestion commandes (un joystick et les bouttons)
    5. Son
    6. Boucle de jeu

    Puis dans les choses qui j'ai pas encore fait:
    1. Gestionnaire de mémoire
    2. Système de messages
    3. Un truc surprise

    Sachant que la partie que j'ai déjà faite (je ne suis pas en retard) a été faite en trois mois... et que point de vue réutilisabilité, bah j'ai juste repris le code d'OpenAWars (et comme l'univ a des logiciels contre le plagiat, il faut bien que je précise d'où vient mon code / le pourquoi / que c'est bien le mien )

    Donc pour vous dire, le code que j'ai pour ce cours, ressemble a celui d'OpenAWars (et l'inclusion des exceptions et un ajout que j'avais surtout fait pour le cours).
    Donc j'ai l'impression que dans le monde du jeux videos (et surtout console) on se fout (je ne dis pas que c'est une vérité) de la conception du fond ... tant que l'on puisse afficher nos trois sprites en bataille.

    Maintenant, personnellement, je suis un peu déçu que la gestionnaire de mémoire arrive après le reste ... mais bon ... de toute façon je me suis fait un petit programme à coté pour tester les méthodes (et avoir les problèmes au plus tot ) (vous parliez de cette méthode un peu avant )

    Revenons à OpenAWars. Oui je travaille la conception, car je me suis rendu compte que c'était un point faible du projet. Peut être pas sur le moteur en lui même même si celui-ci est peu sujet aux évolutions (et d'un coté, cela était normal, car cela n'était absolument pas le but au début ... et je pouvais très bien géré le Renderer en OpenGL comme prévu) ... Mais bon, en période de refactoring, pourquoi ne pas refaire la base :p (et puis je suis sur un système de controle de version et je sens que j'aurai du faire une brance )
    Maintenant, il faut dire que cela commence à bassinner un peu (surtout la responsabilité unique) comme vous allez le voir par la suite.

    Alors, oui, je vais faire en sorte d'avoir mon NEngine (la version que je présente après) de stable et propre ... mais si celle que je présente ne convient toujours pas ... bah ... je crois que je vais un peu abandonné l'idée du tout propre tout clean ... parce que là ... cela m'embête vraiment (surtout que je dois faire le refactoring du reste du jeu, qui est tout aussi important).
    Donc, ne le prenez pas mal si j'ai vais avancé sans trop me soucié de mon design ... mais dans tout les cas je vous écoute, et je réfléchi à propos de tout ce que vous me dites. Maintenant, j'ai passé près d'une semaine à tout cassé / reconstruire là ou je ne pensais pas le faire y a une semaine, et comme en entreprise, même si cela n'y est pas ... je vais avancé.
    Donc demain (ou après demain ) j'annonce ... je vais avoir mon joli NEngine tout propre \o/

    Donc voici ma nouvelle proposition de design:

    En pièce jointe, vous pouvez trouver encore une fois, un schéma "UML".
    Je souhaiterais que gbdivers y jette un coup d'oeil pour me dire si cela peut convenir. Sachant que j'essaie d'appliquer au mieux ce que l'on me dit. (Notamment, j'utilise des loader spécifiques, pour suivre le principe de responsabilité unique (qui risque de m'enerver )).

    Mon deuxième problème, c'est que l'on a toujours une recompilation totale du projet si on veut changer de bibliothèque. Je n'ai pas trouvé de moyen de l'éviter ... :s

    Sinon, par rapport au schéma, il faut que je décrive un peu les fonctions que je veux mettre dedans.

    La classe Window aura:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Window* createWindow(const USize2& winSize, const unsigned short bpp, const bool isFullscreen, const std::string& windowName, const std::string& windowIcon ="", const bool showCursor = false)=0;
    USize2 getWindowSize();
    int getBitsPerPixel();
    void destroyWindow();
    Le Renderer (qui lors de la const:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Renderer(Window* pWin);
     
    clearScreen(const Colour& colour);
     
    bool drawRect(const Rect& tile, const Colour& colour)const;
    bool drawSurface(const IVec2& position, Surface* const pSurface);
    bool drawSurface(const IVec2& position, Surface* const pSurface, const Colour& mask);
    bool drawSurface(const IVec2& position, Surface* const pSurface, const Rect& srcRect);
    bool drawSurface(const IVec2& position, Surface* const pSurface, const Rect& srcRect, const Colour& mask);
     
    bool updateScreen();
    La classe Sound:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    bool play()
    bool stop()
    En fait, comme je ne me suis jamais vraiment interessé au son ... je ne sais pas

    La classe Input:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    ArrowsDirection getDirectionPressed(void)const;
    Buttons getButtonsPressed(void)const;
    Il va surement y avoir une liste d'Input que l'on conservera et dans laquelle on pourra mettre un Input que l'on veut (joystick / clavier)

    La classe TimeSystem:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    unsigned int getTime();
    void delay(unsigned int);
    La classe Surface:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Surface(const USize2& size);
     
    USize2 getSize();
    getNativePtr();	// Surement en friend avec le Renderer ... mais là ... j'ai un GROS doute
    Et puis les Loader avec une méthode load:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Resource* load(const std::string& fileName);
    Les loaders vont faire ce que j'appelle "ResourcesManager" soit ma std::map qui permet de charger qu'une seule fois pour toute le fichier. Est-ce que je casse la réponsabilité unique en faisant cela? Je pense que oui, mais au début, je voulais faire un ResourceManager template, tout cela en forçant les types pris en compte par cette classe à avoir une fonction load / free. En pensant cela, je voulais faire en sorte que la Surface soit donc une Resource (obligation d'avoir un free()) et une FileResource (héritage de Resource), pour l'obligation du load à partir d'un fichier. Mais je me suis dit que cela n'était pas possible et que cela cassait totalement avec cette réponsabilité unique.
    Autre point sur lequel je bute ... c'est que ce "Loader" fera donc la gestion de la libération O_o

    Ah oui! J'oubliais ! L'Engine est une classe qui contient tout les éléments comme marqué dans le diagramme ... et qui propose une fonction init / quit (pour l'initialisation des bibliothèques) et des setter / getter pour mettre en place la Window le Renderer ...

    Note: Je préfère programmer que faire de l'UML ... car j'étais nul en ce dernier pendant les cours (et bon ... je préfère dans tout les cas sauté sur le code )
    Images attachées Images attachées  
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  14. #134
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Quand je disais que tu étais étudiant, ce n'était pas une critique. Au contraire, je voyais ça comme un avantage pour toi : tu peux prendre le temps de bien faire les choses puisque tu n'as pas de contraintes de temps (ie pas de dateline, je me doute que tu as des contraintes de temps disponible ), ce qui ne durera pas...

    Tu as déjà un (très ?) bon niveau en programmation, qui te permet (à priori) de pouvoir travailler sur n'importe quel projet. L'étape suivante est donc d'avoir un vision plus large des projets et d'approfondir la conception. Et après, tu ne pourras plus t'en passer

    - forte dépendance entre tes classes (je ne sais pas si c'est évitable, je n'ai pas regardé l'architecture en détail) et surtout avec SDL. Je ne sais pas si ça se fait habituellement dans les jeux, mais je me dis que si tu avais rassemblé dès le départ toutes tes accès à la SDL dans une classe wrapper unique, tu pourrais plus facilement porter ton programme sur différentes plateforme (par exemple Qt pour mettre sur Symbian je sais, je ne change pas) ou faciliter l'évolution vers OpenGL pour l'accélération matériel.
    Je me cite moi même pour rappeler mon interrogation de base, qui a motivé mes remarques : il est déjà pénible que les différentes plateformes n'utilisent pas le même langage (c++, .net, c#, etc.) et qu'il faut donc réécrire la même application plusieurs fois (ou abandonner l'idée de toucher un public plus large). Le C++ est accepté sur plusieurs plateformes, c'est un avantage qu'il faut utiliser au maximum.
    Imaginez l'avantage pour un employeur (ou un client) si vous lui dite qu'en prenant 1 journée pour bosser correctement la conception, vous pourrez isoler le code spécifique à une plateforme et que vous pourrez donc, à moindre frais, porter l'application et toucher un public plus large !

    C'était aussi un peu l'idée de porter ton application sur Qt pour le porter sur mobile


    Note: Je préfère programmer que faire de l'UML ... car j'étais nul en ce dernier pendant les cours (et bon ... je préfère dans tout les cas sauté sur le code )
    Pareil pour moi, je suis pas fan d'UML. Je préfère de loin faire mes propres diagramme. Du moment que c'est compréhensible.

  15. #135
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par gbdivers Voir le message
    Quand je disais que tu étais étudiant, ce n'était pas une critique. Au contraire, je voyais ça comme un avantage pour toi : tu peux prendre le temps de bien faire les choses puisque tu n'as pas de contraintes de temps (ie pas de dateline, je me doute que tu as des contraintes de temps disponible ), ce qui ne durera pas...
    Je trouvais que lorsque l'on bossait en entreprise (car je l'ai fait toute l'année dernière) cela donnait plus de temps car on avait pas de "devoir maison" à faire
    Sinon, je ne l'ai jamais pris comme une critique Je voulais juste faire le point sur ce que j'apprenais vraiment (car je n'apprends plus vraiment le langage en lui même) et mon point de vue

    Citation Envoyé par gbdivers Voir le message
    Je me cite moi même pour rappeler mon interrogation de base, qui a motivé mes remarques : il est déjà pénible que les différentes plateformes n'utilisent pas le même langage (c++, .net, c#, etc.) et qu'il faut donc réécrire la même application plusieurs fois (ou abandonner l'idée de toucher un public plus large). Le C++ est accepté sur plusieurs plateformes, c'est un avantage qu'il faut utiliser au maximum.
    Imaginez l'avantage pour un employeur (ou un client) si vous lui dite qu'en prenant 1 journée pour bosser correctement la conception, vous pourrez isoler le code spécifique à une plateforme et que vous pourrez donc, à moindre frais, porter l'application et toucher un public plus large !
    J'ai virevolté durant cette dernière semaine, car je n'avais pas défini clairement les contraintes / objectifs du projet. (Dans le sens -> multiplateforme, mais pas multibibliothèque) Et que du coup, j'ai touché plusieurs fois à ces contraintes (surtout de savoir si je faisais en sorte que l'on ne doit pas recompiler le projet pour changer de bibliothèque graphique ou pas). Le point est que je vais garder mon histoire de NEngine2.
    Il faut aussi savoir que vous avez souvent critiquer mon choix sur la SDL, mais, sachez aussi que c'est la bibliothèque qui me permettait le plus de plateforme en sorti, tout cela, sans nécessairement faire mon NEngine2 :p Donc, mon choix était justifié est totalement possible. Juste que l'intégration de Qt aurait été un peu plus dure (pour l'intégrateur) mais .... d'un coté je pouvais ne pas m'en soucier (et de toute façon, l'intégration sera toujours aussi dur car Qt est une bibliothèque trop différente de SFML / SDL.

    Citation Envoyé par gbdivers Voir le message
    Pareil pour moi, je suis pas fan d'UML. Je préfère de loin faire mes propres diagramme. Du moment que c'est compréhensible.
    Je parlais aussi un peu de conception en général ... vu qu'il est très souvent nécessaire de revenir sur la conception à cause des contraintes du langage et des plateformes ...

    Bon ... aller ... espérons que j'ai mon NEngine2 de fini pour ce soir (alors qu'il n'est pas commencé )
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  16. #136
    Inactif  


    Homme Profil pro
    Inscrit en
    Novembre 2008
    Messages
    5 288
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Secteur : Santé

    Informations forums :
    Inscription : Novembre 2008
    Messages : 5 288
    Points : 15 620
    Points
    15 620
    Par défaut
    Il faut aussi savoir que vous avez souvent critiquer mon choix sur la SDL
    Désolé d'avoir donné cette impression. Je n'ai rien contre la SDL (ni n'importe quel lib en général). Je ne l'utilise par ce qu'elle n'est pas adapté à mes besoins et forcement je parle souvent de Qt parce que c'est celle que j'utilise le plus. Mais c'est qu'une question de besoin (et ça fait longtemps que je n'ai pas travaillé sur un projet de jeu)

    Bonne continuation

  17. #137
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Il n'y a pas de mal à critiquer (et je ne vous visez pas (c'était un vous de pluriel ). C'est juste que dans la page 6 de ce fil de discussion vous avez dit que la SDL pouvait être lourde et mal adapter (alors que pour moi, je pensais que c'était la plus adapté).
    Lors de la conception basique au début du jeu, j'avais fait en sorte que l'on puisse implémenté des moteur de rendu différent de ce de la SDL mais ce n'était que pour le rendu. Là, nous sommes parti sur un objectif un peu différent (que je ne critique pas vraiment vu qu'il y a des pour et contre pour les deux).

    Maintenant, personnellement, il est très rare que je pense à Qt pour faire un jeu ... car la bibliothèque est très lourde (taille, fonctionnalité) et n'est pas spécialisé pour les jeux (et ce n'est pas son objectif premier). Après, elle peut très bien le faire ...

    Donc, pardon d'avoir un peu enterré la discussion :p mais je voulais rajouter, que si vous avez des critiques à faire, je vous invite à les faire (c'est toujours enrichissant).

    Maintenant, j'ai une bonne nouvelle (je crois). J'ai mis en place mon deuxième design du NEngine. Pour l'instant j'ai eu quelques conflits avec la classe Sprite du jeu (car j'ai une classe du même nom) mais comme la classe Sprite (et surement l'AnimatedSprite) vont être modifié par la suite, le problème est juste de courte durée.

    Par contre, je suis sur que j'ai fais des erreurs de conception, notamment lorsque je dois utilisé le mot clé 'friend' (qui j'imagine est un mot clé comme beaucoup, qui existe mais pour l'utilisé correctement il faut être un Guru)
    De plus, j'utilise des cast à la C (car ceux à la C++ ne veulent pas passer (honte à moi)) pour pouvoir donner des accès suffisant de la classe Renderer aux classes Sprite et Window.
    Il est vrai que je voyais une méthode pour éviter ceci, mais cela aller donné accès au pointeur natifs des bibliothèques, à l'utilisateur ... ce qui était vraiment non voulu.

    Voilà pour aujourd'hui. Bientot je vais attaquer le refactoring du jeu en lui même
    Joyeux Noël à tous Amusez vous bien et merci de me lire
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  18. #138
    Membre averti
    Homme Profil pro
    Lycéen
    Inscrit en
    Novembre 2008
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Novembre 2008
    Messages : 86
    Points : 355
    Points
    355
    Par défaut
    Bonjour, et joyeux noël

    Je me demandais, quel logiciel de modélisation UML utilisez-vous?
    Perso' je me lance aussi dans un refactoring total de mon projet, et j'utilise Visio 2010, c'est très joli mais un peu lourd à l'usage je trouve...

    Sinon pour le conflit de noms, pourquoi ne pas utiliser un namespace?
    Et pour le 'friend', c'est vrai qu'il faut éviter à tout prix, sauf quand on ne peux pas faire autrement sans "gymnastique"
    Et quel est votre problème de cast à la C++ ? Souvent, recopier les "insultes" du compilateur résout bien des choses

    Bon, à part ça, une remarque : ça fait vraiment C/C++ des fois (mélange quoi), même si c'est beaucoup mieux qu'au début

    Sinon, une question (sans hostilité aucune) : quel intérêt de pouvoir switcher de la SDL à la SFML, par exemple? Autant accélérer la SDL avec OpenGL et ainsi garder une vaste compatibilité, non ?

    Bon courage pour la suite

  19. #139
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 860
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 26 860
    Points : 219 062
    Points
    219 062
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par pierreyoda Voir le message
    Je me demandais, quel logiciel de modélisation UML utilisez-vous?
    Perso' je me lance aussi dans un refactoring total de mon projet, et j'utilise Visio 2010, c'est très joli mais un peu lourd à l'usage je trouve...
    Je pensais que Visual Studio aller en proposer un ... mais pas du tout. Là ... j'utilisais OpenOffice Draw (pour faire les présentation, car on peut faire les carrées et les flèches facilement (et c'est mieux que Gimp )). Mais habituellement (lorsque j'ai une connexion internet qui me permet de le télécharger j'utilise Bouml (sinon, il y aussi ArgoUML mais je ne connais que de noms )

    Citation Envoyé par pierreyoda Voir le message
    Sinon pour le conflit de noms, pourquoi ne pas utiliser un namespace?
    Effectivement J'y ai pensé, mais j'ai été un peu trop fainéant ... je le ferai peut être (surement?) dans les prochains jours. De toute façon l'autre classe va partir :p (là j'ai chercher à avoir le projet qui marche le plus rapidement possible après tout ces changements :p)
    Citation Envoyé par pierreyoda Voir le message
    Et pour le 'friend', c'est vrai qu'il faut éviter à tout prix, sauf quand on ne peux pas faire autrement sans "gymnastique"
    Et quelles sont généralements les solutions que l'on trouve avec la gymnastique ? Sachant que j'ai des fonctions draw dans une classe Renderer qui doivent connaître pas mal de chose (un membre privé) de deux autres classes (Window et Sprite) et que ce membre privé ne doit être visible que pour ce Renderer uniquement
    Citation Envoyé par pierreyoda Voir le message
    Et quel est votre problème de cast à la C++ ? Souvent, recopier les "insultes" du compilateur résout bien des choses
    J'ai utilisé un void* (le pire truc du monde) dans mon code, et que je veux le caster et ce dans une fonctions constante à la classe. Le dynamic_cast rale donc car cela casse le const (ou alors je ne sais pas du tout l'écrire correctement)

    Citation Envoyé par pierreyoda Voir le message
    Bon, à part ça, une remarque : ça fait vraiment C/C++ des fois (mélange quoi), même si c'est beaucoup mieux qu'au début
    Merci Mais j'avoue ... j'ai encore un grand esprit C

    Citation Envoyé par pierreyoda Voir le message
    Sinon, une question (sans hostilité aucune) : quel intérêt de pouvoir switcher de la SDL à la SFML, par exemple? Autant accélérer la SDL avec OpenGL et ainsi garder une vaste compatibilité, non ?
    Aucun intérêt .... du moins pas dans se sens là (et au début du projet c'est ce que j'avais prévu et tout était en ordre pour). Mais y a quelqu'un qui m'a dit ce serai bien de faire un port pour Qt par exemple

    Citation Envoyé par pierreyoda Voir le message
    Bon courage pour la suite
    Merci même si je profite plus de mes vacances (et des fêtes) que de travailler sur cette suite Mais bon, je prends un peu de retard, mais rien de grave.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  20. #140
    Expert confirmé

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2007
    Messages
    1 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1 895
    Points : 4 551
    Points
    4 551
    Par défaut
    En logiciel UML, tu peux aussi tenter d'utiliser STarUML. Il fonctionne sous Windows (et aussi sous Wine, si tu es sous Linux).

    IL faudrait que je reprenne la discussion depuis le début (ou depuis un post déterminé, mais je ne sais pas lequel) pour vous apporter mon grain de sel. Il y a des choses intéressantes à dire, je pense.
    [FAQ des forums][FAQ Développement 2D, 3D et Jeux][Si vous ne savez pas ou vous en êtes...]
    Essayez d'écrire clairement (c'est à dire avec des mots français complets). SMS est votre ennemi.
    Evitez les arguments inutiles - DirectMachin vs. OpenTruc ou G++ vs. Café. C'est dépassé tout ça.
    Et si vous êtes sages, vous aurez peut être vous aussi la chance de passer à la télé. Ou pas.

    Ce site contient un forum d'entraide gratuit. Il ne s'use que si l'on ne s'en sert pas.

Discussions similaires

  1. [Projet en cours] Strategy(nom provisoire) - Advance wars like
    Par TiranusKBX dans le forum Projets
    Réponses: 17
    Dernier message: 29/09/2016, 15h46
  2. [VB6] [ADO] Like sur base Access
    Par dlpxlid dans le forum VB 6 et antérieur
    Réponses: 9
    Dernier message: 24/01/2003, 11h03
  3. Créer un interpréteur de langage inspiré du Basic
    Par Picasso dans le forum Algorithmes et structures de données
    Réponses: 4
    Dernier message: 11/05/2002, 17h10

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo