Update README

This commit is contained in:
Shadow15510 2021-08-14 17:13:34 +02:00
parent 72c9ef161d
commit f13ddd8413
5 changed files with 447 additions and 216 deletions

381
README.md
View File

@ -8,7 +8,7 @@
### Principe
Le moteur repose sur l'évolution de points d'expérience pour déterminer votre avancée dans le jeu. Ces points d'expériences peuvent être donnés au joueur à l'issu de dialogues ou de combats.
Le moteur repose sur l'évolution de points d'expérience pour déterminer votre avancée dans le jeu. Ces points d'expériences sont donnés au joueur à l'issu d'évènements.
### Licence
@ -16,111 +16,127 @@ Tout le projet est soumis à la licence GNU General Public Licence v3.0.
## Utilisation
### Instructions
### Les statistiques
#### Création d'un nouveau projet
Les statistiques sont une liste de variables dont le premier élément est nécessairement les points de vie. Cette liste est donnée au moteur lors de l'initialisation, néanmoins, le moteur ne *modifie en aucun cas* cette variable. Il la stocke pour vous et la modifie sur votre demande, lors des évènements. Il s'agit donc d'une variable maîtresse dans les mécaniques de votre jeu.
Vous devez commencer par copier le fichier `asci_lib.py` dans le répertoire de votre jeu. Créez ensuite un fichier qui va correspondre à votre jeu. Nommez-le comme vous voulez, le nom ne présente pas d'importance pour le moteur.
Les statistiques ne peuvent être modifées que lors d'évènements. Comme vous le verrez dans la suite, les évènements sont des listes dont les derniers éléments ne sont pas déterminés : il s'agit des points que vous pouvez ajouter ou enlever à vos statistiques.
Ici, notre fichier s'appellera `sample.py`.
### Structure du programme
#### Structure du programme
Votre jeu va se diviser en grandes partie :
- création de la carte
- création des évènements
- gestion des combats
- affichage des statistiques
- finalisation
Notre fichier va se découper en plusieurs parties :
- l'importation de la bibliothèque `asci_lib.py`
- la création de la carte
- la création des dialogues
- la création de la fonction qui correspond à votre jeu et finalisation
Vous aurez à plusieurs reprise des fonctions à programmer, ces fonctions auront accès à des variables du moteurs, elles sont toutes en lecture seule, exceptée les statistiques qui peuvent être modifiée par effet de bord.
#### Création de la carte
La carte est un grand tuple qui est de la forme :
Vous allez devoir créer une carte du monde, mais aussi les intérieurs des maisons. Pour cela vous allez avoir besoin d'un tuple qui va devoir remplir quelques conditions :
- toutes les cartes sont des r-docstrings `r""" ... """`
- le premier élément du tuple est la carte du monde
- les autres éléments sont eux-même des tuples de la forme : `(carte, (x_entree, y_entree), (x_sortie, y_sortie))``(x_entree, y_entree)` sont les coordonnées de la porte de la maison *dans la carte du monde* et où `(x_sortie, y_sortie)` sont les coordonnées de la porte de la maison *dans la carte de la maison*
#### Création des évènements
Les évènements sont des listes formatées qui ont cette forme : `[xp_gagnee, "Texte de l'évènement", nb, ...]`.
- `xp_gagnee` : correspond à l'expérience que le joueur gagne lors de l'évènement.
- le texte est ce qui est affiché à l'écran lors de l'évènement.
- `nb` : est une variable utilisée lors de dialogues. C'est une manipulation un peu plus délicate sur laquelle je reviens juste après.
- les `...` correspondent à des modificateurs sur les statistiques. J'y reviendrais également.
Les dialogues permettent au joueur de choisir sa réponse. Si le joueur ne peux pas choisir de réponse, mettez `nb` à 0, sinon mettez `nb` sur le nombre de réponse possible. Les différentes réponses sont à afficher avec un numéro dans le corps du message. Par exemple : `[0, "Ceci est une question ? 1.Première réponse. 2.Seconde réponse.", 2]`. Le numéro de la question correspond alors au nombre de points d'expérience gagnée par le joueur (il est, de se fait, conseillé de ne pas donner de points d'expérience au joueur lors d'un dialogue). Si il n'y a pas de réponses possible, vous pouvez omettre cet argument. Attention, cette astuce n'est valable que si vous ne comptez pas modifier les statistiques.
Ces évènements sont stockés dans des dictionnaires dont les clefs correspondent aux points d'expériences, c'est peut-être pas très clair, mais avec un exemple, ça ira mieux.
Par simplicité, j'utiliserai un dictionnaire par PnJ, vous faites bien comme vous voulez, du moment que vous obtenez un truc qui marche… Ces dictionnaires d'évènements doivent être placés dans une fonction qui doit respecter certaines règles :
- la fonction doit prendre en argument l'expérience, l'id de la map actuelle (qui correspond à son index dans el tuple des maps), les coordonnées du joueur et les statistiques
- la fonction doit renvoyer un dictionnaire d'évènement ou un évènement.
Concrètement, votre fonction va ressembler à :
```
carte_monde = (
<carte_du_monde>,
(<carte_maison_1>, (x_entree1, y_entree1), (x_sortie1, y_sortie1)),
(<carte_maison_2>, (x_entree2, y_entree2), (x_sortie2, y_sortie2)),
...)
def evenement(xp, carte_actuelle, x, y, stat):
coords = (x, y)
# Si on est en extérieur
if carte_actuelle == 0:
if coords == (X1, Y1): return {
xp_1: [...],
xp_2: [...],
...
"base": [...]
}
elif coords == (X2, Y2): return ...
# Si on est dans la première maison
elif carte_actuelle == 1:
...
# Si on a pas encore renvoyé d'évènement, il faut prévoir un "cas par défaut"
return [0, "Hmm ?"]
```
la `<carte_du_monde>` et les `<carte_maison_X>` sont des r-docstrings. Vous pouvez mettre à peu près n'importe quoi, veillez à bien respecter la légende :
- `@` : caractère réservé au joueur (ne pas utiliser)
- `^` : porte de maison
- `*` : PnJ
- `$` : adversaire
Les tests conditionnels testent quel PnJ le joueur regarde (sur quelle carte, et à quelles coordonnées).
Dans le cas des maisons, le premier tuple correspond aux coordonnées de la porte de la maison *dans la carte du monde*. Le second tuple correspond aux coordonnées de la porte de la maison *dans la carte de la maison*.
Ici, on voit peut-être un peu mieux le fonctionnement : les clefs du dictionnaires d'évènements correspondent à des points d'expérience : si le joueur à `xp_1` points d'expérience, alors c'est ce dialogue là qui sera lu, et si aucun évènement ne correspond, mais que le PnJ a quand même un texte à dire à un moment, l'évènement `"base"` sera lu.
#### Création des dialogues
Cette fonction est appelée lors d'un dialogue avec un PnJ, mais aussi à l'issue d'un combat, si le joueur est vainqueur. Le principe reste le même.
Sur votre carte fraîchement créée, vous avez mis des PnJ (si ce n'est pas le cas, mettez-en, la suite sera plus intéressante ;) ). L'idée est assez simple, il va falloir créer une fonction qui va prendre en argument l'expérience, les points de vie, l'id de la carte (l'index de la carte dans le tuple des maps, 0 : carte du monde, 1 : première maison etc), les coordonnées du joueur et les stat (une liste qui peut contenir des variables nécessaires aux mécaniques de votre jeu). Nous avons donc déjà :
#### Gestion des combats
Vous êtes (presque) totalement libre ! Votre fonction doit respecter quelques points :
- la fonction, comme pour les évènements, doit prendre en argument l'expérience, le numéro de la carte, les coordonnées du joueur et les statistiques. (vous pouvez toujours objecter que ça fait beaucoup de variables, mais ça peut servir)
- la fonction doit retourner un booleen égal à `True` si le joueur a gagné, `False` sinon.
Vous devriez avoir une fonction qui ressemble un peu à ça :
```
def dialogue(xp, pv, carte_actuelle, x, y, stat):
def combats(xp, carte_actuelle, x, y, stat):
...
return stat[0] > 0
```
Cette fonction va renvoyer un dictionnaire *ou* une liste.
C'est assez important, car, si vous renvoyez un dictionnaire, le dialogue sera lu en fonction des points d'expériences du joueur. Si vous renvoyez une liste, c'est le dialogue de la liste qui sera lu.
#### Affichage des statistiques
Le seul impératif que vous devez absolument respecter est la forme du dictionnaire et des listes.
La fonction est assez triviale :
- la fonction devra prendre en argument la liste des statistiques (les points d'expérience, au sens du moteur, sont considérés comme ne faisant pas partie des statistiques)
- la fonction devra afficher elle-même les statistiques.
Le dictionnaire est de la forme :
Vous aurez une fonction qui va ressembler ainsi à quelque chose comme :
```
dialogues = {
xp_1: [...],
xp_2: [...],
...
"base": [...]
}
def affichage_stat(stat):
print("<*> Statistiques <*>")
print("Points de vie .: {}".format(stat[0]))
```
`xp_X` correspond au nombre de points d'expérience à avoir pour déclencher ce dialogue.
`"base"` est le dialogue lancé par défaut si aucun autre cas ne marche.
Les listes sont, elles, de la forme :
```
[xp_gagne, "le texte du dialogue", booleen, ...]
```
`xp_gagne` correspond aux nombres de points d'expérience gagné lors de la lecture de ce dialogue.
`booleen` détermine s'il s'agit d'un monologue du PnJ ou si vous pouvez répondre au PnJ.
`...` correspond à des modificateurs des stats. Vous pouvez tout à fait les oublier en première utilisation
La question maintenant est de savoir comment relier les dialogues au PnJ. Vous êtes libre de mettre en place un système d'ID, Nous vous proposons un système peut-être plus simple : les coordonnées des PnJ. Nous allons ainsi avoir une fonction qui va ressembler à :
```
def dialogue(xp, pv, carte_actuelle, x, y, stat):
# Pour des raisons de clareté, on déclare un tuple avec les coordonnées
coords = (x, y)
# Si nous sommes en extérieur
if carte_actuelle == 0:
if coords == (X1, Y1):
return {...}
elif coords == (X2, Y2):
return {...}
# Si nous sommes dans la première maison de la liste
elif carte_actuelle == 1:
...
# Si le PnJ est bien sur la map, mais n'a aucun dialogue d'assigné :
return [0, "Hmm ?", False]
```
Vous pouvez également créer des dialogues. Pour cela, il vous suffit de mettre le booleen sur `True` et de mettre les réponses possibles dans le corps du dialogue, par exemple : `[0, "Ceci est une question ? 1. Réponse 1 2. Réponse 2", True]`. Le numéro de la réponse correspond au nombre de point d'expérience qu'elle rapporte, cela vous permet de gérer les différents cas dans al suite du dialogue.
#### Finalisation
Il reste à faire une petite fonction qui va créer un "modèle" de jeu de rôle vierge, il faudra lui donner la carte, la fonction des dialogues et ce sera fini !
Il ne reste plus qu'à faire une petite fonction de nom de votre jeu qui va créer un modèle vierge de jeu rôle et qui va transmettre toutes ces données au modèle. Il vous restera ensuite à lancer cette fonction pour jouer.
La fonction est vraiment triviale :
Cette fonction devra prendre dans l'ordre :
- le tuple des cartes
- la fonction des évènements
- la fonction des combats
- la fonction d'affichages des statistiques
- les points d'expérience de la partie (lorsque l'expérience du joueur atteint cette valeur, le jeu se termine)
- la liste des statistiques (avec les points de vie en première place)
### Exemples d'utilisation
#### Exemple de manipulations basique
Quelques réflexions préliminaires sur les mécaniques de notre petit jeu :
- en terme de stat : PV et Argent suffiront
- un seul dialogue à deux issues et modification de statistiques par les dialogues, on aura un arbre d'XP qui va ressembler à ça :
```
def mon_jeu():
rpg_python = Asci(carte_monde, dialogue, 10, [100])
rpg_python.mainloop()
+--1--+
-0--+ +--3-
+--2--+
```
Les deux premiers arguments `carte_monde` et `dialogue` ont déjà été vu. Le `10` correspond aux nombres de points d'expérience au bout duquel le programme s'arrête, il s'agit de la fin de la partie si vous voulez. La liste passée en dernier argument correspondent aux stats, vous devez impérativement mettre les points de vie de votre personnage.
### Exemples et astuces
#### Exemples de cartes
Pour commencer simplement, voici une carte assez banale (ne pas oublier la virgule à la fin !) :
Nous allons commencer par créer une carte simple. Juste le monde, sans maison.
```
carte_monde = (
r"""
@ -134,88 +150,153 @@ r"""
|==|==|==|==|==|==|==|""",)
```
Nous n'avons pas de maisons, juste un PnJ
Nous avons un PnJ aux coordonnées `(2, 5)`, et pas d'adversaire, il nous reste à faire les dialogues avec cet unique PnJ, la fonction de combat ne sera pas traitée ici vu qu'il n'y a pas d'ennemi.
#### Exemple de fonction de dialogue
Nous allons faire parler notre PnJ ! Et comme on est chaud, on va directement faire un petit dialogue. Pour bien séparer les réactions à la question du reste, je met un niveau d'indentation supplémentaire, ça ne change rien au comportement du code.
Comme il n'y a pas grand chose à faire, je vais en profiter pour vous montrer les dialogues et les statistiques.
```
def dialogue(xp, pv, carte_actuelle, x, y, stat):
def evenements(xp, carte_actuelle, x, y, stat):
coords = (x, y)
if carte_actuelle == 0:
if coords == (2, 5): return {
0: [0, "Coucou ! Comment ca va ? 1. Ca va, et toi ? 2. Bof... 3. Je t'emmerde.", True],
1: [3, "Je vais bien, merci !", False],
2: [3, "Ow, desole...", False],
3: [4, "He, reviens quand tu sera de meilleure humeur !", False],
0: [0, "Mon bon monsieur, vous n'auriez pas quelques sous pour moi ? 1. He non mon brave... 2. Mais si, bien sur, tenez.", 2],
1: [2, "Radin !"],
# 0 réponse possibles, +0 PV, -1 Argent
2: [1, "Merci !", 0, 0, -1],
4: [2, "Bon et bien, je crois bien que cette premiere carte s'est bien passee !", False],
5: [1, "Je vais y aller, appelle moi si tu as besoin ;)", False],
6: [1, "A pluche o/", False],
"base": [0, "Hmm ?"]
}
"base": [0, "Oui ?", False]
}
return [0, "Hmm ?", False]
```
Pour mettre en place vos dialogues (parce que j'espère que vous aurez un peu plus qu'un seul PnJ) faire un arbre de progression de l'XP peut être une bonne idée ;) je vais essayer de le faire en ASCII-art pour vous montrer, mais avec une feuille et un stylo c'est plus simple.
```
1 4
-=----=---
0 / 2 5 \ 6 7
------=----=------=--=
\ 3 /
-=------------
return [0, "Hmm ?"]
```
#### Fin de l'exemple et récapitulation
Comme dit plus haut : pas de combat, donc la fonction de combat va se résumer à un simple `def ...: pass` :
```
def combat(xp, carte_actuelle, x, y, stat):
pass
```
Il reste la petite fonction à faire :
Pour les statistiques, nous avons des points de vie et de l'argent, on va bricoler un truc simple :
```
def affichage_stat(stat):
pv, argent = stat
print("Statistiques")
print("PV : {}".format(pv))
print("Argent : {}".format(argent))
```
Il ne reste plus qu'à tout donner au moteur !
La limite d'XP de la partie est fixée à 3, on commence la partie avec 100 points de vie et 5 Argent.
```
def mon_jeu():
rpg_python = Asci(carte_monde, dialogue, 7, [])
rpg_python.mainloop()
```
Nous avons le fichier complet :
```
from asci_lib import *
carte_monde = (
r"""
_ ###
/o\__ #####
| <>\ ###
|____| /_\
*
|==|==|==|==|==|==|==|""",)
def dialogue(xp, pv, carte_actuelle, x, y, stat):
coords = (x, y)
if carte_actuelle == 0:
if coords == (2, 5): return {
0: [0, "Coucou ! Comment ca va ? 1. Ca va, et toi ? 2. Bof... 3. Je t'emmerde.", True],
1: [3, "Je vais bien, merci !", False],
2: [3, "Ow, desole...", False],
3: [4, "He, reviens quand tu sera de meilleure humeur !", False],
4: [2, "Bon et bien, je crois bien que cette premiere carte s'est bien passee !", False],
5: [1, "Je vais y aller, appelle moi si tu as besoin ;)", False],
6: [1, "A pluche o/", False],
"base": [0, "Oui ?", False]
}
return [0, "Hmm ?", False]
def mon_jeu():
rpg_python = Asci(carte_monde, dialogue, 7, [])
rpg_python = Asci(carte_monde, evenements, combat, affichage_stat, 3, [100, 5])
rpg_python.mainloop()
```
Et voila ! N'oubliez pas d'importer `asci_lib` ! Pour ceux qui veulent tester, le code complet est dans le fichier `rpg_maker/sample_1.py`
#### Autre exemple basique
Nous allons reprendre la même carte que tout à l'heure, mais nous allons ajouter une porte à la maison, aux coordonnées `(1, 3)` :
```
_ ###
/o\__ #####
|_ <>\ ###
|^|__| /_\
*
|==|==|==|==|==|==|==|
```
Il faut donc dessiner l'intérieur de la maison :
```
+--+--+--------+--+--+
| | | * | | *|
| + + + + |
| |
| + + + + |
+--/ \--------/ \--+
| |
+---|^|--------------+
```
La porte à l'intérieur est aux coordonnées `(5, 7)`. Nous avons donc le tuple des cartes :
```
cartes = (
r"""
_ ###
/o\__ #####
|_ <>\ ###
|^|__| /_\
*
|==|==|==|==|==|==|==|""",
(r"""
+--+--+--------+--+--+
| | | * | | *|
| + + + + |
| |
| + + + + |
+--/ \--------/ \--+
| |
+---|^|--------------+""",
(1, 3), (5, 7)
))
```
Pour les évènements, rien de nouveau, étant donné que nous n'avons a priori pas de statistiques à part la vie, il n'y a pas forcément grand chose à faire, vous pouvez vous amuser à faire des dialogues un peu complexes avec différentes fins.
```
def evenements(xp, carte_actuelle, x, y, stat):
coords = (x, y)
if carte_actuelle == 0:
if coords == (2, 5): return {
0: [0, "Hey ! J'ai entendu du bruit dans la maison, mais je n'ose pas rentrer... 1. Rien entendu. 2. Je vais jeter un oeil.", 2],
1: [3, "Etes-vous sourd ?"],
2: [1, "J'etais sur que vous m'ecouteriez !"],
3: [2, "C'est la maison juste au nord."],
4: [0, "Enfin, vous entendez bien du bruit la ? Et si c'etait un voleur ? 1. Bon ok j'y vais. 2. Mais foutez moi la paix !", 2],
6: [0, "..."],
5: [2, "Soyez prudent !"],
12: [1, "J'etais sur d'avoir entendu un truc !"],
"base": [0, "Vous avez entendu quelque chose ?"]
}
elif carte_actuelle == 1:
if coords == (9, 1): return {
7: [0, "Je crois que le voleur est dans la piece d'a cote... 1. Je vais regarder. 2. Debrouillez-vous !", 2],
8: [2, "Merci !"],
9: [0, "Pleutre ! Hors de ma vue !"],
11: [1, "Ah, merci !"],
"base": [0, "J'ai peur de sortir de cette piece"]
}
elif coords == (20, 1): return {
10: [1, "Ciel, je suis fait !"],
"base": [0, "File avant que je ne te detrousse !"]
}
return [0, "Hmm ?"]
```
De même que pour l'exemple précédent : pas de combat. Je vous laisse gérer l'affichage des statistiques. Il reste la fonction finale :
```
def mon_jeu():
rpg_python = Asci(cartes, evenements, combat, affichage_statistique, 13, [100])
rpg_python.mainloop()
```
La limite est à 13 xp comme on peut le voir sur l'arbre :
```
+--6-X
+--1--4--+ +--8--10--11--12--13-
-0--+ +--5--7--+
+--2--3--+ +--9-X
```
les `X` symbolise les impasses.

View File

@ -1,5 +1,3 @@
from random import randint
class Screen:
def __init__(self, world, screen_width=21, screen_height=6):
# Screen configuration
@ -55,10 +53,10 @@ class Screen:
class Asci:
def __init__(self, maps, fn_dialogue, end_game, stat, data=[0, 100, 0, 0, 0], screen_width=21, screen_height=6):
def __init__(self, maps, fn_events, fn_fight, fn_stat, end_game, stat, data=[0, 0, 0, 0], screen_width=21, screen_height=6):
# Load save ; data = [XP, map_id, x, y]
self.data = data
if not stat:
if not stat or type(stat) != list:
self.stat = [100]
else:
self.stat = stat
@ -68,7 +66,9 @@ class Asci:
self.end_game = end_game
# Custom functions
self.get_dialogue = fn_dialogue
self._game_event = fn_events
self._game_fight = fn_fight
self._game_stat = fn_stat
# Screen configuration
self.screen = Screen(maps[data[2]], screen_width, screen_height)
@ -77,21 +77,21 @@ class Asci:
def _looked_case(self, direction):
# Left
if direction == 1:
return self.data[3] + 9, self.data[4] + 3
return self.data[2] + 9, self.data[3] + 3
# Right
elif direction == 3:
return self.data[3] + 11, self.data[4] + 3
return self.data[2] + 11, self.data[3] + 3
# Up
elif direction == 5:
return self.data[3] + 10, self.data[4] + 2
return self.data[2] + 10, self.data[3] + 2
# Down
elif direction == 2:
return self.data[3] + 10, self.data[4] + 4
return self.data[2] + 10, self.data[3] + 4
return self.data[3] + 10, self.data[4] + 3
return self.data[2] + 10, self.data[3] + 3
def _cell_test(self, direction):
if direction == 1:
@ -119,34 +119,34 @@ class Asci:
cell_test = self._cell_test(key)
# Enter house
if cell_test == 2 or (self.data[2] and cell_test < 0):
self.data[2], self.data[3], self.data[4] = self._get_map(key)
if self.data[2]:
self.screen.set_world(self.maps[self.data[2]][0])
if cell_test == 2 or (self.data[1] and cell_test < 0):
self.data[1], self.data[2], self.data[3] = self._get_map(key)
if self.data[1]:
self.screen.set_world(self.maps[self.data[1]][0])
else:
self.screen.set_world(self.maps[0])
# PnJ
# Talk
elif cell_test == 3:
self._chatting(key)
self._talk(key)
# Fight
elif cell_test == 4:
pass
self._fight(key)
# Left
if key == 1 and cell_test == 1: self.data[3] -= 1
if key == 1 and cell_test == 1: self.data[2] -= 1
# Right
if key == 3 and cell_test == 1: self.data[3] += 1
if key == 3 and cell_test == 1: self.data[2] += 1
# Up
if key == 5 and cell_test == 1: self.data[4] -= 1
if key == 5 and cell_test == 1: self.data[3] -= 1
# Down
if key == 2 and cell_test == 1: self.data[4] += 1
if key == 2 and cell_test == 1: self.data[3] += 1
# Stat
if key == 8:
self.screen.clear()
print("<*> Statistiques <*>\n")
self._game_stat(self.stat)
input()
# Quit
@ -156,32 +156,41 @@ class Asci:
# /!\ TEST /!\ #
if key == 7:
print(self.data[-2:])
print(self.data)
input()
# /!\ TEST /!\ #
def _chatting(self, direction):
def _talk(self, direction):
x, y = self._looked_case(direction)
# Read the dialogue
dialogue = self.get_dialogue(self.data[0], self.data[1], self.data[2], x, y, self.stat)
if type(dialogue) == dict:
if self.data[0] in dialogue: dialogue = dialogue[self.data[0]]
else: dialogue = dialogue["base"]
event = read_event(self.data[0], self._game_event(self.data[0], self.data[1], x, y, self.stat))
# XP and PV modification
self.data[0] += dialogue[0]
# XP and stat modification
self.data[0] += event.xp_earned
for index in range(len(event.stat)):
self.stat[index] += event.stat[index]
# Stat modification
for index in range(len(dialogue[3:])):
stat[index] += dialogue[3 + index]
answer_selected = convert(self.screen.display_text(event.text))
if event.answer and (0 < answer_selected <= event.answer): self.data[0] += answer_selected
answer_selected = self.screen.display_text(dialogue[1])
if dialogue[2]: self.data[0] += convert(answer_selected)
def _fight(self, direction):
x, y = self._looked_case(direction)
# Run the fight
if self._game_fight(self.data[0], self.data[1], x, y, self.stat):
event = read_event(self.data[0], self._game_event(self.data[0], self.data[1], x, y, self.stat))
# XP and stat modification
self.data[0] += event.xp_earned
for index in range(len(event.stat)):
self.stat[index] += event.stat[index]
self.screen.display_text(event.text)
def _get_map(self, direction):
x, y = self._looked_case(direction)
current_map = self.data[2]
current_map = self.data[1]
if current_map:
if (x, y) == self.maps[current_map][2]:
@ -191,7 +200,7 @@ class Asci:
if (x, y) == self.maps[index][1]:
return index, self.maps[index][2][0] - 10, self.maps[index][2][1] - 3
return current_map, self.data[3], self.data[4]
return current_map, self.data[2], self.data[3]
def mainloop(self):
key = key_buffer = 0
@ -208,6 +217,14 @@ class Asci:
self._keyboard(key)
class Event:
def __init__(self, xp_earned, text, answer=0, *stat):
self.xp_earned = xp_earned
self.text = text
self.answer = answer
self.stat = stat
def convert(string):
try: return int(string)
except: return 0
@ -231,3 +248,14 @@ def text_formater(string, screen_width=21, screen_height=6):
lines = line_formater(string, screen_width).split("\n")
return paragraph_formater(lines, screen_height).split("\n\n")
def read_event(xp, event):
if type(event) == dict:
if xp in event: event = event[xp]
else: event = event["base"]
if type(event) != list:
raise TypeError("event is of type {} instead of list".format(type(event)))
return Event(*event)

View File

@ -1,4 +1,5 @@
from asci_lib import *
from random import randint
maps = (
r"""
@ -9,7 +10,7 @@ r"""
/_\ |^| *
__ __
## / \___/ \ ##
$ ## / \___/ \ ##
#### |<> <>| ####
## |___|^|___| ##
|| ||""",
@ -26,38 +27,77 @@ r"""
)
def get_dialogue(xp, pv, current_map, x, y, stat):
def get_dialogue(xp, current_map, x, y, stat):
coords = (x, y)
if current_map == 0:
if coords == (16, 1): return {
0: [1, "Hey, bienvenue dans la map de test d'Asci !", False],
1: [0, "Comment vas-tu aujourd'hui ? 1. Tres bien, merci ! Et vous-meme ? 2. La ferme le vieux ! ", True],
2: [4, "Je vais bien ^.^", False],
3: [0, "Oh, insultant personnage !", False],
0: [1, "Hey, bienvenue dans la map de test d'Asci !", 0],
1: [0, "Comment vas-tu aujourd'hui ? 1. Tres bien, merci ! Et vous-meme ? 2. La ferme le vieux ! ", 2],
2: [4, "Je vais bien, merci ! Voici une epee et une cote de maille.", 0, 0, 10, 10],
3: [0, "Oh, insultant personnage ! Pour la peine tu n'auras rien !", 0],
6: [0, "Belle journée, n'est-ce pas ?", False],
6: [1, "Belle journée, n'est-ce pas ? Dommage que ce brigand un peu au sud soit la...", 0],
8: [0, "Et bien je crois que c'est un test concluant !", 0],
"base": [0, "Bonjour, besoin d'aide ?", False],
"base": [0, "Bonjour, besoin d'aide ?", 0],
}
elif coords == (24, 4):
if pv >= 100: return [0, "Tsst, est-ce que je tape sur des gens moi ? Bah alors ? J'ai panse tes plaies, mais fait gaffe a toi...", False, 50]
else: return [0, "Tu es en pleine forme !", False]
if stat[0] < 100: return [0, "Tsst, est-ce que je tape sur des gens moi ? Bah alors ? J'ai panse tes plaies, mais fait gaffe a toi...", 0, 50]
else: return [0, "Tu es en pleine forme !", 0]
elif coords == (4, 7): return {
6: [2, "Tu as tue le brigand !", 0],
"base": [0, "Il n'y a rien a faire par ici..."]
}
elif current_map == 1:
if coords == (4, 3): return {
3: [0, "Tsst, tu as encore insulte quelqu'un ? 1. Oui... 2. Hein ? Quoi ?", True],
4: [0, "C'est pas tres malin, tu sais ?", False],
5: [0, "Je n'aime pas les menteurs. Sort de chez moi.", False],
3: [0, "Tsst, tu as encore insulte quelqu'un ? 1. Oui... 2. Hein ? Quoi ?", 2],
4: [0, "C'est pas tres malin, tu sais ?", 0],
5: [0, "Je n'aime pas les menteurs. Sort de chez moi.", 0],
"base": [0, "Oui ?", False]
}
return [0, "Hmmm ?", False]
def fight(xp, current_map, x, y, stat):
coords = (x, y)
if current_map == 0:
if coords == (4, 7):
if xp == 6:
enemy = [75, randint(0, 10), 0]
else:
return True
end = 1
while stat[0] > 0 and enemy[0] > 0:
player = stat[1] + randint(1, 5)
adv = enemy[1] + randint(1, 5)
if player > adv:
enemy[0] -= (player - enemy[2])
else:
stat[0] -= (adv - stat[2])
return stat[0] > 0
def display_stat(stat):
print("<*> Statistiques <*>")
print("Points de vie .: {}".format(stat[0]))
print("Points attaque : {}".format(stat[1]))
print("Points defense : {}".format(stat[2]))
def start():
my_game = Asci(maps, get_dialogue, 10, 0)
my_game = Asci(maps, get_dialogue, fight, display_stat, 10, [100, 0, 0])
my_game.mainloop()

45
rpg_maker/sample_1.py Normal file
View File

@ -0,0 +1,45 @@
from asci_lib import *
carte_monde = (
r"""
_ ###
/o\__ #####
| <>\ ###
|____| /_\
*
|==|==|==|==|==|==|==|""",)
def evenements(xp, carte_actuelle, x, y, stat):
coords = (x, y)
if carte_actuelle == 0:
if coords == (2, 5): return {
0: [0, "Mon bon monsieur, vous n'auriez pas quelques sous pour moi ? 1. He non mon brave... 2. Mais si, bien sur, tenez.", 2],
1: [2, "Radin !"],
# 0 réponse possibles, +0 PV, -1 Argent
2: [1, "Merci !", 0, 0, -1],
"base": [0, "Hmm ?"]
}
return [0, "Hmm ?"]
def combat(xp, carte_actuelle, x, y, stat):
pass
def affichage_stat(stat):
pv, argent = stat
print("Statistiques")
print("PV : {}".format(pv))
print("Argent : {}".format(argent))
def mon_jeu():
rpg_python = Asci(carte_monde, evenements, combat, affichage_stat, 4, [100, 5])
rpg_python.mainloop()

View File

@ -1,39 +1,76 @@
from asci_lib import *
carte_monde = (
cartes = (
r"""
_ ###
/o\__ #####
| <>\ ###
|____| /_\
|_ <>\ ###
|^|__| /_\
*
|==|==|==|==|==|==|==|""",)
|==|==|==|==|==|==|==|""",
(r"""
+--+--+--------+--+--+
| | | * | | *|
| + + + + |
| |
| + + + + |
+--/ \--------/ \--+
| |
+---|^|--------------+""",
(1, 3), (5, 7)
))
def dialogue(xp, pv, carte_actuelle, x, y, stat):
def evenements(xp, carte_actuelle, x, y, stat):
coords = (x, y)
if carte_actuelle == 0:
if coords == (2, 5): return {
0: [0, "Coucou ! Comment ca va ? 1. Ca va, et toi ? 2. Bof... 3. Je t'emmerde.", True],
1: [3, "Je vais bien, merci !", False],
2: [3, "Ow, desole...", False],
3: [4, "He, reviens quand tu sera de meilleure humeur !", False],
0: [0, "Hey ! J'ai entendu du bruit dans la maison, mais je n'ose pas rentrer... 1. Rien entendu. 2. Je vais jeter un oeil.", 2],
1: [3, "Etes-vous sourd ?"],
2: [1, "J'etais sur que vous m'ecouteriez !"],
4: [2, "Bon et bien, je crois bien que cette premiere carte s'est bien passee !", False],
5: [1, "Je vais y aller, appelle moi si tu as besoin ;)", False],
6: [1, "A pluche o/", False],
3: [2, "C'est la maison juste au nord."],
4: [0, "Enfin, vous entendez bien du bruit la ? Et si c'etait un voleur ? 1. Bon ok j'y vais. 2. Mais foutez moi la paix !", 2],
6: [0, "..."],
"base": [0, "Oui ?", False]
5: [2, "Soyez prudent !"],
12: [1, "J'etais sur d'avoir entendu un truc !"],
"base": [0, "Vous avez entendu quelque chose ?"]
}
return [0, "Hmm ?", False]
elif carte_actuelle == 1:
if coords == (9, 1): return {
7: [0, "Je crois que le voleur est dans la piece d'a cote... 1. Je vais regarder. 2. Debrouillez-vous !", 2],
8: [2, "Merci !"],
9: [0, "Pleutre ! Hors de ma vue !"],
11: [1, "Ah, merci !"],
"base": [0, "J'ai peur de sortir de cette piece"]
}
elif coords == (20, 1): return {
10: [1, "Ciel, je suis fait !"],
"base": [0, "File avant que je ne te detrousse !"]
}
return [0, "Hmm ?"]
def combat(xp, carte_actuelle, x, y, stat):
pass
def affichage_statistique(stat):
print("Statistiques :")
print("Points de Vie : {}".format(stat[0]))
def mon_jeu():
rpg_python = Asci(carte_monde, dialogue, 7, [])
rpg_python = Asci(cartes, evenements, combat, affichage_statistique, 13, [100])
rpg_python.mainloop()