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. #181
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    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 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Le jeu progresse !

    Voici la première mise à jour d'une nouvelle série.
    En effet, j'attaque maintenant l'ajout de fonctionnalité. Bon là, je triche un peu, car ce sont des choses qui été plus ou moins déjà présente.
    Ainsi, aujourd'hui, j'ai un peu travaillé sur la classe MenuBox (qui affiche une boite de menu, avec plusieurs entrées) pour qu'elle soit prête à répondure à tout les cas que l'on a vu auparavant.
    Effectivement, même si cette classe était déjà présente avant, il n'y avait pas de mécanisme afin d'afficher ou d'effacer certaine entrées non valides. Maintenant si.
    J'utilise une nouvelle structure internet pour les entrées, qui contient 4 champs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    struct MenuItem
    {
    	std::string actionName;		/*!< id of the entry */
    	std::string displayName;	/*!< name to display */
    	AnimatedSprite* pASprite;	/*!< sprite to display */
    	bool enabled;				/*!< true if this entry is displayed */
     
    	MenuItem(const std::string& actionName, AnimatedSprite* const pASprite, const std::string& displayName)
    		:actionName(actionName),displayName(displayName),pASprite(pASprite),enabled(true) {}
    };
    Comme vous pouvez le voir, il y a un booléan pour dire si l'entrée est active ou non. Si elle ne l'est pas, elle n'est ni affichée, ni prise en compte.
    De plus, j'utilise maintenant un nom d'action (qui est aussi utilisé comme identifieur pour l'activation, désactivation de l'entrée) afin de pouvoir retournée une information cohérente pour enclecher une action selon l'entrée sélectionnée. Le mieux, ça serait un mécanisme utilisant des pointeurs de fonctions, mais je ne pense pas que ce serai une bonne idée.
    Une autre idée qui me vient en tête en écrivant ce message, c'est l'utilisation de template. Il faudrait que je me penche là dessus.
    Enfin, bref, pour le moment, cela suffit

    L'autre ajout, ce sont les états du jeu. Ainsi, lorsque le joueur voit la carte / bouge le curseur c'est l'état Neutre. Chaque état à une classe correspondante. En ce moment, j'ai implémenté 4 états qui héritent tous de:
    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
    enum IGState
    {
    	IGS_Idle,
    	IGS_Menu,
    	IGS_Construction,
    	IGS_UnitSelected,
    	IGS_Quit
    };
     
    class InGameState
    {
    protected:
    	Map* pMap;
    	const Camera* pCamera;
    	Cursor* pCursor;
     
    public:
    	InGameState(Map* pMap, const Camera* pCamera, Cursor* pCursor);
    	virtual ~InGameState() {}
     
    	virtual bool draw(NE::Renderer* pRenderer, unsigned int time)=0;
    	virtual IGState update(NE::InputManager::ArrowsDirection direction, NE::InputManager::Buttons buttons, unsigned int time)=0;
    };
    Le principe, assez simple, c'est que chaque état connait ce qu'il doit faire (une méthode de dessin et une méthode de mise à jour). La méthode update (de mise à jour) est intéressante, car elle se doit de renvoyer l'état qui va suivre (selon les différents choix de l'utilisateur).
    S'il n'y a pas de changement, la fonction retourne donc l'enum de l'état actuel. Sinon, on retourne le nouvel état.
    Le changement d'état se fera dans la classe Game, automatiquement, grâce à l'utilisation d'une std::map (dont la clé est le IGState).
    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
    bool Game :: draw(NE::Renderer* pRenderer, unsigned int time)
    {
    	bool bResult = true;
    	// Drawing part
    	bResult &= MapDrawer::draw(*pRenderer,pMap,*pCamera,time);
     
    	bResult &= states[igState]->draw(pRenderer,time);
     
    	return bResult;
    }
     
    bool Game :: update(NE::InputManager::ArrowsDirection direction, NE::InputManager::Buttons buttons, unsigned int time)
    {
    	(void) time;
     
        pCamera->update(*pCursor,*pMap);
     
    	igState = states[igState]->update(direction,buttons,time);
    	if ( igState == IGS_Quit )
    	{
    		return false;
    	}
     
        return true;
    }
    On pourra remarquer, que depuis cette mise à jour, les fonctions de la classe Game sont toutes simples . Donc l'introduction des états permet de faire une meilleure architecture (moins foulli) du code.

    Voilà.
    J'ai implémenté les états:
    - Idle
    - Construction d'unité
    - Menu (un menu très simple pour le moment)
    - Sélection d'unité (par encore complet, car il me faut faire une classe utilitaire)

    Ce qui arrivera prochainement:

    Une nouvelle classe qui contiendra les informations courantes sur le jeu (le joueur actuel (pour la gestion des factions) et les sous qu'il a (pour la construction)).
    Et une autre classe qui aura surement des fonctions statiques (classe utilitaire) qui génèrera des surcouche pour la carte afin d'indiquer là ou le joueur peut attaquer ou se déplacer).
    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. #182
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    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 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Ce week end, il y a encore eu du progrès. Comme je vous l'avais promis, ce sont des choses visibles.

    J'ai ajouté ma classe qui gère l'argent des différentes factions, mais aussi les multiples éléments qui font qu'une partie fonctionne (argent, gestion des tours).
    Pour que l'argent disponible soit visible pour le joueur, j'ai ajouté une classe (un élément visuel) que j'appelle OfficerBox (voir capture d'écran). J'avoue, j'ai repris directement le sprite utilisé dans le jeu original, mais bien sur, ce n'est que temporaire.
    L'ajout fut assez simple, sachant que ce ne sont que deux lignes à ajouter dans un fichier XML pour que le jeu prenne en compte le nouveau fichier.

    Le deuxième ajout est ce que j'appelle un MapMarker (il y en aura trois en tout, et ils héritent tous d'une classe mère donc voici la déclaration:
    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
    class MapMarker
    {
    protected:
     
    	const Map* pMap;
     
    	AnimatedSprite* pMarkerSprite;
     
    	std::vector<std::vector<int>> marks;
     
    	void setMarksInRange(const UVec2& position, unsigned int minRange, unsigned int maxRange);
     
    public:
    	MapMarker(const Map* pMap, AnimatedSprite* pMarkerSprite);
    	virtual ~MapMarker() {}
     
    	virtual void clear();
    	virtual void setMarksForUnitAt(const UVec2& position)=0;
     
    	bool draw(const NE::Renderer& r, const Camera& c, const unsigned int time);
    };
    )
    Ce ne sont juste que des tableaux 2D de la même taille de la carte, qui permette de marquer celle-ci afin d'afficher des informations (les zones d'attaques, comme présenté sur les captures d'écran ou alors là ou l'on peut se déplacer).

    La dernière note que j'aimerai ajouter, ces que les carrés rouges pour symboliser la zone d'attaque on été réalisé par moi sont animés. Certes ces la première animation dans mon programme, mais la classe pour les sprites animés était présente depuis très longtemps. Juste qu'il me fallait un ensemble de sprites.
    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.

  3. #183
    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
    Excellentes avancées :-). Mes félicitations!

    Question : pourquoi un MapMarker et pas juste intégré ces informations dans les Maps ?

    Jc

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    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 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Citation Envoyé par fearyourself Voir le message
    Excellentes avancées :-). Mes félicitations!

    Question : pourquoi un MapMarker et pas juste intégré ces informations dans les Maps ?

    Jc
    Simplement, par choix de design.

    En fait, depuis ma refactorisation, j'ai éclaté la classe Map en plein de classe (statiques) permettant:
    - le chargement ;
    - la création ;
    - la sauvegarde ;
    - l'affichage ;
    - la vérification de l'intégrité (ou de la cohérence des tuiles / unités)

    Pourquoi? Simplement car la classe Map doit être à responsabilité unique et que sa responsabilité, c'est juste d'avoir une représentation des tuiles et des unités de la partie (des getter et setter). C'est genre, un grand conteneur.
    Mais, l'intégration des fonctionnalités du MapMarker était bien possible, oui sauf que, cela agrandirai une classe déjà lourde. De plus, ma carte n'est marqué qu'a certains moment du jeu (certains états). Et puis, il me faut trois types de "marker" différent (trois implémentations), selon les états qui les utilisent. Moi je pense qu'il est préférable de voir la classe à l'extérieur. Après, c'est un choix qui se défend (veuillez donc défendre l’intérêt de l'avoir à l'intérieur )
    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. #185
    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
    L'inconvénient que je vois d'avoir mis un MapMarker dehors est que maintenant comment fais-tu pour chercher un MapMarker du Map. Alors potentiellement tu n'en as pas besoin mais peut-être un jour?

    Moi j'ai une vue plus simple qui est de dire que tout ce qui touche à la map doit être contenue dans la Map. Alors ensuite, effectivement, cela peut faire grossir la classe mais pas forcément car j'ai ma classe Cell qui contient les informations d'une case et ensuite la Map n'a que les informations de la map générique. J'ai une dernière abstraction car je peux avoir des villes à niveaux multiples donc j'ai un MapHandler qui contient les informations pour la ville et les maps de chaque niveau.

    Je pense que tout se défend mais je préfére savoir que quand j'arrive sur une cellule précise je préfére pouvoir tirer toutes les informations nécessaires de là:

    - est-ce qu'elle est visible, atteignable, etc.

    Alors qu'il me semble que toi, tu ne pourras plus savoir cela facilement...

    Après, cela dépend de ton jeu ;-)
    Jc

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    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 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    @fearyourself:
    Je vois votre point (enfin je crois, car le MapHandler, cela sonne étrangement ). Mais, par rapport à votre argument, j'ai répondre que ce que fais le MapMarker n'est pas une information pour la carte en elle même. Je vais essayer d'être plus précis.
    J'ai une Map, qui contient les informations de la carte, tels que les tuiles et les unités. Jusque là, c'est normal.
    Le MapMarker, n'est qu'un élément de l'interface, il est loin d'être obligatoire (mais c'est mieux pour le joueur, pouvant être comparé à une aide). Le MapMarker n'affecte pas le jeu en quoi que ce soit (bien que, dans le code d'aujourd'hui, je l'utilise afin de faire une vérification en plus (qui peut être évité -> car la carte fournit cette information)). Le MapMarker est construit (déterminer) par rapport aux infos de la carte. Ce n'est pas une information supplémentaire en tant que telle, car cette information dépend de tout ce que contient la Map.
    C'est juste un élément à afficher en plus, qui repose sur les infos de la carte.
    (Ok, je l'ai dit 20 fois )
    J'espère que vous avez compris mon point de vue

    ---

    Bonjour,

    Aujourd'hui, je présente une petite mise à jour (dans le sens, ou cela a été rapide à implémenter).
    J'ai enfin écrit le code pour la marquage des tuiles sur lesquelles nous pouvons déplacer les unités (voir capture). Le sprite n'est pas animé (pas grande importance) et toujours réalisé pour moi (il n'est pas très bien, car on ne le voit pas assez).
    Mais au moins, cela fonctionne.
    Pour ce faire, j'ai hérité une deuxième fois la classe MapMarker. Comme au moment de ce second héritage, je me suis rendu compte que la fonction virtuelle pure répété le même code de vérification (-> Si la position passée est valide, si une unité est présente sur cette tuile) alors je me suis dit qu'à la place de faire des copier coller (car c'est le mal!) il serai préférable de mettre se code en tant que fonction publique dans la classe de base, et que cette nouvelle fonction appelle une fonction virtuelle pure pour le coloriage à proprement parler.
    Soit, algorithmiquement:
    - Entré dans l'état de jeu qui a besoin d'une coloration
    - Appel d'une fonction publique qui fait les vérification
    - Après vérification, appelle d'une fonction virutelle pure (protégée) qui utilisera donc les principes de l'héritage afin d'appeler la fonction approprié de coloriage.

    Ainsi, les vérifications ne sont écrites qu'une seule fois, et tout le temps appliqués.

    J'ai aussi rajouté une fonction dans la classe de base pour savoir si une case est marquée ou non.

    Un autre ajout, c'est la gestion du cout de déplacement des tuiles. Pour cela j'ai ajouté deux balises dans mon fichier XML des tuiles (et une pour celui des unités). Ainsi, la montagne, par exemple, provoque un coup de déplacement de deux.
    Les arbres aussi, mais seulement pour les véhicules (les unités d'infanterie (ou à pied) ne sont pas affectés).

    Nous pouvons maintenant déplacer les unités ! \ o /
    Encore mieux , lorsque l'on annule la sélection d'une unité, le curseur revient à la position précédente.

    J'ai aussi écrit le code de coloration des cases à portée d'une unité, que si une unité ennemie se trouve dessus (pour le marqueur qui indiquera les unités attaquables).
    Mais il reste encore un peu de travail là dessus.
    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.

  7. #187
    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
    Excellent ! Bientôt on pourra se faire une partie alors !

    Je comprends mieux ton point de vue et suis d'accord, je n'avais pas vu cela comme cela ;-)

    Jc

  8. #188
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    61
    Détails du profil
    Informations personnelles :
    Âge : 31
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 61
    Points : 33
    Points
    33
    Par défaut
    Bonjour,
    Y a t-il des nouvelles sur votre jeu ?

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    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 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Malheureusement, là, c'est un peu mort. J'espère sincèrement donner des nouvelles rapidement .
    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. #190
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    61
    Détails du profil
    Informations personnelles :
    Âge : 31
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 61
    Points : 33
    Points
    33
    Par défaut
    Ok pas de problème, bonne chance pour la suite

  11. #191
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    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 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Enfin des nouvelles et pas de moindres.

    Tout d'abord, un grand changement dans le jeu. J'ai décidé d'utiliser des .bmp pour mes images, avec la couleur RGB(255,0,255) comme couleur transparente. Avec ce changement, je gagne beaucoup de FPS (~200-300).
    Contrecoup de l'opération, les sprites grisés (qui sont grisés par la fonction de la SDL) ne fonctionne plus.
    Afin de faire ce que je souhaitais, j'ai créé les sprites grisés à la main (donc sauvegardé en .bmp) et je les ai intégrés dans le jeu. L'intégration (XML + changement dans le code) ne m'a pris que quelques minutes.

    J'espère vous donner des nouvelles fraiches très prochainement.
    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.

  12. #192
    Membre éclairé
    Avatar de divxdede
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    525
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Avril 2004
    Messages : 525
    Points : 844
    Points
    844
    Par défaut
    Citation Envoyé par LittleWhite Voir le message
    Enfin des nouvelles et pas de moindres.

    Tout d'abord, un grand changement dans le jeu. J'ai décidé d'utiliser des .bmp pour mes images, avec la couleur RGB(255,0,255) comme couleur transparente. Avec ce changement, je gagne beaucoup de FPS (~200-300).
    Contrecoup de l'opération, les sprites grisés (qui sont grisés par la fonction de la SDL) ne fonctionne plus.
    Afin de faire ce que je souhaitais, j'ai créé les sprites grisés à la main (donc sauvegardé en .bmp) et je les ai intégrés dans le jeu. L'intégration (XML + changement dans le code) ne m'a pris que quelques minutes.

    J'espère vous donner des nouvelles fraiches très prochainement.
    N'aurait-t'il pas été plus robuste de faire la transformation au chargement des images ?
    C'est à dire charger une image rgba (c'est à dire une image avec canal alpha) la convertir en rgb (avec ta couleur 255,0,255) pour la transparence.

    Les avantages:
    - pour la version grisée, tu pouvais faire un load(rgba) --> sdl(griser) --> rgb
    - Les images sources utilisent toujours la vrai transparence ce qui est plus confortable pour le graphiste/designer (même si c'est toi).

    Maintenant, je suis surpris que gérer toi même la transparence sur une image rgb soit beaucoup plus rapide que de laisser s'afficher directement une image rgba...
    JBusyComponent, une API pour rendre occupé un composant swing.
    SCJP Java 6.0 (90% pass score)

  13. #193
    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
    Citation Envoyé par LittleWhite Voir le message
    J'ai décidé d'utiliser des .bmp pour mes images, avec la couleur RGB(255,0,255) comme couleur transparente. Avec ce changement, je gagne beaucoup de FPS (~200-300).
    Citation Envoyé par divxdede
    C'est à dire charger une image rgba (c'est à dire une image avec canal alpha) la convertir en rgb (avec ta couleur 255,0,255) pour la transparence.
    Il s'agit d'un masque dans un cas (donc un simple test : "si la couleur est RGB(255,0,255), on affiche rien") alors que dans l'autre cas, il s'agit d'un calcul de transparence ("source * alpha + dest (1-alpha)"), non ? Ce qui expliquerait la différence.
    Par contre, cela veut dire que ça ne donne pas exactement le même effet (antialiasing pour le alpha). Ca donne quoi en terme de rendu ? Tu aurais des images ? Tu peux changer de monde pendant l’exécution ?
    Dans le version avec alpha, avais tu désactivé la transparence quand c'était pas nécessaire (par exemple pour faire le sol) ?

    Citation Envoyé par divxdede
    N'aurait-t'il pas été plus robuste de faire la transformation au chargement des images ?
    C'est à dire charger une image rgba (c'est à dire une image avec canal alpha) la convertir en rgb (avec ta couleur 255,0,255) pour la transparence.
    Plus robuste ? Le format bmp est standard quand même. Par contre, ce n'est effectivement pas sans conséquences :
    - bmp est pas très bien compressé -> charge mémoire (stockage) plus importante et chargement plus long
    - par contre, pas de décompression à faire à la lecture -> gain en terme de performance
    - les 2 points fait que le chargement est plus ??? aucune idée
    - pas de conversion à faire avec bmp -> gain de temps + pas besoin d'avoir l'image rgba en mémoire (gain de place)
    bref, à passer en profiling pour connaitre les différences en terme de performance (pas que globale mais détaillée) et d'occupation mémoire.

    Citation Envoyé par LittleWhite Voir le message
    L'intégration (XML + changement dans le code) ne m'a pris que quelques minutes.
    C'est l'effet "je me suis pas cassé les pieds pour rien à bosser l'architecture" ?

    Concernant ta classe NEngine (pour laquelle tu créés une variable dans le main), as tu une fonction init(argv, argc) et une fonction pour lancer la boucle d'events ? Il me semble que tu en avais besoin de pour la SDL et je pense que je l'avais créé aussi pour Qt.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct NEngine {
       void init(int argv, char** argc);
       int exec();
       ...
    };

  14. #194
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    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 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Donc, pourquoi un tel gain de performances. C'est exactement la raison que donne gbdivers. Alors la version PNG, lors de l'affichage, le calcul de la couleur du pixel avec la valeur de l'alpha est plus lourd (on peut même voir le processus utilisé dans la documentation).
    Cela explique le changement en terme de performance à l'affichage. Alors, il se peut aussi que je n'ai pas optimisé, comme le remarque gbdivers, pour ce qui est de l'affichage de sprite qui n'ont absolument pas d'alpha.
    Il faut aussi faire attention à un autre point, certains sprites du sol ont de l'alpha.

    Il n'y a qu'un sprite qui utilisait vraiment la transparence (avec des valeurs autre que 255 ou 0).
    De plus, j'ai fait des tests avec les fichiers PNG (en utilisant la couleur de transparence dans le PNG). Cela ne passait pas du tout (ai-je fait des erreurs?).

    Finalement, comme je vise le plus de compatibilité possible (GP2X) et que je ne suis pas sur que SDL_Image fonctionne pour cette plate forme, je préfère cette nouvelle méthode.

    Après avoir lu vos remarques, je vois qu'il me manque quelques essais, que j'espère faire bientôt.


    Pour la question du grisage. J'ai toujours été déçu par la SDL. J'utilisais les masques de la SDL pour le faire, mais lorsque je suis passé au bmp, les mêmes masques ne fonctionnait plus de la même façon. Déjà que j'avais eu beaucoup de mal à réussir à avoir l'effet obtenu.
    Sinon, je pourrais aussi créer un masquage à la main (en touchant directement à la mémoire des SDL_Surface), mais je trouve cela embêttant. D'une part car je souhaite le programme assez modulaire (donc, on est libre de changer les sprites) ce qui veut dire qu'en laissant des sprites grisés, on peut imaginer facilement qu'un artiste décide que le grisement soit d'une autre couleur, ou même totalement différent.

    Maintenant, je remarque que l'analyse de gbdivers est juste (point de vue performances/temps de chargement/mémoire). Je souhaite juste rappeler une chose, c'est que je crains que les sprites sont sauvegardés décompressés dans la mémoire. Donc que j'ai du .bmp ou du .png en entrée, cela ne change pas trop. Ce qui change, c'est la place prise sur le disque dur.

    Oui, je suis moyennement content de mon architecture, juste un peu strict, car le changement de certains flag du XML donnent une erreur. Pourquoi ? Simplement car au chargement, j'ai décidé de faire une vérification de balise que je dois avoir, sinon le jeu refuse de démarrer (dans le sens, il faut un minimum de balises pour que le fichier soit acceptable).

    @gbdivers: Non je n'ai pas ces deux fonctions. Regardons le fichier main.cpp. On remarque que j'alloue de la mémoire pour le NEngine, normal (quoi que, on pourrait éviter le pointeur ). Après, nous initialisons le moteur (des allocations mémoires sont fait à l'intérieur ).
    Et puis, nous créons une fenêtre, ensuite, bah c'est l'Engine qui prend le relais.
    Le run de l'Engine est une boucle, qui récupère les nouveaux évènements, fera l'affichage et l'update du jeu.
    Donc, non pour la SDL, je n'ai pas besoin d'une telle chose. Par contre, je pense que Qt en a besoin ...
    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.

  15. #195
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Je suis étonné que cela te pose problème pour le grissage , il y a deux fonction pour modifier les pixels (sans toucher a SDL_Surface directement).
    Je vois pas le problème , je viens te tester de mettre en gris une image avec la sdl et no soucis.
    Par contre vu qu'il sera pas possible de faire opération inverse (et puis lourd de faire une tel operation en temps réel), donc il faudra charger 2 fois la même image et la deuxième tu l'a met en gris grâce a la fonction que t'aura créer (au pire je peux te la passé), m'enfin t'étais pas obligé de transformer toute les image en gris tu aurais pu évité.

  16. #196
    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
    En effet, le pointeur n'est surement pas utile (de toute façon, c'est jamais utile un pointeur, sauf erreur de conception ) Sinon, tu as bien une fonction init(). Il sur
    ffit juste d'ajouter les arguments argc et argv avec des valeurs par defaut

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    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 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    Alors, tout d'abord, le code. Pour utiliser le masquage, j'en ai résulté au code suivant :
    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
    47
    48
    49
    50
    51
     
    bool NE :: SDL_Renderer :: drawSurface(const IVec2& position,const Sprite& sprite, const Rect& srcRect, const Colour& mask)const 
    { 
        SDL_Surface* pSDLWindow = static_cast<SDL_Surface*>(this->getNativeWindow()); 
        SDL_Surface* pSDLSurface = static_cast<SDL_Surface*>(this->getNativeSurface(sprite)); 
        SDL_Rect sdlDestRect = { static_cast<short int>(position.x), 
                            static_cast<short int>(position.y), 
                            static_cast<unsigned short int>(srcRect.size.width), 
                            static_cast<unsigned short int>(srcRect.size.height) }; 
     
        SDL_Rect sdlSrcRect = { static_cast<short int>(srcRect.position.x), 
                            static_cast<short int>(srcRect.position.y), 
                            static_cast<unsigned short int>(srcRect.size.width), 
                            static_cast<unsigned short int>(srcRect.size.height) }; 
     
        SDL_Surface* pSrc = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_SRCALPHA, srcRect.size.width, srcRect.size.height, pSDLSurface->format->BitsPerPixel, mask.r,mask.g,mask.b, mask.a); 
        if ( pSrc == NULL ) 
        { 
            LWarning << "Fail to produce the copy of the sprite for RSDL :: drawTile"; 
            return false; 
     
        } 
     
        // The masking is done in CreateRGBSurface 
        if ( SDL_BlitSurface(pSDLSurface, &sdlSrcRect, pSrc, NULL)  != 0 ) 
        { 
            LWarning << "Fail to copy the sprite in a temporary surface"; 
            SDL_FreeSurface(pSrc); 
            return false; 
        } 
     
        // Making a pre blit with the original image 
        if ( SDL_BlitSurface(pSDLSurface, &sdlSrcRect, pSDLWindow, &sdlDestRect)  != 0 ) 
        { 
            LWarning << "Fail to copy the sprite in a temporary surface"; 
            SDL_FreeSurface(pSrc); 
            return false; 
        } 
     
        // Apply the filter 
        if ( SDL_BlitSurface(pSrc, NULL, pSDLWindow, &sdlDestRect) != 0 ) 
        { 
            LWarning << "Fail to blit the surface"; 
            SDL_FreeSurface(pSrc); 
            return false; 
        } 
     
        SDL_FreeSurface(pSrc); 
     
        return true; 
    }
    Appeler de la sorte :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    errorFlag &= unitsList[i]->get(faction)->getSprite()->draw(r,unitPosition,Colour(128,128,128,255));
    Et donc, je joins une image généré avec le chargement des fichiers BMP et l'autre avec les fichiers PNG.
    La différence majeure est que l'image généré avec les BMP sera simplement en 24bpp, mais même, l'effet devrait fonctionné, non ?

    De plus, le résultat voulu est plus proche de la version PNG que BMP.
    Finalement, oui il y a plein de choses possible, mais l'utilisation d'un fichier externe permet beaucoup plus de libertés
    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.

  18. #198
    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
    Juste pour faire un peu de mal à LittleWhite, voici les dépendances entre les classes (sauf NEngine)...
    Il y a encore probablement du refactoring à faire
    En particulier, il y a beaucoup de références circulaires entre les modules Game, Editor et UI
    Images attachées Images attachées  

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


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    26 859
    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 859
    Points : 218 580
    Points
    218 580
    Billets dans le blog
    120
    Par défaut
    C'est gentil de penser à moi pendant vos journées .

    Qu'est ce qui vous gène vraiment ? Les références circulaires, ou les liens forts entre Game / Engine / UI. Et pourquoi (pouvez vous me l'expliquer).

    Merci.

    Et non, je n'ai jamais douté du refactoring à faire sur le jeu en lui même
    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. #200
    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
    Les 2
    Des dépendances très fortes entre tes classes impliquent :
    - détection de bugs plus complexes (pour trouver la source d'un problème)
    - évolutivité plus complexe (besoin de modifier plusieurs classes en cascade)

    Tu peux avoir dans certain cas des dépendances complexes mais c'est souvent le signe d'un problème de conception (non respect des principes de POO).
    On a vu hier par exemple que tu avais un problème de non respect du principe d'inversion de dépendance pour le NEngine.

    Il y a peut être aussi des problèmes avec le principe de responsabilité unique (si plusieurs classes utilisent la même classe mais pour des services différents par exemple)

    Le but est de progressivement améliorer la granularité de tes classes pour obtenir finalement que des classes très simples, qui font qu'une seule chose (et qui n'auront donc aucune raison d'être modifiée). Probablement que ces classes auront leurs places dans le NEngine.
    Et tu arriveras progressivement à l'utilisation des concepts (par exemple, tu n'écriras plus différents objets "déplaçable" avec redondance du code, mais tu créeras le concept de "déplaçable", qui sera indépendant du l'objet "déplaçable") et à la programmation générique.
    Il en faut pas s'impressionner de l'augmentation du nombre de classe que cela implique (j'ai fait le coup il y a quelques semaines à un stagiaire, il a réécrit une classe pour en faire 5 templatées) : il vaut mieux 5 classes qui n'auront aucune raison de changer qu'une classe qui changera tout le temps.

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