Python pgzrun游戏开发遇AttributeError: 'list'无'x'属性报错求助
错误排查与修复
你遇到的AttributeError: 'list' object has no attribute 'x'是代码中多处变量名拼写、命名冲突问题导致的,具体问题和修复方案如下:
核心错误原因
create_impostors函数中,你将生成的单个Actor对象追加到列表时,写错了变量名:
# 错误写法 new_impostors.append(impostors) # 正确写法 new_impostors.append(impostor)
这里impostors是你定义的全局空列表,导致new_impostors里的元素都是列表而非单个Actor对象,后续在layout_impostors中遍历修改x属性时,自然会报列表没有x属性的错误。
其他需要修复的错误
- 动画函数名拼写不一致:定义的函数名为
animation_impostors,但在make_impostors中调用的是animate_impostors,二者需要统一为相同名称。 - 全局动画列表变量名错误:初始定义的是
animation = [],后续代码全部使用复数animations操作,需要将初始定义改为animations = []。 - 动画创建时函数名写错:pgzero内置的动画创建函数是
animate,不是animation,同时要避免变量名和函数重名。 - 鼠标点击事件中循环变量覆盖全局列表:
for impostors in impostors会把全局的impostors列表覆盖,循环变量改为单数impostor即可。
修正后完整代码
import pgzrun import random FONT_COLOR = (255, 255, 255) #màu RGB WIDTH = 1300 HEIGHT = 700 CENTER_X = WIDTH / 2 CENTER_Y = HEIGHT / 2 CENTER = (CENTER_X, CENTER_Y) START_SPEED = 10 COLORS = ["orange", "blue"] current_level = 1 final_level = 5 game_over = False game_complete = False impostors = [] animations = [] def draw(): global impostors,current_level,game_over,game_complete screen.clear() screen.blit("dark",(0,0)) if game_over: display_message("Game Over", "Press Space to play again") elif game_complete: display_message("You win", "Press Space to play again") else: for im in impostors: im.draw() def update(): global impostors,current_level,game_over,game_complete if len(impostors) == 0: impostors = make_impostors(current_level) if (game_over or game_complete) and keyboard.space: impostors = [] current_level = 1 game_complete = False game_over = False def make_impostors(number_of_impostors): colors_to_create = get_colors_to_create(number_of_impostors) new_impostors = create_impostors(colors_to_create) layout_impostors(new_impostors) animate_impostors(new_impostors) return new_impostors def get_colors_to_create(number_of_impostors): colors_to_create = ["red"] for i in range(0,number_of_impostors): random_color = random.choice(COLORS) colors_to_create.append(random_color) return colors_to_create def create_impostors(colors_to_create): new_impostors = [] for color in colors_to_create: impostor = Actor(color + "-im") new_impostors.append(impostor) return new_impostors def layout_impostors(impostors_to_layout): number_of_gaps = len(impostors_to_layout) + 1 gap_size = WIDTH/number_of_gaps random.shuffle(impostors_to_layout) for index, impostor in enumerate(impostors_to_layout): new_x_pos = (index + 1)*gap_size impostor.x = new_x_pos def animate_impostors(impostors_to_animate): for impostor in impostors_to_animate: duration = START_SPEED - current_level impostor.anchor = ("center", "bottom") anim = animate(impostor, duration = duration, on_finished = handle_game_over, y = HEIGHT) animations.append(anim) def handle_game_over(): global game_over game_over = True def on_mouse_down(pos): global impostors, current_level for impostor in impostors: if impostor.collidepoint(pos): if "red" in impostor.image: red_impostor_click() else: handle_game_over() def red_impostor_click(): global current_level, impostors, animations, game_complete stop_animations(animations) if current_level == final_level: game_complete = True else: current_level = current_level + 1 impostors = [] animations = [] def stop_animations(animations_to_stop): for anim in animations_to_stop: if anim.running: anim.stop() def display_message(heading_text, sub_heading_text): screen.draw.text(heading_text, fontsize = 60, center = CENTER, color = FONT_COLOR) screen.draw.text(sub_heading_text, fontsize = 30, center = (CENTER_X, CENTER_Y + 30), color = FONT_COLOR) pgzrun.go()
内容的提问来源于stack exchange,提问作者Minh Trí Trần
相关产品推荐
相关产品推荐

