好吧,我用inventwithpython来教自己如何编码。我试图以我自己的方式重用代码来理解它是如何工作的,但这一部分给我带来了麻烦:
在Chapter 17中有一组动画代码,其中不同大小的框从屏幕的侧面反弹
for b in blocks:
# move the block data structure
if b['dir'] == DOWNLEFT:
b['rect'].left -= MOVESPEED
b['rect'].top += MOVESPEED
if b['dir'] == DOWNRIGHT:
b['rect'].left += MOVESPEED
b['rect'].top += MOVESPEED
if b['dir'] == UPLEFT:
b['rect'].left -= MOVESPEED
b['rect'].top -= MOVESPEED
if b['dir'] == UPRIGHT:
b['rect'].left += MOVESPEED
b['rect'].top -= MOVESPEED
# check if the block has move out of the window
if b['rect'].top < 0:
# block has moved past the top
if b['dir'] == UPLEFT:
b['dir'] = DOWNLEFT
if b['dir'] == UPRIGHT:
b['dir'] = DOWNRIGHT
if b['rect'].bottom > WINDOWHEIGHT:
# block has moved past the bottom
if b['dir'] == DOWNLEFT:
b['dir'] = UPLEFT
if b['dir'] == DOWNRIGHT:
b['dir'] = UPRIGHT
if b['rect'].left < 0:
# block has moved past the left side
if b['dir'] == DOWNLEFT:
b['dir'] = DOWNRIGHT
if b['dir'] == UPLEFT:
b['dir'] = UPRIGHT
if b['rect'].right > WINDOWWIDTH:
# block has moved past the right side
if b['dir'] == DOWNRIGHT:
b['dir'] = DOWNLEFT
if b['dir'] == UPRIGHT:
b['dir'] = UPLEFT
我想创建它,使我的块左右移动,并反弹到屏幕的每一边。在
然而,当我尝试自己对代码进行更改时,所发生的一切就是块飞离屏幕而不反弹。尝试了几种不同的方法,结果都是一样的。目前是这样的: 编辑:更新完整代码
^{pr2}$
代码中的问题只是混淆了缩进。如果修复了缩进,则可以正常工作:
Python使用缩进来判断什么嵌套在什么里面。在C和其他使用大括号或其他块分隔符的语言中,只要将大括号放在正确的位置,就可以避免错误的缩进。但是在Python中,缩进非常关键。即使在其他语言中,缩进仍然是关键的(如果其他语言都不关心的话)
将您的代码版本与上面的代码进行比较,您将看到哪里需要修复缩进。在
现在来讨论一个更大的问题。来自Python网站的示例代码是。。。说得好,不太好。在
假设您对编程一无所知,只需浏览一下您开始使用的原始代码。好像有大量的重复吗?在
而且很难重复。看看它管理使用
DOWNLEFT
、DOWNRIGHT
、UPLEFT
、UPRIGHT
的所有不同方法,以及代码如何在每次都要如此小心才能正确地使用它。在任何时候,当你想写这种复杂的代码时,停下来,坐下来,问问自己,“有没有一种更简单的方法可以做到这一点?”在
事实上,你确实走在了正确的轨道上,去掉了一堆复杂的代码,为你的实验做了一些更简单的事情。在
但为了好玩,让我们回到他们的代码,看看我们如何简化它,但仍然做它所做的一切。在
从这四个名字开始,
DOWNLEFT
等等。为什么每个名字都有自己的名字?它们不是基本上都是一样的吗?它们都是对角线,只是不同方向的对角线。在正如名字所暗示的,对角线实际上是两个方向的组合,垂直和水平。在
现在,我们如何指定屏幕/窗口上的位置?我们没有给每个可能的位置命名,而是给它一个带有
x
和y
值的坐标。最左边,最上面的像素是x=0, y=0
,我们从那里开始,加一个向右或向下,减去一个向左或向上。在因此,我们不用为四个对角线方向编造名称,而是使用实际数字!我们将},等等
DOWNRIGHT
表示为x=1, y=1
,UPLEFT
表示为{现在一件美妙的事情发生了。考虑检查左边缘反弹的代码(
if b['rect'].left < 0
)。我们可以忽略y
方向,只需将x=-1
改为x=1
,而不必做特殊的情况来改变。在从右边缘反弹也一样,只是我们将
x=1
更改为x=-1
。实际上,您可以通过将x
乘以-1
来处理这两种情况。在所以我们可以这样做:如果我们碰到左边或右边,我们用
x
方向乘以-1
。上下边缘和y
方向也是一样的。在以下是原始代码的修订版,它实现了这一点,并进行了一些其他简化:
^{pr2}$我还为块和方向创建了类,而不是全部使用内联代码。请注意,主“移动并绘制”循环现在只是三行代码,而不是原始代码中巨大的复杂混乱。在
从你的背景来看,你应该很熟悉这些课程。Python中的表示法有点不同-例如,
__init__()
是构造函数-但是概念非常相似。如果代码中有任何不清楚的地方,请告诉我。在还有一个小错误修复:原始代码允许块在反转之前越过屏幕的边缘,所以我调整了边缘测试,在它越过边缘之前进行反转。这就是为什么它说,例如,}。在
if self.rect.left < SPEED
而不是{相关问题 更多 >
编程相关推荐