在 Pygame 中保存绘图历史以实现 Ctrl Z

Saving history of drawing in Pygame in order to implement Ctrl Z

我试图记住以前的图纸来实现 Ctrl-Z(撤消)和(重做)。为此,我使用了集合中的堆栈(双端队列),我还创建了一个名为 DrawEntity 的对象,它具有矩形列表的属性(pygame class),因为我不知道我不想保存我绘制的 每个 像素,但只保存一个 'brushstroke' 而不是构成他的组件(小的 ractangles 构成了一笔)但是,我不知道如何插入到主 DrawEntity 列表,该列表将为每个笔触而不是每个矩形将这些实体保存在队列中。这是我目前所拥有的:

main.py:

import pygame as pg
from collections import deque
from DrawEntity import DrawEntity

DrawEnt = deque()

def draw(window):
    d_Ent = DrawEntity()
    mouseX, mouseY = pg.mouse.get_pos()
    click = pg.mouse.get_pressed()
    if click[0]:
        rect = pg.draw.rect(window, (0, 0, 0), pg.Rect(mouseX, mouseY, 3, 3), 3)
        d_Ent.add(rect)

    if d_Ent.entity:
        print("new Entity")
        print(d_Ent)
        DrawEnt.append(d_Ent)



def main():

    running = True
    window = pg.display.set_mode((640, 480))
    window.fill((255, 255, 255))


    while running:
        clock.tick(3200)

        for event in pg.event.get():
            if event.type == pg.QUIT:
                running = False

            if event.type == pg.KEYDOWN:

                if event.key == pg.K_z and pg.key.get_mods() & pg.KMOD_LCTRL:

                    print(len(DrawEnt))

            draw(window)

        pg.display.flip()
    #end main loop
    pg.quit()

if __name__ == '__main__':

    pg.init()
    clock = pg.time.Clock()
    main()

和DrawEntity.py:

class DrawEntity:
def __init__(self):
    self.entity = []

def add(self, toAdd):
    self.entity.append(toAdd)

def remove(self):
    self.entity = []

def __str__(self):
    return ' '.join(map(str, self.entity))

基本上,我想进入一个 while 循环并停留在那里,同时我一直单击,以便将所有矩形收集到列表中,然后将其附加到主实体列表中,但是这不会进入 while 循环每次我绘制时,它都会为每个新实体附加一个矩形而不是一系列矩形。 (如果我尝试使用 while 循环游戏会崩溃)
所以:

-1 单击时收集我目前绘制的所有矩形

1.1 如果我停止单击然后将新的 d_Ent 和矩形列表附加到主实体列表(main.py 中第 5 行的 DrawEnt)

  1. 继续计划
  2. 如果我再次点击,转到1

每次单击鼠标按钮时,您都必须创建一个新的 DrawEntity 对象:

if event.type == pg.MOUSEBUTTONDOWN and event.button == 1:
    DrawEnt.append(DrawEntity())

draw 中,您必须将 Rect 添加到 deque 中的最后一个 DrawEntity (DrawEnt):

def draw(window):
    if len(DrawEnt) > 0:
        d_Ent = DrawEnt[-1]

        mouseX, mouseY = pg.mouse.get_pos()
        click = pg.mouse.get_pressed()
        if click[0]:
            rect = pg.draw.rect(window, (0, 0, 0), pg.Rect(mouseX, mouseY, 3, 3), 3)
            d_Ent.add(rect)

On ctrl-zDrawEnt (pop) 中删除最后一个元素,清除显示并再次绘制所有剩余元素:

if event.type == pg.KEYDOWN:
    if event.key == pg.K_z and pg.key.get_mods() & pg.KMOD_LCTRL:
        if len(DrawEnt) > 0:
            DrawEnt.pop()
            window.fill((255, 255, 255))
            for entity in DrawEnt:
                for r in entity.entity:
                    pg.draw.rect(window, (0, 0, 0), r, 3)

看例子:

class DrawEntity:
    def __init__(self):
        self.entity = []

    def add(self, toAdd):
        self.entity.append(toAdd)

    def remove(self):
        self.entity = []

    def __str__(self):
        return ' '.join(map(str, self.entity))

DrawEnt = deque()

def draw(window):
    if len(DrawEnt) > 0:
        d_Ent = DrawEnt[-1]

        mouseX, mouseY = pg.mouse.get_pos()
        click = pg.mouse.get_pressed()
        if click[0]:
            rect = pg.draw.rect(window, (0, 0, 0), pg.Rect(mouseX, mouseY, 3, 3), 3)
            d_Ent.add(rect)

def main():

    running = True
    window = pg.display.set_mode((640, 480))
    window.fill((255, 255, 255))


    while running:
        clock.tick(3200)

        for event in pg.event.get():
            if event.type == pg.QUIT:
                running = False

            if event.type == pg.MOUSEBUTTONDOWN and event.button == 1:
                d_Ent = DrawEntity()
                DrawEnt.append(DrawEntity())

            if event.type == pg.KEYDOWN:

                if event.key == pg.K_z and pg.key.get_mods() & pg.KMOD_LCTRL:

                    if len(DrawEnt) > 0:
                        DrawEnt.pop()
                        window.fill((255, 255, 255))
                        for entity in DrawEnt:
                            for r in entity.entity:
                                pg.draw.rect(window, (0, 0, 0), r, 3)

            draw(window)

        pg.display.flip()
    #end main loop
    pg.quit()

if __name__ == '__main__':

    pg.init()
    clock = pg.time.Clock()
    main()