Add an advanced exemple

This commit is contained in:
Shadow15510 2021-08-14 22:27:07 +02:00
parent f349f0b821
commit fcf9e44434
4 changed files with 283 additions and 72 deletions

201
README.md
View File

@ -299,4 +299,203 @@ La limite est à 13 xp comme on peut le voir sur l'arbre :
-0--+ +--5--7--+
+--2--3--+ +--9-X
```
les `X` symbolise les impasses.
les `X` symbolise les impasses.
Le fichier complet est disponible sous le nom `rpg_maker/sample_2.py`
#### Exemple de manipulation avancées
Maintenant que vous êtes bien chaud, on va commencer les choses sérieuses. Enfin "sérieuses" je vous propose de faire pas à pas un petit jeu avec disons une quête et quelques mécaniques un peu bidon (ça reste un exemple). On peut déjà poser quelques petits trucs :
- le joueur a des points de vie, d'attaque et de défense
- le scénario se résumera à une seule quête : tuer un adversaire. La quête peut être refusée.
On peut déjà rapidement voir à quoi va ressembler l'arbre d'XP (j'en fait pas mal et je vous invite à en faire aussi, ça aide vraiment à voir le déroulement de l'histoire) :
```
+--1--3--4--5-
-0--+
+--2-X
```
Pour expliquer rapidement :
- 0 : début de l'histoire, énoncé de la quête
- 1 : quête acceptée
- 2 : quête refusée
- 3 : combat avec le bandit
- 4 : debrief avec le PnJ
- 5 : fin de la partie (limite de l'XP pour le jeu)
Comme on est vraiment chaud, on va essayer de faire une map un peu plus joli que d'habitude avec des PnJ qui vont avoir des dialogues sans forcément avoir un rôle dans l'histoire, ça va être l'occasion de sortir un peu du modèle "1 PnJ = 1 dictionnaire d'évènements" et de vous rappeller que vous pouvez renvoyer un évènement seul.
Allez ! On est parti avec une map et deux maisons :
```
cartes = (
r"""
__
/ \___ ### *
|<> \ ##### _
|^|____| ### / \
/_\ |^| *
__ __
$ ## / \___/ \ ##
#### |<> <>| ####
## |___|^|___| ##
|| ||""",
(r"""
+--+--+--------+--+--+
| | | | | |
| + + + + |
| |
| + + + + |
+--/ *\--------/ \--+
| |
+---|^|--------------+""",
(1, 3), (5, 7)),
(r"""
+-------+
| |
| |
| |
+--|^|--+
""",
(19, 4), (4, 4))
)
```
On va commencer par faire le PnJ qui n'a pas un rôle énorme dans le scénario. On va faire un médecin (comme y a du combat, c'est pratique de mettre un medecin dans la place). L'idée est simple : si le joueur a moins de 100 points de vie, il est blessé, donc on lui rajoute des points de vie avec un texte. Si il est en pleine forme, on le lui signale et on ne touche pas aux points de vie.
On a donc la fonction qui ressemble à ça (je met des `...` au niveau des trucs pas encore définis):
```
def evenements(xp, carte_actuelle, x, y, stat):
coords = (x, y)
if carte_actuelle == 0:
if coords == (...):
# Joueur blessé
if stat[0] < 100: return [0, "Oh, mais tu es blesse !", 0, 50]
else: return [0, "Reviens me voir quand tu seras blesse."]
return [0, "Hmm ?"]
```
Comme il s'agit d'un personnage très secondaire (voir inutile) on peut prendre pour médecin le PnJ tout à l'est, aux coordonnées `(24, 4)`. On prend alors l'autre PnJ pour le personnage qui donne la quête au joueur (aux coordonnées `(16, 1)`)
On peut compléter notre fonction avec la proposition de la quête :
```
def evenements(xp, carte_actuelle, x, y, stat):
coords = (x, y)
if carte_actuelle == 0:
if coords == (24, 4):
if stat[0] < 100: return [0, "Oh, mais tu es blesse !", 0, 50]
else: return [0, "Reviens me voir quand tu seras blesse."]
elif coords == (16, 1): return {
"base": [0, "Alors ? T'en sorts-tu ?"],
0: [0, "J'ai une quete pour toi ! Un ami a moi a des problemes : un personnage louche traine autour de sa maison... Si tu pouvais l'en debarasser, il t'en serai reconnaissant. 1. Je m'en charge ! 2. Trouve quelqu'un d'autre.", 2],
1: [2, "J'etais sur que je pouvais compter sur toi ! Tiens, voila une dague et une petit bouclier.", 0, 0, 10, 10],
2: [2, "Si un jour tu as besoin de moi, tu seras sympa de m'oublier."],
3: [0, "Alors ? Il est mort ce bandit ?"],
4: [1, "Merci, tu as rendu un grand service a mon ami !"]
}
return [0, "Hmm ?"]
```
Maintenant il reste à programmer la fin du combat, en d'autre terme, si le joueur gagne le combat, la fonction `evenements` va être appelée, il faut donc renvoyer un petit texte qui signale que le combat est gagné et qui incrémente les points d'XP de 2 points (pour passer de 1 à 3). Le bandit est sur les coordonnées `(4, 7)`.
```
def evenements(xp, carte_actuelle, x, y, stat):
coords = (x, y)
if carte_actuelle == 0:
if coords == (24, 4):
if stat[0] < 100: return [0, "Oh, mais tu es blesse !", 0, 50]
else: return [0, "Reviens me voir quand tu seras blesse."]
elif coords == (16, 1): return {
"base": [0, "Alors ? T'en sorts-tu ?"],
0: [0, "J'ai une quete pour toi ! Un ami a moi a des problemes : un personnage louche traine autour de sa maison... Si tu pouvais l'en debarasser, il t'en serai reconnaissant. 1. Je m'en charge ! 2. Trouve quelqu'un d'autre.", 2],
1: [2, "J'etais sur que je pouvais compter sur toi ! Tiens, voila une dague et une petit bouclier.", 0, 0, 10, 10],
2: [2, "Si un jour tu as besoin de moi, tu seras sympa de m'oublier."],
3: [0, "Alors ? Il est mort ce bandit ?"],
4: [1, "Merci, tu as rendu un grand service a mon ami !"]
}
elif coords == (4, 7):
# Si le bandit vient d'être tué
if xp == 3: return [1, "Vous avez reussi la quete !"]
# Si le bandit est encore vivant
elif xp < 3: return [0, "Qu'est-ce que tu regardes toi ? Casses-toi !"]
# Si le bandit est déjà mort
else: return [0, "Vous regardez le cadavre froid du bandit."]
return [0, "Hmm ?"]
```
Il reste à faire une fonction pour les combats !
Le principe est simple, la fonction va regarder de quel bandit il s'agit, si c'est le moment du combat, la fonction va lancer le combat, sinon elle déclare le combat gagnée ce qui va déclencher la fonction `evenements` (donc afficher le texte prévu juste avant)
```
def combats(xp, carte_actuelle, x, y, stat):
coords = (x, y)
if carte_actuelle == 0:
if coords == (4, 7):
if xp == 3: ennemi_stat = [75, randint(5, 10), randint(5, 10)]
else: return True
defense_temporaire = defense_temporaire_ennemi = 0
while stat[0] > 0 and ennemi_stat[0] > 0:
print("Vos PV : {0}\nPV ennemi : {1}".format(stat[0], ennemi_stat[0]))
print("<*> Actions <*>")
print("1. Attaquer")
print("2. Defendre")
action = int(input(">"))
defense_temporaire = 0
if action == 1:
pv = (stat[1] - ennemi_stat[2] - defense_temporaire_ennemi) + randint(-5, 10)
if pv < 0: pv = 0
ennemi_stat[0] -= pv
elif action == 2:
defense_temporaire = randint(1, 5)
defense_temporaire_ennemi = 0
if randint(1, 2) == 1:
pv = (ennemi_stat[1] - stat[2] - defense_temporaire) + randint(-5, 10)
if pv < 0: pv = 0
stat[0] -= pv
else:
defense_temporaire_ennemi = randint(1, 5)
return stat[0] > 0
```
Il reste à faire la fonction d'affichage des statistiques et la petite fonction d'appel :
```
def affichage_stat(stat):
pv, pa, pd = stat
print("<*> Statistiques <*>")
print("Points de vie .: {}".format(pv))
print("Points attaque : {}".format(pa))
print("Points defense : {}".format(pd))
```
et :
```
def mon_jeu():
rpg_python = Asci(cartes, evenements, combats, affichage_stat, 5, [100, 0, 0])
rpg_python.mainloop()
```
Vous pouvez retrouver le fichier complet dans `rpg_maker/sample_3.py`

View File

@ -1,17 +1,10 @@
class Screen:
def __init__(self, world, screen_width=21, screen_height=6):
def __init__(self, screen_width=21, screen_height=6):
# Screen configuration
self.screen_width = screen_width
self.screen_height = screen_height
self._data = [[" " for _ in range(screen_width)] for _ in range(screen_height)]
# Load map data
self.set_world(world)
def clear_data(self):
self._data = [[" " for _ in range(self.screen_width)] for _ in range(self.screen_height)]
def clear(self):
print("\n" * self.screen_height)
@ -43,7 +36,8 @@ class Screen:
if paragraph:
self.clear()
print(paragraph)
return input(">")
last_input = input(">")
return last_input
def get_cell(self, x, y):
return self._data[y][x]
@ -71,7 +65,8 @@ class Asci:
self._game_stat = fn_stat
# Screen configuration
self.screen = Screen(maps[data[2]], screen_width, screen_height)
self.screen = Screen(screen_width, screen_height)
self.screen.set_world(maps[data[2]])
self.map_width, self.map_height = self.screen.get_map_size()
def _looked_case(self, direction):
@ -205,7 +200,7 @@ class Asci:
def mainloop(self):
key = key_buffer = 0
while key != 9 and self.stat[0] > 0 and self.data[0] < self.end_game:
self.screen.clear_data()
# self.screen.clear_data()
self.screen.set_data(self.data[-2:])
self.screen.set_cell(10, 3, "@")

View File

@ -22,8 +22,8 @@ r"""
+--/ \--------/ \--+
| |
+---|^|--------------+""",
(1, 3), (5, 7)
))
(1, 3), (5, 7))
)
def evenements(xp, carte_actuelle, x, y, stat):

View File

@ -1,7 +1,8 @@
from asci_lib import *
from random import randint
maps = (
cartes = (
r"""
__
/ \___ ### *
@ -16,89 +17,105 @@ r"""
|| ||""",
(r"""
+------------------------------+
| |
| |
| * |
| |
| |
+--|^|-------------------------+
""", (1, 3), (4, 6))
+--+--+--------+--+--+
| | | | | |
| + + + + |
| |
| + + + + |
+--/ *\--------/ \--+
| |
+---|^|--------------+""",
(1, 3), (5, 7)),
(r"""
+-------+
| |
| |
| |
+--|^|--+
""",
(19, 4), (4, 4))
)
def get_dialogue(xp, current_map, x, y, stat):
def evenements(xp, carte_actuelle, 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 !", 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],
if carte_actuelle == 0:
if coords == (24, 4):
if stat[0] < 100: return [0, "Oh, mais tu es blesse !", 0, 50]
else: return [0, "Reviens me voir quand tu seras blesse."]
6: [1, "Belle journée, n'est-ce pas ? Dommage que ce brigand un peu au sud soit la...", 0],
elif coords == (16, 1): return {
"base": [0, "Alors ? T'en sorts-tu ?"],
8: [0, "Et bien je crois que c'est un test concluant !", 0],
"base": [0, "Bonjour, besoin d'aide ?", 0],
}
0: [0, "J'ai une quete pour toi ! Un ami a moi a des problemes : un personnage louche traine autour de sa maison... Si tu pouvais l'en debarasser, il t'en serai reconnaissant. 1. Je m'en charge ! 2. Trouve quelqu'un d'autre.", 2],
1: [2, "J'etais sur que je pouvais compter sur toi ! Tiens, voila une dague et une petit bouclier.", 0, 0, 10, 10],
2: [2, "Si un jour tu as besoin de moi, tu seras sympa de m'oublier."],
elif coords == (24, 4):
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..."]
3: [0, "Alors ? Il est mort ce bandit ?"],
4: [1, "Merci, tu as rendu un grand service a mon ami !"]
}
elif coords == (4, 7):
# Si le bandit vient d'être tué
if xp == 3: return [1, "Vous avez reussi la quete !"]
elif current_map == 1:
if coords == (4, 3): return {
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],
# Si le bandit est encore vivant
elif xp < 3: return [0, "Qu'est-ce que tu regardes toi ? Casses-toi !"]
"base": [0, "Oui ?", False]
}
# Si le bandit est déjà mort
else: return [0, "Vous regardez le cadavre froid du bandit."]
return [0, "Hmmm ?", False]
return [0, "Hmm ?"]
def fight(xp, current_map, x, y, stat):
def combats(xp, carte_actuelle, x, y, stat):
coords = (x, y)
if current_map == 0:
if carte_actuelle == 0:
if coords == (4, 7):
if xp == 6:
enemy = [75, randint(0, 10), 0]
else:
return True
if xp == 3: ennemi_stat = [75, randint(5, 10), randint(5, 10)]
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)
defense_temporaire = defense_temporaire_ennemi = 0
while stat[0] > 0 and ennemi_stat[0] > 0:
if player > adv:
enemy[0] -= (player - enemy[2])
print("Vos PV : {0}\nPV ennemi : {1}".format(stat[0], ennemi_stat[0]))
print("<*> Actions <*>")
print("1. Attaquer")
print("2. Defendre")
action = int(input(">"))
defense_temporaire = 0
if action == 1:
pv = (stat[1] - ennemi_stat[2] - defense_temporaire_ennemi) + randint(-5, 10)
if pv < 0: pv = 0
ennemi_stat[0] -= pv
elif action == 2:
defense_temporaire = randint(1, 5)
defense_temporaire_ennemi = 0
if randint(1, 2) == 1:
pv = (ennemi_stat[1] - stat[2] - defense_temporaire) + randint(-5, 10)
if pv < 0: pv = 0
stat[0] -= pv
else:
stat[0] -= (adv - stat[2])
defense_temporaire_ennemi = randint(1, 5)
return stat[0] > 0
def affichage_stat(stat):
pv, pa, pd = stat
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]))
print("Points de vie .: {}".format(pv))
print("Points attaque : {}".format(pa))
print("Points defense : {}".format(pd))
def start():
my_game = Asci(maps, get_dialogue, fight, display_stat, 10, [100, 0, 0])
my_game.mainloop()
def mon_jeu():
rpg_python = Asci(cartes, evenements, combats, affichage_stat, 5, [100, 0, 0])
rpg_python.mainloop()