Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can't serialized pygame.Surface objects with pickle

Tags:

python

pygame

I am developing a game with python 3.6, I want in its multiplayer version to send to the server objects modified by the client ( the player) I thought to serialize them for transfer. I use pygame and thus pygame.Surface in my objects

I have objects with this structure:

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

When I serialize another object without pygame instance it's ok But with the object described above I get this error message:

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

Do you have any idea how to transport these items to the server. Or bypass this pickle restriction?
The same problem would arise if I wanted to save a part, so save these objects

like image 490
patol Avatar asked Apr 24 '26 14:04

patol


1 Answers

Here is an example of what @IonicSolutions pointed to in the comments:

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)

To see what modes you can use to store the data as a string (here "RGB") look into the documentation

like image 123
MegaIng Avatar answered Apr 27 '26 04:04

MegaIng



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!