复制表面并将其 blit 显示在屏幕上

Copying the surface and bliting it on the screen

所以我正在开发我的 pygame 版本的 Paint,目前正在开发 UNDO 属性。我已经弄清楚我将保存屏幕的位置(正在考虑使用双端队列)但无法弄清楚如何将内容保存在屏幕上,将内容保存在屏幕上的方法是什么以便我可以附加它每次在屏幕上进行更改时在双端队列上,如果用户单击撤消按钮则返回到旧屏幕。我试过 copy() 方法,但我想我没有正确实施它..

如果你能给我一个如何 blit 旧表面副本的例子,那将很有帮助。

希望我说得够清楚了。

下面是制作屏幕表面副本的快速示例。

它调用 window.copy() 在开始时和用户单击 [KEEP] 时创建一个“撤消点”。如果用户单击 [UNDO],复制的表面将重新块化到屏幕以擦除现有表面。

我不确定保留屏幕副本是否是执行此操作的好方法,它会占用大量内存。更好的方法是将绘图基元存储在列表中,然后在撤消时只重新绘制最多 N-1 个条目。

import pygame

# Window size
WINDOW_WIDTH    = 400
WINDOW_HEIGHT   = 400
WINDOW_SURFACE  = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE

DARK_BLUE = (   3,   5,  54 )
YELLOW    = ( 250, 250,   0 )
RED       = ( 200,   0,   0 )


### initialisation
pygame.init()
pygame.mixer.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), WINDOW_SURFACE )
pygame.display.set_caption("Undo Example")


font = pygame.font.SysFont('freesansbold.ttf', 30)
undo_text = font.render( "[UNDO]", True, YELLOW )
undo_rect = undo_text.get_rect()
undo_rect.x = 50
keep_text = font.render( "[KEEP]", True, YELLOW )
keep_rect = keep_text.get_rect()
keep_rect.x = 200

window.fill( DARK_BLUE )

### The undo buffer
undo_save = None

### Main Loop
clock = pygame.time.Clock()
pen_down = False
last_point = None
done = False
while not done:

    # Handle user-input
    for event in pygame.event.get():
        if ( event.type == pygame.QUIT ):
            done = True
        elif ( event.type == pygame.MOUSEMOTION ):
            mouse_pos = event.pos
            if ( pen_down ):
                if ( last_point != None ):
                    pygame.draw.line( window, RED, last_point, mouse_pos )
                    last_point = mouse_pos
        elif ( event.type == pygame.MOUSEBUTTONDOWN ):
            pen_down = True
            if ( last_point == None ):
                last_point = event.pos
        elif ( event.type == pygame.MOUSEBUTTONUP ):
            pen_down = False
            last_point = None

            ### Handle the KEEP/UNDO button presses
            if ( undo_rect.collidepoint( event.pos ) ):
                if ( undo_save != None ):
                    window.blit( undo_save, ( 0, 0 ) )
                    print( "UNDO Image Restored" )
            if ( keep_rect.collidepoint( event.pos ) ):
                undo_save = window.copy()
                print( "UNDO Image Saved" )

    window.blit( undo_text, undo_rect )
    window.blit( keep_text, keep_rect )

    # Update the window, but not more than 60fps
    pygame.display.flip()

    # make the first undo automatically
    if ( undo_save == None ):
        undo_save = window.copy()

    # Clamp FPS
    clock.tick(60)


pygame.quit()