не может сериализовать pygame.Surface объекты с рассолом - PullRequest
0 голосов
/ 03 мая 2018

Я занимаюсь разработкой игры на python 3.6, и я хочу, чтобы в многопользовательской версии она отправляла на сервер объекты, измененные клиентом (игроком), которые я думал, чтобы сериализовать их для передачи. Я использую pygame и, следовательно, pygame.Surface в моих объектах

У меня есть объекты с такой структурой:

class Cargo(Bateau):
  dictCargos = dict()
  def __init__(self, map, nom, pos, armateur=None):
    Bateau.__init__(self, map, nom, armateur, pos)
    self.surface = pygame.image.load(f"images/{self.nom}.png").convert_alpha()
    self.rect = self.map.blit(self.surface, self.pos)
    ...
    Cargo.dictCargos[self.nom] = self

Когда я сериализую другой объект без экземпляра Pygame, это нормально Но с объектом, описанным выше, я получаю это сообщение об ошибке:

import pickle as pickle
pickle.dump(Cargo.dictCargos, open('file2.pkl', 'wb'), protocol=pickle.HIGHEST_PROTOCOL)

Traceback (most recent call last):
  File "./pytransit.py", line 182, in <module>
    encreG(joueur, event)
  File "/home/patrick/Bureau/PyTransit/modulesJeu/tests.py", line 25, in encreG
    pickle.dump(Cargo.dictCargos, open('file2.pkl', 'wb'), protocol=pickle.HIGHEST_PROTOCOL)
TypeError: can't pickle pygame.Surface objects

У вас есть идеи, как перенести эти предметы на сервер. Или обойти это ограничение рассола?
Та же проблема возникнет, если я захочу сохранить деталь, поэтому сохраните эти объекты

1 Ответ

0 голосов
/ 03 мая 2018

Вот пример того, на что @IonicSolutions указал в комментариях:

import pickle
import pygame


class Test:
    def __init__(self, surface):
        self.surface = surface
        self.name = "Test"

    def __getstate__(self):
        state = self.__dict__.copy()
        surface = state.pop("surface")
        state["surface_string"] = (pygame.image.tostring(surface, "RGB"), surface.get_size())
        return state

    def __setstate__(self, state):
        surface_string, size = state.pop("surface_string")
        state["surface"] = pygame.image.fromstring(surface_string, size, "RGB")
        self.__dict__.update(state)


t = Test(pygame.Surface((100, 100)))
b = pickle.dumps(t)
t = pickle.loads(b)

print(t.surface)

Чтобы увидеть, какие режимы вы можете использовать для хранения данных в виде строки (здесь «RGB»), посмотрите в документации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...