BlockLogic超类中的hit方法未被调用问题排查
问题分析与解决方案
核心问题
你的代码有几个关键问题导致按下L键没效果:
- 类定义放在主循环内部:每次循环都会重新定义
BlockLogic和BlockNorm类,之前的实例状态完全丢失。 - 每次循环创建新方块实例:旧的方块实例被销毁,修改后的尺寸无法保留,相当于每次循环都重新画两个新的20x20方块。
- 从未调用
hit方法:你只定义了hit方法,但代码里没有任何地方触发这个方法,自然不会执行尺寸修改逻辑。 - 按键检测位置错误:把L键检测放在
hit方法里,而hit又没被调用,所以print('test')永远不会执行。
修正步骤及代码
- 将类定义移到主循环外面,避免重复定义。
- 在循环外创建方块实例并保存到列表,循环内复用这些实例进行绘制和更新。
- 在主循环中检测L键按下,调用每个方块的
hit方法。 - 调整
BlockNorm的hit方法,移除内部的按键检测,只保留尺寸修改逻辑。
修正后的完整代码:
import pygame pygame.init() win = pygame.display.set_mode((800, 500)) # 类定义移到循环外面 class BlockLogic: def __init__(self, blen, bwid, posx, posy): self.blen = blen # 方块的长、宽、位置 self.bwid = bwid self.posx = posx self.posy = posy def hit(self): self.blen -= 5 # 每次按下L键,长宽各减5 self.bwid -= 5 if self.blen < 1: # 这里可以加入分数逻辑 pass class BlockNorm(BlockLogic): def __init__(self, posx=None, posy=None): super().__init__(20, 20, posx, posy) # 初始化普通方块的默认尺寸 def draw(self, win): # 把绘制逻辑单独抽成draw方法,避免在__init__里绘制 pygame.draw.rect(win, (250, 0, 0), (self.posx, self.posy, self.blen, self.bwid)) run = True # 循环外创建方块实例,保存到列表 blocks = [BlockNorm(200, 200), BlockNorm(500, 250)] while run: pygame.time.delay(100) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False keys = pygame.key.get_pressed() # 检测L键按下,调用每个方块的hit方法 if keys[pygame.K_l]: for block in blocks: block.hit() win.fill((0, 0, 0)) # 遍历方块列表,绘制每个方块 for block in blocks: block.draw(win) pygame.display.update() pygame.quit()
关键修改说明
- 把
BlockLogic和BlockNorm移到主循环外,确保类只定义一次。 - 新增
draw方法,把绘制逻辑从__init__中分离出来,__init__只负责初始化属性。 - 用列表
blocks保存方块实例,循环内复用这些实例,保证修改后的尺寸能被保留。 - 在主循环中检测L键,遍历所有方块调用
hit方法,触发尺寸修改。
内容的提问来源于stack exchange,提问作者user21004237
相关产品推荐
相关产品推荐

