蛇游戏开发中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
相关产品推荐
相关产品推荐

