gpt4 book ai didi

python - Pygame:矩形对象在 For 循环中无法正确渲染

转载 作者:太空宇宙 更新时间:2023-11-03 18:10:50 25 4
gpt4 key购买 nike

我目前正在使用 Pygame 开发游戏,并且我决定将所有 GUI 对象分组在一个字典中,如下所示:

gui_objects = {
# The GuiObject parameters define a rect (for positioning) and background colour.
"healthbar" : GuiObject((10, 10, 100, 20), Colour.BLUE),
"mini_map" : GuiObject((10, 400, 50, 50), Colour.WHITE)
}

我像这样对 GUI 对象进行分组的原因是这样我可以轻松地修改它们,例如:

gui_objects.get("mini_map").set_enabled(false)

现在,当我想将 GUI 对象渲染到屏幕上时,我只需这样做:

for key, value in gui_objects.iteritems():
value.render(screen)

这可行,但由于某种原因,白色的“mini_map”GuiObject 被渲染在“healthbar”GuiObject 的下方。我决定将“mini_map”放在字典中的“healthbar”之上,但这没有改变。但现在奇怪的部分来了。如果我单独渲染 GUI 对象,即分别调用它们的 render() 函数,如下所示:

gui_objects.get("healthbar").render(screen)
gui_objects.get("mini_map" ).render(screen)

然后 GuiObjects 正确重叠。我现在的问题是,为什么当我使用 for 循环渲染 GuiObjects 时它们没有正确重叠?但单独渲染时它们重叠得很好?

不幸的是,我无法上传图片,因为我没有足够的声誉 Ø_Ø 但是,这是源代码:

import pygame

# Just a definition of a few colours
class Colour(object):
WHITE = (255, 255, 255)
GREY = (128, 128, 128)
BLUE = ( 64, 128, 255)

# GuiObject is just a rectangle with a colour at the moment (for testing purposes).
class GuiObject(object):
def __init__(self, rect, colour):
self.rect = rect
self.colour = colour

def render(self, screen):
pygame.draw.rect(screen, self.colour, self.rect)

def main():
############################################################################
# Initialise
pygame.init()
screen = pygame.display.set_mode((800, 600))

# if render_type = 0 then render GuiObjects using a for loop
# if render_type = 1 then render GuiObjects separately.
render_type = 1

gui_objects = {
"hpbar_bg" : GuiObject(( 0, 0, 150, 600), (Colour.BLUE)),
"enemy_hpbar" : GuiObject((10, 10, 200, 400), (Colour.WHITE)),
}

############################################################################
# Main loop
while True:
########################################################################
# Event Handling
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit(0)

########################################################################
# Render
screen.fill((0, 0, 0))

# Here, I render the GuiObjects.
if render_type == 0:
# This for loop messes up overlapping.
for key, value in gui_objects.iteritems():
value.render(screen)
elif render_type == 1:
# This works fine.
gui_objects.get("hpbar_bg").render(screen)
gui_objects.get("enemy_hpbar").render(screen)

pygame.display.flip()

if __name__ == "__main__":
main()

有人知道为什么在使用 for 循环时重叠的 GuiObjects 不能正常工作吗?

我希望我已经足够清楚地解释了自己。如果没有,请询​​问,我会尽力澄清。

最佳答案

因为字典没有排序,并且它以与其他方法不同的顺序绘制对象。

字典并不是为保存需要保持有序的对象而设计的。

您可以:

  1. 使用 pygame 渲染 group相反。

这将是 pygame 推荐的存储将要绘制的对象组的方法,但是我相信您必须将 GUI 对象转换为 Sprite 。编辑:此外,pygame 渲染组仍未排序,因此这无法解决您的特定问题。

  • 使用元组列表[(name,value),...](这将与您当前的方法最相似,因为这实际上是iteritems() 字典方法返回)。
  • 这是使用方法 2 重写的代码:

    import pygame

    # Just a definition of a few colours
    class Colour(object):
    WHITE = (255, 255, 255)
    GREY = (128, 128, 128)
    BLUE = ( 64, 128, 255)

    # GuiObject is just a rectangle with a colour at the moment (for testing purposes).
    class GuiObject(object):
    def __init__(self, rect, colour):
    self.rect = rect
    self.colour = colour

    def render(self, screen):
    pygame.draw.rect(screen, self.colour, self.rect)

    def main():
    ############################################################################
    # Initialise
    pygame.init()
    screen = pygame.display.set_mode((800, 600))

    # if render_type = 0 then render GuiObjects using a for loop
    # if render_type = 1 then render GuiObjects separately.
    render_type = 0

    gui_objects = [
    ("hpbar_bg", GuiObject(( 0, 0, 150, 600), (Colour.BLUE))),
    ("enemy_hpbar", GuiObject((10, 10, 200, 400), (Colour.WHITE))),
    ]

    ############################################################################
    # Main loop
    while True:
    ########################################################################
    # Event Handling
    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    pygame.quit()
    exit(0)

    ########################################################################
    # Render
    screen.fill((0, 0, 0))

    # Here, I render the GuiObjects.
    if render_type == 0:
    # This for loop no longer messes up overlapping.
    for key, value in gui_objects:
    value.render(screen)

    pygame.display.flip()

    if __name__ == "__main__":
    main()

    因为您希望能够执行诸如 gui_objects.hpbar_bg.set_enabled(False) 之类的操作,所以我会考虑第三个选项:

  • 重构代码以将 GUI 包含在类本身中,然后在其绘制方法中命令其组件的绘制。
  • 这是 3 的示例,与您所得到的并没有相差太远:

    import pygame

    # Just a definition of a few colours
    class Colour(object):
    WHITE = (255, 255, 255)
    GREY = (128, 128, 128)
    BLUE = ( 64, 128, 255)

    # GuiObject is just a rectangle with a colour at the moment (for testing purposes).
    class GuiObject(object):
    def __init__(self, rect, colour):
    self.rect = rect
    self.colour = colour
    self.enabled = True

    def render(self, screen):
    if self.enabled:
    pygame.draw.rect(screen, self.colour, self.rect)

    class Gui(object):
    def __init__(self):
    self.hpbar_bg = GuiObject(( 0, 0, 150, 600), (Colour.BLUE))
    self.enemy_hpbar = GuiObject((10, 10, 200, 400), (Colour.WHITE))
    self.enabled = True

    def render(self, screen):
    #render my gui in the order i want
    if self.enabled:
    self.hpbar_bg.render(screen)
    self.enemy_hpbar.render(screen)


    def main():
    ############################################################################
    # Initialise
    pygame.init()
    screen = pygame.display.set_mode((800, 600))

    gui = Gui()

    #uncomment to get the enabled/disabled behavior
    #gui.hpbar_bg.enabled = False

    #or disable the whole gui
    #gui.enabled = False

    ############################################################################
    # Main loop
    while True:
    ########################################################################
    # Event Handling
    for event in pygame.event.get():
    if event.type == pygame.QUIT:
    pygame.quit()
    exit(0)

    ########################################################################
    # Render
    screen.fill((0, 0, 0))

    # Render GUI
    gui.render(screen)

    pygame.display.flip()

    if __name__ == "__main__":
    main()

    关于python - Pygame:矩形对象在 For 循环中无法正确渲染,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25999769/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com