python - 如何在Pygame中正确继承Surface类

标签 python oop pygame

为了将 OOP 付诸实践,我创建了自己的 Window 类,该类继承自 pygame.Surface,并添加了功能。根据following来源,这就是我应该做的:

class MyWindow(pygame.Surface):
    def __init__(self, w, h):
        pygame.Surface.__init__(self, size=(w, h))
        self.screens: list[Screen] = []  # For example

我尝试了以下代码,它似乎工作正常,直到调用 display.update() 为止。这会抛出一个 pygame.error

myWin: MyWindow = MyWindow(200, 200)
print(myWin)    # This correctly prints: <Surface(200x200x32 SW)>

pygame.draw.rect(myWin, (255, 255, 255), (90, 90, 20, 20))
pygame.display.update()
pygame.time.delay(1000)

该代码甚至没有创建实际的窗口。相比之下,以下代码工作得很好,而是依赖 display.set_mode() 函数来初始化 Surface。

pyWin: pygame.Surface = pygame.display.set_mode((200, 200))
pygame.draw.rect(pyWin, (255, 255, 255), (90, 90, 20, 20))
pygame.display.update()  # Actually shows the square
pygame.time.delay(1000)

The desired output

显然 display.set_mode() 做了 Surface.__init__() 没有做的事情。

TL;DR:如何初始化从 Surface 继承的对象,使其能够实际显示和更新窗口?

谢谢!

最佳答案

TL;DR: How can I initialize an object inheriting from Surface, in such a way that it actually shows and updates the window?

我想说你不能按照你想的方式去做,而且有充分的理由不想这样做。
需要记住以下几点:

  1. Surface 只是一个二维像素数组,具有方便的方法来读取/编辑/写入这些像素的值。写在哪里?到其他表面。您可以在游戏中拥有任意多个表面,每个表面都存储游戏不同元素的图像(您的主角、敌人、 map 元素等)。您可以将一个 Surface 的内容写入另一个 Surface 的顶部,以制作复杂的图像。
    Surface 本身与屏幕没有任何联系(即与您在 PC 显示器上看到的窗口上显示的内容)。
  2. display是一个特殊的Surface,由pygame.display.set_mode()实例化。它是一个 Surface ,就像您可以使用 Surface 类创建的所有其他 Surface 一样,但是只有那个 Surface 代表显示,即您在监视器上看到的内容。

这意味着 pygame.Surface 实例从不显示在屏幕上。要在屏幕上显示内容,您需要在特殊的显示 Surface 上的某个位置位 block 传输其他 Surface(即复制其内容)。

现在让我们回到你的问题。考虑到我刚刚解释的内容,您可能会问:那么我可以编写一个 Surface 子类,以便每次 Surface 值发生变化时,它都会自动在 displaydisplay.update() 被调用`?

嗯,这会很复杂。如果您使用 pygame.draw 中的函数,Surface 是一个参数,因此您需要一些好技巧来让参数理解何时使用它。
然而,相信我:你不想这样做。一旦你的游戏变得稍微复杂一点,它的效率就会非常低。原因是位图传输和绘制需要时间,因此您需要优化这些操作,仅在需要时执行它们。如果您的游戏中有许多表面,您希望在主循环的每次迭代(或每个帧,如果您愿意)上将它们 block 传输到 display 上,以“准备”新帧,并调用 display.update 仅一次。

关于python - 如何在Pygame中正确继承Surface类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58562086/

相关文章:

python - Django 表单在创建用户时不保存密码

java - 用 Java 编写台球游戏 - 如何定义球并移动它们(通过 Graphics g)?

python - 在运行时重置/重新加载嵌套类的类属性

oop - 在 Lua 中指定新对象的元表

python - 部分由文件系统支持的数据结构?

python - `driver.execute_script(".. .")` 和 `driver.get("javascript : . 之间有什么区别。 ."` 与 geckodriver/Firefox?

javascript - 使用plotly.js 从 JSON 构建绘图

python - 为什么这个小小的 pygame 程序会死机并且什么都不做?

python - 寻找一种将矩形拟合到轮廓点的方法

python - 在 pygame 中使方 block 从线上弹起