You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 19:25:41