简体   繁体   English

pygame:绘制矩形的奇怪行为

[英]Pygame: strange behaviour of a drawn rectangle

I'm trying to make a lifebar class for my game in Pygame. 我正在尝试为我在Pygame中的游戏制作救生棒课程。 I've done this: 我已经做到了:

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)

It works, but when I tried it to down its health to zero, the rectangle surpasses the left limit by a bit. 它可以工作,但是当我尝试将其运行状况降低到零时,矩形稍微超出了左限制。 Why does this happen? 为什么会这样?

Here you have a code to try it on your own (just run it if my explanation of the problem wasn't clear): 在这里,您有一个代码可以自己尝试(如果我对问题的解释不清楚,请运行它):

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()  

I think it's because your code draws rectangles less than 1 pixel wide, and even though the pygame documentation says "The area covered by a Rect does not include the right- and bottom-most edge of pixels", apparently that implies that it always does include the left- and top-most edges, which is what is giving the results. 我认为这是因为您的代码绘制的矩形宽度小于1像素,即使pygame 文档说“ Rect所覆盖的区域不包括像素的最右端和最底端”,这显然意味着它始终包括最左边和最上面的边缘,这就是结果。 This arguably could be considered a bug—and it shouldn't draw anything in those cases. 可以将其视为错误,并且在那种情况下不应画任何东西。

Below is a workaround that simply avoids drawing Rect s which are less than a whole pixel wide. 以下是一种解决方法,可以避免绘制小于整个像素宽的Rect I also simplified the math being done a bit to make things more clear (and faster). 我还简化了一些数学运算,以使事情更清楚(更快)。

    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))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM