pygame试图绘制具有随机大小和收缩率的收缩矩形,但它们会闪烁

2024-10-02 00:33:57 发布

您现在位置:Python中文网/ 问答频道 /正文

我制作了一个名为“粒子”的类,这些粒子基本上只是矩形,当它们太小时会收缩、移动并被破坏

我的init方法有5个可选参数,如果没有,将被分配一个随机值

粒子是使用pygame.draw.rect绘制的 当“size”和“sizeDecay”参数是随机的时,粒子在移动时闪烁,我不知道为什么,因为字面上唯一的区别是有随机的起始值(减少是线性的)

以下是我认为可能相关的代码: 初始方法

    RSizeR = [50, 100] # short for RandomSizeRange
    RSizeDecayR = [10, 30] # short for RandomSizeDecayRange (NOTE : this value is divided by 10)
    RSpeedR = [15, 50] # short for RandomSpeedRange (NOTE : this value is divided by 10)

    # shape = "s" for square or "c" for circle
    def __init__(self, startpos, shape, colour = None, size = None, sizeDecay = None, angle = None, speed = None):

        self.pos = [int(startpos[0]), int(startpos[1])]
        self.shape = shape

        if colour == None: self.colour = tuple(random.randint(0, 255) for i in range(3))
        else: self.colour = colour

        if size == None: self.size = random.randint(Particle.RSizeR[0], Particle.RSizeR[1])
        else: self.size = size

        if sizeDecay == None: self.sizeDecay = random.randint(Particle.RSizeDecayR[0], Particle.RSizeDecayR[1])
        else: self.sizeDecay = sizeDecay

        if angle == None: self.angle = random.randint(0, 360)
        else: self.angle = angle

        if speed == None: self.speed = random.randint(Particle.RSpeedR[0], Particle.RSpeedR[1])
        else: self.speed = speed


        self.xspeed = sin(self.angle) * self.speed
        self.yspeed = cos(self.angle) * self.speed

        self.rect = pygame.Rect(self.pos[0], self.pos[1], self.size, self.size)

update方法(返回的True告诉程序删除该粒子)

    def update(self):

        self.pos[0] += self.xspeed / 10
        self.pos[1] += self.yspeed / 10

        self.size -= self.sizeDecay / 10

        if self.size <= 0:
            return True

        self.rect.width = int(self.size)
        self.rect.height = int(self.size)

        self.rect.center = (int(self.pos[0]), int(self.pos[1]))

        return False

画法

    def draw(self):
        if self.shape == "s":
            pygame.draw.rect(screen, self.colour, self.rect)
        elif self.shape == "c":
            pygame.draw.circle(screen, self.colour, self.rect.center, int(self.size/2))

我曾尝试在类之外定义随机值并将其传递给init方法,但问题仍然存在

我最好的猜测是,计算两个额外的随机数不知何故会减慢程序的速度

更新

我用来更新屏幕的代码在while循环中,如下所示

gameState = "running"

while gameState != "exit":

    # catching events here

    # rest of code here


    pygame.display.flip()
    clock.tick(fps)

我这样定义我的窗口:

pygame.init()
clock = pygame.time.Clock()
fps = 60
SCREENSIZE = SCREENX, SCREENY = 800, 800
screen = pygame.display.set_mode(SCREENSIZE)

此外,这是我用来更新粒子并将其绘制到屏幕上的代码(它位于粒子类内部)

    @classmethod
    def UpAndDrawAll(cls):

        for index, par in enumerate(cls.Particles):
            delete = par.update()
            if delete:
                del cls.Particles[index]
            else:
                par.draw()

更新2

我注意到随机速度也有很小的性能下降,问题是由使用随机生成的值引起的,而不是由生成随机数引起的(仍然没有解决问题)

我还注意到,有些粒子比其他粒子闪烁得更频繁,有些甚至不闪烁


Tags: posrectselfnoneforsizeif粒子
2条回答

我已经解决了这个问题。 问题是当粒子被删除时(当它们变得太小时),没有对某些粒子调用draw()方法

我发现了这一点,当粒子变得太小时不可见,而不是删除它们,这绝对不会导致闪烁

我已将UpdateAll()方法替换为:

    @classmethod
    def UpAndDrawAll(cls):
        dellist = []

        for ind, par in enumerate(cls.Particles):
            delete = par.update()
            if delete:
                dellist.append(ind)
            else:
                par.draw()

        offset = 0
        for delind in dellist:
            del cls.Particles[ delind+offset ]
            offset -= 1

我将把这个问题留待以后,以防其他人也有类似的问题

这里真的没有足够的答案回答你

但是,每次游戏循环多次调用pygame.display.update或pygame.display.flip通常会导致闪烁。确保blit所有需要的显示更改,并且只有在所有位置更新和blit完成后,才能在循环结束时调用pygame.display.update或pygame.display.flip(但不能同时调用两者)

相关问题 更多 >

    热门问题