Python Forum
[PyGame] Best way to pass data to the few game states with the same superclass?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
[PyGame] Best way to pass data to the few game states with the same superclass?
#1
Hello, I wonder what is the best way to pass data to the few game states with the same superclass? I'm gonna use state machine with control class. States class is a superclass for Game and MainMenu(and there'll be few more) because they gonna use attributes with the same names. In the project I'm gonna use only one instance of Game and MainMenu class. GameData is a class which loads(from files) and store data like images, sounds etc. and it's attributes are read-only. I'd like to pass GameData object to the Game and MainMenu instances and I wonder, if my solution where I put it in the superclass is correct or there's maybe better way?
game_data module:
import os
import pickle

import pygame


class GameData:
    """Loads and share game data: images, sounds and enemies"""
    def __init__(self) -> None:
        self.__images = {}
        self.__sounds = {}
        pygame.init()  # OGARNĄĆ TO !!!!!!!!
        pygame.mixer.set_num_channels(50)
        # Dictionary where key is a game level, values are tuples with parameters(x, y, style)
        # used for creating each 'Enemy' spaceship object
        self.__enemies_args = {}

        self.__load_images()
        self.__load_sounds()
        self.__load_level_enemies()

    @property
    def textures(self):
        return self.__images

    @property
    def sounds(self):
        return self.__sounds

    @property
    def enemies_args(self):
        return self.__enemies_args

    def __load_images(self) -> None:
        """Loads images"""
        print(os.listdir())
        for img in os.listdir('../../resources/img/Other'):
            if img.endswith('.png'):
                self.__images[img.replace('.png', '')] = pygame.image.load(f'../../resources/img/Other/{img}')  # => surface
        for img in os.listdir('../../resources/img/Background'):
            self.__images[img.replace('.png', '')] = pygame.image.load(f'../../resources/img/background/{img}')  # => surface

    def __load_sounds(self) -> None:
        """Loads sounds"""
        for sound in os.listdir('../../resources/sounds'):
            self.__sounds[sound.replace('.wav', '')] = pygame.mixer.Sound(f'../../resources/sounds/{sound}')  # => sound

    def __load_level_enemies(self) -> None:
        """Loads level enemies from pickle file"""
        with open('../game_levels.pickle', 'rb') as handle:
            self.__enemies_args = pickle.load(handle)
states module:
from game_data import GameData


class States:
    """Superclass for each state"""
    game_data = GameData()  # Is it correct and 'pythonic'?

    def __init__(self):
        self.done = False
        self.next = None
        self.quit = False
        self.previous = None


class Game(States):
    def __init__(self):
        States.__init__(self)

    def some_method(self):
        pass # Here I'm gonna use game_data


class MainMenu(States):
    def __init__(self):
        States.__init__(self)

    def some_method(self):
        pass # Here I'm gonna use game_data
Other solution but I think it's incorrect because it's not optimal(2 instances of GameData()):
from game_data import GameData


class States:
    """Superclass for each state"""
    def __init__(self):
        self.done = False
        self.next = None
        self.quit = False
        self.previous = None


class Game(States):
    def __init__(self):
        States.__init__(self)
        self.game_data = GameData()  # First instance

    def some_method(self):
        pass # Here I'm gonna use self.game_data


class MainMenu(States):
    def __init__(self):
        States.__init__(self)
        self.game_data = GameData()  # Second instance

    def some_method(self):
        pass # Here I'm gonna use self.game_data
Or maybe it should be passed as an argument?:
from game_data import GameData


class States:
    """Superclass for each state"""
    def __init__(self):
        self.done = False
        self.next = None
        self.quit = False
        self.previous = None


class Game(States):
    def __init__(self, game_data):  # As arg
        States.__init__(self)
        self.game_data = game_data  # Assignment
    def some_method(self):
        pass # Here I'm gonna use self.game_data


class MainMenu(States):
    def __init__(self, game_data):  # As arg
        States.__init__(self)
        self.game_data = game_data  # Assignment

    def some_method(self):
        pass # Here I'm gonna use self.game_data


game_data = GameData()
game = Game(game_data)
main_menu = MainMenu(game_data)
Is one of these solutions correct or it should be done in another way? Maybe just use cfg module and import it in each module? Or maybe i just made a mistake in the beginning and game data shouldn't be stored in a class?
Reply


Messages In This Thread
Best way to pass data to the few game states with the same superclass? - by Milosz - Oct-16-2021, 11:06 AM

Possibly Related Threads…
Thread Author Replies Views Last Post
  [PyGame] Variables shared between game states, how to? michael1789 5 3,539 Dec-10-2019, 10:09 PM
Last Post: metulburr

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020