如何使用 pygame.Surfaces 将对象保存到使用 pickle 的文件中
How to save object using pygame.Surfaces to file using pickle
如果我创建了自己的 class,它有一些 pygame.Surfaces 的属性,我想将这个对象保存到一个文件中,我该如何做,因为当我试试。
我创建的 class 是一个对象,本质上是以下内容(包含项目 class 是因为播放器的项目具有 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
s 不应该被腌制。您可以将图像放入字典中,以便可以通过它们的 name/dictionary 键(字符串)检索它们。然后将此名称存储在您的 sprite 中,以使用 pickle 或 json(更安全)将其序列化,并在您加载游戏时使用它重新创建 sprite。
这是一个简单的示例,您可以通过按 s 和 w 来保存和加载一些精灵(仅相关属性):
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()
如果我创建了自己的 class,它有一些 pygame.Surfaces 的属性,我想将这个对象保存到一个文件中,我该如何做,因为当我试试。
我创建的 class 是一个对象,本质上是以下内容(包含项目 class 是因为播放器的项目具有 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
s 不应该被腌制。您可以将图像放入字典中,以便可以通过它们的 name/dictionary 键(字符串)检索它们。然后将此名称存储在您的 sprite 中,以使用 pickle 或 json(更安全)将其序列化,并在您加载游戏时使用它重新创建 sprite。
这是一个简单的示例,您可以通过按 s 和 w 来保存和加载一些精灵(仅相关属性):
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()