我的pygame运行速度太慢。在不使用类oop的情况下,它运行得很好,但是现在在使用oop时,它的运行速度非常慢。
我已经测试了将单独的类文件也放入主文件中,但是结果是相同的。
import pygame
from snake import Snake
pygame.init()
surf_width = 800
surf_height = 600
clock = pygame.time.Clock()
dis_surf = pygame.display.set_mode((surf_width, surf_height))
pygame.display.set_caption("snake game")
run = True
def game_loop():
x = 255
y = 255
x_change = 0
y_change = 0
while run:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
dis_surf.fill((255, 255, 255))
game = Snake(dis_surf, x, y, x_change, y_change)
x = game.x
y = game.y
另一个文件: 导入pygame
class Snake():
def __init__(self, dis_surf, x, y, x_change, y_change):
self.dis_surf = dis_surf
self.x = x
self.y = y
self.width = 20
self.height = 20
self.x_change = x_change
self.y_change = y_change
self.vel = 5
self.draw()
def draw(self):
pygame.draw.rect(self.dis_surf, (0, 255, 0), (self.x, self.y, self.width, self.height))
self.run()
pygame.display.update()
def run(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
self.x_change = self.vel
self.y_change = 0
elif event.key == pygame.K_LEFT:
self.x_change = -self.vel
self.y_change = 0
elif event.key == pygame.K_UP:
self.y_change = -self.vel
self.x_change = 0
elif event.key == pygame.K_DOWN:
self.y_change = self.vel
self.x_change = 0
print(event)
self.x += self.x_change
self.y += self.y_change
x_change = game.x_change
y_change = game.y_change
pygame.display.update()
clock.tick(60)
game_loop()
答案 0 :(得分:1)
有些错误。
1)在while循环中执行Snake
时,您将在每个游戏循环中实例化一个新的 game = Snake()
类。结合数字2是您的主要问题。我为您将这一行移到了while循环之外。
2)您正在呼叫 run()
__init__
内部。这是您永远不要在构造函数中执行的操作,构造函数通常仅应用于设置初始数据。这也极大地导致了问题1的出现,因为这在每个游戏循环中都会发生。我为您删除了self.run()
内部的呼叫__init__
。
3)pygame.display.update()
被叫了两次。不是造成问题的原因,但仍然没有必要。
为您进行一些小更正。
import pygame
pygame.init()
surf_width = 800
surf_height = 600
clock = pygame.time.Clock()
dis_surf = pygame.display.set_mode((surf_width, surf_height))
pygame.display.set_caption("snake game")
run = True
def game_loop():
x = 255
y = 255
x_change = 0
y_change = 0
game = Snake(dis_surf, x, y, x_change, y_change)
while run:
dis_surf.fill((255, 255, 255))
game.draw()
class Snake():
def __init__(self, dis_surf, x, y, x_change, y_change):
self.dis_surf = dis_surf
self.x = x
self.y = y
self.width = 20
self.height = 20
self.x_change = x_change
self.y_change = y_change
self.vel = 5
def draw(self):
pygame.draw.rect(self.dis_surf, (0, 255, 0), (self.x, self.y, self.width, self.height))
self.run()
def run(self):
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
self.x_change = self.vel
self.y_change = 0
elif event.key == pygame.K_LEFT:
self.x_change = -self.vel
self.y_change = 0
elif event.key == pygame.K_UP:
self.y_change = -self.vel
self.x_change = 0
elif event.key == pygame.K_DOWN:
self.y_change = self.vel
self.x_change = 0
self.x += self.x_change
self.y += self.y_change
pygame.display.update()
clock.tick(60)
game_loop()
答案 1 :(得分:0)
如果要在pygame中使用OOP,请使用pygame的Sprite
类。正是为此目的而制作的。
您的代码应如下所示(我尝试更改的幅度不大):
import pygame
pygame.init()
surf_width = 800
surf_height = 600
clock = pygame.time.Clock()
screen = pygame.display.set_mode((surf_width, surf_height))
pygame.display.set_caption("snake game")
class Snake(pygame.sprite.Sprite):
def __init__(self, pos):
super().__init__()
self.image = pygame.Surface((20, 20))
self.image.fill(pygame.Color('orange'))
self.rect = self.image.get_rect(topleft=pos)
self.x_change = 0
self.y_change = 0
self.vel = 5
def update(self, events):
for event in events:
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
self.x_change = self.vel
self.y_change = 0
elif event.key == pygame.K_LEFT:
self.x_change = -self.vel
self.y_change = 0
elif event.key == pygame.K_UP:
self.y_change = -self.vel
self.x_change = 0
elif event.key == pygame.K_DOWN:
self.y_change = self.vel
self.x_change = 0
self.rect.move_ip(self.x_change, self.y_change)
def main():
snake = Snake((0, 0))
snakes = pygame.sprite.Group(snake)
while True:
events = pygame.event.get()
for event in events:
if event.type == pygame.QUIT:
return
snakes.update(events)
screen.fill((30, 30, 30))
snakes.draw(screen)
pygame.display.flip()
clock.tick(60)
if __name__ == '__main__':
main()
确保每帧只调用一次pygame.display.flip()
和pygame.event.get()
。
如果要处理代码其他部分中的事件,只需将当前框架的事件存储在变量中并传递它们即可。使用Group
可以简化此过程。
看看我们如何明确区分游戏逻辑:
主循环仅执行应做的三件事。处理事件,更新游戏状态并绘制到屏幕上。这样做是在游戏中没有“知道实际发生了什么”的情况。
Snake
子画面仅在主循环告知时才响应(调用其update
方法时),并且它并不关心事件的来源以及实际显示方式和位置