如何解决Pygame 窗口未更新
我正在编写一个小型的 Python 游戏,只是为了学习如何更好地使用 Python。我想尝试开始使用多个脚本,因为将所有代码保存在一个脚本中可能会有点拥挤。我制作了第二个脚本,创建了一个函数 main(scrn),一切似乎都运行良好。在我的主脚本 game.py 中调用该函数,它将创建屏幕并显示 main(scrn) 函数中的所有内容。但是,什么都不会更新。我的角色根本不会移动,使用我之前测试过的重力控制器,或者向左或向右。我尝试将角色控制器从 hi.py 脚本 (main(scrn)) 移动到 while Running: 函数,但仍然没有移动。然后我尝试将 main(scrn) 函数移回我的原始脚本,但它仍然不起作用。好像什么都没有更新。 这是组合脚本,描述中提到的最后一个
import pygame
from pygame.locals import *
pygame.init()
SIZE = 800,600
screen = pygame.display.set_mode(SIZE)
def main(scrn):
#VARIABLES
RED = (255,0)
GRAY = (150,150,150)
DGRAY = (75,75,75)
rx = 0
ry = 450
x = 50
y = 50
grounded = False
grv = 0
acc = .1
ground = Rect(rx,ry,200,800)
ch = Rect(x,y,50,50)
#INPUT MOVEMENT
pressed = pygame.key.get_pressed()
if pressed[pygame.K_RIGHT]:
x += 3
if pressed[pygame.K_LEFT]:
x -= 3
if pressed[pygame.K_UP] and grounded:
for z in range(1):
grv = -5
grounded = False
#GraviTY
self = ch
if ch.colliderect(ground):
grounded = True
if not grounded:
acc = .1
y += grv
grv += acc
if grounded:
y = 400
acc = 0
if y > 600:
return False
#UPDATE
scrn.fill(GRAY)
pygame.draw.rect(scrn,DGRAY,ground)
pygame.draw.rect(scrn,RED,ch)
pygame.display.update()
#RUNNING
running = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
if event.key == pygame.K_r and main:
main
main(screen)
pygame.quit()
解决方法
实际上,窗口的更新工作正常。但是,变量在每一帧中都被初始化。
必须在应用程序循环之前初始化变量,但更改循环中的变量。由于使用函数,因此必须在全局命名空间中初始化变量。您必须使用 global
statement 将变量解释为全局变量并在函数内更改它们。
def main(scrn):
global x,y,grounded,rx,ry,grv,acc
# [...]
在更改变量 pygame.Rect
和 x
之后但在碰撞测试之前创建 y
对象:
def main(scrn):
# [...]
pressed = pygame.key.get_pressed()
if pressed[pygame.K_RIGHT]:
x += 3
if pressed[pygame.K_LEFT]:
x -= 3
# [...]
ground = Rect(rx,200,800)
ch = Rect(x,50,50)
if ch.colliderect(ground):
# [...]
您可以使用 init_varaibles
函数来初始化变量。如果您想重置变量并重新启动游戏,请再次调用此函数。
def init_varaibles():
global x,acc
rx = 0
ry = 450
x = 50
y = 50
grounded = False
grv = 0
acc = .2
使用 pygame.time.Clock
控制每秒帧数,从而控制游戏速度。
tick()
对象的方法 pygame.time.Clock
以这种方式延迟游戏,即循环的每次迭代消耗相同的时间段。见pygame.time.Clock.tick()
:
这个方法应该每帧调用一次。
这意味着循环:
clock = pygame.time.Clock()
running = True
while running:
clock.tick(100)
每秒运行 100 次。
完整示例:
import pygame
from pygame.locals import *
pygame.init()
SIZE = 800,600
screen = pygame.display.set_mode(SIZE)
clock = pygame.time.Clock()
RED = (255,0)
GRAY = (150,150,150)
DGRAY = (75,75,75)
def init_varaibles():
global x,acc
rx = 0
ry = 450
x = 50
y = 50
grounded = False
grv = 0
acc = .2
def main(scrn):
global x,acc
pressed = pygame.key.get_pressed()
if pressed[pygame.K_RIGHT]:
x += 3
if pressed[pygame.K_LEFT]:
x -= 3
if pressed[pygame.K_UP] and grounded:
grv = -5
grounded = False
y += grv
grv += acc
ground = Rect(rx,50)
if ch.colliderect(ground):
grounded = True
ch.bottom = ground.top
grv = 0
y = ch.y
scrn.fill(GRAY)
pygame.draw.rect(scrn,DGRAY,ground)
pygame.draw.rect(scrn,RED,ch)
pygame.display.update()
return y > 600
init_varaibles()
running = True
while running:
clock.tick(100)
for event in pygame.event.get():
if event.type == QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_ESCAPE:
running = False
if event.key == pygame.K_r and main:
init_varaibles()
game_over = main(screen)
if game_over:
break
pygame.quit()
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。