Chaque fois que j'essaie d'écrire un jeu dans n'importe quel langage orienté objet, le premier problème auquel je suis toujours confronté (après avoir réfléchi au type de jeu à écrire) est de savoir comment concevoir le moteur. Même si j'utilise des bibliothèques ou des frameworks existants comme SDL, je dois toujours prendre certaines décisions pour chaque jeu, comme l'utilisation d'une machine à états pour gérer les menus, le type de classe à utiliser pour le chargement des ressources, etc.
Qu'est-ce qu'une bonne conception et comment serait-elle mise en œuvre? Quels sont les compromis à faire et leurs avantages / inconvénients?
architecture
moteur extropique
la source
la source
Réponses:
Je doute que quelqu'un puisse dire "Vous devez faire ceci et cela et ceci et cela avec ce modèle X".
Cependant, quelques ressources utiles:
Enginuity - une série d'articles sur la construction de moteurs sur Gamedev.net.
Game Coding Complete - Je possède ce livre, et il couvre bien tous (enfin, presque) tous les aspects de la programmation de jeux. Il a également un moteur construit tout au long du livre.
Game Engine Architecture - Ceci est un autre grand livre pour la conception de moteurs.
Disposition du moteur C4 - Tiré de mon commentaire, mais cela montre une manière de haut niveau d'assembler chaque partie du moteur ensemble.
Celles-ci peuvent être un peu trop pour ce dont vous avez besoin, mais vous ne pouvez pas en savoir trop sur quelque chose, et je suis sûr que vous obtiendrez un bon plan de leur part.
EDIT: J'ai oublié que les articles Gamedev ont été archivés depuis le nouveau site, corrigé :)
la source
À titre d'exemple, voici comment mon projet roguelike actuel est structuré (en Java). Il utilise un moteur graphique 2D, donc une grande partie du code de rendu a déjà été pris en charge pour moi. La critique est la bienvenue.
class Game
Cette classe configure la machine d'état qui gère l'état actuel du jeu. (dans un menu vs commencer une nouvelle partie vs jouer une partie enregistrée)
interface State
Chaque classe State contient deux boucles: une boucle pour la mise à jour de la logique et une boucle pour le rendu. Ils contiennent également du code pour appeler la
Game
classe et demander un changement dans un état différent.class ResourceManager
Singleton qui est initialisé par la
Game
classe qui charge toutes les ressources nécessaires et permet d'y accéder. Je n'aime pas cette conception car elle rend difficile le chargement / déchargement des ressources à différents niveaux, par exemple. Je concevoirais probablement ceci différemment si je recommençais.class Map
Une carte contient un tableau de tuiles et une liste de toutes les créatures et objets sur la carte. C'est une classe assez basique.
class Creature
Les créatures contiennent des informations sur elles-mêmes, y compris des calculs de mouvement (leur demandant de savoir dans quelle carte elles se trouvent et de pouvoir l'interroger pour connaître les obstacles). Décider de faire cela, ou de faire en sorte qu'une classe de manager s'en occupe pour toutes les créatures est une chose avec laquelle je me bats.
interface AITask
Les créatures peuvent avoir une liste de tâches AIT, qui sont exécutées chaque fois que la boucle logique de la créature est exécutée. L'AITask a sa propre boucle logique qui émet des commandes à la créature, et une condition de terminaison qui détermine si la tâche s'est terminée avec succès ou non.
interface UIElement
J'ai implémenté ma propre interface utilisateur pour ce moteur. Chaque UIElement a une boucle de rendu et une boucle logique. Ils ont également une boucle pour le traitement des entrées clavier / souris. Tous les éléments peuvent avoir un certain nombre d'éléments enfants, qui sont rendus après leurs parents, et prennent en charge l'entrée clavier / souris. Cela vous permet d'avoir des menus avec des sous-menus, par exemple.
la source
Le premier point important à souligner est qu'il n'y a pas de «bonne» réponse à cette question.
La chose la plus proche d'une bonne réponse serait quelque chose comme: cela dépend beaucoup du type de jeu, de la plate-forme cible, des contraintes (temps) etc.
Cela dit, il existe de très bons articles qui vous montreront comment d'autres personnes ont essayé de répondre à ce problème (comme j'ai essayé de trouver des informations à ce sujet dans le passé).
Comme The Canard communiste l'a mentionné, l' article sur l' ingénierie des développeurs de jeux m'a aidé à comprendre certaines parties de l'architecture des jeux.
Ma conception actuelle est un hybride de Quake3 / Doom3 et un peu de la bibliothèque de classes .NET :)
J'ai deux bibliothèques (statique ou dynamique dépend de la façon dont vous voulez construire / livrer) le
Framework
et leLibrary
.La bibliothèque contient toutes les classes d'assistance qui sont là pour aider à la production de logiciels de jeu, mais ne se limitent pas à ce type de produit. c'est-à-dire qu'il a une implémentation d'une liste chaînée qui est optimisée pour le code du jeu mais pourrait être utilisée par tout ce qui a besoin du service d'une liste chaînée.
Le Framework est le courage du «moteur» si vous voulez l'appeler ainsi. Beaucoup de ceci suit les philosophies de conception de Quake3 (juste d'une manière plus orientée objet). Il contient la CLI , la gestion du temps, le code spécifique au système d'exploitation, et éventuellement les couches réseau, etc.
Ces deux sont ensuite liés à l'application réelle en cours de production. Le
Game
si vous le souhaitez, qui contient le code spécifique au jeu. De la même manière, Quake3 charge les DLL en fonction du «mod» en cours de lecture.Pour vous donner une idée de la structure, voici une ventilation rapide des dossiers et du contenu de chaque bibliothèque:
HTH! Devrait vous donner quelques conseils ...
la source
Choses à considérer
Bon design
Les données sont essentielles à la programmation. Si vous concevez vos données correctement, un algorithme en émerge généralement (si vous ne comptez pas certains algorithmes numériques, comme le déterminant informatique).
la source