如何在一个类中使用pyglet

问题描述 投票:5回答:3

在我使用Pyglet看到的所有Web教程中,似乎它们中的任何一个都没有使用包含pyglet.window.Window实例的类。例如,大多数教程似乎都类似于

import pyglet

game_window = pyglet.window.Window()

@game_window.event
def on_draw():
    #dostuff

while __name__ == "__main__":
    pyglet.app.run()

我在将这段代码重组为一个类时遇到麻烦。我打算这样做的代码在这里:

import pyglet
from pyglet.gl import *
from Board import Board

class Frontend:
    def __init__(self,xs, ys):
        self.GameInstance = Board(xs,ys)
        self.GameWindow = pyglet.window.Window(width=512, height=512,visible=False)

    @GameWindow.event
    def on_draw(self):
        self.GameWindow.clear()

f = Frontend()

运行此代码时,出现以下错误:

Traceback (most recent call last):
  File "C:/Users/PycharmProjects/Nothing/2048/Frontend.py", line 7, in <module>
    class Frontend:
  File "C:/Users/PycharmProjects/Nothing/2048/Frontend.py", line 13, in Frontend
    @GameWindow.event
NameError: name 'GameWindow' is not defined

当我尝试用@GameWindow.event替换@self.GameWindow.event以解决NameError时得到:

Traceback (most recent call last):
    File "C:/Users/PycharmProjects/Nothing/2048/Frontend.py", line 7, in <module>
    class Frontend:
    File "C:/Users/PycharmProjects/Nothing/2048/Frontend.py", line 13, in Frontend
    @self.GameWindow.event
NameError: name 'self' is not defined

我期望。但是,我不确定该代码为什么不起作用-有人可以解释为什么以及如何解决它吗?

python class pyglet overriding
3个回答
5
投票

您可以inherit from Window。这应该工作:

class Frontend(pyglet.window.Window):
    def __init__(self, xs, ys):
        self.GameInstance = Board(xs,ys)
        super().__init__(width=512, height=512,visible=False)

    def on_draw(self):
        self.clear()

您的代码不起作用,因为您无法在方法之外引用Frontend类的实例。如果您只有Frontend类的一个实例,则可以执行以下操作:

class Frontend:
    window = pyglet.window.Window()
    def __init__(self):
        ...
    @window.event
    def on_draw():
        ...

2
投票

当我评论了ragezor的答案时,pyglet文档建议继承。

但是另一种选择是将事件处理逻辑作为EventDispatcher分隔在其自己的类中:http://pyglet.org/doc-current/programming_guide/events.html#creating-your-own-event-dispatcher

[就个人而言,如果我知道只有一个Frontend实例,我会质疑有一堂课的必要性。但这就是一堆蠕虫。以为我会给你另一个不错的选择,至少,尽管从Window继承,也不会出错,尤其是在所有事件都与Window相关的情况下。

第三个想法(自ragezor给您两个选择以来,我猜是第四个):

class Frontend:

def __init__(self,xs, ys):
    self.GameInstance = Board(xs,ys)
    self.GameWindow = pyglet.window.Window(width=512, height=512,visible=False)

    self.on_draw = self.GameWindow.event(self.on_draw)

def on_draw(self):
    self.GameWindow.clear()

换句话说,手动应用@GameWindow.event装饰器。

[最后一件事,不要使用驼峰式的属性,它违反了PEP8的约定,在编辑此代码时让我感到困惑。改名为game_window


-1
投票

我的猜测是您需要做

@self.Gamewindow.event
© www.soinside.com 2019 - 2024. All rights reserved.