Il y a quelques jours, sur ce thread, je m'étais avancé en disant que j'envisageais d'ouvrir un topic sur la création de jeux d'aventures en mode textuel.
Plutôt que me focaliser uniquement sur l'analyseur de syntaxe(qui restera basique : verbe + objet), je compte présenter:
-comment représenter une carte
-gérer les déplacements sur cette carte
-gérer les objets
-interagir avec le joueur(c'est pas inutile...)
Je me suis demandé comment organiser le bazar, et j'en suis là:
-Le topic est ouvert, on peut poser des questions, critiques, etc...
-Je maintiens ce premier post à jour pour donner des liens vers les différente parties
Le but final, c'est qu'on arrive à voir des jeux de ce style présentés ici.
Avant de commencer, j'ai une question cependant:
Même si la différence est minime, je pars sur une présentation d'un tel jeu en console, ou bien en SDL(avec affichage de chaque salle, saisie de texte via la SDL, etc...)?
edit:
les différences:
- en console se sera plus court
- en SDL, ça permet de présenter des sujets tel que la saisie de texte...
c'est un choix.
Avant de commencer, j'ai une question cependant:
Même si la différence est minime, je pars sur une présentation d'un tel jeu en console, ou bien en SDL(avec affichage de chaque salle, saisie de texte via la SDL, etc...)
Je dirais en console : plus simple, plus rapide, plus adapté aux débutants.
Sinon, je n'ai pas très bien compris, tu veux créer un jeu en mode textuel et nous faire partager tes avancements et on en discute ou tu veux juste donner des liens et discuter ?
Sinon, je n'ai pas très bien compris, tu veux créer un jeu en mode textuel et nous faire partager tes avancements on en discute ou tu veux juste donner des liens et discuter ?
C'est vraiment plus pour discuter.
Bon, j'avoue, je compte présenter la manière que je connais.
Mais ce n'est surement pas la meilleure donc:
- je peux adapter(j'adapterai) si on propose mieux
Clairement, le but c'est proposer une base, qui permet à toute personne intéressée de produire un jeu de ce genre(moyennant imagination, patience, etc...)
C'est malgré tout aussi l'occasion de présenter la saisie de texte la SDL(en utilisant SDL_TTF ou pas).
C'est vrai qu'on ne voit pas souvent d'exemple de gestion d'entrée/sortie avec la SDL. D'autant que je serais curieux de voir un affichage de texte sans SDL_ttf (tu utilises une image contenant toutes les lettres utilisées?). Bon, tu m'as convaincus je vote SDL
Pour la saisie sdl, tout le monde connait la lib de cookies_forever (ou ce genre là), mais pour l'affichage pur et simple, c'est déjà moins courant.
Mais à mon avis, gérer les retours à la ligne, ça doit pas être trop dur.
Sinon, il y a d'autres lib de texte que SDL_ttf, qui sont pas mal.
Les 2 premières parties, n'auront aucun rapport avec l'affichage ou la manière de récupérer les entrées.
Donc, je peux me lancer sans préférence pour la SDL ou la console...
Mais ce qui est possible aussi, c'est de présenter les 2.
Il y aura moins de déçus(j'espère...)
Citation : paraze
Pour la saisie sdl, tout le monde connait la lib de cookies_forever (ou ce genre là), mais pour l'affichage pur et simple, c'est déjà moins courant.
Mais à mon avis, gérer les retours à la ligne, ça doit pas être trop dur.
Sinon, il y a d'autres lib de texte que SDL_ttf, qui sont pas mal.
Pas d'inquiétude, si je présente un truc en SDL, je présenterai une solution basée sur SDL_TTF, et une solution avec des fontes bitmap...
Moi, je commencerai à faire un prog' en console puis je l'adapterai à la SDL (si j'aurai envie) car la méthode d'affichage, c'est pas ce qu'il y a de plus important (à mon avis).
Personnellement je vote pour la SDL : nombreux sont ceux qui postent ici pour demander comment écrire ou récupérer une saisie de texte en SDL , cela permettra donc, en même temps, aux moins expérimentés de voir quelques lignes de codes utilisant SDL_ttf ou autre.
edit ( pour répondre au message qui suit et éviter de post pour rien ): j'y ai déjà jeté un coup d’œil et il a l'air pas mal , c'est pas spécialement pour moi ce que j'ai dis ci-dessus mais bon après à vous de voir.
Sympa. Suite à ton sujet, j'ai voulu en faire un.
Voilà ce que je te conseil :
D'abord, met toutes les lettres en MAJUSCULES (avec toupper() et une boucle) car c'est plus simple après pour gérés les caractères
A, et fait le en console
EDIT : Les deux, comme ça tout le monde est content
@Gomei> Il existe une lib pour la gestion des saisies en C+SDL (une mini-lib fait par un membre du sdz)
EDIT : Vous voulez un bout de code ? (Vu que j'en fait un... )
Je pense que console ou graphique, ça n'a pas d'importance. Si le programme est bien pensé, la partie 'logique', évènements et la partie d'affichage sont à part et donc avoir console ou graphique, ça ne pose pas de problèmes.
Je pense que console ou graphique, ça n'a pas d'importance. Si le programme est bien pensé, la partie 'logique', évènements et la partie d'affichage sont à part et donc avoir console ou graphique, ça ne pose pas de problèmes.
D'accord avec pouet...
A demain!
edit:
Les membre Joe78 et fvirtman ont leur mot à dire vu que je vais pomper l'intégralité de leurs codes...
La première chose c'est déjà d'avoir une idée de scénario.
Là, je ne peux pas aider, c'est à chacun de faire travailler son imagination.
Représentation du monde.
Une fois que vous avez une idée de scénario, l'étape suivante c'est la réalisation du plan.
Cette étape est très importante et dois être réalisée avec rigueur, pour faciliter le codage ensuite.
Pour rester simple, ici, je vais partir sur une grille de 3 x 3 cases.
1
2
3
4
5
6
7
8
9
Libre à vous d'utiliser une grille de n'importe quelle dimension.
On est bien sur pas obligé d'employer toutes les cases de la grille.
Un exemple(désolé j'ai pas trouvé mieux que cette bidouille.)
Les cases ne pouvant pouvant pas communiquer entre elles sont séparée par des traits gras.
Attention à conserver un minimum de cohérence.
Stockage de la carte
Vous l'aurez compris en voyant la première grille, la carte va être stockée sous forme de tableau.
J'ai choisi d'utiliser un tableau à une dimension, ce qui permet d'avoir un indice unique pour chaque case.
Les déplacements
On observant la première grille, on trouve facilement une logique pour avancer dans une autre direction.
Par convention, on considère que le nord est vers le haut.
Soit CASE, la case actuelle
avec notre grille 3 x 3
Pour aller au nord: CASE = CASE - 3
Pour aller au sud: CASE = CASE + 3
Pour aller à l'ouest: CASE = CASE - 1
Pour aller à l'est: CASE = CASE + 1
et pour une grille de taille quelconque avec
CARTE_W /* largeur de la carte */
On a:
Pour aller au nord: CASE = CASE - CARTE_W
Pour aller au sud: CASE = CASE + CARTE_W
Pour aller à l'ouest: CASE = CASE - 1
Pour aller à l'est: CASE = CASE + 1
C'est tout pour l'instant.
Je pense que ce n'est pas utile d'aller trop vite, pour pemettre de
-digérer les infos
-penser à un scénario
-réaliser un plan
C'est un topic qui va certainement m'intéresser ... Tu balances pas des lignes de code , j'aime bien tes explications, je vais suivre avec attention le déroulement des opérations ...
Bonne initiative
Vu que la première partie était il me semble assez simple, je poste rapidement la seconde.
Gestion des déplacements.
Maintenant que l'on a vu comment représenter notre carte en mémoire.
Sur une carte, toutes les cases adjacentes ne peuvent pas communiquer entre elle.
Comment représenter cette limitation?
Nous allons créer un tableau aNSEO de même taille que notre carte.
Ici, avec l'exemple précédent
Pour calculer les valeurs de chaque élément de a_NSEO, on va procéder de la sorte:
-Il y a un accès au nord, j'ajoute 1 à la valeur
-Il y a un accès au sud, j'ajoute 2
-Il y a un accès à l'est, j'ajoute 4
-Il y a un accès à l'ouest j'ajoute 8
Petit exemple
En regardant la carte de mon post précédent:
La case 5 qui correspond au hall d'entrée à 2 accès possibles:
- à l'est par la rue
- à l'ouest par le couloir.
Donc a_NSEO[5] = 4 + 8 = 12
C'est clair?
Pour tester si une direction est possible, on va utiliser l'opérateur &
si a_NSEO[case] & 1 != 0 -> le nord est accessible.
si a_NSEO[case] & 2 != 0 -> le sud est accessible.
si a_NSEO[case] & 4 != 0 -> l'est est accessible.
si a_NSEO[case] & 8 != 0 -> l'ouest est accessible.
On teste!
Cette fois çi, il y a aura un exemple de code.
Alors, mes excuses les tableaux sont globaux, et tout est dans le main.
#include <stdio.h>
#include <ctype.h>
#include <assert.h>
#define MAP_W 3
#define MAP_H 3
unsigned char a_NSEO[] =
{
2, /* Chambre 1 */
0, /* Vide */
2, /* Rue */
7, /* Couloir */
12, /* Hall d'entrée */
11, /* Rue */
1, /* Chambre 2 */
0, /* Vide */
1, /* Rue */
};
char const *a_description[] =
{
"Chambre 1",
"",
"Rue",
"Couloir",
"Hall d'entree",
"Rue",
"Chambre 2",
"",
"Rue"
};
void clear(void)
{
int c;
while((c = getchar()) != '\n')
;
}
int main(void)
{
int crtCell = 8;
int c;
printf("%s\n", a_description[crtCell]);
putchar('>');
while((c = getchar()) != EOF)
{
int dir = 0;
if(isalpha(c))
{
c = toupper(c);
switch(c)
{
case 'N':
dir = -MAP_W;
break;
case 'S':
dir = MAP_W;
break;
case 'E':
dir = 1;
break;
case 'O':
dir = -1;
break;
default:
break;
}
}
if(dir)
{
/* On a une direction, on teste si elle est valide */
if((dir == -MAP_W && !(a_NSEO[crtCell] & 1))
||(dir == MAP_W && !(a_NSEO[crtCell] & 2))
||(dir == 1 && !(a_NSEO[crtCell] & 4))
||(dir == -1 && !(a_NSEO[crtCell] & 8)))
puts("Impossible d'aller par la !");
else
{
/* Direction valide, on change de case */
crtCell += dir;
/* La case doit posséder une description, sinon
* erreur dans le code */
assert(a_description[crtCell]);
printf("%s\n", a_description[crtCell]);
}
}
else
{
puts("Oo Pas compris ...");
}
/* On nettoie stdin */
clear();
putchar('>');
}
return 0;
}
Un exemple de sortie
Rue
>n
Rue
>o
Hall d'entree
>o
Couloir
>s
Chambre 2
>n
Couloir
>n
Chambre 1
>s
Couloir
>e
Hall d'entree
>e
Rue
>n
Rue
>n
Impossible d'aller par la !
^Z
Process returned 0 (0x0) execution time : 24.688 s
Press any key to continue.
La prochaine fois, on verra comment ouvrir, fermer une direction.
Ne serait-il pas mieux de faire correspondre les valeurs de la variable dir avec celles du tableau a_NSEO? Par exemple, on pourrait utiliser une enum et un tableau:
enum direction {
VIDE = 0,
NORD = 1,
SUD = 2,
EST = 4,
OUEST = 8,
NB
};
static int const a_direction[NB] = {
/* Ce type d'initialisation n'est possible qu'en C99 */
[NORD] = -MAP_W,
[SUD] = MAP_W,
[EST] = 1,
[OUEST] = -1
};
Ainsi, on rend plus lisible les directions possibles pour chaque cases:
unsigned char a_NSEO[] = {
SUD, /* Chambre 1 */
VIDE, /* Vide */
SUD, /* Rue */
SUD | EST | NORD, /* Couloir */
EST | OUEST, /* Hall d'entrée */
SUD | OUEST, /* Rue */
NORD, /* Chambre 2 */
VIDE, /* Vide */
NORD, /* Rue */
};
Pour l'implémentation, j'avoue que c'est "à l'arrache." .
Je laisse comme ça, pour l'instant, mais pour les prochains je prend compte de tes remarques(et peut être des suivantes).
A propos
Citation : jolfo
Moi, je fait des fonctions pour chaques salles...
Tu peux préciser?
Sinon, vous verriez quoi comme rythme?
J'étais parti sur 1 semaine, mais je me suis rendu compte que le contenu du 1er post était plutôt léger finalement, et j'ai posté le second rapidement.
J'accélère?
@darkipod:
Merci.
Je compte vraiment expliquer, sans que le code soit nécessaire.
Pour l'implémentation, j'avoue que c'est "à l'arrache." .
Franchement, mis à part le if, on ne dirait pas
Citation : GurneyH
Sinon, vous verriez quoi comme rythme?
J'étais parti sur 1 semaine, mais je me suis rendu compte que le contenu du 1er post était plutôt léger finalement, et j'ai posté le second rapidement.
J'accélère?
Je pense que pour celle-ci, un ou deux jours cela suffit, histoire que toutes les personnes intéressées aient le temps de lire
En fait, j'ai une fonction par action possible par salles, du genre "void chapitre1_s1(void);", mais je ne pense pas que ce soit la meilleurs façon (de toute façon, tu n'es pas encore arriver là dans tes explications...)
En fait, j'ai une fonction par action possible par salles, du genre "void chapitre1_s1(void);", mais je ne pense pas que ce soit la meilleurs façon (de toute façon, tu n'es pas encore arriver là dans tes explications...)
D'accord, je pense comprendre.
Dans ce que je vais présenter la méthode sera générique pour chaque salle.
Il y a aura ensuite des cas particuliers.
En gros les actions dans une salle donnée sont:
- se déplacer
- prendre un objet
- utiliser un objet
> write() est une fonction inventée affichant le texte à l'écran comme sur un machine à écrire, dans une certaine couleur . >>> J'utilise Sleep() sous windows ou sleep() sous linux, et une boucle pour afficher les caractères un par un. > writeUserWrong() est un fonction inventée (aussi ) permettant d'afficher un message indiquant que la réponse de l'utilisateur est fausse en piochant aléatoirement dans des phrases prédéfinits. >>> Là, j'utilise rand() et un switch > read() récupère les données de l'utilisateur et les mets en majuscules... >>> J'utilise la saisie sécurisée du tuto de m@théo21 et toupper() > pause() permet de faire une pause. >>> avec getch() pour windows et getchar() pour linux.
Pour ma part tu peux accélérer mais très lentement... Il me faut du temps pour ingurgiter mais j aime bien tes explications pour moi pour l instant c est OK
× 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.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.