Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

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

python - How to save a pygame sprite-group using the shelve module

I'm making a game in which I want to have a save game feature. I have a sprite group which I want to save using the shelf module, but I get a 'can't pickle Surface objects' error when trying to save my sprite group. I was wondering if there is any way to use the shelf module to save a sprite group, and if there isnt, what other saving method should I use?

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

I'd store the relevant values of the sprites in a json file when the user wants to save the game. To load the game, empty the sprite group, reconstruct the sprites with the loaded data and add them to the group. E.g. (click on the sprites to drag them around and press "s" to save and "w" to load):

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...