[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

Re: [pygame] global class instances?



Here's the way I typically handle this issue:

Create a module (like your globals module, call it whatever you like) that you can use as a namespace to hold you global instances. These are typically called singletons.

Then in the globals module, add a method called init() that sets up the global instances. Doing the imports inside the init() function is not strictly necessary, but it can be a nice way to avoid implicit module dependancies (since basically everything will import globals) which can cause crummy side-affects like circular imports as you add more modules that depend on one-another.

def init():
  from console import Console
  from fps import FPS
  from map import Map
  from mouse import Mouse
  from player import Player
  global console, fps, map, mouse, player
  console = Console()
  fps = FPS()
  map = Map()
  mouse = Mouse()
  player = Player()

You can call globals.init() from your main initializer right after the basic pygame stuff is setup.

When you refer to globals, you must use late binding, thus you cannot use "from globals import *" which attempts to bind the stuff in globals before it is initialized. Instead just use "import globals". So, for example, in the Player class when you want to refer to the mouse instance you need to use "globals.mouse" which will lookup the mouse object only after everything is setup properly. IMO it make the code easier to read too since it is clear where mouse is coming from.

hth,

-Casey

On Nov 24, 2007, at 12:33 PM, Jake b wrote:

I'm starting a basic game. I have a few classes. I'm having trouble
figuring out how to handle some global class instances.

Here's my current classes.

FPS() = handles fps rendering, and calc's delta for time-based movement
Player() = Player's class
Console() = buffer that I can pass strings to, and it shows them on screen.
Map() = stores map tile info, and renders it.
Mouse() = some basic mouse helper functions, mouse location, etc...
ZombieHuntMain() = The main entry point, main loop, etc.

I want a few class instances to be global so that I don't have to pass
a pointer in every constructor that needs them. ( Like I am doing
right now in the snippet )

Right now I my game initialization looks like:

# ZombieHunt.py : snippet of main logic class
class ZombieHuntMain:
	"""entry point. initialization, and game logic."""

	def __init__(self, width=1024, height=768):
		"""Initialize PyGame"""
		pygame.init()
		self.width, self.height = width, height
		self.screen = pygame.display.set_mode(( self.width, self.height ))
		
# some of these should be accessible to any file that includes "Globals.py"
		self.console = Console()
		self.fps = FPS( self.console )
		self.map = Map(self.console)
		self.mouse = Mouse(self.console, self.map)

		self.player = Player(self.console, self.map, self.mouse, self.fps)

		# add player to the sprite group
		self.unit_sprites = RenderPlain()
		self.unit_sprites.add( self.player )

So you can see that the constructor arguments are getting crazy. Most
will want access to the Console() instance. And probably Map(). Maybe
others.

I tried just moving the constructors to Globals.py, but then pygame
doesn't initialize in time for Console().__init__() to work. ( Fails
because pygame fonts don't load in time ) I even tried "pygame.init()"
before the line "from Globals import *", but It still seemed to not
work. (And that seemed like a bad way to fix it )

I also tried creating the instances like normal ( same as in the above
code ) as members of ZombieHuntMain, then in Globals.py create a
reference to that instance:

        # grab pointer / reference of instance in ZombieHunt
        console = ZombieHuntMain.console

But I couldn't get that to work, even with "from ZombieHunt import *"
( I don't know if ZombieHunt.py being the entry point has anything to
do with that? If something else happens if you attempt to import the
entry point ? )

(1) How would you organize the classes?

(2) I'm going to be creating a sprite group: "bullet_sprites". Do you
think my sprite groups should be global? Because I need to spawn
bullets from within Player().

thanks,
--
Jake