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

Programmation multimédia/Jeux Python Discussion :

Bliter un Rect sur Pygame ? [Python 3.X]


Sujet :

Programmation multimédia/Jeux Python

  1. #1
    Membre averti
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2018
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Octobre 2018
    Messages : 11
    Par défaut Bliter un Rect sur Pygame ?
    Salut,
    Est-ce que quelqu'un saurait comment faire un blit() sur un Rect (je précise que ce Rect a été obtenu avec pygame.draw.Circle(), qui revoie un Rect) ?
    Pour ceux que ça aide, le code, dans les grandes lignes, ressemble à ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import pygame
    pygame.init()
    s = pygame.display.set_mode((640, 480))
     
    cercle = pygame.draw.Circle(s, couleur, (100, 100), 50)
     
    quit = False
    while quit is not True:
        #mes events
        s.blit( # là je sais pas comment faire )
     
    exit(0)
    Merci !

  2. #2
    Membre très actif

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Billets dans le blog
    1
    Par défaut
    Salut.

    Les grandes lignes ne précisent pas ce que tu veux faire.
    Les fonctions du module pygame.draw tracent des formes sur des surfaces, on blit des surfaces sur d'autres surfaces, rien de plus.
    Là tu dessines un cercle sur la surface de l''écran, y a rien a blit, ni à actualiser.

    Citation Envoyé par anat3000 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    quit = False
    while quit is not True:
    Y a comme un gros souci.

  3. #3
    Membre averti
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2018
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Octobre 2018
    Messages : 11
    Par défaut
    Salut,
    Citation Envoyé par bistouille Voir le message
    Y a comme un gros souci.
    Oui, effectivement (j'ai refait le code rapidement pour la discu), j'avais changé cette partie entre temps :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    while True:
        for ev in pygame.event.get():
            if ev.type == QUIT:
                pygame.quit()
    Je suis novice avec pygame, je ne sais pas si ce code st très optimisé ou s'il convient...

    Quant à au Rect, je voulais faire en sorte de le bouger avec move() et ensuite de le bliter, mais il suffirait de l'effacer pour le réafficher à un autre endroit avec pygame.draw.Circle() , non ?

  4. #4
    Membre très actif

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Billets dans le blog
    1
    Par défaut
    Salut.

    Citation Envoyé par anat3000 Voir le message
    Quant à au Rect, je voulais faire en sorte de le bouger avec move() et ensuite de le bliter, mais il suffirait de l'effacer pour le réafficher à un autre endroit avec pygame.draw.Circle() , non ?
    C'est exactement ça, d'abord tracer le cercle et récupérer le rectangle comme tu as fait.
    Puis tu changes les coordonnées du rectangle avec Rect.move_ip dans ton cas, tu remplis l’écran avec la couleur de départ (ou image), puis tu redessines le cercle en utilisant la position centrale du rectangle (center) comme position x, y du cercle.
    Ne pas oublier de mettre à jour l'écarn avec display.update.

    Bien sûr, on peut bien évidemment créer une surface destinée à contenir le cercle, et agir sur cette surface (position) plutôt que de redessiner le cercle chaque fois, ça revient à peu près au même

  5. #5
    Membre averti
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2018
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Octobre 2018
    Messages : 11
    Par défaut
    Salut,

    Citation Envoyé par bistouille Voir le message
    C'est exactement ça, d'abord tracer le cercle et récupérer le rectangle comme tu as fait.
    Puis tu changes les coordonnées du rectangle avec Rect.move_ip dans ton cas, tu remplis l’écran avec la couleur de départ (ou image), puis tu redessines le cercle en utilisant la position centrale du rectangle (center) comme position x, y du cercle.
    Ne pas oublier de mettre à jour l'écarn avec display.update.
    J'ai essayé de le mettre en application :
    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
     
        pygame.init()
     
        spacetime = pygame.display.set_mode((640, 480))
     
        fps_lim = pygame.time.Clock()
        color = rcolor()
        obj1 = pygame.draw.circle(spacetime, color, (320, 240), 50)
     
        game_continue = True
        while game_continue:
            for event in pygame.event.get():
                if event.type == QUIT:
                    game_continue = False
     
            obj1.move_ip(3, 0)
            # mettre un fond
            fond = pygame.image.load("background.jpg").convert()
     
            obj1 = pygame.draw.circle(spacetime, color, (obj1.x+50, obj1.y+50), 50)
     
            pygame.display.update()
            fps_lim.tick(FPS)
    Le bg ne s'affiche pas et le cercle reste
    J'ai fait quelque chose de mal ?

  6. #6
    Membre très actif

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Billets dans le blog
    1
    Par défaut
    Salut.

    Citation Envoyé par anat3000 Voir le message
    Le bg ne s'affiche pas et le cercle reste
    J'ai fait quelque chose de mal ?
    Pour que quelque chose s'affiche à l'écran, il faut utiliser blit, donc le fond sur l'écran.
    Le chargement des images doit se faire hors boucle.

    obj1.move_ip(3, 0) déplace donc ton rectangle, de là, comme précisé, tu as juste à redessiner le cercle en utilisant le point central de ce rectangle.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pygame.draw.circle(spacetime, color, obj1.center, 50)
    Et plus besoin de récupérer le rectangle retourné puisque tu travailleras avec uniquement le premier.

  7. #7
    Membre averti
    Homme Profil pro
    Lycéen
    Inscrit en
    Octobre 2018
    Messages
    11
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Octobre 2018
    Messages : 11
    Par défaut
    Citation Envoyé par bistouille Voir le message
    Pour que quelque chose s'affiche à l'écran, il faut utiliser blit, donc le fond sur l'écran.
    Le chargement des images doit se faire hors boucle.
    Ah oui c'est vrai... Avec tous ces Rect, Surface et blit on s'y pert...

    VICTOIRE, ça marche !

    Merci bistouille

    Je vais mettre le code final est le sujet en résolu !

    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
    #coding: utf-8
    #!/usr/bin/env python3
     
    from random import randint as r
     
    import pygame
    from pygame.locals import *
     
    def rcolor():
        return r(0, 255), r(0, 255), r(0, 255)
     
    def gen(gravit):
        pass
     
    def main(FPS):
        pygame.init()
     
        spacetime = pygame.display.set_mode((640, 480))
     
        fps_lim = pygame.time.Clock()
        color = rcolor()
        obj1 = pygame.draw.circle(spacetime, color, (320, 240), 50)
     
        fond = pygame.image.load("background.jpg").convert()
     
        game_continue = True
        while game_continue:
            for event in pygame.event.get():
                if event.type == QUIT:
                    game_continue = False
     
            obj1.move_ip(3, 0)
            spacetime.blit(fond, (0, 0))
     
            obj1 = pygame.draw.circle(spacetime, color, (obj1.x+50, obj1.y+50), 50)
     
            pygame.display.update()
            fps_lim.tick(FPS)
     
    main(10)
    exit(0)
    Le code de mon projet est disponible sur GitHub, voici le lien :

    https://github.com/anat3000/Gravit/

  8. #8
    Membre très actif

    Homme Profil pro
    Bidouilleur
    Inscrit en
    Avril 2016
    Messages
    721
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Bidouilleur

    Informations forums :
    Inscription : Avril 2016
    Messages : 721
    Billets dans le blog
    1
    Par défaut
    Salut.


    Citation Envoyé par anat3000 Voir le message
    VICTOIRE, ça marche !
    Bravo

    A la place de (obj1.x+50, obj1.y+50), tu peux simplement utiliser obj1.center.

    Maintenant que tu as réussi à faire ça, dans le module pygame.draw, il est préconisé d'utiliser une surface plutôt que de redessiner une figure chaque fois.

    Rendering to hardware Surfaces will be slower than regular software Surfaces.
    Donc l'idéal est de créer une surface transparente, puis de dessiner le cercle dessus, puis d'agir sur cette surface avec pygame.

    Un exemple avec une surface transparente de départ pour le cercle.

    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
    import pygame as pg
     
    CIRCLE_COLOR = pg.Color('yellow')
    CIRCLE_WIDTH = 2
    CIRCLE_RADIUS = 30
    CIRCLE_STEP = 5
     
    CIRCLE_MOTIONS = {
        pg.K_UP:(0, -CIRCLE_STEP),
        pg.K_DOWN:(0, CIRCLE_STEP),
        pg.K_LEFT:(-CIRCLE_STEP, 0),
        pg.K_RIGHT:(CIRCLE_STEP, 0),
    }
     
    FPS = 30
     
    pg.init()
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()
    # Chargement de l'image de fond (à ne jamais faire dans une boucle)
    background = pg.image.load("background.jpg").convert()
    # Surface transparente destinée au cercle
    size = ((CIRCLE_WIDTH + CIRCLE_RADIUS) * 2,) * 2
    circle_surf = pg.Surface(size, pg.SRCALPHA, 32).convert_alpha()
    # Récupération du rectangle englobant la surface
    circle_rect = circle_surf.get_rect()
    pg.draw.circle(
        circle_surf, CIRCLE_COLOR, circle_rect.center,
        CIRCLE_RADIUS, CIRCLE_WIDTH
    )
     
    # Affichage
    # Apposition de l'image sur l'écran
    screen.blit(background, (0, 0))
    # Centrage du rect de la surface au centre de l'écran
    circle_rect.center = (320, 240)
    # Apposition de la surface du cercle sur l'écran
    screen.blit(circle_surf, circle_rect)
    # Mise à jour
    pg.display.update()
     
    # Rectangle de la portion de l'écran à mettre a jour
    # On se sert du pas de déplacement * 2 pour agrandir circle_rect
    rect_update = circle_rect.inflate(CIRCLE_STEP*2, CIRCLE_STEP*2)
     
    pg.key.set_repeat(10, 10)
     
    tournicoti = True
    while tournicoti :
        clock.tick(FPS)
        for evt in pg.event.get() :
            if (evt.type == pg.QUIT or
                (evt.type == pg.KEYUP and evt.key == pg.K_ESCAPE)) :
                tournicoti = False
                break
            elif evt.type == pg.KEYDOWN and evt.key in CIRCLE_MOTIONS :
                # Déplacement du rectangle de la portion de l'écran à actualiser
                rect_update.move_ip(CIRCLE_MOTIONS[evt.key])
                # Remplissage de l'écran sur la portion à mettre à jour
                screen.blit(background, rect_update, rect_update)
                # Déplacement du rectangle de la surface du cercle
                circle_rect.move_ip(CIRCLE_MOTIONS[evt.key])
                # Apposition de la surface du cercle sur l'écran
                screen.blit(circle_surf, circle_rect)
                # Mise à jour de la portion de l'écran où des changements sont faits
                pg.display.update(rect_update)
    pg.quit()
    Et dans ce code pour l'exemple, seule la portion de l'écran devant être changée sera mise à jour (arguments de update), cela n'a pas l'air de grand chose, mais c'est une bonne pratique à adopter de seulement mettre à jour les zones de l'écran modifiées (gain de ressources, vitesse de jeu).

    A toi de triturer ce bout de code pour comprendre le fonctionnement.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Saut d'un personnage sur pygame
    Par eragon014 dans le forum Développement 2D, 3D et Jeux
    Réponses: 0
    Dernier message: 04/03/2018, 22h06
  2. problème de collision sur Pygame
    Par SmartGoat dans le forum Programmation multimédia/Jeux
    Réponses: 1
    Dernier message: 17/12/2016, 16h49
  3. Un Quiz sur Pygame
    Par louphoque dans le forum Général Python
    Réponses: 2
    Dernier message: 22/04/2016, 18h55
  4. Problème de déplacement du personnage sur Pygame
    Par Youpat97 dans le forum Programmation multimédia/Jeux
    Réponses: 7
    Dernier message: 08/05/2013, 02h04
  5. Problème de déplacement du personnage sur Pygame
    Par Youpat97 dans le forum Général Python
    Réponses: 15
    Dernier message: 24/04/2013, 00h42

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