Re: [pygame] State Machine Organization
"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
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)
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
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
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.