5
\$\begingroup\$

I am writing a simple game with pyGame.

Structure-wise, I have separated my game into several files:

  • main.py # the main runner, it loads up the environment
  • class_tank.py # it defines the player-controlled tank class
  • class_shell.py # it defines the shells that shoot from the player's tank
  • class_mob.py # it defines the enemies

The relationship of the modules above is:

  • main.py imports class_tank.py, class_shell.py and class_mob.py
  • all of class_tank.py, class_shell.py and class_mob.py are subclasses of pygame.Sprite.sprite.

Currently, I noticed that I am repeating myself by having the following code snippets in all four files:

current_path = os.path.dirname(os.path.realpath(__file__))
resource_path = os.path.join(current_path, 'Resources')
img_folder_path = os.path.join(resource_path, 'Images')
bg_img_path = os.path.join(img_folder_path, "xxxx.png")

xxxx.png is the image I need to load for the background (main.py), for the player (class_tank.py), for bullets (class_shell.py) and for enemies (class_mob.py).

Logically, this code snippet does belong to each of the file, but is there any elegant way to not repeat myself? The only way I can think of is to define an additional helper class.

\$\endgroup\$
  • \$\begingroup\$ What is the class hierarchy (if any) in your program? Which files import which other files? Without more context, we can’t give you a very good answer. \$\endgroup\$ – AJNeufeld Mar 31 '19 at 23:04
  • \$\begingroup\$ @AJNeufeld, thanks. I added more info to my post. \$\endgroup\$ – Yu Zhang Mar 31 '19 at 23:11
  • 4
    \$\begingroup\$ I want to answer your question, but as it currently stands, without actual code, it is not really a "Code Review" question. There are several ways to avoid repeating yourself. 1) Your "helper" class. 2) An Entity class that derives from pygame.sprite.Sprite, with an image load method, that your other classes derive from. 3) Dependency injection; your main module could load all images and inject them into each class. Or combinations of the above. \$\endgroup\$ – AJNeufeld Apr 1 '19 at 2:23
  • \$\begingroup\$ @AJNeufeld, thank you so much. I did not know anything about dependency injection, I will take a look. \$\endgroup\$ – Yu Zhang Apr 1 '19 at 2:55
1
\$\begingroup\$

You don't necessarily need classes in Python. The helper class approach is the same direction as I would go, just with a plain module.
Basically, your resource_path and img_folder_path are constants, so I would simply create a module constants.py with the following:

import os

RESOURCE_PATH = os.path.join(os.path.realpath(__file__), 'Resources')
IMG_FOLDER_PATH = os.path.join(resource_path, 'Images')

You can then simply import constants.py everywhere you need to know those paths.

| improve this answer | |
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.