在 Pygame 中调整大小期间更新 [英] Update during resize in Pygame

查看:94
本文介绍了在 Pygame 中调整大小期间更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在 pygame 中开发基于网格的游戏,并希望窗口可以调整大小.我使用以下初始化代码完成此操作:

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)# 重新调整其他重要表面大小的代码

我遇到的问题是,似乎只有在用户完成调整窗口大小后才会推送 pygame.VIDEORESIZE 事件,即放开边框.screen.get_size() 更新类似.由于我的游戏图形非常简单,我真的希望它们在用户拖动窗口时调整大小.这在许多其他语言中是微不足道的,但我在 pygame 中找不到任何参考 - 尽管我无法想象这种基本的功能是不可能的.

如何在 pygame 中调整屏幕大小时更新我的​​游戏?

这是一个最小的工作示例.在 Windows 10 pygame 1.9.4 上运行,以下代码只会在用户完成拖动窗口后绘制更新的矩形.

导入系统导入pygamepygame.init()大小 = 320, 240黑色 = 0, 0, 0红色 = 255, 0, 0屏幕 = pygame.display.set_mode(大小,pygame.RESIZABLE)为真:对于 pygame.event.get() 中的事件:如果 event.type == pygame.QUIT:系统退出()elif event.type == pygame.VIDEORESIZE:pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE)屏幕填充(黑色)pygame.draw.rect(屏幕,红色,(10,10,screen.get_width(),screen.get_height()))pygame.display.flip()

解决方案

如果您遇到此类问题,总是值得使用 SDL 而不是 pygame 谷歌它>,因为 pygame 是一个非常低级的 SDL 包装器.

所以这不是 pygame 本身的问题,而是 sdl 和您的窗口管理器如何交互,例如请参阅

使用RedrawWindow:

I'm developing a grid based game in pygame, and want the window to be resizable. I accomplish this with the following init code:

pygame.display.set_mode((740, 440), pygame.RESIZABLE)

As well as the following in my event handler:

elif event.type == pygame.VIDEORESIZE:
     game.screen = pygame.display.set_mode((event.w, event.h),
                                            pygame.RESIZABLE)
     # Code to re-size other important surfaces

The problem I'm having is that it seems a pygame.VIDEORESIZE event is only pushed once the user is done resizing the window, i.e. lets go of the border. screen.get_size() updates similarly. Since the graphics of my game are very simple, I'd really prefer for them to resize as the user drags the window. This is trivial in many other languages, but I can't find any reference for it in pygame - although I can't imagine a feature this basic would be impossible.

How can I update my game as the screen is being resized in pygame?

EDIT: Here is a minimal working example. Running on Windows 10, pygame 1.9.4, the following code will only draw the updated rectangle after the user finishes dragging the 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()

解决方案

If you run into this kind of problem, it's always worth to google it using SDL instead of pygame, since pygame is a pretty low-level SDL wrapper.

So that's not a problem of pygame itself, but rather how sdl and your window manager interact, e.g. see this SDL bug report.

Nonetheless, if you really need to update the window while resizing, if you're using Windows, you can listen for the actual WM_SIZE event of Windows, redraw your screen, and update the "Windows"-window by calling RedrawWindow.

Here's a simple example:

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()

Default behaviour:

With RedrawWindow:

这篇关于在 Pygame 中调整大小期间更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆