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

如何向Pymunk碰撞处理器传递数据?解决数组更新报错问题

在Pymunk的separate碰撞处理器中正确传入并更新数组的方法

核心问题分析

你遇到的“set change in size iteration”错误,本质是在遍历集合(或列表)的同时直接修改其长度导致的。另外使用全局数组particles不仅代码耦合度高,也容易引发这类遍历修改冲突,正确的做法是通过Pymunk碰撞处理器的data参数传入数组,再安全地更新它。

解决方案步骤

1. 通过data参数传入数组,替代全局变量

注册碰撞处理器时,将particles和temperature等需要的参数作为data传入,这样在处理器函数中可以直接获取,无需依赖全局变量:

# 注册碰撞处理器并传入数据
handler = space.add_collision_handler(碰撞类型1, 碰撞类型2)
handler.separate = self.remove_particle1
# 将需要的变量存入handler的data字典
handler.data["particles"] = particles
handler.data["temperature"] = temperature

2. 安全更新数组:先收集待移除元素,再批量处理

不管particles是列表还是集合,都不要在遍历过程中直接修改原容器。先把需要移除的元素收集到临时列表,再一次性移除,避免遍历冲突:

def remove_particle1(self, arbiter, space, data): 
    particle1_shape = arbiter.shapes[0] 
    particle2_shape = arbiter.shapes[1]
    # 从data中取出需要的变量
    particles = data["particles"]
    temperature = data["temperature"]
    
    if temperature > 50:
        # 收集所有需要移除的粒子
        to_remove = []
        for particle in particles:
            if particle.body in (particle1_shape.body, particle2_shape.body):
                to_remove.append(particle)
        
        # 批量移除粒子
        for particle in to_remove:
            particles.remove(particle)
        
        # 从物理空间中移除对应的形状和刚体
        space.remove(particle1_shape, particle1_shape.body)
        space.remove(particle2_shape, particle2_shape.body)

补充说明

  • 如果particles是集合类型,批量移除可以用particles.difference_update(to_remove),效率更高;如果是列表,用上述循环remove即可(注意列表的remove是按元素值匹配,确保元素可唯一识别)。
  • 始终通过data传递碰撞处理器需要的外部变量,避免全局变量带来的耦合和不可预见的问题。

内容的提问来源于stack exchange,提问作者MatthewO

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 04:20:23