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

[pygame] Event Handling and Collision Detection



Hi there,

I'm working on a game SDK for making old-school games like those from
the NES and SNES eras ( http://code.google.com/p/scrollback ). It has a
very simple event handling system and an "engine" which is based heavily
on that event handling system.

The problem I'm having is sort of difficult to describe; it has to do
with event handling and collision detection.

Right now the engine works as follows.

(NOTE: `sbak` is the main package of the SDK's library.)

- - -

0.) The user setups up the game's "environment," i.e. pre-loading any
graphics that will be used frequently, loading the first level's data,
setting up the player object, etc.

1.) The user registers some "event hooks." (An event hook basically
associates an event type and state information with a handler that will
be called when the event with matching type and state occurs. This is
done using the `sbak.event.create_hook(handler, type, state)` function.)
A typical hook to create is one that associates the Escape key with the
`sbak.engine.finish()` function, which makes the game end.

2.) The user calls `sbak.engine.start()` which then starts the main loop
code for the engine.

3.) Inside the main loop, the following occurs in order:

  a.) The engine posts a custom event, "BEGIN", to Pygame's event queue.
This signifies the beginning of a game cycle.

  b.) The engine calls `pygame.event.pump()` which puts events from the
system into the queue.

  c.) The engine posts another custom event, "UPDATE", which is used to
run game logic (moving entities around, AI, and whatever).

  d.) The engine posts yet another custom event, "COLLISIONCHECK", which
is used to check for collisions between entities and post "COLLISION"
events for each collision detected. It is expected that this is the only
time that COLLISION events ever get posted, but at the moment it is up
to the coder to make sure they actually are.

  e.) The second-to-last custom event, "END", gets posted. This
signifies the end of the game logic cycle and is only needed for certain
special situations.

  f.) The final event, "DRAW", occurs. This is where all objects are
drawn to the display buffer--BUT, the screen is not flipped until later.

  g.) The engine is done posting events and it is now time to handle
them. This is done by calling `sbak.event.update()` which iterates over
`pygame.event.get()` and calls the handlers for registered event hooks
that have even descriptions which match the events that have occurred.

  h.) The screen is flipped, and the cycle is over.

4.) After the main loop has ended the various subsystems are shut down.
Among other things, this calls `pygame.quit()`.

- - -

That's basically the bulk of the engine, though there are of course lots
of smaller things that happen which I didn't mention...

Anyway, my problem is more-or-less with part (d) above. Using this
system, COLLISION events can't be handled until after the DRAW event for
the current cycle, which is just stupid. I want collision handling code
to occur before "END" code or "DRAW" code is run, but I can't think of a
(good) way to do it. Also, I can see this sort of problem coming up with
other custom events I may implement later.

One idea I had is to implement a `sbak.event.send()` function which
accepts an Event and immediately runs hooks associated with that event,
but using something like that I would have to "send" every single custom
event, as well as Pygame standard events (KEYDOWN, KEYUP, etc.). That
would quickly lead to all kinds of recursion problems and would
effectively defeat the purpose of using events at all...

Any help is appreciated. Thank you.