如何使用搁置模块保存 pygame 精灵组

Posted

技术标签:

【中文标题】如何使用搁置模块保存 pygame 精灵组【英文标题】:How to save a pygame sprite-group using the shelve module 【发布时间】:2017-07-27 20:39:29 【问题描述】:

我正在制作一款游戏,我希望在其中拥有游戏存档功能。我有一个想要使用架子模块保存的精灵组,但是在尝试保存我的精灵组时出现“无法腌制表面对象”错误。我想知道是否有任何方法可以使用货架模块来保存精灵组,如果没有,我应该使用其他什么保存方法?

【问题讨论】:

pygame.sprite.Spritespygame.sprite.Groups 不是表面对象,可与 pickle 一起使用。也许您正试图搁置一些应该在加载时重新创建的额外游戏对象。 看起来精灵不能被腌制,因为它们包含pygame.Surface。另外,请记住 pickle 是不安全的,因此切勿从不受信任的来源取消文件。这可能会有问题,例如,如果用户向您发送保存文件以调试某些内容。 【参考方案1】:

当用户想要保存游戏时,我会将精灵的相关值存储在 json 文件中。要加载游戏,请清空精灵组,使用加载的数据重建精灵并将它们添加到组中。例如。 (点击精灵拖动它们,按“s”保存,按“w”加载):

import json

import pygame as pg


class Actor(pg.sprite.Sprite):

    def __init__(self, pos, color):
        super().__init__()
        self.color = color
        self.image = pg.Surface((32, 52))
        self.image.fill(self.color)
        self.rect = self.image.get_rect(topleft=pos)


class Game:

    def __init__(self):
        self.fps = 30
        self.done = False
        self.bg_color = pg.Color('gray13')
        self.clock = pg.time.Clock()
        self.screen = pg.display.set_mode((640, 480))
        actor1 = Actor((250, 120), pg.Color('steelblue1'))
        actor2 = Actor((400, 260), pg.Color('sienna1'))
        self.all_sprites = pg.sprite.Group(actor1, actor2)
        self.selected = None

    def run(self):
        while not self.done:
            self.handle_events()
            self.run_logic()
            self.draw()
            self.clock.tick(self.fps)

    def handle_events(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                self.done = True
            elif event.type == pg.MOUSEBUTTONDOWN:
                if self.selected:
                    self.selected = None
                else:
                    for sprite in self.all_sprites:
                        if sprite.rect.collidepoint(event.pos):
                            self.selected = sprite
            elif event.type == pg.MOUSEMOTION:
                if self.selected:
                    self.selected.rect.x += event.rel[0]
                    self.selected.rect.y += event.rel[1]
            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_s:
                    self.save()
                elif event.key == pg.K_w:
                    self.load()

    def run_logic(self):
        self.all_sprites.update()

    def draw(self):
        self.screen.fill(self.bg_color)
        self.all_sprites.draw(self.screen)
        pg.display.flip()

    def save(self):
        with open('save_game.json', 'w') as file:
            print('Saving')
            data = [(sprite.rect.topleft, sprite.color[:4])
                    for sprite in self.all_sprites]
            json.dump(data, file)

    def load(self):
        with open('save_game.json', 'r') as file:
            print('Loading')
            data = json.load(file)
            self.selected = None
            self.all_sprites.empty()
            for pos, color in data:
                self.all_sprites.add(Actor(pos, color))


if __name__ == '__main__':
    pg.init()
    Game().run()
    pg.quit()

【讨论】:

以上是关于如何使用搁置模块保存 pygame 精灵组的主要内容,如果未能解决你的问题,请参考以下文章

pygame精灵组和读取图片

如何检测何时单击矩形对象、图像或精灵

如何在 Pygame 中使用 Sprite Sheets 创建动画精灵?

如何在 Pygame 中使用 Sprite Sheets 创建动画精灵?

pygame之精灵对象和精灵组

如何检测pygame中的碰撞?