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