CODINGCROSSDEV ★ P.J.A (DEMONIAK) ★

PJACoding Crossdev

Mon approche des jeux d'aventures.

Comment faire un jeu d'aventure ? Voila une bonne question !
Voici donc mon approche, qui est biensur personnelle, mais qui je pense convient dans pas mal de cas de jeux d'aventures.

Mais tout d'abord, qu'est ce qu'un jeu d'aventures ?
Pour moi, un jeu d'aventure est un jeu dans lequel le joueur évolue dans un univers composée de "pièces" ou de "salles".
Le joueur peut se déplacer de salles en salles, y découvrir des objets, les prendres, les posers.
Il dispose d'un minimum d'actions possibles à éffectuer (les déplacements, prendre/poser des objets, examiner la salle, et d'autres actions simples.)
Il peut également interagir sur les salles : par exemple, le fait d'ouvrir une porte avec une clé permet de libérer un passage bloqué auparavent.
Il se déplace d'un point de départ à un point d'arrivée, et pour parvenir au point d'arrivée, il devra résoudre plusieurs énigmes.
Voici donc ma petite définition d'un jeu d'aventures.

Les variables et les constantes
Définissons d'abord ce que sont les variables et les constantes:
les variables peuvent évoluer au cours du jeu, et lorsque le joueur demande à faire une sauvegarde de sa partie en cours, c'est ces variables que nous devons sauvegarder.
Les constantes, par contre, n'évoluent pas au cours du jeu, mais définissent la trame du jeu : le scénario.

Voyons ce que nous pouvons classer dans l'une ou l'autre des catégories...

Tout d'abord, les constantes :

  • Le plan du jeu: les différentes salles, la position de départ du joueur et la position d'arrivée,
  • Les objets existants dans le jeu,
  • Les images représentant chaque salles,
  • Les différents textes à afficher au cours du jeu.

Ensuite, les variables :

  • La position du joueur (la salle ou il se trouve à l'instant T),
  • L'inventaire du joueur (les objets qu'il porte),
  • Les objets présents dans chaque salles,
  • Le plan du jeu: les directions possibles de chaque salle.
    Cette dernière variable mérite une explication : oui, le plan du jeu est une variable, car, au cours du jeu, une direction, auparavant impossible, peut se libérer sur une action précise du joueur (la clé dans la porte...)

Plus loin dans les structures
Oui, mais avant d'aller plus loin, quelques petites précisions :
J'ai codé P.J.A. en C. Pourquoi le C ? Pour plusieurs raisons :

  • C'est un language que je connais bien ;-),
  • C'est un language à la fois de haut niveau, et assez proche du coeur du système,
  • C'est un language bien adapté pour définir des structures,
  • C'est un language qui permet un portage facile sur d'autres plate-formes,
  • C'est le language le mieux adapté à la programmation sous Windows. (Enfin, c'est mon avis personnel.)

Donc, j'espère que vous avez de bonnes notions de programmation en language C pour pouvoir continuer... Désolé pour les autres, mais c'est une doc. orientée "technique"...
J'aurai également pu m'orienter vers le C++, mais j'ai préféré gader le C classique pour d'autres raisons:

  • le C++ est plus difficilement "transposable" en assembleur (pour passer sur CPC, il vaux mieux utiliser l'assembleur, à mon avis),
  • le C++ n'est pas aussi répandu que le C sur d'autres plate-formes,
  • Je ne suis pas aussi bon en C++ qu'en C...

Cette petite mise au point effectuée, continuons...

Voici la structure que j'ai utilisé pour définir une salle :

typedef struct
{
BYTE Nord, Sud, Est, Ouest, Haut, Bas;
StObj ObjetsVisibles[ MAX_OBJETS_VISIBLES ];
StObj ObjetsDecor[ MAX_OBJETS_DECOR ];
BYTE Cmd[ MAX_COMMANDES ];
BYTE NumVue;
BYTE VarBit;
} StLieu;

Et les explications....

  • Les directions : Nord, Sud... Bas : contiennent le numéro de salle vers laquelle on se dirrige en allant dans la direction choisie.
    Par exemple, si nous nous trouvons dans la salle 1, et que le membre Nord de la structure contient 2, nous allous nous déplacer à la salle 2 en allant vers le Nord.
    Si une direction est interdite, le membre contient 255.
    Cela nous donne une limite aux nombres de salles : tout d'abord, le type BYTE représente un octet non signé, donc variant de 0 à 255, ce qui limite le nombre de salles à 256. Et comme 255 est utilisé pour indiquer une direction impossible, on ramène le nombre de salles possibles à 255 (de 0 à 254). Dans P.J.A, je me suis limité à 220, ce qui fait déjà un beau jeu d'aventures je crois...
  • Les ObjetsVisibles : une structure StObj, que nous verrons plus bas.
    Avec une constante : MAX_OBJETS_VISIBLES. Ces objets dit "visibles" sont les objets que le joueur pourra prendre et poser dans les salles.
  • Les ObjetsDecor : même structure StObj, avec une autre constante :
    MAX_OBJETS_DECOR. Ces objets dit "decor" sont des objets que le joueur ne pourra pas prendre. Par exemple, une porte, un mur...
  • Cmd : tableau de MAX_COMMANDES. Contient les commandes que le joueur peut exécuter dans la salle.
  • NumVue : indique le numéro de vue à charger (=numéro d'image)
  • VarBit : variable testée par les actions, que nous verrons plus bas.

Bon, voyons la structure StObj :

typedef struct
    {
    BYTE NumObj;
    BYTE ModeObj;
    } StObj;
  • NumObj : représente le numéro de l'objet. Les objets serons numérotés de 0 à 255.
  • ModeObj : représente le mode de l'objet. Les modes d'objets possibles seront les suivants : rien, fermé, ouvert, eteind, allumé, rempli, vide.
    (Par exemple, une porte ouverte par une clé doit rester ouverte tant que le joueur ne l'a pas refermée...)

J'ai utilisé un tableau de strutures StLieu pour définir la "carte" dans laquelle le joueur peut évoluer. C'est cette carte ainsi que quelques autres variables qui peuvent être sauvegardées/rechargées au cours du jeu.

Voici une autre structure contenant le reste de ces variables :

typedef struct
    {
    char Identite[ 16 ];
    USHORT Version;
    char NomJeu[ 32 ];
    USHORT Taille;
    BYTE Position;
    StObj Inventaire[ MAX_OBJETS_INVENTAIRE ];
    } StJeu;
  • Identite : Indique l'identité du jeu, permet de savoir que l'on se trouve en présence d'une sauvegarde d'un jeu.
  • Version : Indique la version du jeu.
  • NomJeu : Indique le nom du jeu.
  • Taille : Indique la taille du reste des données (cette taille varie en fonction du nombre de salles définies pour le jeu).
  • Position : contient la position du joueur (numéro de salle) à l'instant T.
  • Inventaire : une structure StObj contenant les objets portés par le joueur.

Voila, pour résumer, nos variables se composent de :

  • une variable de type StJeu,
  • un tableau de 220 éléments de type StLieu.

Passons maintenant à nos constantes...
Voici la structure qui définit les constantes du jeu :

typedef struct
    {
    char Identite[ 16 ];
    USHORT Version;
    char NomJeu[ 32 ];
    BYTE DepartMin, DepartMax;
    BYTE Arrivee;
    StCmdFixe CmdLieu[ MAX_LIEU ];
    StDeclObj Obj[ MAX_OBJETS ];
    StVue Vue[ MAX_VUES ];
    StAction Action[ MAX_LIEU ][ MAX_ACTIONS ];
    StSound Mus[ MAX_MUS ];
    StSound Snd[ MAX_SND ];
    USHORT PosLibelle;
    char Libelle[ TAILLE_LIBELLE ];
    } StConstantes;
  • Identite : Indique l'identité du jeu, permet de savoir que l'on se trouve en présence d'une sauvegarde d'un jeu.
  • Version : Indique la version du jeu.
    (Ces 3 constantes permettent de savoir si l'on a relu une sauvegarde correspondant à notre jeu en cours...)
  • DepartMin : position de départ du joueur (numéro de salle)
  • DeparMax : position de départ maxi du joueur. En fait, j'avais pensé définir une position aléatoire de départ du jeu, entre DepartMin et DepartMax. Mais je ne sais pas si c'est facilement utilisable, et, par défaut, DepartMax est égal à DepartMin.
  • Arrivee : position d'arrivée du jeu : lorsque le joueur atteind cette salle, le jeu est terminé, le joueur est arrivé au terme de son aventure.
  • CmdLieu : structure de type StCmdFixe (que nous verrons plus bas), qui permet de définir les commandes possibles dans chaque salles.
  • Obj : structure de type StDeclObj, décrivant tous les objets du jeu.
  • Vue : structure de type StVue, décrivant les vues de chaque salle.
  • Action : structure de type StAction, qui permet d'exécuter une action en fonction du résultat du test d'une variable et d'un masque de bits.
  • Mus : structure de type StSound, pas utilisée pour le moment.
  • Snd : structure de type StSound, pas utilisée pour le moment.
  • PosLibelle : indique la dernière position libre dans le tableau des libellés
  • Libelle : tableau de caractères contenant tous les libellés du jeu : les libellés décrivang les salles, ainsi que les libellés décrivant les objets (les noms des objets).

Voyons maintenant les structures utilisées dans StConstantes...

typedef struct
    {
    StCommande Cmd[ MAX_COMMANDES ];
    } StCmdFixe;

typedef struct
    {
    BYTE TypeCommande;                      // Type de commande
    BYTE ObjCommande1;                      // Objets associés à la commande
    BYTE ObjCommande2;                      // Objets associés à la commande
    BYTE Resultat1;                         // Resultat obtenu
    BYTE ObjResultat1;                      // Objets associé au résultat
    BYTE Resultat2;                         // Resultat obtenu
    BYTE ObjResultat2;                      // (apparition, changement mode...)
    } StCommande;

StCmdFixe est donc un tableau de MAX_COMMANDES structures StCommande.
StCommande contient les champs suivants :

  • TypeCommande : type de commande,
  • ObjCommande1 : premier objet associé à la commande,
  • ObjCommande2 : second objet associé à la commande,
  • Resultat1 : premier résultat à effectuer si la commande est réalisée,
  • ObjResultat1 : objet associé au premier résutat,
  • Resultat2 : second résultat à effectuer si la commande est réalisée,
  • ObjResultat1 : objet associé au second résutat.
typedef struct
    {
    BYTE Type;
    USHORT PtLibelle;
    } StDeclObj;
  • Type : indique le type d'objet (masculin ou féminin),
  • PtLibelle : un pointeur vers le tableau de caractères, décrivant le nom de l'objet.
typedef struct
    {
    BYTE Face;
    USHORT PtLibelle;
    } StVue;
  • Face : indique le numéro de face sur laquelle se trouve l'image associée à la salle,
  • PtLibelle : un pointeur vers le tableau de caractères, décrivant le libellé associée à la salle.

typedef struct

    {
    BYTE VarBit;
    BYTE TypeAction;
    BYTE ValParam;
    } StAction;

StAction permet d'exécuter une action particulière en fonction du résultat de l'opérateur "AND" entre une variable et un masque de bits.
Si le résultat est différent de zéro, l'action est exécutée.

  • VarBit : contient le masque de bits qui sera comparé avec la variable,
  • TypeAction : contient le type d'action à effectuer,
  • ValParam : contient un paramètre éventuellement associé à l'action.

Remarque : Si le bit 7 de TypeAction est à 1, le test s'effectue sur une variable globale au jeu, si le bit 7 de TypeAction est à 0, le test s'effectue sur une variable locale à la salle en cours.

typedef struct
    {
    USHORT Adr;             // Adresse début son ou musique
    } StSound;

StSound sert à indiquer l'adresse des différents sons/musiques pouvant être joué au cours du jeu. Les sons et musiques sont au format Starkos.

Voila donc un bref descriptif des structures utilisées dans P.J.A.
Voyons maintenant l'algorithme du moteur de jeu...
Première chose à faire : lire nos données.
Nous allons donc lire un fichier contenant notre structure StConstantes, et un fichier contenant une variable de type StJeu et un tableau de x éléments de type StLieu.
Ensuite, initialiser la position de départ du joueur.
Puis, vient la boucle principale.
En fait, deux méthodes sont possibles :

  • la méthode itérative (la boucle),
  • la méthode événementielle.

Sur PC, j'ai utilisé la méthode événementielle, car Windows se programme généralement de cette manière. Par contre, le moteur de jeu sur CPC est lui programmé de façon itérative, la boucle se contentant d'attendre une action du joueur pour la traiter.

Donc, la boucle principale se contente de :

  • exécuter les actions définies dans la salle,
  • attendre une action du joueur
  • décoder l'action que le joueur a fait,
  • exécuter cette action,
  • vérifier si le joueur se trouve dans la salle d'arrivée
  • si pas arrivée, alors on reboucle.

Starkos et le player Starkos sont créé par Targhan/Arkos
Pour me contacter :

http://cpc-pja.forumactif.com

★ LICENCE: ???
★ ANNÉE: 2005
PLATFORME: WIN32
★ LANGAGE:
★ AUTEUR: DEMONIAK
★ INFOS: http://cpc-pja.forumactif.com

★ AMSTRAD CPC ★ DOWNLOAD ★

Other platform tool:
» pja131DATE: 2005-12-10
DL: 76 fois
TYPE: ZIP
SIZE: 173Ko

Je participe au site:
» Newfile(s) upload/Envoye de fichier(s)
★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding » Cours d'assembleur par Demoniak - Partie 2: La mémoire
» Coding » Cours d'assembleur par Demoniak - Partie 8: La 3D en faces pleines sur CPC
» Coding » Sdcc - 07 - Ecrire un Fichier sur uneDisquette
» Coding » Sdcc - 24 - Bezier
» Demoscene » Demoniak 2
» Coding » Sdcc - 19 - 3D - Optimisation

QUE DIT LA LOI FRANÇAISE:

L'alinéa 8 de l'article L122-5 du Code de la propriété intellectuelle explique que « Lorsque l'œuvre a été divulguée, l'auteur ne peut interdire la reproduction d'une œuvre et sa représentation effectuées à des fins de conservation ou destinées à préserver les conditions de sa consultation à des fins de recherche ou détudes privées par des particuliers, dans les locaux de l'établissement et sur des terminaux dédiés par des bibliothèques accessibles au public, par des musées ou par des services d'archives, sous réserve que ceux-ci ne recherchent aucun avantage économique ou commercial ». Pas de problème donc pour nous!

CPCrulez[Content Management System] v8.75-desktop/c
Page créée en 051 millisecondes et consultée 1092 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.