[PYTHON] [Fiche d'apprentissage] Créez un mystérieux jeu de donjon avec Pyhton's Tkinter

Je veux faire quelque chose qui fonctionne avec python! J'ai pensé: " Introduction au développement de jeux avec Python " ( Practice ).

Pourquoi le tkinter de python → Mon objectif ultime n'est pas le développement de jeux, mais la collecte de données telles que le scraping, l'analyse de données et l'efficacité opérationnelle. Par conséquent, C ++ ou Unity adapté au développement de jeux? Créez plutôt un jeu avec python. La même raison n'utilise pas la bibliothèque pygame.

Même si j'étudie le scraping, l'analyse de données et l'apprentissage automatique avec précision, je ne peux penser à aucune méthode d'application pour le moment, c'est donc un détour, mais j'ai l'âme d'apprendre la programmation tout en créant un jeu. Je suis impatient d'intégrer l'apprentissage automatique et l'apprentissage en profondeur pour faire évoluer NCP et acquérir une expérience pratique dans ce domaine.

Depuis que j'ai pu apprendre dans une certaine mesure, j'ai essayé de faire quelque chose comme un mystérieux jeu de donjon en me référant à l'exemple de code (ou plutôt en remodelant).
Beaucoup de gens pensent aux épreuves de Kazerai et Torneko, mais quand je pense à un donjon mystérieux, je pense au mystérieux donjon de Chocobo. (Le reste est Terry's Wonderland?) En fin de compte, je veux faire quelque chose de similaire à Chocobo.
Pour le moment, github .
La puce de personnage a été empruntée à Pipoya Warehouse . Je l'ai divisé en maze_maker.py, qui génère automatiquement une carte, et tkmaze.py, qui est le corps principal du jeu.

maze_maker.py



import random

class maze_maker:
    """
Générer automatiquement un donjon
    """

    def __init__(self,MAZE_W,MAZE_H):
        self.MAZE_W = MAZE_W
        self.MAZE_H = MAZE_H
        self.maze = [[0]*self.MAZE_W for y in range(self.MAZE_H)]
        self.DUNGEON_W = MAZE_W*3
        self.DUNGEON_H = MAZE_H*3
        self.dungeon = [[0]*self.DUNGEON_W for y in range(self.DUNGEON_H)]

    def make_maze(self):
        """
Faire un labyrinthe
        """
        XP = [ 0, 1, 0,-1]
        YP = [-1, 0, 1, 0]

        #Piliers environnants
        for x in range(self.MAZE_W):
            self.maze[0][x] = 1
            self.maze[self.MAZE_H-1][x] = 1
        for y in range(self.MAZE_H):
            self.maze[y][0] = 1
            self.maze[y][self.MAZE_W-1] = 1

        #Vide à l'intérieur
        for y in range(1,self.MAZE_H-1):
            for x in range(1,self.MAZE_W-1):
                self.maze[y][x] = 0

        #Pilier
        for y in range(2,self.MAZE_H-2,2):
            for x in range(2,self.MAZE_W-2,2):
                self.maze[y][x] = 1

        for y in range(2,self.MAZE_H-2,2):
            for x in range(2,self.MAZE_W-2,2):
                d = random.randint(0,3)
                if x > 2:
                    d = random.randint(0,2)
                self.maze[y+YP[d]][x+XP[d]] = 1

    def make_dungeon(self):
        """
Faire un donjon à partir d'un labyrinthe
        """
        self.make_maze()
        for y in range(self.DUNGEON_H):
            for x in range(self.DUNGEON_W):
                self.dungeon[y][x] = 9
        for y in range(1,self.MAZE_H-1):
            for x in range(1,self.MAZE_W-1):
                dx = x*3+1
                dy = y*3+1
                if self.maze[y][x] == 0:
                    if random.randint(0,99) < 20:
                        for ry in range(-1,2):
                            for rx in range(-1,2):
                                self.dungeon[dy+ry][dx+rx] = 0
                    else:
                        self.dungeon[dy][dx] = 0
                        if self.maze[y-1][x] == 0:
                            self.dungeon[dy-1][dx] = 0
                        if self.maze[y+1][x] == 0:
                            self.dungeon[dy+1][dx] = 0
                        if self.maze[y][x-1] == 0:
                            self.dungeon[dy][dx-1] = 0
                        if self.maze[y][x+1] == 0:
                            self.dungeon[dy][dx+1] = 0


    def put_event(self):
        while True:
            x = random.randint(3,self.DUNGEON_W-4)
            y = random.randint(3,self.DUNGEON_H-4)
            if(self.dungeon[y][x] == 0):
                for ry in range(-1,2):
                    for rx in range(-1,2):
                        self.dungeon[y+ry][x+rx] = 0
                self.dungeon[y][x] = 1
                break
        for i in range(60):
            x = random.randint(3,self.DUNGEON_W-4)
            y = random.randint(3,self.DUNGEON_H-4)
            if(self.dungeon[y][x] == 0):
                self.dungeon[y][x] = random.choice([2,3,3,3,4])


tkmaze.py


"""
Recherchez un sol sombre dans le sol sombre. C'est un voyage sans fin. Il n'y a pas de but, et je descends simplement les escaliers en évitant l'ennemi.
Compte de score pour chaque étape. De plus lorsque vous descendez les escaliers. Visez un score élevé!
"""
import tkinter
import maze_maker
from PIL import Image,ImageTk
import random

#Entrée clé
key = ''
koff = False
def key_down(e):
    global key,koff
    key = e.keysym
    koff = False

def key_up(e):
    global koff
    koff = True

CHIP_SIZE = 32
DIR_UP = 3
DIR_DOWN = 0
DIR_LEFT = 1
DIR_RIGHT = 2
chara_x = chara_y = 146
chara_d = chara_a = 0
obj_a = 0
emy_num = 4
emy_list_x = [0]*emy_num
emy_list_y = [0]*emy_num
emy_list_d = [0]*emy_num
emy_list_a = [0]*emy_num
ANIMATION = [1,0,1,2]
#Le matériel est "Pipoya http://blog.pipoya.net/De
imgplayer_pass = 'image/charachip01.png'
emy_img_pass = 'image/pipo-charachip019.png'
emy2_img_pass = 'image/hone.png'
emy3_img_pass = 'image/majo.png'
emy3_kageimg_pass = 'image/majo_kage.png'
takara_img_pass = 'image/pipoya_mcset1_obj01.png'
obj_pass = 'image/pipoya_mcset1_obj02.png'
obj2_pass = 'image/pipo-hikarimono005.png'
yuka_pass = 'image/pipoya_mcset1_at_gravel1.png'
kebe_pass = 'image/pipoya_mcset1_bridge01.png'

map_data = maze_maker.maze_maker(11,7)
map_data.make_dungeon()
map_data.put_event()

tmr = 0
idx = 1
floor_count = 0
item_count = 0
pl_life=150
pl_stamina = 150
pl_damage = 0

def move_player():
    global chara_x,chara_y,chara_a,chara_d,pl_stamina,pl_life
    if key == 'Up':
        chara_d = DIR_UP
        check_wall()
    if key == 'Down':
        chara_d = DIR_DOWN
        check_wall()
    if key == 'Left':
        chara_d = DIR_LEFT
        check_wall()
    if key == 'Right':
        chara_d = DIR_RIGHT
        check_wall()
    check_event()
    if tmr%4 == 0:
        if pl_stamina > 0:
            pl_stamina -= 1
        else:
            pl_life -= 1
            if pl_life <= 0:
                pl_life = 0
                idx = 2
    chara_a = chara_d*3 + ANIMATION[tmr%4]


def emy_set(emy_num):
    while True:
        x = random.randint(3,map_data.DUNGEON_W-4)
        y = random.randint(3,map_data.DUNGEON_H-4)
        if map_data.dungeon[y][x] == 0:
            emy_list_x[emy_num] = x*CHIP_SIZE+(CHIP_SIZE//2)
            emy_list_y[emy_num] = y*CHIP_SIZE+(CHIP_SIZE//2)
            break


def draw_text(txt):
    st_fnt = ('Times New Roman',60)
    canvas.create_text(200,200,text=txt,font=st_fnt,fill='red',tag='SCREEN')


def damage_cal(pl_damage):
    global pl_life,idx
    if pl_life <= pl_damage:
        pl_life = 0
        idx = 2
    else:
        pl_life -= pl_damage


def move_emy(emy_num):
    cy = int(emy_list_y[emy_num]//CHIP_SIZE)
    cx = int(emy_list_x[emy_num]//CHIP_SIZE)
    emy_list_d[emy_num] = random.randint(0,3)
    if emy_list_d[emy_num] == DIR_UP:
        if map_data.dungeon[cy-1][cx] != 9:
            emy_list_y[emy_num] -= 32
    if emy_list_d[emy_num] == DIR_DOWN:
        if map_data.dungeon[cy+1][cx] != 9:
            emy_list_y[emy_num] += 32
    if emy_list_d[emy_num] == DIR_LEFT:
        if map_data.dungeon[cy][cx-1] != 9:
            emy_list_x[emy_num] -= 32
    if emy_list_d[emy_num] == DIR_RIGHT:
        if map_data.dungeon[cy][cx+1] != 9:
            emy_list_x[emy_num] += 32
    emy_list_a[emy_num] = emy_list_d[emy_num]*3 + ANIMATION[tmr%4]
    if abs(emy_list_x[emy_num]-chara_x) <= 30 and abs(emy_list_y[emy_num]-chara_y) <= 30:
        pl_damage = 10*random.choice([1,2,2,3,3])
        damage_cal(pl_damage)


def obj_animation():
    global obj_a
    obj_a = ANIMATION[tmr%4]


def check_wall():
    global chara_x,chara_y,chara_a,chara_d
    cy = int(chara_y//CHIP_SIZE)
    cx = int(chara_x//CHIP_SIZE)
    if chara_d == DIR_UP:
        if map_data.dungeon[cy-1][cx] != 9:
            chara_y -= 32
    if chara_d == DIR_DOWN:
        if map_data.dungeon[cy+1][cx] != 9:
            chara_y += 32
    if chara_d == DIR_LEFT:
        if map_data.dungeon[cy][cx-1] != 9:
            chara_x -= 32
    if chara_d == DIR_RIGHT:
        if map_data.dungeon[cy][cx+1] != 9:
            chara_x += 32

def check_event():
    global chara_x,chara_y,chara_a,chara_d,idx,pl_damage
    global floor_count,emy_count,item_count,pl_life,pl_stamina
    cy = int(chara_y//CHIP_SIZE)
    cx = int(chara_x//CHIP_SIZE)
    if map_data.dungeon[cy][cx] == 1:
        #Monter sur le cercle magique de Warp
        map_data.make_dungeon()
        map_data.put_event()
        emy_set(0)
        emy_set(1)
        emy_set(2)
        floor_count += 1
        chara_x = chara_y = 146
    if map_data.dungeon[cy][cx] == 2:
        #Monter sur le cercle magique des pièges
        if item_count > 0:
            item_count -= 1
            map_data.dungeon[cy][cx] = 0
        else:
            pl_damage = 5*random.choice([1,2,2,3,4,3])
            damage_cal(pl_damage)
            map_data.dungeon[cy][cx] = 0
    if map_data.dungeon[cy][cx] == 3:
        #Contactez l'article
        item_count += 1
        map_data.dungeon[cy][cx] = 0
    if map_data.dungeon[cy][cx] == 4:
        #Contact avec la nourriture
        pl_stamina_recover = 5*random.choice([1,2,2,3,4,3])
        if pl_stamina + pl_stamina_recover > 150:
            pl_stamina = 150
        else:
            pl_stamina += pl_stamina_recover
        map_data.dungeon[cy][cx] = 0


def split_chip(chip_pass,chip_img_x,chip_img_y):
    '''
Divisez plusieurs jetons en une seule unité
    '''
    chip_list = []
    for cy in range(0,chip_img_y,CHIP_SIZE):
        for cx in range(0,chip_img_x,CHIP_SIZE):
            chip_list.append(ImageTk.PhotoImage(Image.open(chip_pass).crop((cx,cy,cx+CHIP_SIZE,cy+CHIP_SIZE))))
    return chip_list


def draw_screen():
    st_fnt = ('Times New Roman',30)
    canvas.delete('SCREEN')
    for my in range(len(map_data.dungeon)):
        for mx in range(len(map_data.dungeon[0])):
            if map_data.dungeon[my][mx] != 9:
                canvas.create_image(mx*CHIP_SIZE+(CHIP_SIZE//2),my*CHIP_SIZE+(CHIP_SIZE//2),image=yuka_img[8],tag='SCREEN')
            if map_data.dungeon[my][mx] == 1:
                canvas.create_image(mx*CHIP_SIZE+(CHIP_SIZE//2),my*CHIP_SIZE+(CHIP_SIZE//2),image=obj2_img[obj_a],tag='SCREEN')
            if map_data.dungeon[my][mx] == 2:
                canvas.create_image(mx*CHIP_SIZE+(CHIP_SIZE//2),my*CHIP_SIZE+(CHIP_SIZE//2),image=obj2_img[6+obj_a],tag='SCREEN')
            if map_data.dungeon[my][mx] == 3:
                canvas.create_image(mx*CHIP_SIZE+(CHIP_SIZE//2),my*CHIP_SIZE+(CHIP_SIZE//2),image=takara_img[5],tag='SCREEN')
            if map_data.dungeon[my][mx] == 4:
                canvas.create_image(mx*CHIP_SIZE+(CHIP_SIZE//2),my*CHIP_SIZE+(CHIP_SIZE//2),image=obj_img[25],tag='SCREEN')
            if map_data.dungeon[my][mx] == 9:
                canvas.create_image(mx*CHIP_SIZE+(CHIP_SIZE//2),my*CHIP_SIZE+(CHIP_SIZE//2),image=kabe_img[28],tag='SCREEN')
    canvas.create_image(chara_x,chara_y,image=imgplayer[chara_a],tag='SCREEN')
    canvas.create_image(emy_list_x[0],emy_list_y[0],image=emy_img[emy_list_a[0]],tag='SCREEN')
    canvas.create_image(emy_list_x[1],emy_list_y[1],image=emy2_img[emy_list_a[1]],tag='SCREEN')
    canvas.create_image(emy_list_x[2],emy_list_y[2],image=emy3_img[emy_list_a[2]],tag='SCREEN')
    canvas.create_image(emy_list_x[2],emy_list_y[2],image=emy3_kageimg[emy_list_a[2]],tag='SCREEN')
    canvas.create_text(1110,50,text='{}Sol'.format(floor_count),font=st_fnt,fill='black',tag='SCREEN')
    canvas.create_text(1110,100,text='{}Pièces'.format(item_count),font=st_fnt,fill='black',tag='SCREEN')
    canvas.create_rectangle(1060,135,1210,160,fill='black',tag='SCREEN')
    canvas.create_rectangle(1060,135,1060+pl_life,160,fill='limegreen',tag='SCREEN')
    canvas.create_text(1130,148,text='LIFE',font=('Times New Roman',15),fill='white',tag='SCREEN')
    canvas.create_rectangle(1060,165,1210,190,fill='black',tag='SCREEN')
    canvas.create_rectangle(1060,165,1060+pl_stamina,190,fill='blue',tag='SCREEN')
    canvas.create_text(1130,178,text='STAMINA',font=('Times New Roman',15),fill='white',tag='SCREEN')
    canvas.create_text(1155,210,text='{}A été endommagé!'.format(pl_damage),font=('Times New Roman',15),fill='black',tag='SCREEN')


def main():
    global tmr,koff,key,idx
    tmr += 1
    draw_screen()
    if idx == 1:
        if tmr == 1:
            for emy in range(0,emy_num):
                emy_set(emy)
        move_player()
        obj_animation()
        if tmr%2 == 0:
            for emy in range(0,emy_num):
                move_emy(emy)
        if pl_life == 0:
            idx = 2
    if idx == 2:
        draw_text('You Died')
        if tmr == 20:
            idx = 1
            print('hiu')

    if koff == True:
        key = ''
        koff = False

    root.after(130,main)



root = tkinter.Tk()
root.title('Explorez le sol sombre avec une femme de chambre!')
root.bind('<KeyPress>',key_down)
root.bind('<KeyRelease>',key_up)
canvas = tkinter.Canvas(width=1256,height=864)
imgplayer = split_chip(imgplayer_pass,96,128)
emy_img = split_chip(emy_img_pass,96,128)
emy2_img = split_chip(emy2_img_pass,96,128)
emy3_img = split_chip(emy3_img_pass,96,128)
emy3_kageimg = split_chip(emy3_kageimg_pass,96,128)
takara_img = split_chip(takara_img_pass,256,64)
obj_img = split_chip(obj_pass,256,224)
obj2_img = split_chip(obj2_pass,96,128)
yuka_img = split_chip(yuka_pass,64,160)
kabe_img = split_chip(kebe_pass,256,192)
canvas.pack()
main()
root.mainloop()

Écran de lecture.

範囲を選択_008.png

Ce n'est pas du tout intéressant, mais pour le moment, le traitement de base requis pour un jeu de donjon, comme la génération de carte, le changement de direction du joueur en marchant dessus, l'animation de la zone de distorsion, le placement / mouvement des personnages ennemis, le calcul des dégâts, etc., est raisonnable. L'avez-vous? Je pense. Au fait, l'attaque contre l'ennemi n'a pas encore été mise en œuvre (sueur)

Ce que je souhaite améliorer
  • L'ennemi est tout simplement stupide et se promène correctement. Je veux le poursuivre, changer la vitesse de déplacement, etc.
  • Permet d'attaquer et de détruire les ennemis
  • (Êtes-vous assez développé?) Créez des niveaux et des statistiques pour les joueurs
  • [Wish] Incorporez l’apprentissage amélioré ou l’apprentissage automatique à l’ennemi

J'ai l'impression que le code n'a pas encore été organisé, alors j'aimerais l'améliorer petit à petit.

Êtes-vous particulier à ce sujet?

Une fonction qui décompose les puces de caractères en spécifiant le nombre de pixels. J'ai fait de mon mieux tout en collectant diverses informations.

Recommended Posts

[Fiche d'apprentissage] Créez un mystérieux jeu de donjon avec Pyhton's Tkinter
Créez un jeu de vie mis à jour manuellement avec tkinter
Créer une application graphique avec Tkinter de Python
Créer un cadre avec un arrière-plan transparent avec tkinter [Python]
Créez une interface utilisateur de jeu à partir de zéro avec pygame2!
Créer une matrice avec PythonGUI (combo tkinter)
Créez une application graphique native avec Py2app et Tkinter
Essayez de créer un Checkbutton dynamiquement avec Tkinter en Python
[Python] Créez un fichier de distribution pour le programme Tkinter avec cx_Freeze
Créez un environnement d'apprentissage automatique à partir de zéro avec Winsows 10
J'ai fait un jeu de frappe simple avec tkinter de Python
Créez une application de gestion de partition shogi à l'aide de Django 4 ~ Créer une vue ~
[Python] Créez un écran de spécification de chemin de fichier et de dossier avec tkinter
Créer une page d'accueil avec django
Créer une visionneuse d'images avec Tkinter
J'ai fait un jeu de puzzle (comme) avec Tkinter of Python
Créer un répertoire avec python
Créez une application de gestion de partition shogi à l'aide de Django 6 ~ Split Template ~
Comment créer une API de machine learning sans serveur avec AWS Lambda
Créez un environnement virtuel avec Python!
Créez un stepper de poisson avec numpy.random
Créer un téléchargeur de fichiers avec Django
Créez une application de gestion de score shogi à l'aide de Django 3 ~ Paramètres du site de gestion par défaut de Django ~
Créer un enregistrement avec des pièces jointes dans KINTONE à l'aide du module de requêtes Python
Créer un décorateur de fonction Python avec Class
Faisons un jeu de shiritori avec Python
Créez une image factice avec Python + PIL.
[Python] Créez un environnement virtuel avec Anaconda
Créons un groupe gratuit avec Python
Une histoire sur l'apprentissage automatique avec Kyasuket
Créer un gros fichier texte avec shellscript
Créez un système stellaire avec le script Blender 2.80
Créer une machine virtuelle avec un fichier YAML (KVM)
Créez une application Web simple avec Flask
Créer un compteur de fréquence de mots avec Python 3.4
J'ai fait un jeu de vie avec Numpy
Créer un voisin le plus proche de connexion avec NetworkX
Créer un service Web avec Docker + Flask
Créer un référentiel privé avec AWS CodeArtifact
Créez un compteur de voiture avec Raspberry Pi
Créez une image diabolique avec le script de Blender
J'ai fait un jeu rogue-like avec Python
Créer une matrice avec PythonGUI (zone de texte)
Créer un graphique avec des bordures supprimées avec matplotlib
[Apprentissage automatique] Créez un modèle d'apprentissage automatique en effectuant un apprentissage par transfert avec votre propre ensemble de données