在 Pygame 调整大小时更新
Update during resize in Pygame
我正在 pygame 中开发基于网格的游戏,并希望 window 可以调整大小。我使用以下初始化代码完成此操作:
pygame.display.set_mode((740, 440), pygame.RESIZABLE)
以及我的事件处理程序中的以下内容:
elif event.type == pygame.VIDEORESIZE:
game.screen = pygame.display.set_mode((event.w, event.h),
pygame.RESIZABLE)
# Code to re-size other important surfaces
我遇到的问题是,似乎 pygame.VIDEORESIZE 事件仅在用户 完成 调整 window 大小后才会推送,即让去边境。 screen.get_size() 更新类似。由于我的游戏图形非常简单,我真的更喜欢它们在用户拖动 window 时调整大小。这在许多其他语言中是微不足道的,但我在 pygame 中找不到任何参考 - 虽然我无法想象这个基本的功能是不可能的。
在 pygame 中调整屏幕大小时如何更新我的游戏?
编辑:这是一个最小的工作示例。 运行 on Windows 10, pygame 1.9.4,下面的代码只会在用户拖动完 window.
后绘制更新的矩形
import sys
import pygame
pygame.init()
size = 320, 240
black = 0, 0, 0
red = 255, 0, 0
screen = pygame.display.set_mode(size, pygame.RESIZABLE)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.VIDEORESIZE:
pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE)
screen.fill(black)
pygame.draw.rect(screen, red, (10,10,screen.get_width(),screen.get_height()))
pygame.display.flip()
如果您 运行 遇到这种问题,使用 SDL
而不是 pygame
总是值得 google,因为 pygame 是一个漂亮 low-level SDL 包装器。
所以这不是 pygame 本身的问题,而是 sdl 和您的 window 经理如何互动的问题,例如参见 this SDL bug report。
尽管如此,如果您确实需要在调整大小时更新 window,如果您正在使用 Windows,您可以监听 [=36= 的实际 WM_SIZE
事件],重新绘制屏幕,并通过调用 RedrawWindow
.
更新“Windows”-window
这是一个简单的例子:
import pygame
import win32gui
import win32con
def wndProc(oldWndProc, draw_callback, hWnd, message, wParam, lParam):
if message == win32con.WM_SIZE:
draw_callback()
win32gui.RedrawWindow(hWnd, None, None, win32con.RDW_INVALIDATE | win32con.RDW_ERASE)
return win32gui.CallWindowProc(oldWndProc, hWnd, message, wParam, lParam)
def main():
pygame.init()
screen = pygame.display.set_mode((320, 240), pygame.RESIZABLE | pygame.DOUBLEBUF)
def draw_game():
screen.fill(pygame.Color('black'))
pygame.draw.rect(screen, pygame.Color('red'), pygame.Rect(0,0,screen.get_width(),screen.get_height()).inflate(-10, -10))
pygame.display.flip()
oldWndProc = win32gui.SetWindowLong(win32gui.GetForegroundWindow(), win32con.GWL_WNDPROC, lambda *args: wndProc(oldWndProc, draw_game, *args))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
elif event.type == pygame.VIDEORESIZE:
pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE| pygame.DOUBLEBUF)
draw_game()
if __name__ == '__main__':
main()
默认行为:
与RedrawWindow
:
我正在 pygame 中开发基于网格的游戏,并希望 window 可以调整大小。我使用以下初始化代码完成此操作:
pygame.display.set_mode((740, 440), pygame.RESIZABLE)
以及我的事件处理程序中的以下内容:
elif event.type == pygame.VIDEORESIZE:
game.screen = pygame.display.set_mode((event.w, event.h),
pygame.RESIZABLE)
# Code to re-size other important surfaces
我遇到的问题是,似乎 pygame.VIDEORESIZE 事件仅在用户 完成 调整 window 大小后才会推送,即让去边境。 screen.get_size() 更新类似。由于我的游戏图形非常简单,我真的更喜欢它们在用户拖动 window 时调整大小。这在许多其他语言中是微不足道的,但我在 pygame 中找不到任何参考 - 虽然我无法想象这个基本的功能是不可能的。
在 pygame 中调整屏幕大小时如何更新我的游戏?
编辑:这是一个最小的工作示例。 运行 on Windows 10, pygame 1.9.4,下面的代码只会在用户拖动完 window.
后绘制更新的矩形import sys
import pygame
pygame.init()
size = 320, 240
black = 0, 0, 0
red = 255, 0, 0
screen = pygame.display.set_mode(size, pygame.RESIZABLE)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.VIDEORESIZE:
pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE)
screen.fill(black)
pygame.draw.rect(screen, red, (10,10,screen.get_width(),screen.get_height()))
pygame.display.flip()
如果您 运行 遇到这种问题,使用 SDL
而不是 pygame
总是值得 google,因为 pygame 是一个漂亮 low-level SDL 包装器。
所以这不是 pygame 本身的问题,而是 sdl 和您的 window 经理如何互动的问题,例如参见 this SDL bug report。
尽管如此,如果您确实需要在调整大小时更新 window,如果您正在使用 Windows,您可以监听 [=36= 的实际 WM_SIZE
事件],重新绘制屏幕,并通过调用 RedrawWindow
.
这是一个简单的例子:
import pygame
import win32gui
import win32con
def wndProc(oldWndProc, draw_callback, hWnd, message, wParam, lParam):
if message == win32con.WM_SIZE:
draw_callback()
win32gui.RedrawWindow(hWnd, None, None, win32con.RDW_INVALIDATE | win32con.RDW_ERASE)
return win32gui.CallWindowProc(oldWndProc, hWnd, message, wParam, lParam)
def main():
pygame.init()
screen = pygame.display.set_mode((320, 240), pygame.RESIZABLE | pygame.DOUBLEBUF)
def draw_game():
screen.fill(pygame.Color('black'))
pygame.draw.rect(screen, pygame.Color('red'), pygame.Rect(0,0,screen.get_width(),screen.get_height()).inflate(-10, -10))
pygame.display.flip()
oldWndProc = win32gui.SetWindowLong(win32gui.GetForegroundWindow(), win32con.GWL_WNDPROC, lambda *args: wndProc(oldWndProc, draw_game, *args))
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
return
elif event.type == pygame.VIDEORESIZE:
pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE| pygame.DOUBLEBUF)
draw_game()
if __name__ == '__main__':
main()
默认行为:
与RedrawWindow
: