Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
103 views
in Technique[技术] by (71.8m points)

python - Update during resize in Pygame

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()
question from:https://stackoverflow.com/questions/65933112/pygame-change-window-elements-while-resizing-window

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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:

enter image description here

With RedrawWindow:

enter image description here


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...