Partage

Comment structurer un jeu en c++

6 juillet 2013 à 22:19:04

Bonjour,

Je viens de finir les cours c++ et je penche actuellement sur un mini rpg pour mettre en pratique mes connaissances :)
J'ai une question concernant la structure globale du jeu : Imaginons que j'ai plusieurs classes dans le jeu qui ont des fonctions totalement différentes. Par exemple une classe Personnage, Carte et Camera. Est-ce que je dois créer une classe "de base" (Jeu par exemple) qui serait une classe abstraite dont toutes les autres classes du jeu en hériteraient ?

Merci pour votre aide :)

6 juillet 2013 à 23:01:51

Salut !

Alors, la création d'un jeu et l'organisation du code est quelque chose n'ayant pas trop de convention (je pense). Il y à pas mal d'écrit là dessus sur le net si tu cherches à approfondir tes connaissances sur le processus de création d'un jeu.

Enfin certes, personnellement je crée une classe pour chaque élément "majeur" (ou plusieurs, ça dépends du jeu, entre autre). Ensuite, j'appellerais toutes les classes (globalement, sachant qu'elles font déjà pas mal d'appel en interne) depuis un fichier nomdujeu.cpp par exemple que j'instancie ensuite dans le main.

En gros, je te conseille de faire une classe Camera, Personnage, Minimap, etc...; de tout regrouper (en les instanciant au passage) dans MonJeu.cpp et d'instancier MonJeu dans le main. Et puis, pourquoi pas un MonJeu.configure() par exemple; ça c'est toi qui vois (je pense que Ogre3D s'y prends comme ça, je préfère configurer le tout directement dans MonJeu.cpp sauf si il y à des trucs à faire avant, histoire de pas donner une impression de chargement interminable au lancement si c'est un programme qui bouffe des ressources).

Après je te déconseille de tout faire hériter d'une classe Jeu. Ca n'as pas trop de sens puisque, au final, ton jeu est la somme de l'addition des classes qui le forment entre elles. Donc ton jeu est un tout; formé par différents éléments qui, eux, ne sont pas formés par le jeu; à part dans l'éventualité de leur présence (puisque sans le concept du jeu, ils n'existeraient probablement pas).

Voila, j'ai l'impression d'avoir divagué mais le truc est là ^^ bonne continuation en tout cas !

-
Edité par Flaco 6 juillet 2013 à 23:04:47

Minie a Free(dom), lightweight & simple web browser!
6 juillet 2013 à 23:12:38

Hello!

Je suis en plein dedans depuis quelques mois et je pense tout comme Flaco en fait

J'ai une classe "Base" qui instancie les classes majeures comme  "joueur", "camera", "map_manager", "interaction_manager" (comme sont nom l'indique, ou toutes les "objets" du jeu interagissent entre eux: collisions, tir, MAJ des autres joueurs connectés) etc etc...

Cette classe effectue aussi le chargement des ressources, et lance le rendu (comme les exemples de base d'Ogre en fait ^^)

Après tu verras que par la suite, tu feras des changements (ex mineur: j'ai mis ma classe camera directement dans joueur car de toute façon, l'instance de camera ne sera pas utilisée ailleurs)

Je te conseille de faire des petits shema pour l'architecture de ton code...mais bon, même en faisant comme ça, tu effectuera tout de même des changements ;)

Bonne chance à toi!

6 juillet 2013 à 23:22:43

En effet, des diagrammes pour l'organisation et une conception sur papier de ton code (et donc, du fonctionnement global de ton programme implicitement si j'ose dire ^^ ) sont un bon moyen d'être bien mieux organisé (notamment au niveau cérébral) et tu verra que ça sera bien plus facile de coder avec un support que de tout faire de tête (c'est plus reposant aussi, donc bon).

>j'ai mis ma classe camera directement dans joueur

Comment ça, tu à instancié la classe directement dans le perso où tu as codé la caméra directement dans la classe du personnage ? Le premier exemple me semble être tout à fait ça mais coder directement la caméra dans le personnage sans distinction pour l'objet est un peu mauvais niveau organisation non ? (Désolé si j'ai pas bien compris, j'suis crevé ^^ )

Bonne soirée les gars :)

-
Edité par Flaco 6 juillet 2013 à 23:23:27

Minie a Free(dom), lightweight & simple web browser!
6 juillet 2013 à 23:42:22

Non non ne t'en fait pas, Camera est bien une classe ;) mais vu qu'elle est uniquement en relation avec le joueur, je l'ai instanciée directement dans joueur

C'était un exemple à la noix pour lui expliquer le principe :) (et en effet je me suis mal exprimé!)

6 juillet 2013 à 23:55:15

Ah non, c'est ma faute. Mais c'est ce que je fais aussi ^^ instancier toutes les classes dans un seul et même fichier ça revient à mettre le bordel sous le lit ^^

Le truc Kazuhira c'est de penser "Est-ce que A devrait être un objet, si oui; est-ce que A à un rapport avec B" etc... la clé est, je pense, d'organiser son code sur un support visuel (je te recommande Dia si je ne me trompe pas, je l'avais utilisé à un moment et j'ai bien aimé... et sans oublier le pseudo-code et autres conception sur papier).

May the Force be with you et bonne soirée à vous deux :)

Minie a Free(dom), lightweight & simple web browser!
7 juillet 2013 à 0:06:13

Ah oui et on a même pas parlé de l'héritage, hihihi

Par exemple, tu pourrais avoir une classe Enemy et une classe Friend_NPC, et au final, tu pourrais te rendre compte que malgrès la différence que ces classes auraient dans le jeu, elles pourraient finalement ne pas être si différentes dans ton code car peut être que pour toutes les 2, il faudra que tu les déplace, que tu leur enleve des points de vie etc etc...du coup l'héritage devient interessant! tu fais une classe NPC, avec en classe filles Friendly et Ennemy

Enfin, voilà c'est juste pour l'idée quoi

Allez zou! papier et crayon! :D

Flaco: c'est vrai que ça à l'air pas mal Dia, j'en avais déjà entendu parlé mais je n'ai jamais testé (pour le moment je fais tout à la main, mais bon, c'est le boxon! je testerai donc, merci

Bonne chance pour ton projet kazuhira et bonne soirée également :)

7 juillet 2013 à 0:15:22

Mais à ton service ^^

Sinon pour ce qui est de cet (excellent) exemple sur les NPC; ça ramène à la question de la lecture sur le jeu vidéo, par exemple un "Mob" est l’abréviation de "Mobile Object", désignant plus précisément un "personnage non joueur mobile" si on veux (mais ça dépends du codeur ça, encore une fois). Donc tu peux en déduire que tous les personnages non-joueurs héritent de la même classe (je la passerais abstraite perso) et comme ça la plupart des algos de base de l'IA n'est à implémenter qu'une seule fois dans une seule classe et tu ajoute le reste dans la classe dédiée aux ennemis, etc...

Si je peux te filer un petit coup de main : Googlise "making an indie game" et autres recherches à propos d'indie games et tu tombera sur tout un univers qui pourrait bien d'être utile ^^

Tiens je te file ma pearl sur la gamedev. J'ai pas tout lu mais il doit y avoir des trucs sur la structure d'un jeu au niveau de son code & co... bon amusement ^^

Minie a Free(dom), lightweight & simple web browser!
7 juillet 2013 à 17:03:23

Merci beaucoup pour vos conseils :)
C'est vrai que je ne voyais pas trop l'interet de créer une classe Jeu puis je saurais pas trop quoi y mettre dedans d'ailleurs...

Asphodelus, j'ai pas bien compris lorsque tu dis que t'as une classe Base qui instancie tes classes majeures :( Comment peux-tu instancier des objets d'une autre classe depuis ta classe Base? Je vois pas bien le lien qui les uni (désolé je encore débutant).
Peux-tu me montrer un exemple du contenu de ta classe Base s'il te plaît? Merci d'avance :)

-
Edité par kazuhira 7 juillet 2013 à 17:03:51

7 juillet 2013 à 22:17:25

Et bien par exemple un truc comme ça: (attention c'est obsolete, c'est juste pour te montrer le principe)

Base.h

class Base
{

public: 
    Base();
    ~Base();
 
	SceneManager* smgr;
	Joueur* joueur;
	NCP_container* npcs;
	SoundSystem* soundMgr;
	InteractionMgr* interactionMgr;
	GUIsystem* gui;
   
	void load();
};


Base.cpp

void Base::load()
{

	smgr = new SceneManager();

	soundMgr = new SoundSystem();

	Joueur* joueur = new Joueur(smgr, soundMgr);

	NCP_container* npcs = new NCP_container(smgr, joueur); // enfin...ici on préférea prendre un container du genre list, vector (avec des classes NPC_friend, NPC_ennemy qui hériterait d'une classe Entity par exemple)

	InteractionMgr* interactionMgr = new InteractionMgr(smgr, soundMgr, joueur,npcs) ; // classe qui regroupe les classes qui peuvent intéragir en temps réel entre elles

	GUIsystem* gui = new GUIsystem(joueur);

}

Tu alloues dynamiquement tes classes principales et tes autres classes pointerons sur les autres

Après...je suis sûr que certains diront de faire autrement donc bon...:lol:



8 juillet 2013 à 1:17:37

Ce qui est aussi important est de ne pas mélanger la logique du jeu avec le hardware. Par exemple, une classe entité ne devrait pas contenir d'instructions de rendu. Une classe entityActor pourrait contenir l'information de l'entité sous forme d'aggrégation (référence ou pointeur qui pointe vers l'entité) et qui pourrait à la limite être amie avec celle-ci (friend). Cet acteur devrait donner l'interface nécessaire pour communiquer avec le hardware (fenêtre de rendu, les entrées, etc.). Après tu fais comme Asphodelus pour structurer tes entités et tes entitéActors.

8 juillet 2013 à 2:21:15

Ouep Lucas c'est un peu ce que je fais justement, en fait, quasiment tout se fait dans l'interaction_manager (déplacement du joueur, interaction avec les autres joueurs, envoie vers serveur etc etc)

Sinon, Kazuhira, tu verras que des fois, même si tu fais bien ton ptit diagramme UML avant, ben, il arrivera forcement à un moment où tu te diras: oulà, ça me parait crade ce que je fais là, j'aurais pas un petit problème de conception?? :waw: et là te te rendra compte que tu dois refaire une bonne partie du code (c'est ce qu'il m'arrive au moment ou j'écris :p) mais ne t'en fais pas, ça fait partit du jeu!

Et puis...rêver de l'architecture de son code toutes les nuits, ça n'a pas de prix, tu verras :D (j’exagère à peine)

Bonne chance dans ton projet en tout cas

8 juillet 2013 à 2:52:44

Asphodelus : >Et puis...rêver de l'architecture de son code toutes les nuits, ça n'a pas de prix, tu verras

Oh ça...

Lucas92 : >Ce qui est aussi important est de ne pas mélanger la logique du jeu avec le hardware.

Bien vu, c'est noté. Merci ! :)

-
Edité par Flaco 8 juillet 2013 à 2:53:25

Minie a Free(dom), lightweight & simple web browser!
8 juillet 2013 à 9:06:41

Juste une petite chose sur l'exemple de @Asphodelus, il y a un truc qui me chiffonne avec cette classe "Base" et la méthode load. Qu'est ce que la classe Base ? Quel est son rôle ? A mon avis, il est un peu bizarre d'avoir une classe comme celle-ci parce qu'il est difficile de lui donner une sémantique précise. En particulier, tu as une méthode "load" qui se contente d'allouer des ressources sur les pointeurs membres en interne (sans faire de destruction préalable). Cela veut dire deux choses : 

  • elle ne peut être appelée qu'une fois
  • elle fait le travail du constructeur

Donc tout ceci devrait être fait ... dans le constructeur ;) .

Ensuite allouer dynamiquement les ressources ... à moins d'avoir besoin de polymorphisme, c'est quelque chose qui doit être assez rare : on préférera créer ses objets de manière classique à chaque fois que c'est possible, passer des références (et un minimum de pointeurs) et éviter de trop lier les classes entre elles. Enfin, si on a besoin de données allouées dynamiquement : smart pointers (unique_ptr/shared_ptr).

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
8 juillet 2013 à 10:27:25

:/ Je file des liens sur des liens vers des  liens car je sens que les gens ne prennent pas la peine de lire ce qui se dit dans les 15 derniers jours ...

La dérivation character -> NPC -> friendly/hostile ne scale pas un seul instant. La seule différence entre ces entités, c'est le centre de décision des bestioles d'un jeu. Il peut être local (clavier/souris/pad), distant (réseau, pour un autre PC), IA, sort de possession. Et dans le cas des IA cela ne se réduira pas à friendly ou hostile. Chaque espèce peut être plus ou moins hostile. Parfois avec des mécanismes de meutes, parfois en attaques furtives, parfois lâche, parfois suicidaire, etc. Et créature va avoir ses allégeances. Depuis quand les araignées vont arrêter de chercher à bouffer d'autres bestioles sous prétexte qu'il y a des vilains PC dans le coin ?

Bref, ce n'est pas la notion de personnage/bestiole qui doit être dérivée pour modéliser les familles d'intelligence derrière ces personnages. (c'est le même combat que pour les classes & races)

-
Edité par lmghs 8 juillet 2013 à 10:29:30

C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
8 juillet 2013 à 10:30:14

Et il y a ce que dit le monsieur au dessus de moi aussi effectivement :lol: .
Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
8 juillet 2013 à 10:34:01

Merci pour tes remarques Ksass' Peuk, c'est vrai que ce n'est peut être pas très conventionnel

En fait, ma classe Base est le "coeur" de mon application, c'est là qu'on va créer les objets principaux (système de rendu, gestionnaire de son, ajout des ressources etc etc)

Tu as raison, ça devrait être dans le constructeur mais j'ai pris la mauvaise habitude avec mon application Ogre (certaines chose doivent être initialisées avant d'autre, enfin...c'est pas si simple) j'ai mis dans ma liste ToDo d'y regarder ;)

Pour le choix pointeur / référence, j'avais regardé pas mal de truc là dessus et au final j'avais même vu que c'était une question de gout, vu que j'ai été habitué à travaillé avec...Mais ici encore tu as raison, vaut mieux prendre la solution la plus simple: les références

Je me doutai bien que j'aurai une remarque et c'est normal :), mais moi je suis comme ça, c'est pas bien mais je me dis que ça fonctionne, que je n'ai pas de perte de perf (le temps d'accès pointeur / ref est identique), je pense aux delete, ça fonctionne, donc voilà

PS: Ne me crie pas dessus, pour la dernière phrase, je sais que j'ai tord à 100% hein et que c'est pas bien ce que je fais ;)

Merci pour tes conseils en tout cas

EDIT suite à la réponse de lmghs: oui, enfin, l'exemple était simplifié, après, il fera ce qu'il veut suivant le niveau de son IA, ça n’empêche que tu auras toujours des NPC_friendly (dans un rpg par exemple: un donneur de quete, un garde...) et dans les NPC_ennemy, ok, là il faudra creuser un peu + :))

-
Edité par Asphodelus 8 juillet 2013 à 10:39:52

8 juillet 2013 à 11:34:50

>Et dans le cas des IA cela ne se réduira pas à friendly ou hostile.

Bien sûr; mais on allais pas commencer à dériver le thread sur l’intelligence artificielle, etc... le pauvre Kazuhira ^^

Dis moi Ksass`Peuk, comment t'y prends-tu sans classe base. Enfin je veux dire, pour moi ça me semblait un bon moyen de m'organiser... si je ne dois pas trop lier les classes entre elles comment j'initialise l’entièreté des classes et aie une fonction main de taille raisonnable ?

-
Edité par Flaco 8 juillet 2013 à 11:35:23

Minie a Free(dom), lightweight & simple web browser!
8 juillet 2013 à 12:51:18

Flaco a écrit:

Dis moi Ksass`Peuk, comment t'y prends-tu sans classe base. Enfin je veux dire, pour moi ça me semblait un bon moyen de m'organiser... si je ne dois pas trop lier les classes entre elles comment j'initialise l’entièreté des classes et aie une fonction main de taille raisonnable ?


Quelle différence entre avoir une classe fourre-tout et mettre plus de choses dans le main ? Tu déplaces juste la désorganisation, et ta classe fourre-tout n'organise rien. Sans compter qu'elle n'assure plus un service, elle assure du stockage de donnée, chose que l'on ne veut pas faire avec une classe. Il faut toujours penser les classes en terme de service et la classe "Base" n'assure pas de service.

Commencer par un design statique peut déjà être un bon moyen de voir ce qui pêche quand c'est posé sur papier. Pour ce qui est de ne pas trop lier les classes entre elles, en fait l'idée est assez simple, tes classes ne sont pas sensées tout faire : elles fournissent un nombre limité de service et interagissent pas conséquent avec un nombre limité d'autre classes. Ensuite, il est bon de définir la portée des objets que tu crées, elle doit être aussi limitée que possible : créé dès qu'on en a besoin (pas avant), détruit lorsqu'il n'est plus utile (pas après), ce n'est pas toujours simple mais c'est un bon moyen de garder un code léger.

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
8 juillet 2013 à 13:59:55

NPC/friendly vs hostile, est une simplification. Un NPC va avoir des attitudes envers d'autres groupes (éventuellement il appartient à un groupe -- cela peut simplifier des choses) et pas juste une seule attitude envers un seul groupe de persos.

Quant à la dichotomie creature/centre_de_decision, je l'avais même utilisée pour le tic-tac-toe posé en exercice ici même. Certes le gain était minime dans ce cas. Dans le cas d'un RPG il apparait bien plus vite.

C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
8 juillet 2013 à 15:26:57

Ok, merci Ksass`Peuk.

J'adoptais cette démarche tout simplement parce que les exemples d'utilisations fournis avec les API en général (Ogre3D pour y revenir) faisaient comme ça. (Et aussi parce qu'on m'as dit à plusieurs reprise qu'un main ne devait pas comporter plus d'une dizaine de lignes plus ou moins).

Mais c'est vrai que, si je réfléchi, instancier simplement les classes dans le main, y mettre quelques structures de contrôle et un return ne devrait pas être énorme... J'ai surtout peur de déroger à la convention qui veut qu'on aie un petit main. ^^ En tout cas je vais voir pour appliquer ça sur mon navigateur. :)

Pour un gros programme, que penses-tu d'une fonction bool initialize(), par exemple, qui serait appelée dans le main ? Elle instancierait tous les objets, tout en restant une simple fonction. Et retournerais true si tout s'est bien passé, false au contraire.

Ah non mais c'est clair ça lmghs. On ne faisait que simplifier grossièrement; je pense que kazuhira est assez intelligent pour pas créer des mobs qui s'entre-tuent hahaha. :)

-
Edité par Flaco 8 juillet 2013 à 15:29:56

Minie a Free(dom), lightweight & simple web browser!
8 juillet 2013 à 15:49:20

Flaco a écrit:

Mais c'est vrai que, si je réfléchi, instancier simplement les classes dans le main, y mettre quelques structures de contrôle et un return ne devrait pas être énorme... J'ai surtout peur de déroger à la convention qui veut qu'on aie un petit main. ^^

"Petit" est une notion assez relative ^^

Flaco a écrit:

Pour un gros programme, que penses-tu d'une fonction bool initialize(), par exemple, qui serait appelée dans le main ? Elle instancierait tous les objets, tout en restant une simple fonction. Et retournerais true si tout s'est bien passé, false au contraire.

Je n'ai jamais travaillé sur de très gros programmes aussi je n'ai pas d'idée précise de ce qui est fait dans ce cas. Cela dit il y a quelque petites choses qui me semblent importantes à garder à l'esprit :

  • Si des composants ont une portée globale sur le système, les déclarer static est assez logique.
  • Si tu n'arrives pas à initialiser ne serait ce qu'une des parties du programme au démarrage, il y a de bonnes chances que soit irréparable : exception (on la rattrape si on veut pour le dire à l'utilisateur).
  • On a rarement du mal à initialiser les objets de manière séparée avec des objets dont le rôle est clairement définis.

A mon avis, l'initialize est une mauvaise idée. Cela ressemble plus à une méthode C qu'à une conception C++. En fait il est même assez facile d'avoir une initialisation propre, dans un main court, avec peu d'objets (et bien hiérarchisée) en utilisant les design pattern qui correspondent aux problèmes que l'on est en train de résoudre. Par exemple pour une GUI, avec un pattern MVC, le main sera nécessairement très court si l'on a bien défini la responsabilité de chaque pièce du système ^^ .

-
Edité par Ksass`Peuk 8 juillet 2013 à 15:52:53

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
8 juillet 2013 à 15:49:55

L'aspect que pointe lmghs, n'est pas lié spécifiquement à l'IA, il est lié a tout l'aspect règles du jeu et gameplay. Tu vas avoir le même type de problème avec les compétences/traits raciaux/pouvoirs spéciaux, les armes (magiques ou pas) et les armures (magiques ou pas), sorts, potions, poisons, projectiles (magiques ou pas) et tous les objets de manière générale, stockage dans l'inventaire, dans un coffre ou pas, objets qui s'usent, qui peuvent être détruits, avec ou sans notions de charge, avec des fonctions précises (crochets,clés par exemple), objets de quête, outils d'artisan, nourriture, boisson, matière première pour l'artisanat... Un objet sera utilisable par un personnage ou pas (par exemple un mage ne pourra pas utiliser d'arme, un guerrier ne pourra pas équiper en même temps une hache à deux main et un bouclier...). La structure telle qu'imaginée par le PO va mener à une explosion de classe qui à terme devient complètement ingérable. Utiliser l'héritage pour représenter tout ça n'est pas envisageable à cause de la compléxité d'intégration de contenu, si à chaque fois qu'un producteur de contenu (graphiste, game designer, musicien...) qui ne possède à priori que des compétences très limitées en programmation (voir pas de compétences du tout), doit ajouter une classe qui dérive de 50 interfaces pour ajouter une bestiole ou un objet, il n'y arrivera pas, et même en tant que programmeur, dériver tes 50 interfaces va vite devenir un cauchemar, parce que tu ne sauras plus ce que tu dois dériver ou pas.
Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
8 juillet 2013 à 18:05:10

Encore merci Ksass`Peuk ^^ je vois mieux. Je vais faire comme ça du coup !

@int21h : Ah mais c'est clair. Personnellement, j'utilise l'héritage quand c'est vraiment nécessaire (une hache et un marteau descendent tout deux d'une arme par exemple ou alors sur mon navigateur la barre d'url hérite de QComboBox).

Mais merci pour les précisions, c'est bien clarifié du coup ^^

Bonne journée/soirée à vous tous et bonne continuation :) (Et bonne digestion de topic kazuhira ;) )

Minie a Free(dom), lightweight & simple web browser!
8 juillet 2013 à 18:26:46

Flaco a écrit:

@int21h : Ah mais c'est clair. Personnellement, j'utilise l'héritage quand c'est vraiment nécessaire (une hache et un marteau descendent tout deux d'une arme par exemple ou alors sur mon navigateur la barre d'url hérite de QComboBox).

Justement normalement, sauf à fin d'exercice pour s'entraîner à utiliser l'héritage, on ne doit pas avoir une classe Hache, un classe Marteau qui descendent d'une classe Arme, relis bien le post de @int21h. Si tu fais ça, tu devras créer un nouvel héritage à chaque nouveau type d'arme que tu veux ajouter même si elle a des comportements semblables à d'autres armes.

Encore plus flagrant, une hallebarde peut servir à tenir l'ennemi éloigné, comme la lance, ou à découper une tête, comme la hache cependant il y a des actions que tu peux faire avec la hache ou la lance que tu ne peux pas faire avec la hallebarde et dans ce cas tu vas te retrouver à dupliquer du code partout pour quelque chose que l'on peut résoudre bien plus simplement avec le concept indiqué dans les posts de @lmghs et @int21h : les traits.

-
Edité par Ksass`Peuk 8 juillet 2013 à 18:27:45

Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C
8 juillet 2013 à 20:37:34

Ah je vois... les traits comme ici ?

Minie a Free(dom), lightweight & simple web browser!
8 juillet 2013 à 20:39:55

@Flaco Une classe Hache et une classe Marteau qui descendent d'une classe Arme est justement ce qu'il faut éviter Cf l'exemple de Ksass Peuk avec la hallebarde, mais tu peux encore trouver plus vicieux, arme à une main/arme à deux mains, tu pourras equiper 2 armes à une mains ou une arme à une main et un bouclier, mais tu ne pourras pas équiper une arme à deux mains et un bouclier. Cette règle pourrait être être rendue caduque si dans mon jeu, j'ai une classe de personnage géant  ou un pouvoir spécial force de la nature, qui permettrait aux presonnages/PNJ de cette race ou à ceux qui ont ce pouvoir spécial d'utiliser une arme à deux mains avec une seule main. Cette règles pourrait également être invalidée par une race de personnage/PNJ ayant 4 mains, ce qui lui permettrait d'utiliser un bouclier et une arme à deux mains. Imagine un peu le nombre de classes de personnages/PNJ que tu vas devoir dériver rien que pour gérer le talent force de la nature ou la race de géant, imagine le bazar avec une race qui aura 4 bras au lieu de deux, tu vas devoir redériver toutes tes sous-classes de personnage, juste pour cette race là. Autre exemple toujours avec les armes,je vais aller le pêcher dans Skyrim, la dague Fléortie, c'est une dague avec un skin spécial, récompense de quête et qui est nécessaire pour terminer une quête, en dehors de ça c'est une dague tout à fait ordinaire que le personnage peut utiliser en lieu et place de n'importe quelle autre dague. Sa spécificité d'objet de quête fait que ça ne peut pas être une simple instance d'une classe Dague qui dériverait d'une classe Arme, elle doit être plus que ça pour qu'il soit possible de gérer les quêtes auxquelles elle est associée.

Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
8 juillet 2013 à 20:49:15

Je vois, donc ce que tu ferais c'est écrire la classe Hallebarde (pour l'exemple) depuis 0 c'est ça ? C'est vrai que sinon, si j'ai un oubli par exemple, je devrais naviguer entre les sources de la classe abstraite Arme et celle de l'arme sur laquelle je bosse... merci pour la mise au point les mecs... (et pour les traits c'est bien ce que j'ai posté ? Car j'avais jamais entendu ce terme avant... )

Minie a Free(dom), lightweight & simple web browser!
8 juillet 2013 à 21:47:02

Non certainement pas, ce serait bien pire. Je ne vais manipuler que des entités neutres, une entité sera composée d'un identifiant unique et d'une liste de composants. Si je veux une épée qui soit une récompense de quête je fais une entité, je lui ajoute les composants qu'il faut pour une  épée plus un composant récompense de quête. Si je veux un loup, je vais mettre les composants de bestiole, ceux de loup, et si je veux une meute, j'ajouterai à chaque loup de la meute un composant meute qui permettra de piloter plusieurs loups agissant de concert. Si je veux un cheval sauvage qui se balade, je metttrais bestiole, plus un gestionnaire de décision pour qu'il se balade, pour un troupeau de chevaux, je rajouterai une composant troupeau qui les fera se déplacer tous ensembles, si je veux une monture, je mettrais à mon cheval un composant selle, peut être un composant armure, et un composant décision qui sera inféodé à celui de son cavalier. Si au lieu d'une monture  cheval, j'ai une monture dragon, je lui rajoute un composant pour voler et j'ai ma monture dragon.  Si je fournis les outils adéquats, le graphiste qui bosse avec moi sur le jeu n'a pas besoin de moi pour ajouter une monture griffon, il va ajouter dans les données du jeu une entité à laquelle il va assigner les composants qui correspondent à ce qu'il veut. Moi développeur je n'interviendrai que pour lui développer de nouveaux composants. 

C'est le modèle Entity Component System décrit dans les liens posté x fois par lmghs.

Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
8 juillet 2013 à 22:06:13

Je vais détailler ma méthode qui vaut ce qu'elle vaut.

C'est un jeu avec SFML.

Donc j'ai une classe Etat abstraite pur, une classe Menu, et Menu_S (qui gère les 3 sauvegardes) ainsi q'un Menu_P pour la pause.

Pour le jeu en lui même.

On a un Gest d'image qui enregistre toute les textures.

Le jeu a une caméra et appelle ELement_Gest qui gèrent tout les éléments en jeu.

La classe héro hérite de Element et permet l'implémention de 6 personnages différents avec pouvoirs différents.

En résumé un tour de boucle:

Jeu dit à Element_Gest d'interagir les élements.

Tous les éléments agissent (décision).

Gestion des collisions.

Puis on "recharge" (remise à  des variables de décision).

Enfin on dessine le tout.

Je suis assez brouillon mais il y a en tout beaucoup de chose, l'important c'est de les prendre en module et de pas penser à tout à la fois.

Ce qui permet d'aller petit à petit et de pas tout modifier à chaque fois. Bon j'ai pas fais toute la base du "moteur" donc il faut encore que je modifie des trucs mais j'ai déjà des trucs qui bougent à peine.

Merci pour les système de traits je connaissais pas ça va me servir (Je souffrais justement parce que j'allais faire les objets en faisant tout dériver).

-
Edité par Yame 8 juillet 2013 à 22:12:45

Comment structurer un jeu en c++

× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
  • Editeur
  • Markdown