如何在Pygame中使用Python字典实现瓦片的放置与删除?
解决瓦片重复生成卡顿的问题
问题出在哪
TileDict白定义了:你把它放在for blocks in TileGroup循环里,每次循环都重置成空列表,根本存不住已放置的瓦片位置。- 位置判断逻辑错了:用
x/y当位置标识,比如(20,20)和(40,40)算出来都是1,会把不同位置当成同一个,要么漏生成要么误判。 - 右键按住狂生成:
pygame.mouse.get_pressed()只要按住就一直返回True,每帧都跑生成代码,瞬间堆一堆瓦片不卡才怪。 - 列表查存在太慢:用列表判断位置是否存在,瓦片越多越卡,字典的查询速度是O(1),比列表高效多了。
改好的代码
# 把TileDict提到循环外面,作为全局或类成员变量,用来存已放置的瓦片位置 TileDict = {} # 加个变量记录上一帧右键状态,防止按住持续生成 last_rmb = False for blocks in TileGroup: lmb, rmb = pygame.mouse.get_pressed()[0], pygame.mouse.get_pressed()[2] mouse_x, mouse_y = pygame.mouse.get_pos() mouse_hover = blocks.rect.collidepoint(mouse_x, mouse_y) # 左键删除逻辑,删完同步更新字典 if lmb and mouse_hover: pos_key = (blocks.rect.x, blocks.rect.y) if pos_key in TileDict: del TileDict[pos_key] blocks.kill() # 把右键生成逻辑移到循环外面,不用遍历每个瓦片都跑一遍 if rmb: # 计算对齐后的瓦片坐标,用元组当字典的键,唯一标识位置 x = mouse_x - (mouse_x % 20) y = mouse_y - (mouse_y % 20) pos_key = (x, y) # 只有右键刚按下(不是按住)且位置没瓦片时才生成 if not last_rmb and pos_key not in TileDict: platform = ground(x, y) TileDict[pos_key] = platform # 把瓦片存进字典,方便后续操作 TileGroup.add(platform) last_rmb = rmb
核心改进
- 用字典存位置:以
(x,y)坐标元组为键,瓦片对象为值,查位置是否存在秒出结果,比列表快太多。 - 修复位置标识:坐标元组是每个瓦片位置的唯一标识,不会像
x/y那样出现重复。 - 限制右键单次触发:通过
last_rmb记录上一帧状态,只有右键从松到按的瞬间才生成,按住不会重复生成。 - 删瓦片同步更新字典:删完瓦片必须把字典里对应的键删掉,不然下次没法在这个位置重新放。
内容的提问来源于stack exchange,提问作者Dergus
相关产品推荐
相关产品推荐

