我正在尝试为我的A-Level最终项目学习PyGame,并且我已经开始使用Atari Breakout。我有一个球在球拍周围跳出的阶段。但是代码非常不整洁所以我想把它放到函数中。
代码无需函数:
import pygame, sys
from pygame.locals import *
pygame.init()
DISPLAYSURF = pygame.display.set_mode((1280, 720))
pygame.display.set_caption('Breakout')
padX = 310
padY = 680
dotX = 150
dotY = 150
dotMX = -1
dotMY = -1
loss = False
while loss != True:
DISPLAYSURF.fill(pygame.Color(0,0,0))
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEMOTION:
padX = event.pos[0]-75
if padX < 3:
padX = 3
elif padX > 1127:
padX = 1127
pygame.draw.rect(DISPLAYSURF, pygame.Color(0, 0, 255),(padX, padY, 150, 30))
dotX += dotMX
dotY += dotMY
if dotY >= 720 - 30:
loss = True
#hor colis
if dotX <= 0 + 20:
if dotMX == 1:
dotMX = -1
else:
dotMX = 1
elif dotX >= 1280 - 20:
if dotMX == 1:
dotMX = -1
else:
dotMX = 1
#vert colis
if dotY <= 0 - 20:
if dotMY == 1:
dotMY = -1
else:
dotMY = 1
elif dotY >= 720 - 20:
if dotMY == 1:
dotMY = -1
else:
dotMY = 1
#pad colis
if dotX >= padX and dotX <= padX + 150 and dotY == 665:
if dotMY == 1:
dotMY = -1
else:
dotMY = 1
pygame.draw.circle(DISPLAYSURF, pygame.Color(255,0,0), (dotX, dotY), 20)
pygame.display.update()
但是这里是它,但分为功能:
import pygame, sys
from pygame.locals import *
DISPLAYSURF = pygame.display.set_mode((1280, 720))
padX = 310
padY = 680
dotX = 150
dotY = 150
dotMX = -1
dotMY = -1
lives = 5
def main(padX, padY, dotX, dotY, dotMX, dotMY, lives):
pygame.init()
pygame.display.set_caption('Breakout')
while lives != 0:
DISPLAYSURF.fill(pygame.Color(0,0,0))
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEMOTION:
padX = event.pos[0]-75
if padX < 3:
padX = 3
elif padX > 1127:
padX = 1127
pygame.draw.rect(DISPLAYSURF, pygame.Color(0, 0, 255),(padX, padY, 150, 30))
dotX += dotMX
dotY += dotMY
colis(dotX, dotY, dotMX, dotMY, padX, padY, lives)
pygame.display.update()
def colis(dotX, dotY, dotMX, dotMY, padX, padY, lives):
if dotY >= 720 - 30:
lives -= 1
#hor colis
if dotX <= 0 + 20:
if dotMX == 1:
dotMX = -1
else:
dotMX = 1
elif dotX >= 1280 - 20:
if dotMX == 1:
dotMX = -1
else:
dotMX = 1
#vert colis
if dotY <= 0 - 20:
if dotMY == 1:
dotMY = -1
else:
dotMY = 1
elif dotY >= 720 - 20:
if dotMY == 1:
dotMY = -1
else:
dotMY = 1
#pad colis
if dotX >= padX and dotX <= padX + 150 and dotY == 665:
if dotMY == 1:
dotMY = -1
else:
dotMY = 1
pygame.draw.circle(DISPLAYSURF, pygame.Color(255,0,0), (dotX, dotY), 20)
main(padX, padY, dotX, dotY, dotMX, dotMY, lives)
任何人都可以看到为什么它在分离成函数时不起作用?对不起,如果它是一个愚蠢的简单修复,我仍然缺乏python经验。 谢谢!
为了澄清,通过功能,球飞向左上方并消失!
答案 0 :(得分:0)
我可以看到第二块cede的几个问题。第一个与格式有关。你有线,比如
self.tableWidget.setItem(...
这将不允许您编译代码,因为它受到不正确缩进的影响。 第二个问题是,你将一些变量传递给函数,在函数内修改它们,但你没有返回它们。
函数参数是名称。当您调用函数时,Python会将这些参数绑定到您传递的任何对象(通过调用方范围中的名称)。 对象可以是可变的(如列表)或不可变的(如Python中的整数,字符串)。
作为dotX,dotY,dotMX,todMY,padX,padY,生命是整数,你不能修改它们有副作用,它们需要从函数返回。 我建议创建一个类或使用一些数据结构来传递和返回所有必要的参数。
要快速检查,您可以通过在其末尾添加返回状态网络来修改if dotY >= 720 - 30
lives -= 1
功能,例如
colis
并将调用更改为return (dotX, dotY, dotMX, dotMY, padX, padY, lives)
函数中的函数,如下所示
main
在你明白了之后,你可以开始进一步的重构,因为我的更新不是那么优雅和干净。
答案 1 :(得分:0)
您正在将函数传递给函数(colis
),在函数内部重新定义它们,但这些更改不会反映在函数之外(这就是Python的工作原理)。
最简单的更改只是返回colis
中更改的三个变量,并将这些更改传播到main
:
def colis(dotX, dotY, dotMX, dotMY, padX, padY, lives):
...
pygame.draw.circle(DISPLAYSURF, pygame.Color(255,0,0), (dotX, dotY), 20)
return dotMX, dotMY, lives # This line
和
def main(padX, padY, dotX, dotY, dotMX, dotMY, lives):
...
dotX += dotMX
dotY += dotMY
dotMX, dotMY, lives = colis(dotX, dotY, dotMX, dotMY, padX, padY, lives) # This line
pygame.display.update()
“更好”的方法(可能在未来)可能是为那些可以传递给{{1}的参数(例如Dot
,Pad
)定义和实例化类对象。功能。
(完整代码)
colis
答案 2 :(得分:0)
好的,这是对您的代码的简单修复,您没有正确使用全局变量:
import pygame
import sys
from pygame.locals import *
DISPLAYSURF = pygame.display.set_mode((1280, 720))
padX = 310
padY = 680
dotX = 150
dotY = 150
dotMX = -1
dotMY = -1
lives = 5
def main():
global padX, padY, dotX, dotY, dotMX, dotMY, lives
pygame.init()
pygame.display.set_caption('Breakout')
while lives != 0:
DISPLAYSURF.fill(pygame.Color(0, 0, 0))
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEMOTION:
padX = event.pos[0] - 75
if padX < 3:
padX = 3
elif padX > 1127:
padX = 1127
pygame.draw.rect(DISPLAYSURF, pygame.Color(
0, 0, 255), (padX, padY, 150, 30))
dotX += dotMX
dotY += dotMY
colis()
pygame.display.update()
def colis():
global padX, padY, dotX, dotY, dotMX, dotMY, lives
if dotY >= 720 - 30:
lives -= 1
# hor colis
if dotX <= 0 + 20:
if dotMX == 1:
dotMX = -1
else:
dotMX = 1
elif dotX >= 1280 - 20:
if dotMX == 1:
dotMX = -1
else:
dotMX = 1
# vert colis
if dotY <= 0 - 20:
if dotMY == 1:
dotMY = -1
else:
dotMY = 1
elif dotY >= 720 - 20:
if dotMY == 1:
dotMY = -1
else:
dotMY = 1
# pad colis
if dotX >= padX and dotX <= padX + 150 and dotY == 665:
if dotMY == 1:
dotMY = -1
else:
dotMY = 1
pygame.draw.circle(DISPLAYSURF, pygame.Color(255, 0, 0), (dotX, dotY), 20)
if __name__ == "__main__":
main()
这是你的代码有点重构,使用PEP8和更多OOP方法(有点):
import pygame
import sys
from pygame.locals import *
class Game():
def __init__(self):
self.pad_x = 310
self.pad_y = 680
self.dot_x = 150
self.dot_y = 150
self.dot_mx = -1
self.dot_my = -1
self.lives = 5
def run(self):
self.display = pygame.display.set_mode((1280, 720))
pygame.init()
pygame.display.set_caption('Breakout')
while self.lives != 0:
self.display.fill(pygame.Color(0, 0, 0))
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEMOTION:
self.pad_x = event.pos[0] - 75
if self.pad_x < 3:
self.pad_x = 3
elif self.pad_x > 1127:
self.pad_x = 1127
pygame.draw.rect(self.display, pygame.Color(
0, 0, 255), (self.pad_x, self.pad_y, 150, 30))
self.dot_x += self.dot_mx
self.dot_y += self.dot_my
self.colis()
pygame.display.update()
def colis(self):
if self.dot_y >= 720 - 30:
self.lives -= 1
# hor colis
if self.dot_x <= 0 + 20:
if self.dot_mx == 1:
self.dot_mx = -1
else:
self.dot_mx = 1
elif self.dot_x >= 1280 - 20:
if self.dot_mx == 1:
self.dot_mx = -1
else:
self.dot_mx = 1
# vert colis
if self.dot_y <= 0 - 20:
if self.dot_my == 1:
self.dot_my = -1
else:
self.dot_my = 1
elif self.dot_y >= 720 - 20:
if self.dot_my == 1:
self.dot_my = -1
else:
self.dot_my = 1
# pad colis
if self.dot_x >= self.pad_x and self.dot_x <= self.pad_x + 150 and self.dot_y == 665:
if self.dot_my == 1:
self.dot_my = -1
else:
self.dot_my = 1
pygame.draw.circle(self.display, pygame.Color(
255, 0, 0), (self.dot_x, self.dot_y), 20)
if __name__ == "__main__":
Game().run()