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

蛇游戏开发中Bomb类出现AttributeError错误的排查求助

蛇游戏添加炸弹触发Game Over时出现AttributeError错误

错误追踪信息

Traceback (most recent call last):
  File "/Users/adityakumar/PycharmProjects/SnakeGame/venv/main.py", line 26, in <module>
    bomb = Bomb()
           ^^^^^^
  File "/Users/adityakumar/PycharmProjects/SnakeGame/venv/bomb.py", line 13, in __init__
    self.shape("bombshape") #actually make the shape the bomb here
    ^^^^^^^^^^^^^^^^^^^^^^^
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/turtle.py", line 2778, in shape
    self.turtle._setshape(name)
  File "/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/turtle.py", line 2494, in _setshape
    if self._type == "polygon" == screen._shapes[shapeIndex]._type:
                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'str' object has no attribute '_type'

Process finished with exit code 1

相关代码

主文件代码

# 
# **Main file:**
# 
#main project workspace here:

#Date: 17th of August, 2023

#1. Creating the turtle sprite => the body
from turtle import Screen
from snake import Snake
from food import Food
from scoreboard import Scoreboard
import time
from bomb import Bomb

#setting up the screen to play:
screen = Screen()
screen.setup(width = 600, height = 600) #put dimensions of screen here, width x height
#KEYWORD ARGUMENTS => avid confusion
screen.bgcolor("black") #put this before the exitonclick or the program will wait for a click     before turning it black
screen.title("The Snake Game made by an amateur programmer!") #put the title at the top of     the screen
#STEP 1: Creating the snake body
screen.tracer(0) #the tracer is off

snake = Snake() #create a snake object
food = Food()
highScore = 0
scoreboard = Scoreboard() #NO ARGUMENTS
bomb = Bomb()


#DATE: 21ST OF AUGUST, 2023: CONTROLLING THE SNAKE => REFER TO SNAKE CLASS AS WELL
screen.listen() #to make the computer "listen" to key-presses
screen.onkey(snake.up, "Up") #bind these keys to a function, e.g snake.up
screen.onkey(snake.down, "Down")
screen.onkey(snake.left, "Left")
screen.onkey(snake.right, "Right")


#Date: 18th of August, 2023:
#STEP 2: ANIMATING THE SNAKE => CHECK SNAKE CLASS

gameOn = True #set a condition to create a while loop
while gameOn:
    screen.update()  # the entirety of the snake shows, putting this outside the for loop makes    the whole snake block move

    time.sleep(0.1)  #delays the execution of the program, makes it faster here => decimals


    if snake.head.distance(food) < 15:
        #print("FOOD DIGESTED")
        food.refresh() #call the function from the food class here
        scoreboard.increaseScore() #call function from Scoreboard class
        snake.grow()

    if abs(snake.head.xcor()) > 290 or abs(snake.head.ycor()) > 290:
        gameOn = False
        scoreboard.GAMEOVER() #call gameover function stored in the scoreboard class


    #if head crashes into snake body: the game is over
    for segment in snake.segments[1:]: #after the second segment, second segment onwards
        if snake.head.distance(segment) < 10:
            gameOn = False
            scoreboard.GAMEOVER()

    if snake.head.distance(bomb) < 15:
        gameOn = False
        scoreboard.GAMEOVER()
        screen.write("EXPLODED", align = "center", font = ("Courier", 18, "normal"))

screen.exitonclick() #to exit the screen upon clicking

Bomb类代码

from turtle import Turtle
import random

class Bomb(Turtle):
    def __init__(self):
        super().__init__() #don't put anything in there
        self.screen = self.getscreen() #return the object referred to
        #get the screen object to return the objects(e.g the bomb) associated with it
        self.screen.register_shape("bombshape", "/Users/adityakumar/Desktop/bomb.png") #put the filename here
        #((NO ERRORS: CODE WORKS: IMAGE IS REGISTERED))
        self.shape("bombshape") #actually make the shape the bomb here
        #the shape is registered first, then the shape is changed afterward
        self.penup() #to not draw
        #THIS WILL MAKE THE BOMB APPEAR => NOTHING HAPPENS YET
        #CREATE AN IF STATEMENT IN MAIN.PY TO INTERACT WITH IT

问题原因与解决方法

原因

turtle.register_shape() 方法注册图片形状时,只需要传入图片路径作为唯一参数。你错误地传入了两个参数(自定义名称+路径),导致注册的形状不是有效的图形对象,而是字符串,调用self.shape("bombshape")时就会触发AttributeError。

解决方法

修改Bomb类中register_shape的调用方式,直接传入图片路径,并用路径作为形状名称,或者省略自定义名称:

修改后的Bomb类代码:

from turtle import Turtle
import random

class Bomb(Turtle):
    def __init__(self):
        super().__init__()
        self.screen = self.getscreen()
        # 直接传入图片路径注册形状
        self.screen.register_shape("/Users/adityakumar/Desktop/bomb.png")
        # 使用图片路径作为形状名称
        self.shape("/Users/adityakumar/Desktop/bomb.png")
        self.penup()
        # 让炸弹随机出现在游戏区域内
        self.goto(random.randint(-280, 280), random.randint(-280, 280))

如果一定要用自定义名称bombshape,需要确保注册的是符合要求的形状数据。对于静态图片,更简单的方式是直接使用路径作为形状名,避免额外的参数错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 15:47:10