Re: Event Based or Get-Key based
- From: Ray Dillinger <bear@xxxxxxxxx>
- Date: Mon, 03 Dec 2007 12:49:40 -0800
awhite wrote:
How many are programming their RLs using an event-based model? That is to say, much like you'd program a GUI - the main loop just collects input, and that input is then passed to (dynamic) call backs. Pressing "i" for inventory sets up a call-back for future input to apply to the inventory display dialog.(clip)
Alternatively, most traditional RLs seem to be written on a "get-key" basis - where input is read from the player as needed. So, for example, that same "i" for inventory immediately passes control to the inventory display, then waits for input there. No need to save state, or set up call-backs.(clip)
Has anyone else faced this? What did you decide?
Hmmm. Neither is an accurate description of how my framework
is working now.
I originally wrote a "getkey based" framework but found that
there were some UI things I couldn't really do that way.
I'm now using an "event based" model but aside from checking to
see if the screen has been resized, the main loop doesn't
collect input -- my "events" are things that happen in or to the
dungeon or game settings, not input events. Therefore they can
collect input locally and use it locally, and there's no problem
that way.
The game has a timequeue structure where events that haven't
happened yet wait. It's an array of pointers to linked lists,
where each linked list is an ordered list of the events that
will happen on a particular "beat" (modulo array length) of
gametime and each event is a record containing a bunch of
arguments and a code pointer.
The main game loop looks like this:
void mainloop(gametype *game)
{
eventtype *event = NULL;
int lasteventtype = ENDGAME - 1;
insertevent(game, makegamestartevent(), 0);
game->clock = 0;
while (lasteventtype != ENDGAME) {
event = popnextevent(game);
event->evcode(game, nextevent);
lasteventtype = event->evtype;
free(event);
}
}
notes: popnextevent may increment game->clock. If there
are no more events, popnextevent allocates and returns an
ENDGAME event. ENDGAME events are normally entered in
the queue when character death (or win) is detected.
Executing an ENDGAME event removes all pending events
still in the timequeue.
Each event, when executed, adds zero or more additional
events to the timequeue. For example the gamestart event
queues up game initialization, dungeon generation,
random character generation, character placement, and
character customization actions, then exits.
The character customization event loops, displaying the
character, executing a getkey then doing something to the
character based on locally comparing the getkey result to
its own action table. When the key indicates the player
is ready to start playing, it queues up a select-action
event for the player character and exits.
The select-action event calls the AI routine associated
with that monster (a code pointer in the actor record)
to find out how long until the next select-action for that
monster, queues up the next select-action for that monster,
and exits. The AI routine for the player displays the
dungeon, executes getkey, compares the result to its local
action table, then queues up the selected action and returns
the amount of time it'll take. The AI routine for the
monsters determines action in other ways, but it also
returns the amount of time the action will take.
Note I've my input routine wraps getkey to check for screen-
resizing events, so those get handled no matter what event
code is calling for player input.
rinse, repeat. Sooner or later the character wins or dies,
the ENDGAME event is executed, the queue is cleared, and the
mainloop returns.
Bear
.
- References:
- Event Based or Get-Key based
- From: awhite
- Event Based or Get-Key based
- Prev by Date: Re: AsciiDraw build #6 released
- Next by Date: Re: Event Based or Get-Key based
- Previous by thread: Re: Event Based or Get-Key based
- Next by thread: Re: Event Based or Get-Key based
- Index(es):
Relevant Pages
|