繁体   English   中英

如何使用PyGame.Surfaces将对象保存到使用Pickle的文件中

[英]How to save object using pygame.Surfaces to file using pickle

如果我创建了自己的类,该类具有一些pygame.Surfaces属性,并且想将该对象保存到文件中,那么在尝试时会出现错误,该如何处理。

我创建的类本质上是一个对象(包括Item类,因为玩家拥有的物品具有pygame.Surfaces属性):

class Item:
    def __init__(self,name,icon):
        self.name = name
        self.icon = pygame.image.load(icon)

class Player(pygame.Sprite):
    def __init__(self,{some_attrs})
        skins = [{a pygame.Surface from a load image},{another}]
        self.money = 0
        self.items = [{Item object}]

然后,当我尝试保存时,使用以下命令:

with open('save.dat','wb') as file:
    pickle.dump(player , file , protocol = 4)
    #I have also tried without the protocol argument

但是我收到以下错误:

Traceback (most recent call last):
  File "{file path}", line 883, in <module>
    save_progress()
  File "{file path}", line 107, in save_progress
    pickle.dump(player,file,protocol=4)
TypeError: can't pickle pygame.Surface objects

仅供参考,我用大括号({和})加上的所有内容都是我缩写或遗漏的,因为不需要

如果您需要更多详细信息,如果您回复需要的信息,我可以轻松添加

pygame.Surface并非要腌制。 您可以将图像放入字典中,以便按其名称/字典键(字符串)进行检索。 然后将此名称存储在您的sprite中,以使用pickle或json(更安全)进行序列化,并在加载游戏时使用它重新创建sprite。

这是一个简单的示例,您可以通过按sw来保存和加载一些精灵(仅相关属性):

import json
import pygame as pg


pg.init()
IMAGE_BLUE = pg.Surface((32, 52))
IMAGE_BLUE.fill(pg.Color('steelblue1'))
IMAGE_SIENNA = pg.Surface((32, 52))
IMAGE_SIENNA.fill(pg.Color('sienna1'))
# Put the images into a dictionary, so that we can get them by their name.
IMAGES = {'blue': IMAGE_BLUE, 'sienna': IMAGE_SIENNA}


class Entity(pg.sprite.Sprite):

    def __init__(self, pos, image_name):
        super().__init__()
        # Store the image name to save it with json later.
        self.image_name = image_name
        self.image = IMAGES[image_name]
        self.rect = self.image.get_rect(topleft=pos)


class Game:

    def __init__(self):
        self.done = False
        self.bg_color = pg.Color('gray13')
        self.clock = pg.time.Clock()
        self.screen = pg.display.set_mode((640, 480))
        # Pass the image names (i.e. keys of the IMAGES dict).
        entity1 = Entity((250, 120), 'blue')
        entity2 = Entity((400, 260), 'sienna')
        self.all_sprites = pg.sprite.Group(entity1, entity2)
        self.selected = None

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

    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.move_ip(event.rel)
            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_game1.json', 'w') as file:
            print('Saving')
            # Create a list of the top left positions and the
            # image names.
            data = [(sprite.rect.topleft, sprite.image_name)
                    for sprite in self.all_sprites]
            json.dump(data, file)

    def load(self):
        with open('save_game1.json', 'r') as file:
            print('Loading')
            data = json.load(file)
            self.selected = None
            self.all_sprites.empty()
            # Use the positions and image names to recreate the sprites.
            for pos, image_name in data:
                self.all_sprites.add(Entity(pos, image_name))


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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM