IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement 2D, 3D et Jeux Discussion :

Freeze étrange et problème de boucle Pygame


Sujet :

Développement 2D, 3D et Jeux

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif Avatar de viper1094
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2019
    Messages
    570
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2019
    Messages : 570
    Par défaut Freeze étrange et problème de boucle Pygame
    Salut à tous,

    Alors je suis en train de faire un petit Snake avec pygame et j'ai un drôle de problème. Tout d'abord voici mon code ( il est légèrement long donc je mettrais les parties concernés quand j'en parlerais. Je donne les images juste en bas au cas où quelqu'un voudrait tester le code ( ne pas oublier de les mettre dans un répertoire 'img' ou de modifier le code).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    import pygame,sys,time,os
    from pygame.locals import *
    #Global Variable
    EventKey=None
    CurrentSnakeHeadX=400
    CurrentSnakeHeadY=200
    CurrentSnake1Number=0 
    CurrentSnakeHeadOrientation=1 # 1:top, 2:right, 3:bottom, 4:left
    #Initialize The Window
    window = pygame.display.set_mode((900, 550))
    pygame.display.set_caption('Snake')
     
    #Load Sprite
    white=(255,255,255)
    Snake1 = pygame.image.load("img/Snake1.png").convert()
    SnakeQueue = pygame.image.load("img/SnakeQueue.png").convert()
    SnakeHead = pygame.image.load("img/SnakeHead.png").convert()
    Black= pygame.image.load("img/BlackCube.png").convert()
     
     
    #Setup the colorkeys
    Snake1.set_colorkey(white)
    SnakeQueue.set_colorkey(white)
    SnakeHead.set_colorkey(white)
     
    #This Function Load Basic Background
    def background () :
        for ScreenHeight in range(18):
            for ScreenWeight in range(11):
               window.blit(Black,(50*ScreenHeight,50*ScreenWeight)) 
     
     
    def snake():
        global CurrentSnakeHeadX, CurrentSnakeHeadY,CurrentSnake1Number
        if EventKey==None :
            window.blit(SnakeHead,(CurrentSnakeHeadX,CurrentSnakeHeadY))
            window.blit(SnakeQueue,(400,250))
        elif EventKey==1 :
            for repeat in range(5) :
                if CurrentSnakeHeadY!=0:
                    CurrentSnakeHeadY=CurrentSnakeHeadY-20
                    background()
                    window.blit(SnakeHead,(CurrentSnakeHeadX,CurrentSnakeHeadY))
                    window.blit(SnakeQueue,(CurrentSnakeHeadX,CurrentSnakeHeadY+50))
                    refresh()
                    time.sleep(0.4)
     
                else :
                    CurrentSnakeHeadY=490
                    for repeat in range(5) :
                        CurrentSnakeHeadY-=10
                        background()
                        window.blit(SnakeHead,(CurrentSnakeHeadX,CurrentSnakeHeadY))
                        window.blit(SnakeQueue,(CurrentSnakeHeadX,CurrentSnakeHeadY+50))
                        refresh()
                        time.sleep(0.4)
     
    def refresh ():
        pygame.display.flip()
     
    def start ():    
        background()
        snake()
        refresh()
    start()
    while 1:
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_UP:
                        print(EventKey)
                        EventKey=0
                        snake()
                        refresh()
                        EventKey=None
                        pygame.event.clear()
                    if event.key == pygame.K_RIGHT:
                        EventKey=2
                        lancelot()
                        refresh()
                        EventKey=None
                        pygame.event.clear()
                    if event.key == pygame.K_LEFT:
                        EventKey=3
                        snake()
                        refresh()
                        EventKey=None
                        pygame.event.clear()
            else :
                print(EventKey)
                EventKey=1
                snake()
                pygame.event.clear()
     
            if event.type == pygame.QUIT:
                pygame.quit()
    Ensuite voilà mon problème, j'étais en train de gérer les sprites pour que la tête ressorte de l'autre coté de l'écran si elle touche un bord, j'ai lancer mon sript et j'ai remarqué plusieurs freeze de quelques seconde. Parfois cliquer sur la fenêtre relancer le script, parfois pas. C'est donc pas une histoire de focus de la fenêtre je pense. Je me suis donc dit " Regardons dans le gestionnaire des tâches". Et à chaque freeze, mon script passer de 5 à 25% d'utilisation de processeurs. Ca élimine donc le focus de fenêtre et me laisse supposer que y a une histoire de boucle qui n'a rien à faire là ou quelques chose s'en rapprochant. J'ai donc, tout bêtement fait ceci dans mon code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    while 1:
    print('a')
        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:
                    if event.key == pygame.K_UP:
                        print(EventKey)
                        EventKey=0
                        snake()
                        refresh()
                        EventKey=None
                        pygame.event.clear()
                    if event.key == pygame.K_RIGHT:
                        EventKey=2
                        lancelot()
                        refresh()
                        EventKey=None
                        pygame.event.clear()
                    if event.key == pygame.K_LEFT:
                        EventKey=3
                        snake()
                        refresh()
                        EventKey=None
                        pygame.event.clear()
            else :
                print(EventKey)
                EventKey=1
                snake()
                pygame.event.clear()
            
            if event.type == pygame.QUIT:
                pygame.quit()
    En gros j'ai fait en sorte qu'il y a un print a sur la fenêtre de l'IDLE en dessous de ma fenêtre pygame. Et étrangement, pas de a jusqu'a ce que ça freeze, et à ce moment les ben il s'arrêter pas, la boucle faisait :
    Et c'est tout. Pas de relancement de l'animation là. Au fait, je précise que j'ai, pour également vérifier l'état de la variable EventKey, mis ceci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    else :
                print(EventKey)
    dans mon code, à chaque passage jusqu'au freeze à chaque passage de la boucle.
    Je précise que il y a des time.sleep dans ma fonction snake, et que les passage se faisait donc toutes les 5*0.4secondes, donc 2 seconde. Pour le moment j'avais pas mis quoi que ce soit pour déplacer le serpent excepté l'animation où il bouge automatiquement donc.
    La fonction en question :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    def snake():
        global CurrentSnakeHeadX, CurrentSnakeHeadY,CurrentSnake1Number
        if EventKey==None :
            window.blit(SnakeHead,(CurrentSnakeHeadX,CurrentSnakeHeadY))
            window.blit(SnakeQueue,(400,250))
        elif EventKey==1 :
            for repeat in range(5) :
                if CurrentSnakeHeadY!=0:
                    CurrentSnakeHeadY=CurrentSnakeHeadY-20
                    background()
                    window.blit(SnakeHead,(CurrentSnakeHeadX,CurrentSnakeHeadY))
                    window.blit(SnakeQueue,(CurrentSnakeHeadX,CurrentSnakeHeadY+50))
                    refresh()
                    time.sleep(0.4)
     
                else :
                    CurrentSnakeHeadY=490
                    for repeat in range(5) :
                        CurrentSnakeHeadY-=10
                        background()
                        window.blit(SnakeHead,(CurrentSnakeHeadX,CurrentSnakeHeadY))
                        window.blit(SnakeQueue,(CurrentSnakeHeadX,CurrentSnakeHeadY+50))
                        refresh()
                        time.sleep(0.4)
    Et je comprend pas vraiment ces freezes, malgré quelques recherches et plusieurs relectures de mon code.
    J'aurais donc bien besoin d'un coup de main

    Deux trois précisions pour vous faire gagner du temps : refresh()== pygame.display.flip (j'ai juste créer la fonction refresh pour un souci de lisibilité et de gain de temps)
    Faites pas attention au nom de fonction, j'essaie de pas passer 4h à en choisir des super explicite, je prend ce qui viens.
    background() est juste égal à 18 blocs noir sur 11 blocs noir.
    Les images sont les suivantes :
    Nom : Snake1.png
Affichages : 168
Taille : 233 octets

    Nom : SnakeQueue.png
Affichages : 159
Taille : 267 octets

    Nom : BlackCube.png
Affichages : 160
Taille : 195 octets

    Nom : SnakeHead.png
Affichages : 158
Taille : 310 octets

    Je crois avoir tout dit, désolé pour la longueur du message j'ai essayé d'apporter le maximum de précision. Je suis sûr que c'est une erreur toute bête mais je trouve vraiment pas.

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 153
    Billets dans le blog
    4
    Par défaut
    Ton code est assez moyen
    Tu as des boucles de boucle de boucle et fais de sleep de partout
    Le code est beaucoup dupliqué
    Tu fais un refresh de l'affichage n'importe où
    Tu utilises des valeurs magiques à tout va
    > Crées toi des enum
    Tu utilises des variables globales qui ont pas lieu d'être
    > EventKey n'a rien à faire en globale
    Le background pourrait être affiché en 1 fois

    Une boucle de jeu c'est
    - dépilement des évènements
    - mise à jour de l'état du jeu
    - affichage du jeu
    https://alexandre-laurent.developpez...boucle-de-jeu/

    Ensuite pour parler du snake en soit tu devrais avoir
    - un tableau représentant les positions de chaque morceau du corps
    - une fonction de collision pour pas qu'il puisse se mordre
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  3. #3
    Membre très actif Avatar de viper1094
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2019
    Messages
    570
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2019
    Messages : 570
    Par défaut


    Citation Envoyé par Bousk Voir le message
    Ensuite pour parler du snake en soit tu devrais avoir
    - un tableau représentant les positions de chaque morceau du corps
    - une fonction de collision pour pas qu'il puisse se mordre
    D'acc je note, je reprendrai le code pour qu'il corresponde à ce que tu me dis. Le problème vient de là tu penses ?
    Des enums ça sert à quoi ? Une recherche internet m'explique globalement que c'est une liste de variable, mais j'avoue que j'aimerais en comprendre l'utilité. ( Les explications sur l'utilité utilisant des exemples que je ne comprend pas )

    Le background pourrait être affiché en 1 fois :
    Euh pas sur, je sais qu'il faut split le background à chaque modification des sprites se trouvant au dessus, afin remplacer les anciens. Sauf si j'ai fait mal compris quelque part.

    Tu as des boucles de boucle de boucle et fais de sleep de partout
    Le code est beaucoup dupliqué
    Tu fais un refresh de l'affichage n'importe où
    Je te serais gré de m'expliquer où les boucles de boucles posent problème ( je crois que tu parles du for ():
    for():
    mais je vois pas comment faire autrement). Les refreshs devrait être fait où ?
    Une boucle de jeu c'est
    - dépilement des évènements
    - mise à jour de l'état du jeu
    - affichage du jeu
    https://alexandre-laurent.developpez...boucle-de-jeu/
    Du coup le refresh doit être dans la boucle ? Ca répond à une de mes questions. D'accord merci.

    Ton code est assez moyen
    Ah bah ça pour le coup je suis d'accord, et je te remercie d'avoir pris le temps de m'expliquer les défauts que tu as pu y voir

Discussions similaires

  1. Problème de boucles imbriquées
    Par Gnux dans le forum Algorithmes et structures de données
    Réponses: 9
    Dernier message: 09/12/2005, 20h26
  2. [Tableaux] Problème avec boucle
    Par MYster dans le forum Langage
    Réponses: 6
    Dernier message: 11/11/2005, 18h39
  3. Problème de boucle
    Par TheUltimaSephiroth dans le forum C
    Réponses: 8
    Dernier message: 10/10/2005, 13h58
  4. Problème de boucle
    Par Louis-Guillaume Morand dans le forum Langage SQL
    Réponses: 3
    Dernier message: 25/09/2005, 09h10
  5. Problème de boucle
    Par basclln dans le forum C++
    Réponses: 19
    Dernier message: 02/04/2005, 09h13

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo