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

碰撞时如何摧毁防护墙周边方块?求邻接方块坐标获取方案

解决防护墙邻接矩形摧毁问题

核心思路

要实现碰撞时摧毁目标矩形及其左右、下方邻接块,关键是给每个防护墙矩形标记网格坐标(即生成时的i列索引和j行索引),通过坐标快速定位邻接块后统一删除。


步骤1:给Boden类添加网格坐标属性

生成防护墙时,每个矩形是按i(列)、j(行)循环创建的,把这两个索引作为实例属性存下来,方便后续定位邻接块。

快速修改方式:直接给实例加属性

for j in range(int(bodenebenen)):              
    for i in range(int(bodenspalten)):
        m = Boden(int(i)*bodenbreite, int(j)*bodenhoehe, int(bodenbreite), int(bodenhoehe), 620, schutzcolor[random.randint(0, len(schutzcolor)-1)])
        # 标记当前矩形的网格坐标
        m.grid_i = i
        m.grid_j = j
        protectivewall.add(m)
        alle_sprites.add(m)

规范修改方式:调整Boden类初始化

class Boden(pygame.sprite.Sprite):
    def __init__(self, x, y, width, height, param, color, grid_i, grid_j):
        super().__init__()
        # 原有初始化逻辑(比如创建rect、设置颜色等)
        self.rect = pygame.Rect(x, y, width, height)
        self.color = color
        # 新增网格坐标属性
        self.grid_i = grid_i
        self.grid_j = grid_j

# 创建防护墙时传入网格坐标
for j in range(int(bodenebenen)):              
    for i in range(int(bodenspalten)):
        m = Boden(int(i)*bodenbreite, int(j)*bodenhoehe, int(bodenbreite), int(bodenhoehe), 620, schutzcolor[random.randint(0, len(schutzcolor)-1)], i, j)
        protectivewall.add(m)
        alle_sprites.add(m)

步骤2:捕获碰撞并处理邻接块

不要直接用groupcollide的True,True参数立即删除对象,先收集所有要摧毁的矩形,再批量删除:

# 获取碰撞关系,暂不删除任何对象
hits = pygame.sprite.groupcollide(bombs, protectivewall, False, False)

# 用集合存储待删除矩形(避免重复)
to_remove = set()

for bomb, collided_blocks in hits.items():
    # 先把碰撞的矩形加入待删除集合
    to_remove.update(collided_blocks)
    
    for block in collided_blocks:
        # 定义邻接网格坐标:左(i-1,j)、右(i+1,j)、下(i,j+1)
        adjacent_grids = [
            (block.grid_i - 1, block.grid_j),
            (block.grid_i + 1, block.grid_j),
            (block.grid_i, block.grid_j + 1)
        ]
        
        # 遍历防护墙,匹配邻接坐标的矩形
        for candidate in protectivewall:
            if (candidate.grid_i, candidate.grid_j) in adjacent_grids:
                to_remove.add(candidate)
    
    # 摧毁当前炸弹
    bomb.kill()

# 批量删除所有待摧毁的防护墙矩形
for block in to_remove:
    block.kill()

优化:用字典加速邻接块查找

如果防护墙数量较多,遍历全部块找邻接会影响性能,可以提前构建网格坐标到矩形实例的映射字典:

# 创建防护墙时同时构建坐标映射字典
grid_map = {}
for j in range(int(bodenebenen)):              
    for i in range(int(bodenspalten)):
        m = Boden(int(i)*bodenbreite, int(j)*bodenhoehe, int(bodenbreite), int(bodenhoehe), 620, schutzcolor[random.randint(0, len(schutzcolor)-1)], i, j)
        protectivewall.add(m)
        alle_sprites.add(m)
        grid_map[(i, j)] = m

# 处理碰撞时直接通过字典查找邻接块
hits = pygame.sprite.groupcollide(bombs, protectivewall, False, False)
to_remove = set()

for bomb, collided_blocks in hits.items():
    to_remove.update(collided_blocks)
    
    for block in collided_blocks:
        adjacent_grids = [
            (block.grid_i - 1, block.grid_j),
            (block.grid_i + 1, block.grid_j),
            (block.grid_i, block.grid_j + 1)
        ]
        # 直接从字典取邻接块,无需遍历全部防护墙
        for grid in adjacent_grids:
            if grid in grid_map:
                to_remove.add(grid_map[grid])
    
    bomb.kill()

for block in to_remove:
    block.kill()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 13:05:41