import random import cli import time import getkey import sqlite3 class Animation: """ class de gestion des animations du personnage""" def __init__(self, x, y, shape): self.x = x self.y = y self.shape = shape self.state = 'right' def blink(self, start_color, end_color): """ Fait clignoter le calque""" self.layer = cli.Layer(gui, self.x, self.y, self.shape[0].split('\n')) for i in range(8): self.layer.refresh() if i % 2 == 0: self.display(self.state, color=start_color) else: self.display(self.state, color=end_color) gui.display() time.sleep(0.2) del self.layer def display(self, side, **kwargs): """affiche le personnage""" self.state = side if side == 'right': cuted_shape = self.shape[0].split('\n') else: cuted_shape = self.shape[1].split('\n') for i in range(len(cuted_shape)): for key, value in kwargs.items(): if key == 'color': gui.draw(cuted_shape[i], self.x, self.y + i, color=value) def move(self, x, y, speed, **kwargs): """le fait bouger selon x et y""" self.layer = cli.Layer(gui, self.x, self.y, self.shape[0].split('\n')) colori = 'WHITE' for key, value in kwargs.items(): if key == 'color': colori = value try: direction = x // abs(x) * speed except: direction = 1 for i in range(0, x, direction): self.x += direction self.layer.refresh() self.layer.x += direction self.display(self.state, color=colori) gui.display() time.sleep(0.3) try: direction = y // abs(y) * speed except: direction = 1 for i in range(0, y, direction): self.y += direction self.layer.refresh() self.layer.y += direction self.display(self.state, color=colori) gui.display() time.sleep(0.3) del self.layer class Personnage(Animation): """Class de base du personnage""" def __init__(self, nom, x, y, categorie, xp=1, bot=False): self.bot = bot if not self.bot: conn = sqlite3.connect('bdd.db') c = conn.cursor() c.execute("SELECT * from Personnage join Categorie on Personnage.categorie=Categorie.name join Profil on Categorie.profil=Profil.name where Personnage.name = ?", (nom,)) data = c.fetchone() if data is None: c.execute("insert into Personnage(name, pdv, xp, max_pdv, potion, categorie) Values(?, ?, ?, ?, ?, ?) ", (nom, "20", str(xp), "20", "2", categorie)) conn.commit() c.execute("SELECT * from Personnage join Categorie on Personnage.categorie=Categorie.name join Profil on Categorie.profil=Profil.name where Personnage.name = ?", (nom,)) data = c.fetchone() conn.close() # Affectation du résultat de la requête aux attributs correspondants self.nom = nom self.pdv = data[1] self.xp = data[2] self.max_pdv = data[3] self.weapon = data[7] self.coef_attack = data[8] self.coef_defense = data[9] self.class_name = data[11].split('\n') self.shape = [data[13].replace('%', '\n'), data[14].replace('%', '\n')] self.potion = data[5] else: # récupération des attributs de la catégorie conn = sqlite3.connect('bdd.db') c = conn.cursor() c.execute("SELECT * from Categorie join Profil on Categorie.profil=Profil.name where Categorie.name = ?", (categorie,)) data = c.fetchone() conn.close() self.nom = nom self.pdv = 20 self.xp = xp self.max_pdv = 20 self.weapon = data[1] self.coef_attack = data[2] self.coef_defense = data[3] self.class_name = data[5].split('\n') self.shape = [data[7].replace('%', '\n'), data[8].replace('%', '\n')] self.potion = 2 self.x = x self.y = y super().__init__(self.x, self.y, self.shape) def jet_attaque(self): return random.randint(1, 20) + self.xp * self.coef_attack def jet_defense(self): return random.randint(1, 20) + self.xp * self.coef_defense def change_xp(self, nb_xp): self.xp += nb_xp if not self.bot: conn = sqlite3.connect('bdd.db') c = conn.cursor() c.execute("UPDATE Personnage SET xp=? where name=?", (self.xp, self.nom)) conn.commit() c.close() def change_pdv(self, nb_pdv): self.pdv += nb_pdv if not self.bot: conn = sqlite3.connect('bdd.db') c = conn.cursor() c.execute("UPDATE Personnage SET pdv=? where name=?", (self.pdv, self.nom)) conn.commit() c.close() def change_max_pdv(self, pdv): self.max_pdv = pdv if not self.bot: conn = sqlite3.connect('bdd.db') c = conn.cursor() c.execute("UPDATE Personnage SET max_pdv=? where name=?", (self.max_pdv, self.nom)) conn.commit() c.close() def add_potion(self): """ Ajoute une potion à l'invetaire et à la base de donnée""" self.potion += 1 if not self.bot: conn = sqlite3.connect('bdd.db') c = conn.cursor() c.execute("UPDATE Personnage SET potion=? WHERE name=?", (self.potion, self.nom)) c.close() def remove_potion(self): """ Enlève une potion à l'invetaire et à la base de donnée""" self.potion -= 1 if not self.bot: conn = sqlite3.connect('bdd.db') c = conn.cursor() c.execute("UPDATE Personnage SET potion=? WHERE name=?", (self.potion, self.nom)) conn.commit() c.close() class App: def __init__(self): self.width = 120 self.height = 37 self.character = 0 self.potion_shape = """ _____ `.___,' (___) < > ) ( /`-.\\ / \\ / _ _\\ :,' `-.' `: | | : ; \\ / `.___.' """.split('\n') self.opponent = [Personnage("Guerrier", 80, 45, "guerrier", 1, True), Personnage("Voleur", 80, 45, "voleur", 1, True), Personnage("Magicien", 80, 45, "magicien", 1, True), Personnage("Elfe", 80, 45, "elfe", 1, True)] self.title = """ ██ ███████ ██ ██ ██████ ███████ ██████ ██████ ██ ███████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ █████ ██ ██ ██ ██ █████ ██████ ██ ██ ██ █████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ █████ ███████ ██████ ██████ ███████ ██ ██ ██████ ███████ ███████ """.split('\n') def draw_arena(self, ennemi, choice): """Dessine toute l'arène et les joueur durant la phase jeu""" gui.wipe() self.character.display('right', color='BLUE') self.opponent[ennemi].display('left', color='GREEN') gui.draw_bar(self.character.pdv * 100 // self.character.max_pdv, 5, 25, 30, color='RED') gui.draw_bar(self.character.xp * 100 // 20, 5, 27, 30, color='GREEN') gui.draw(self.character.nom, 15, 2, weight='BOLD') gui.draw(str(self.character.pdv), 38, 25, color='RED') gui.draw(str(self.character.xp), 38, 27, color='GREEN') gui.draw_bar(self.opponent[ennemi].pdv * 100 // self.opponent[ennemi].max_pdv, 75, 25, 30, color='RED') gui.draw_bar(self.opponent[ennemi].xp * 100 // 20, 75, 27, 30, color='GREEN') gui.draw(self.opponent[ennemi].nom, 90, 2) gui.draw(str(self.opponent[ennemi].pdv), 108, 25, color='RED') gui.draw(str(self.opponent[ennemi].xp), 108, 27, color='GREEN') gui.draw(''.join(['_' for i in range(self.width)]), 0, 28) gui.draw('Attaquer', 5, 30) gui.draw('Inventaire', 5, 31) gui.draw('Quiter', 5, 32) gui.draw('->', 2, 30 + choice) gui.display() def show_inventory(self, position): """Dessine l'inventaire""" gui.wipe() gui.draw("Pressez échape pour sortir de l'inventaire", 45, 0) gui.draw('+' + ''.join(['-' for i in range(self.width-2)]) + '+', 0, 1) gui.draw('+' + ''.join(['-' for i in range(self.width-2)]) + '+', 0, self.height-2) for i in range(1, self.height-3): if i == 16: gui.draw(''.join(['+'+''.join(['-' for j in range(29)]) for k in range(4)]), 0, 1+i) else: gui.draw(''.join(['|'+''.join([' ' for j in range(29)]) for k in range(4)]), 0, 1+i) for j in range(self.character.potion): x = j % 4 y = j // 4 if [x, y] == position: color_fill = 'YELLOW' else: color_fill = 'WHITE' gui.draw('Cidre fermier', 30*x+10, 17*y+2, color=color_fill) for i in range(len(self.potion_shape)): gui.draw(self.potion_shape[i], 30*x+6, 17*y+3+i, color=color_fill) gui.display() def combat(self, ennemi): """Simule l'attaque des joeurs""" # attaque du joueur if self.character.jet_attaque() > self.opponent[ennemi].jet_defense(): self.opponent[ennemi].change_pdv(-1*random.randint(1, 8)) self.opponent[ennemi].blink('RED', 'GREEN') # test si l'ennemi est mort if self.opponent[ennemi].pdv <= 0: self.opponent[ennemi].move(40, 0, 4) self.character.change_xp(1) self.character.change_max_pdv(self.character.max_pdv + 5) self.character.change_pdv(round(self.character.max_pdv * 0.2)) if random.randint(0,5) == 0: self.character.add_potion() ennemi = random.randint(0, 3) cat = ['guerrier', 'elfe', 'magicien', 'voleur'] self.opponent[ennemi].__init__(self.opponent[ennemi].nom, 120, 5, cat[ennemi], random.randint(max(1, self.character.xp - 2), self.character.xp+1), True) self.opponent[ennemi].change_max_pdv(20 + 5 * (self.opponent[ennemi].xp-1)) self.opponent[ennemi].change_pdv(self.opponent[ennemi].max_pdv - self.opponent[ennemi].pdv) self.opponent[ennemi].move(-40, 0, 4) return ennemi else: self.character.change_pdv(-1*random.randint(1, 4)) self.character.blink('RED', 'BLUE') # test si le joueur est toujours en vie if self.character.pdv <= 0: return None # attaque de l'ennemi if self.opponent[ennemi].jet_attaque() < self.character.jet_defense(): self.opponent[ennemi].change_pdv(-1*random.randint(1, 4)) self.opponent[ennemi].blink('RED', 'GREEN') # test si l'ennemi est mort if self.opponent[ennemi].pdv <= 0: self.opponent[ennemi].move(40, 0, 4) self.character.change_xp(1) self.character.change_max_pdv(self.character.max_pdv + 5) self.character.change_pdv(round(self.character.max_pdv * 0.2)) if random.randint(0,5) == 0: self.character.add_potion() ennemi = random.randint(0, 3) cat = ['guerrier', 'elfe', 'magicien', 'voleur'] self.opponent[ennemi].__init__(self.opponent[ennemi].nom, 120, 5, cat[ennemi], random.randint(max(self.character.xp - 3, 1), self.character.xp+1), True) self.opponent[ennemi].change_max_pdv(20 + 5 * (self.opponent[ennemi].xp-1)) self.opponent[ennemi].change_pdv(self.opponent[ennemi].max_pdv - self.opponent[ennemi].pdv) self.opponent[ennemi].move(-40, 0, 4) return ennemi else: self.character.change_pdv(-1*random.randint(1, 8)) self.character.blink('RED', 'BLUE') # test si le joueur est toujours en vie if self.character.pdv <= 0: return None def play(self): """Gère la phase de jeu""" gui.wipe() self.character.move(-40, 0, 4, color='BLUE') ennemi = random.randint(0, 3) self.opponent[ennemi].xp = random.randint(max(1, self.character.xp-3), self.character.xp + 1) self.opponent[ennemi].change_max_pdv(20 + 5 * (self.opponent[ennemi].xp-1)) self.opponent[ennemi].pdv = self.opponent[ennemi].max_pdv self.opponent[ennemi].move(0, -40, 4, color='GREEN') choice = 0 while self.character.pdv > 0: self.draw_arena(ennemi, choice) while True: key = getkey.getkey() if key == getkey.keys.UP: choice = abs((choice-1) %3) break elif key == getkey.keys.DOWN: choice = abs((choice+1) %3) break elif key == getkey.keys.ENTER: if choice == 0: # combat result = self.combat(ennemi) if result != None: ennemi = result if choice == 1: # affichage de l'inventaire position = [0, 0] while True: self.show_inventory(position) key = getkey.getkey() if key == getkey.keys.UP: if position[1] > 0: position[1] -= 1 elif key == getkey.keys.DOWN: if position[1] < 1: position[1] += 1 elif key == getkey.keys.RIGHT: if position[0] < 3: position[0] += 1 elif key == getkey.keys.LEFT: if position[0] > 0: position[0] -= 1 elif key == getkey.keys.ENTER: if self.character.potion > 0: self.character.change_pdv(round((self.character.max_pdv - self.character.pdv) * 0.5)) if self.character.pdv > self.character.max_pdv: self.character.change_pdv(self.character.max_pdv - self.character.pdv) self.character.remove_potion() elif key == getkey.keys.ESCAPE: break if choice == 2: exit() break # le joueur à perdu gui.wipe() #suppression du joueur de la bdd conn = sqlite3.connect('bdd.db') c = conn.cursor() c.execute("DELETE FROM Personnage where name=?", (self.character.nom,)) conn.commit() c.close() game_over = """ ██████ █████ ███ ███ ███████ ██████ ██ ██ ███████ ██████ ██ ██ ██ ████ ████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ███ ███████ ██ ████ ██ █████ ██ ██ ██ ██ █████ ██████ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██████ ██ ██ ██ ██ ███████ ██████ ████ ███████ ██ ██ """.split('\n') for i in range(len(game_over)): gui.draw(game_over[i], 60 - len(game_over[i])//2, 12+i, color='RED') gui.display() def setting(self, name, number_char): """permet de choisir son type de personnage""" gui.wipe() characters = [Personnage(name, 0, 5, "guerrier", 1, True), Personnage(name, 0, 5, "voleur", 1, True), Personnage(name, 0, 5, "magicien", 1, True), Personnage(name, 0, 5, "elfe", 1, True)] for char in characters: char.x = 60 - len(char.shape[0].split('\n')[0])//2 for i in range(len(characters[number_char].class_name)): gui.draw(characters[number_char].class_name[i], 60-(len(characters[number_char].class_name[0])//2), 25+i, color='RED', weight='BOLD') for i in range(2): gui.draw('/', 4-i, 17+i) gui.draw('\\', 4-i, 20-i) gui.draw('\\', -4+i, 17+i) gui.draw('/', -4+i, 20-i) characters[number_char].display('right', color='BLUE') gui.draw('Utilisez les flèche pour changer de personnage puis appuyez sur entrée', 30, 1) gui.display() while True: key = getkey.getkey() if key == getkey.keys.RIGHT: self.setting(name, (number_char+1) % 4) break elif key == getkey.keys.LEFT: self.setting(name, (number_char-1) % 4) break elif key == getkey.keys.ENTER: self.character = Personnage(name, 0, 5, ['guerrier', 'voleur', 'magicien', 'elfe'][number_char]) self.character.x = 60 - len(self.character.shape[0].split('\n')[0])//2 del characters self.play() break def menu(self): """permet de choisir son nom""" for i in range(len(self.title)): gui.draw(self.title[i], 60 - len(self.title[0]) //2, 10+i) gui.draw('>', 40, 30, color='RED') gui.draw(' Taper votre nom et presser entrée ', 41, 30, weight='BOLD') gui.draw('<', 76, 30, color='RED') gui.display() name = input('=>') # test si le joueur à déjà joué conn = sqlite3.connect("bdd.db") c = conn.cursor() c.execute("SELECT * from Personnage join Categorie on Personnage.categorie=Categorie.name join Profil on Categorie.profil=Profil.name where Personnage.name = ?", (name,)) data = c.fetchone() c.close() if data is None: self.setting(name, 0) else: self.character = Personnage(name, 0, 5, data[4]) self.character.x = 60 - len(self.character.shape[0].split('\n')[0])//2 self.play() app = App() gui = cli.Cli(width=app.width, height=app.height) app.menu()