微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Pygame 窗口未更新

如何解决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.Rectx 之后但在碰撞测试之前创建 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 举报,一经查实,本站将立刻删除。