Re: [pygame] State Machine Organization

2007-07-06 Thread Dave LeCompte (really)
"Greg Ewing" <[EMAIL PROTECTED]> wrote:
> Kris Schnee wrote:
>> The idea is that instead of calling a shop screen from a walking-around
>> screen, which risks having you get into some tangled recursion, the
>> program "drops" from the walking screen back to the main loop, with a
>> state variable saying "the next screen to go to is the shop screen."
>
> This sounds similar to the way I've organised a couple of
> my recent PyGame entries. I have a Shell object at the top
> which implements the main loop. The Shell has an instance
> variable called current_screen which at any moment points
> to one of a number of different Screen subclasses which
> present different user interfaces. The Screen objects have
> methods for drawing the display, handling input events,
> etc.

I did something similar, sort of, for my most recent entry. Everything was
a "state", and I maintained a stack of states. Call this a Hierarchical
Finite State Machine, if you like. When I needed to interrupt a state to
pop up a dialog box (a good example was during my tutorial sequence), I'd
simply push a dialog box state onto my stack. When the dialog was done,
it'd pop itself off, and the old state would be the top of the stack.

Each state would implement OnDraw and OnUpdate events, with a few states
doing quasi-fancy things. For example, those dialog boxes would let their
parents draw first before drawing themselves, which gave the effect of
dialogs being "in front of" the main game screen. When I wanted to go back
to the main menu, I popped everybody off the stack, and pushed a new
instance of the main menu state onto the stack.

That worked pretty well for me, but I ended up keeping some data in the
state objects that probably belonged in a more intelligently encapsulated
place.

Thinking about MVC, this approach does separate out the logic (model) from
the display (view) - I didn't mention it above, but there's also
OnMouseDown and OnKeyDown which gets you the controller, as well. So I
didn't break up M/V/C into three separate classes, but each state object
had a pretty clean division of code.


If people are still looking for arguments in favor of separating out the
update logic from the display, there were two cases where it paid off in
my game:

- As I mentioned above, dialog boxes could be considered "child" states of
main gameplay states. By having the display of the parent state callable
without any update, I could suspend the progress of the game for a
temporary interruption (the "pause" menu that came up when you hit escape
or the window lost focus, tutorial dialog boxes, level intros).

- Having the game logic in one place, unentangled with display code made
it easier (after the challenge was over) to pull it out into a clean
location, so the AI could call it multiple times as a cheap form of
"lookahead". Rather than make the AI smart, it just simulated trying a
bunch of random options, and picked from the best results.


> (I'm going to have to write a wysiwig ascii-art drawing
> editor one day...)

I recently found out about emacs' "artist-mode", which seems just about
the level of quality that I'd need for ASCII art. I've even considered
(ab)using it as a level editor.

http://www.tulrich.com/geekstuff/emacs.html (look for artist-mode, towards
the bottom.)


I really gotta get back to working on my RPG.

-Dave LeCompte


Re: [pygame] State Machine Organization

2007-07-06 Thread Greg Ewing

Kris Schnee wrote:
The idea is that instead of calling a shop screen from a walking-around 
screen, which risks having you get into some tangled recursion, the 
program "drops" from the walking screen back to the main loop, with a 
state variable saying "the next screen to go to is the shop screen."


This sounds similar to the way I've organised a couple of
my recent PyGame entries. I have a Shell object at the top
which implements the main loop. The Shell has an instance
variable called current_screen which at any moment points
to one of a number of different Screen subclasses which
present different user interfaces. The Screen objects have
methods for drawing the display, handling input events,
etc.

All the Screen objects hold a reference to a single Game
object which contains all of the game state (the "model"
in MVC terminology).

+-++--+
| ||  |
|   Screen1   |--->|  |
| ||  |
+--++-+|  |
|  |   |  |
| Shell|+-+|  |
|  || ||  |
|  current_screen ->|   Screen2   |--->|   Game   |
|  || ||  |
+--++-+|  |
   |  |
+-+|  |
| ||  |
|   Screen3   |--->|  |
| ||  |
+-++--+


(I'm going to have to write a wysiwig ascii-art drawing
editor one day...)

--
Greg


Re: [pygame] FastRenderGroup revised (update4)

2007-07-06 Thread DR0ID

Hallo

since my last email (with attachment) did not get through to the mailing 
list, this time I only will provide a link :-)


http://www.mypage.bluewin.ch/DR0ID/pygame_projects.html#fast_dirty1

or direct donwload:

http://www.mypage.bluewin.ch/DR0ID/pygame/FastRenderGroup_v1.1.83.zip

I have been trying different tiling methods and timing methods. All 
tiling methods I tried were about 3 times slower as current 
implementation in the average case. Because of that result it still uses 
the original implementation which is an O(n**2) algorithm in worst case 
(I think average case is something between O(n) and O(n**2) ).
Perhaps I have done something wrong so if you implement a fast tiling 
algorithm let me know please. If you are interested in what i have done 
then look into the subfolders tiling and timing and search for "try" 
in the source code of TilingFastRenderGroup.py  or in the other case 
TimingFastRenderGroup.py.


I have changed the timing code to the very simplest approach: it checks 
the time needed to render the frame at each frame and decides using a 
threshold value what mode to use. The problem now lies in finding the 
correct threshold (which at the moment has to be set by the programmer). 
This approach works even smother than the old one.


I have modified testsprite.py to use FRG, please test following 
configurations:


testsprite.py
testsprite.py -update_rects
testsprite.py -FastRenderGroup

testsprite.py -static
testsprite.py -static -update_rects
testsprite.py -static -FastRenderGroup

What do you think? For that tests I have added a new image, as you can see.

I have written a demo to demonstrate that all sprites have to be in the 
same FRG to be drawn correctly:


multi_FRG_demo.py

use the same arguments as for testsprite.py and you will see what 
happens when using the FRG.



~DR0ID



Brian Fisher schrieb:

On 6/29/07, DR0ID <[EMAIL PROTECTED]> wrote:

I think this is only a O(n^2) in worst case otherwise it is less (but I
cant tell you what it is). The drawback of that method is, that in the
worst case it ends up with a big rect covering the entire screen.
Perhaps using Gustavos rect splitting thing would be better (? faster?).


At work we use tiled rects for our dirty rect system for software
rendering. It's a C++ engine, but the 2 really big wins for a tiling
system is that you never need to merge rects (merging is in general
O(n^2) unless you maintain some kind of partitioning system, then it
can by n log n) and you don't need to manage a pool for
allocating/deleting (a fixed size linked list pool can be constant
allocation and deletion time, but naive object allocation and deletion
from a variable sized heap/pool can be very very slow)

We tested a lot of different approaches and tiling was by far the
fastest we tried (in C++ anyways). In particular the fastest
implementation for us was where each tile has it's own rect, and it
does min/max ops on the cells rect to grow it to cover the overlap
being the dirty rect and the cell area. So in cases with a fairly
small number of objects, you oftenget a perfectly tight fit even
though the cells are like 16x8, but it's still all O(n) where n is the
number of objects.





Re: [pygame] State Machine Organization

2007-07-06 Thread Kris Schnee

Andre LeBlanc wrote:
I've spent the past 24 hours or so looking through the source for the 
PGU Engine and Phil's Pyweek3 example code, and its convinced me that I 
need to do alot of re-writing.  I'm trying to figure out how to best 
organize the various states of my RPG, but I'm a little stuck.  should a 
state be responsible for all of the rendering at a given time?  for 
example in the case of a top-down RPG, Walking around town is a state, 
being in a battle is a state, but what about talking to an npc or a 
vendor in a town?  This would have to bring up menus for the user to 
navigate, but the scenery in the town should still be painting. NPCs can 
walk around while you are talking to a shop owner, so should that be a 
separate state?  I like the way the 'rooms' were subclassed and imported 
for the pyweek3 game and that's what I'm going for, but how would you 
transition between these 2 states, if indeed they should be separate.


The way I'm organizing the different states of my game is something like 
this. I've got a main Game class with a function called Notify, that 
takes messages from the interface or elsewhere. Then there are functions 
like WanderingScreen that set some overridden version of Notify and 
create one of several interface objects. Then there's a main loop that 
switches between the various "Screen" functions until one of them 
changes the Game object's state to "quit." Paraphrased code:



def WanderingScreen(self):
self.interface = 
WanderingScreen(screen=self.screen,pen=self.pen,input_pen=self.smallpen,parent=self)

self.Notify = self.NotifyOnWanderingScreen
done = False
while not done:
pass ## Do stuff

def Go(self):
"""This is the main loop of the game.

Go between various screens until the game is over."""
game_over = False
while not game_over:
##print "Returned to main loop. Now switching to: 
"+str(self.game_state)
function_to_call = 
self.functions_for_each_game_state.get(self.game_state)

if function_to_call:
function_to_call()
else:
game_over = True
print "Game over. Thanks for playing!"



The idea is that instead of calling a shop screen from a walking-around 
screen, which risks having you get into some tangled recursion, the 
program "drops" from the walking screen back to the main loop, with a 
state variable saying "the next screen to go to is the shop screen."


So, adding a new screen to my game involves creating a new class of 
interface, adding a new version of the Notify function, and adding a 
Screen function to switch to. I was thinking lately that a simpler way 
to do this system would be to eliminate the different "Notify" functions 
and just do something like:


def Notify(self,message):
self.messages.append(message)

And then the Screen functions could just read through their messages and 
process or ignore them however is appropriate.


Re: [pygame] multiple key presses

2007-07-06 Thread Nick Moffitt
John Eikenberry:
> My Kinesis Maxim doesn't have the issue described in the article. I can
> hold down as many keys as I like (within the limits of 2 hands) and all
> other keys work fine.

When I bought a kinesis keyboard, it was US$180.  I'd certainly hope
that for that kind of money you'd get a diode in each key!

-- 
The insipid neologism "blog" appears to mean little more  Nick Moffitt
than a Web site that *actually* gets updated, as opposed [EMAIL PROTECTED]
to one that *promises* to be updated REAL SOON NOW and
includes an animation of a MEN AT WORK sign.