如何解决这个 OOP 海龟游戏中的关键错误?

问题描述 投票:0回答:1

我正在尝试使用乌龟做一个 Pong 游戏来练习一点 OOP。我的目标是制作桨并设置它们的位置。

有两个不同的文件:

主要>

from turtle import Screen
from paddle import Paddle


screen = Screen()
screen.setup(width=800, height=600)
screen.bgcolor("blue")
screen.title("Pong Game")
screen.tracer(0)

r_paddle = Paddle((350, 0))
l_paddle = Paddle((-350, 0))

screen.update()

screen.listen()
screen.onkeypress(r_paddle.go_up, "Up")
screen.onkeypress(r_paddle.go_down, "Down")

screen.exitonclick()

和 Paddle 文件>

from turtle import Turtle


class Paddle(Turtle):

    def __int__(self, position):
        super().__init__()
        self.shape("square")
        self.color("white")
        self.shapesize(stretch_wid=5, stretch_len=1)
        self.penup()
        self.goto(position)

    def go_up(self):
        new_y = self.ycor() + 20
        self.goto(self.xcor(), new_y)

    def go_down(self):
        new_y = self.ycor() - 20
        self.goto(self.xcor(), new_y)

当我运行它时,出现错误:按键错误。

我尝试修改代码,将所有内容放在同一个文件中,谷歌搜索一些东西......直到现在我真的不明白为什么它不起作用。

python turtle-graphics python-turtle pong
1个回答
1
投票

错误是好事!您得到的不仅仅是 KeyError——您得到了发生错误的确切行以及导致错误的所有函数调用的堆栈跟踪:

Traceback (most recent call last):
  File "/home/g/programming/test.py", line 11, in <module>
    r_paddle = Paddle((350, 0))
  File "/usr/lib/python3.10/turtle.py", line 3815, in __init__
    RawTurtle.__init__(self, Turtle._screen,
  File "/usr/lib/python3.10/turtle.py", line 2545, in __init__
    self.turtle = _TurtleImage(screen, shape)
  File "/usr/lib/python3.10/turtle.py", line 2488, in __init__
    self._setshape(shapeIndex)
  File "/usr/lib/python3.10/turtle.py", line 2502, in _setshape
    self._type = screen._shapes[shapeIndex]._type
KeyError: (350, 0)

永远不要忽略这个错误,当您对代码有疑问时,请务必分享它。我们可以从这个错误中学到什么?我们了解到

(350, 0)
被传递到 RawTurtle 内部构造函数中,而一些在海龟库中初始化海龟的代码对此并不满意。下一步是尽量减少问题。可以用两行代码重现:

from turtle import RawTurtle

RawTurtle((350, 0))  # same KeyError

库不喜欢这个元组,但使用可选参数似乎确实没问题。它实际期望什么参数? 文档揭示:

乌龟类.RawTurtle(画布)

类乌龟.RawPen(画布)

参数

canvas – tkinter.Canvas、ScrolledCanvas 或 TurtleScreen

我们不会传递画布。但我们传递的参数不是似乎崩溃的

super().__init__()
调用的一部分。目的是我们将该元组传递给 our
Paddle
初始化器,而不是
super().__init__()
。奇怪的是,在堆栈跟踪中,我们甚至没有看到我们的
Paddle
构造函数被调用。通过在您希望控制流向的位置添加打印语句来进行调试:

class Paddle(Turtle):
    def __int__(self, position):
        print("This should print")

这个打印吗?否。再次检查初始化器:

def __int__(self, position):

看起来像是一个拼写错误:本意是

__init__
,而不是
__int__
。这就是修复!
Paddle()
正在从超类而不是我们的初始化器调用初始化器,就 Turtle 而言,由于拼写错误,它并不存在。

然而,由于一分预防胜于一分治疗,如果您完全避免对 Turtle 进行子类化,您将为自己节省大量未来的压力。始终使用组合,而不是使用乌龟继承。请参阅这篇文章了解详细说明。如果您没有对乌龟进行子类化,则错误会更容易调试:

Traceback (most recent call last):
  File "/home/greg/programming/test.py", line 11, in <module>
    r_paddle = Paddle((350, 0))
TypeError: Paddle() takes no arguments

这是产生上述更清晰错误的代码:

from turtle import Turtle


class Paddle:
    def __int__(self, position):  # typo: should be __init__
        self.turtle = t = Turtle()
        t.shape("square")
        t.color("white")
        t.shapesize(stretch_wid=5, stretch_len=1)
        t.penup()
        t.goto(position)

    def go_up(self):
        t = self.turtle
        new_y = t.ycor() + 20
        t.goto(t.xcor(), new_y)

    def go_down(self):
        t = self.turtle
        new_y = t.ycor() - 20
        t.goto(t.xcor(), new_y)

现在您的代码不再涉及海龟库的内部结构,如果您收到错误,就会清楚它来自哪里。

© www.soinside.com 2019 - 2024. All rights reserved.