[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [pygame] Hi, I'm new...



>   I've been told to develop a game, and have been given very detailed
> specs. My first inclination was to do it with tkinter, as I had done
> all my previous python games.

well i would definitely promote using pygame. the one advantage
tkinter has is the nice widgets. in pygame its easy enough to do
pushbuttons and simple things, but to do more complex controls
like listboxes, sliders, dropdown submenus, you'll need to implement
those by yourself.

there is a project named pyui which offers some of these controls
under pygame, but it may be a little work to get it working smoothly
inside your own game engine.


> The first thing I'll need is a relatively big
> resolution, say eg 1024x768.  Also, the main area where all the
> action takes place would be lovely as a changeable camera angle
> in a 3d world - but I think I'm dreaming there.  I'll probably
> end up with something ala Diablo I&II.  If I did have the time,
> could I develop a 3d engine for pygame?  Or (even better) is
> there one already available?

here's my honest opinion. SDL is an awesome tool for working with
2d software surfaces and effects. it also is unbeatable for getting
raw access to hardware framebuffers. the one thing it doesn't give
you is a lot of fine control over hardware surfaces. this is because
it must generalize the hardware devices across many architectures
and drivers.

to get a full animated screen at 1024 resolution can really only
be done with hardware support or hand-crafted assembly. this is
going to be really hard to do in pygame, but could be doable with
a small amount of C extension modules to handle the intensive parts
of the render.

as for 3d, there is full support for pyopengl, which works nearly
as well as using straight 3d with opengl. both c and python can
feed buffers of data to opengl at comparable speeds. unfortunately
a state of the art game engine won't be that simple. you'll need
to get into things like bsp trees, portals, raycasting, collisions.
those types of things are much better handled in C than in python.
the good news would be that, again, it is straightforward and easy
to create C functions that are called from python code.

there's my opinion about where things are. it seems to me like
your going to need to get some C code in there to support the
graphics requirements. if you lock your code into using hardware
support for blitting you can likely get the 2d rendering speed
you will need. 



>   I have plenty of other questions, but I'm almost 90% sure they
> can be done so I'll just ask this one - how well does pygame support
> threads?  One major problem with tkinter is the fact that you can't
> have threaded operations which all update the GUI - tcl crashes,
> every time.  And the workaround is not pretty.

SDL does a good job at being threadsafe in all the event handling,
music processing, and timers. it does not offer any sort of thread
safety on the display and surfaces (mainly because there is not a
single way to handle that, so it leaves it up to the game).

pygame does a good job at maintaining the thread safety of SDL,
so you shouldn't have a problem with that.

as for the graphics, it is generally a good idea to have only a
single rendering thread. only one thread should have access to
the graphics. if you really want each thread to be able to handle
its own rendering, make simple use of a semaphore or mutex to
make sure only one thread is rendering at a time.

for a small example of pygame threading, you can look at my
solarwolf game. it loads all the game images and sounds on a
background thread while the main thread animates the starfield
and draws a progress slider. the same thing happens as the game
downloads news information from the internet. the http is handled
in a background thread, while the main thread keeps the game running.
this worked very well for me, but i spent a bit of work making
certain the image loading didn't cause any problems with the main
graphics thread. it was a bit more work than i would have liked.



>   Say eg that 4 warriors were standing in a dungeon room.  I
> would like them all to be doing something each - breathing,
> reading a scroll, playing with magic in the air, practising
> swings etc.  My solution would be to use a seperate thread
> for each warrior - would this work in pygame, and if not how
> would you approach it?

i don't know of any games that really handle game objects on
their own thread. the standard method is each object (or warrior)
has a function that is supposed to run in a small timeslice.
basically the function updates what variables it needs to and
returns quickly. the main gameloop then calls this function
for all objects in the game, and then renders all the objects.
if one of these functions takes too long, the game appears to
lockup briefly while that object makes its calculations.

giving each object its own thread solves the problem of each
object 'hogging' the timeslices, but introduces a ton of 
synchronization issues. for example, what if one of the warrior
threads is in a small animation loop like this...

for step in self.path:
    self.walk_to(step)

this simple loop just animates the character to a list of
positions. but what if some other warrior thread kills this
walking warrior halfway through his path? how do you switch
the walking warrior to his dying animation? you need to have
one warrior thread break the walking warrior thread out of
its walking loop and start a different loop.

this becomes an absolute nightmare, and just doesn't work.
using threads for all the objects gets too out of control.
going with the timeslice functions ends up working out much
better once you have it implemented.

basically each warrior becomes a "state machine". which 
basically means a big sack of variables that describes
everything about the object. it is easy to create a single
function that quickly looks at this state machine, updates
a few of the variables, then returns. it doesn't need to
worry at all about rendering the warrior, just updating
the state of the warrior. for example, the function may
work something like this...


def warrior_timeslice(self):
    if self.mode == WALKING:
        self.direction = self.target - self.position
        self.direction.adjust(self.speed)
        self.walkframe += 1
        self.image = self.images['walking'][self.walkframe]
        if self.position == self.target:
            self.warrior_startbreathing()
    elif self.mode == BREATHING:
        self.breathframe += 1
        self.image = self.images['breath'][self.breathframe]

def warrior_walkto(self, position)
    self.walkframe = 0
    self.target = position
    self.mode = WALKING

def warrior_startbreathing(self)
    self.breathframe = 1
    self.mode = BREATHING


hopefully this crude little example shows what i mean. this is
the method used to handle pretty much every game out there. the
game simply calls warrior_timeslice() once per frame. the game
then renderer can simply draw each object using a predetermined
method. in this example here it would likely look at the warriors
"image" and "position" variables to blit an image on the screen.


whew, this got long. hopefully it all wasn't too obvious. if you
end up going with pygame, you can always get help form here while
getting up to speed. :]


____________________________________
pygame mailing list
pygame-users@seul.org
http://pygame.seul.org