Pyglet Batch对象无add()属性问题排查求助
Pyglet Batch对象无add()方法的问题
问题描述
我在Pyglet中查找的几乎所有向Batch添加顶点列表的示例都调用了Batch的add()方法,但我创建的Batch对象却没有该方法。我可以通过pyglet.shapes对象向Batch添加形状,但希望直接使用add()方法。
尝试的代码片段
import pyglet from pyglet.window import key class Player: def __init__(self, pos, color): self.pos = pos self.color = color self.speed = 5 def move(self, direction): if direction[0] == 0 and direction[1] == 0: return; self.pos = addV(self.pos, scaleV(direction, self.speed / magnitude(direction))) class Block: def __init__(self, x, y, w, h, nomask = False): self.nomask = nomask self.w, self.h = w, h self.l, self.r, self.b, self.t = x, x+w, y, y+h class MainWindow(pyglet.window.Window): def __init__(self): super().__init__() pyglet.clock.schedule_interval(self.update, 1/60.0) self.player = Player((10, 10), (255, 0, 0)) self.blocks = [Block(50, 50, 100, 50)] self.blockBatch = pyglet.graphics.Batch() for b in self.blocks: self.blockBatch.add(4, pyglet.gl.GL_POLYGON, None, ("v2i", (b.l,b.b,b.l,b.t,b.r,b.t,b.r,b.b)), ("c3B", (0,0,255)*4))
错误输出
Traceback (most recent call last): File "C:\Users\(me)\OneDrive\Desktop\Coding\Python\CTF\scripts\masktest.py", line 85, in <module> window = MainWindow() ^^^^^^^^^^^^ File "C:\Users\(me)\OneDrive\Desktop\Coding\Python\CTF\scripts\masktest.py", line 52, in __init__ self.blockBatch.add(4, pyglet.gl.GL_POLYGON, None, ("v2i", (b.l,b.b,b.l,b.t,b.r,b.t,b.r,b.b)), ("c3B", (0,0,255)*4)) ^^^^^^^^^^^^^^^^^^^ AttributeError: 'Batch' object has no attribute 'add'
原因及解决方案
这确实是版本差异导致的问题:
- Pyglet 1.x版本中,
pyglet.graphics.Batch确实提供add()方法用于直接添加顶点列表。 - 而在Pyglet 2.x版本中,官方重构了图形API,
Batch类不再直接提供add()方法,而是需要通过pyglet.graphics.vertex_list()或者pyglet.graphics.vertex_list_indexed()创建顶点列表后关联到Batch;或者使用pyglet.shapes模块的图形类(你已经能正常使用的方式)。
适配Pyglet 2.x的修改方案
如果使用的是Pyglet 2.x,调整代码即可实现相同功能:
import pyglet from pyglet.window import key # 补充代码中用到的辅助函数 def addV(v1, v2): return (v1[0]+v2[0], v1[1]+v2[1]) def scaleV(v, scale): return (v[0]*scale, v[1]*scale) def magnitude(v): return (v[0]**2 + v[1]**2)**0.5 class Player: def __init__(self, pos, color): self.pos = pos self.color = color self.speed = 5 def move(self, direction): if direction[0] == 0 and direction[1] == 0: return; self.pos = addV(self.pos, scaleV(direction, self.speed / magnitude(direction))) class Block: def __init__(self, x, y, w, h, nomask = False): self.nomask = nomask self.w, self.h = w, h self.l, self.r, self.b, self.t = x, x+w, y, y+h class MainWindow(pyglet.window.Window): def __init__(self): super().__init__() pyglet.clock.schedule_interval(self.update, 1/60.0) self.player = Player((10, 10), (255, 0, 0)) self.blocks = [Block(50, 50, 100, 50)] self.blockBatch = pyglet.graphics.Batch() for b in self.blocks: # 使用vertex_list创建顶点列表并关联到Batch vertices = (b.l,b.b,b.l,b.t,b.r,b.t,b.r,b.b) colors = (0,0,255)*4 pyglet.graphics.vertex_list(4, ('v2i', vertices), ('c3B', colors), batch=self.blockBatch) def update(self, dt): # 补充update方法避免报错 pass if __name__ == "__main__": window = MainWindow() pyglet.app.run()
另外,如果你坚持要使用add()方法的语法,可以降级到Pyglet 1.x版本(比如执行pip install pyglet==1.5.27),原代码即可正常运行。
内容的提问来源于stack exchange,提问作者Aledax
相关产品推荐
相关产品推荐

