2017-08-14 3 views
1

J'essaie de faire une classe de barre de vie pour mon jeu dans Pygame. Je l'ai fait:Pygame: comportement étrange d'un rectangle dessiné

class Lifebar(): 
    def __init__(self, x, y, max_health): 
     self.x = x 
     self.y = y 
     self.health = max_health 
     self.max_health = max_health 

    def update(self, surface, add_health): 
     if self.health > 0: 
      self.health += add_health 
      pygame.draw.rect(surface, (0, 255, 0), (self.x, self.y, 30 - 30 * (self.max_health - self.health)/self.max_health, 10)) 


    print(30 - 30 * (self.max_health - self.health)/self.max_health) 

Il fonctionne, mais quand je l'ai essayé en bas de sa santé à zéro, le rectangle dépasse la limite gauche par un bit. Pourquoi cela arrive-t-il?

Ici vous avez un code pour l'essayer sur votre propre (il suffit d'exécuter si mon explication du problème n'a pas été clair):

import pygame 
from pygame.locals import * 
import sys 

WIDTH = 640 
HEIGHT = 480 

class Lifebar(): 
    def __init__(self, x, y, max_health): 
     self.x = x 
     self.y = y 
     self.health = max_health 
     self.max_health = max_health 

    def update(self, surface, add_health): 
     if self.health > 0: 
      self.health += add_health 
      pygame.draw.rect(surface, (0, 255, 0), (self.x, self.y, 30 - 30 * (self.max_health - self.health)/self.max_health, 10)) 
     print(30 - 30 * (self.max_health - self.health)/self.max_health) 

def main(): 
    pygame.init() 

    screen = pygame.display.set_mode((WIDTH, HEIGHT)) 
    pygame.display.set_caption("Prueba") 


    clock = pygame.time.Clock() 

    lifebar = Lifebar(WIDTH // 2, HEIGHT // 2, 100) 

    while True: 
     clock.tick(15) 
     for event in pygame.event.get(): 
      if event.type == pygame.QUIT: 
       sys.exit() 

     screen.fill((0,0,255)) 

     lifebar.update(screen, -1) 

     pygame.display.flip() 

if __name__ == "__main__": 
    main() 

Répondre

2

Je pense qu'il est parce que votre code dessine des rectangles moins de 1 pixel large, et même si le pygamedocumentation dit "La zone couverte par un Rect n'inclut pas le bord le plus à droite et le plus bas des pixels", apparemment cela implique d'inclure les bords gauche et supérieur, c'est ce qui donne les résultats. Cela pourrait sans doute être considéré comme un bug - et il ne devrait rien dessiner dans ces cas-là. Voici une solution de contournement qui évite simplement de dessiner Rect s dont la largeur est inférieure à un pixel entier. J'ai aussi simplifié un peu les maths pour rendre les choses plus claires (et plus rapides).

def update(self, surface, add_health): 
     if self.health > 0: 
      self.health += add_health 
      width = 30 * self.health/self.max_health 
      if width >= 1.0: 
       pygame.draw.rect(surface, (0, 255, 0), 
           (self.x, self.y, width, 10)) 
       print(self.health, (self.x, self.y, width, 10)) 
+0

N'est-ce pas 10 ou 0 la hauteur? – Foon

+0

@ Foon: Vous avez absolument raison, mon erreur. Voir la mise à jour – martineau

+0

Merci. Il résout entièrement le problème. – HastatusXXI