Oct-16-2021, 11:06 AM
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:
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_dataOther 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_dataOr 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?
