Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411582 Posts in 69386 Topics- by 58445 Members - Latest Member: Mansreign

May 06, 2024, 03:18:23 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)The Struggle for a Python Game GUI
Pages: [1] 2
Print
Author Topic: The Struggle for a Python Game GUI  (Read 9356 times)
Lynx
Level 5
*****


Upstart Feline Miscreant


View Profile WWW
« on: February 19, 2009, 04:04:32 PM »

Edit: changed subject from 'Where do you get your essential game infrastructure?'
Edit: changed subject from 'Adventures with wxPython and Pyglet'

After years of thinking 'it'd be cool to make a game that does this and that', I've started on one, using Python because I like the 'try it out immediately' feel it has.  (I have a fair bit of background in general software engineering, but none in game programming)

Unfortunately I'm finding that a lot of things I figured would be easy, really don't come standard with the basic packages like Pygame and Pyglet that I've been looking at.  Things like...  UI implementations, UI themes, tile and map editors, so far that I've noticed.

"Lynx, there are tons of libraries out there, use them!"

Sure - but I'm looking for recommendations and 'working approaches' that people use to deal with the nitty gritty issues.

For the UI end of things, I'm being a little picky here, but I don't want "standard" buttons, I want to be able to make themed buttons.  I'm looking for recommendations.  What do you do when you want to show buttons, radial menus, file browsers, and the like?  Do you implement them in code, or in data, and if in data, how do you hook it up?

For tile and map editors, there seem to be a few choices around, but what strategies do you use to work with your levels and maps?  The feeling I get from these editors is that people load them up, edit maps, save the data files out, then start their games up and test the levels.  What I'd like to do ideally would be to build the level editor into the game so that iterating on level designs is far easier.

I've looked at cocos2d, and I like the approach they take but the editor that came with the package was so dog-slow (3 fps when editing a 20x20 map) that I've taken a step back and am pondering just rolling my own...  And I'm dreading the ground-breaking I'll have to do to get all these things working.  Right now I'm just puttering around in pyglet with rabbyt for the sprite-management.
« Last Edit: March 19, 2009, 09:26:12 PM by Derek » Logged

Currently developing dot sneak - a minimalist stealth game
nihilocrat
Level 10
*****


Full of stars.


View Profile WWW
« Reply #1 on: February 19, 2009, 05:35:11 PM »

I usually just have a very very basic "widget" class and subclass stuff from there. I try to make things data-driven using my prototype class, which will accept a dictionary and basically just run object.__dict__.update(template_dict) to insert data into the instance. I load the dict at run-time using some import library sorcery which ensures that if I py2exe it, it will still load and interpret the modules where those dicts are at run-time. It's a pretty cool way of making Python do config file parsing for you.

There is some WidgetManager or other component which does an AABB collision between the mouse and all the widgets in the active window(s). It tells the widgets when they are being hovered, clicked, etc. The widgets decide what to do in each of these cases with their own functions. There's no hard math involved, you just need to take a little bit to think through how everything works so you can design your code properly, so it's a pretty easy task in my book. I am half-motivated to clean my code up and submit it as a patch to pyglet.

As for cocos2d, for stuff like tile maps you will want to use pyglet or rabbyt sprites instead. The cocos2d sprites seem to be very heavyweight, I had the same experience where having more than about 50 sprites on the screen would slow things down. Thankfully, all these libraries can work on the same OpenGL context so you can mix-and-match them.
Logged

Lynx
Level 5
*****


Upstart Feline Miscreant


View Profile WWW
« Reply #2 on: February 19, 2009, 06:05:38 PM »

Thanks for the advice!  It's good to know that someone else experienced slowdowns with cocos2d tiles, I was wondering if it was something I was doing wrong on my end somehow, given that cocos2d appears to be a popular iPhone development choice.

How did you manage things like dragging with your widget manager?  Or modal dialogs?
Logged

Currently developing dot sneak - a minimalist stealth game
increpare
Guest
« Reply #3 on: February 19, 2009, 06:14:43 PM »

I ended up just hardcoding my own widget library in the end; I don't have dragging, but I do have mouse capturing, so presumably it wouldn't be that hard to implement.

I tend to implement modal dialogs as game-states.  It's not ideal, but it works.  I haven't thought of a particularly pretty proper way of doing it yet.

The handiest thing was that I found I was able to port the code to work in different graphics libraries quite easily. It was deeply pleasurable.

Map editors are, once you get the hang of them, not that time-consuming to code.  I've tended to use mappy recently for some projects.

I don't have much experience with python; maybe pythonpeeps have different ways of working with things, but I thought I'd post my own experiences anyway.
Logged
Kaelan
Level 1
*


Malcontent


View Profile WWW
« Reply #4 on: February 19, 2009, 06:26:09 PM »

The general answer here (since you seem to mostly be talking about infrastructure needed for building tools) is to give up on trying to build tools on top of GL/SDL/DX. Don't bother.

Use a real windowing toolkit like wxWindows, GTK, QT, WinForms, WPF, SWT or Cocoa. If you want to render stuff, take your existing rendering code and point it at a rendering context - you can get one in any decent windowing toolkit and use GL or DX to paint onto it.

The amount of effort that goes into building a solid user experience is tremendous, and having a hand-rolled UI will hurt you in hundreds of little ways that you simply won't have time to address. Everybody tries to build their own UI once or twice, and that's fine - you learn a lot by doing it - but a lot of people never realize that it's a giant black hole that will suck up your time forever.

My personal preferences for UI building are wxPython and WinForms. I've also heard great things about SWT and QT. wx and WinForms both offer extremely straightforward ways of getting a GL or DirectX context inside a window so you can have top quality rendering and native UI.
Logged

george
Level 7
**



View Profile
« Reply #5 on: February 19, 2009, 06:30:01 PM »

It's good to know that someone else experienced slowdowns with cocos2d tiles, I was wondering if it was something I was doing wrong on my end somehow, given that cocos2d appears to be a popular iPhone development choice.

One thing to remember is that cocos2d for the iPhone is not executing Python, rather it's porting the concepts.
Logged
increpare
Guest
« Reply #6 on: February 19, 2009, 06:39:23 PM »

wx and WinForms both offer extremely straightforward ways of getting a GL or DirectX context inside a window so you can have top quality rendering and native UI.
i think QT also allows for rendering of widgets inside an opengl context, which would be potentially very handy provided one can get the examples to compile (I couldn't get some stuff compiling on OSX).

this is the main reason of my current lack of enthusiasm for third party widget sets: the embeddable ones are a fucking pain to get working(I must have tried over 10 different openGL widget libraries before trying my own).  And it's several times as worse still when you have to try getting the stuff working on several platforms. >_< 

I found QT's API extremely beautiful, but the extra layer of compilation to be rather a turn-off. (in addition to the other problem mentioned above).

One other library to mention, CeGUI is very highly-regarded by some as a context-embeddable GUI library.  I gave it a try, and couldn't quite get it working, and gave up in the end.  Might have another look at it at some point.
Logged
Chris Whitman
Sepia Toned
Level 10
*****


A master of karate and friendship for everyone.


View Profile
« Reply #7 on: February 19, 2009, 07:49:50 PM »

I've been using CeGUI for all the tools for my recent project.

My only complaints are that the GUI editor application is a bit crappy (no real alignment features to speak of) and that there are a few things, like tabbing in between windows, which are not supported when I think they really should be.

Other than that, though, I've found it pretty quick to implement GUI elements and bind them into C++ code, and it's quite reliable. I haven't used the Lua module for this particular application, but I've used it before and it seems to work pretty well.

Currently my GUI code is a bit of a mess: I could have abstracted a lot of stuff that ends up being repeated with only small variations, but this has been my first try making an entire suite of editing tools. It works, anyway, and it isn't like I'll be shipping it.

Edit: I guess another complaint might be that it relies a bit too much on the C++ "everything in namespaces and buckets o' singletons" strategy, which tends to get on my nerves a bit with all the typing, but that's something you tend to have to live with in the C++ world.
Logged

Formerly "I Like Cake."
Lynx
Level 5
*****


Upstart Feline Miscreant


View Profile WWW
« Reply #8 on: February 19, 2009, 10:51:02 PM »

george - thanks for the correction.  That makes more sense, re: cocos2d for iPhone being a different technology.

I'll look at Kaelan's recommendations, but to be honest I'm not sure about my ability to integrate an outside GUI package that requires separate compilation while still learning to (as it were) knap flint and build wheels in Pyglet and OpenGL.  For instance, I'm still puzzled by the following.

In pyglet.window.on_draw:
1. I draw some Rabbyt sprites
2. I then draw some OpenGL lines.

The lines come out black, rather than the color I set with glColor3f.  This doesn't happen if I comment out the Rabbyt sprites, meaning Rabbyt leaves OpenGL in a different state, one that glColor3f will not suffice to fix.

The problem went away when I changed the sprites to pyglet Sprites, but you can see that I'm nervous about invoking more complex technologies.
Logged

Currently developing dot sneak - a minimalist stealth game
Greg
Level 0
***


has a compass, lost my map


View Profile
« Reply #9 on: February 19, 2009, 11:05:39 PM »


I would just make the quick distinction between GUI's for Tools vs. GUI's for ingame experience. In the case of in-game, it is practically expected of you to roll your own, it's part of the experience. whereas for tools, definitely go with the proven desktop widget kits already mentioned.  I've used Gtk++, Win32, wxWindows, but I've also rolled my own window classes with dialog boxes and drop menus that draw inside of OpenGL, and they weren't that hard honestly.  They dont look friggen awesome, but I'm not a triple-A studio either. and really, they're definitely good enough and I enjoyed doing it.

If you think about in-game UI buttons, you just need: 1) solid mouse pointer detection code, 2) a button drawing class customized to how you like, that draws the right way for mouse-overs and mouse-clicks and has a handler with the name of the function to call onClick(), and then wrap it up nicely so you can just drop a button with a simple call and be done with it.  Then again, I say this while I fret over the next bout of more dynamic dialog boxes that I still need to write and am putting off as long I can.. 
Logged

A day for firm decisions!!! Or is it?
Lynx
Level 5
*****


Upstart Feline Miscreant


View Profile WWW
« Reply #10 on: February 20, 2009, 09:01:41 AM »

Well, it's both really.  I want UI for in-game use, i.e. the start menu, but I also want to be able to edit levels and resources conveniently.

I was able to locate the 'experimental' wxPython+Pyglet application someone had written:

http://pyglet.googlecode.com/svn/trunk/experimental/wxtest.py

I verified that wxPython UI elements would float on top of the OpenGL canvas:


The 'Hello World' text is a wxPython static text element.  I'll have to look at whether I can make custom-appearance widgets.  After looking through the wxPython demo app, it looks like they do have bitmap buttons, among other tools.  It will take some playing around to see how viable this proves.
Logged

Currently developing dot sneak - a minimalist stealth game
Chris Whitman
Sepia Toned
Level 10
*****


A master of karate and friendship for everyone.


View Profile
« Reply #11 on: February 20, 2009, 01:49:01 PM »

If you think about in-game UI buttons, you just need: 1) solid mouse pointer detection code, 2) a button drawing class customized to how you like, that draws the right way for mouse-overs and mouse-clicks and has a handler with the name of the function to call onClick(), and then wrap it up nicely so you can just drop a button with a simple call and be done with it.  Then again, I say this while I fret over the next bout of more dynamic dialog boxes that I still need to write and am putting off as long I can.. 

Yeah, but what if you're making a strategy game that requires text boxes, sliders, radio and check buttons and selectable lists? You really might as well use a pre-existing solution, if one exists.

I mean, making your own from scratch is definitely preferable if the items you list are the only things you need and you aren't already familiar enough with an existing solution to make that easier; I just don't think it's flat-out always the best decision.
Logged

Formerly "I Like Cake."
Lynx
Level 5
*****


Upstart Feline Miscreant


View Profile WWW
« Reply #12 on: February 21, 2009, 01:21:37 PM »

What I've got so far.  This is just a tech test.



I've set up wxPython to run a timer event as often as it can, which requests a refresh of the game window.  (without that, it would only repaint if deemed necessary)  This seems to cap out at 60fps.  I don't know if this is a wxPython limitation or not.

If I didn't do any per-sprite work (i.e. moving stuff around) then the test application will happily run at 400 or more sprites without dropping below the 60fps mark.  However, the moment I start applying a position change to each sprite, fps drops considerably.  At 100 sprites, it runs at about 45fps on my system (a 2GHz Athlon) as seen above.

Anyway, it looks to me like I can work with this for a start, but I'll have to watch how much processing work I'm doing on the backside - that, not drawing speed, is the limiting factor.

Next step, designing a resource manager and editor so I can start building game levels!
Logged

Currently developing dot sneak - a minimalist stealth game
Lynx
Level 5
*****


Upstart Feline Miscreant


View Profile WWW
« Reply #13 on: February 21, 2009, 03:18:41 PM »

I can has UI?



Ugly Windows standard UI, but good enough for now.  Left button can be used to drag the map around, right button brings up what should be a context-specific menu.
Logged

Currently developing dot sneak - a minimalist stealth game
Lynx
Level 5
*****


Upstart Feline Miscreant


View Profile WWW
« Reply #14 on: February 22, 2009, 11:52:04 PM »

This has been a learning experience so far.  I've got an editor in progress that will import images and break them up (automatically only) into tiles.  This gets popped up as a palette, then you click on one to select it and...

Actually, I'm running into a problem here, anyone familiar enough with wxPython/pyglet to suggest what's going on?  I'm trying to use wx.BoxSizer to control the layout, but it is pointedly Not Working; it refuses to extend the box sizer (and contents thereof) to the maximum size of the window, despite the WX_EXPAND | WX_ALL directive.

I can hack it by just specifying the locations of all widgets in absolute terms, of course, but that means having to write a lot of code to handle it if the window should ever get resized, i.e. for different monitor resolutions.
Logged

Currently developing dot sneak - a minimalist stealth game
Lynx
Level 5
*****


Upstart Feline Miscreant


View Profile WWW
« Reply #15 on: February 23, 2009, 11:14:50 PM »

I has another shinee picture!  Tiger



Placeholder art, doesn't actually save out data or set properties or the like, but nevertheless there's nothing like actually being able to see a program do something.
Logged

Currently developing dot sneak - a minimalist stealth game
Lynx
Level 5
*****


Upstart Feline Miscreant


View Profile WWW
« Reply #16 on: February 24, 2009, 03:53:31 PM »

Question for people - how do you manage your game creation workflow?

Is the normal development cycle:

1. Create or edit the level you're working on
2. Start a new game, use a cheat code to warp directly to that level
3. Test the level
4. Go back to the editor

If so, how do you handle save/restore games with edited levels, or do you just throw out any data that doesn't match?  I.E. user is in a dungeon with a big dragon blocking the next room, then you decide that the dragon is maybe a little too overkill and replace it with a bunch of kobolds.

Or, do you have some kind of editor that works in-game (or game that works in editor)?  If so, how do you structure your game's internals to make it possible?

I'm not really up to the point where any kind of gameplay is yet possible, but I want to make sure the structure is good for an efficient workflow.  It seems intuitive that being able to play and edit as you go would be fast, but it also seems like a complicated program structure since it has to know when you're editing or playing, and not save the 'played' state of the game as the 'starting' state.
Logged

Currently developing dot sneak - a minimalist stealth game
george
Level 7
**



View Profile
« Reply #17 on: February 24, 2009, 08:56:49 PM »

I really like the idea of editing and playing as you go too, and one thing you might want to look at as a fruitful place for ideas is the Inform 7 and TADS 3 Workbench applications (tools for interactive fiction writing). Both of these IDEs have the concept of skeins or threads that you can run (basically threads of gameplay) to get to certain points in the game with different parameters. The I7 model also allows you to do some interesting things with 'approving' a thread of play and so on. No doubt the requirements for a shooter, platformer, RTS game and so on will be different but I think in general the concept could be applied to those games.
Logged
Lynx
Level 5
*****


Upstart Feline Miscreant


View Profile WWW
« Reply #18 on: February 24, 2009, 09:19:54 PM »

Hmmm.  That's kind of a different take, but interesting.  Let me quote what I found on Wikipedia:

Quote
As a developer tests the game in the built-in interpreter, progress is tracked in the "skein" and "transcript" views of the IDE. The skein tracks player commands as a tree of branching possibilities. Any branch of the tree can be quickly re-followed, making it possible to retry different paths in a game under development without replaying the same portions of the game. Paths can also be annotated with notes and marked as solutions, which can be exported as text walkthroughs. The transcript, on the other hand, tracks both player commands and the game's responses. Correct responses from the game can be marked as "blessed." On replaying a transcript or a branch of the skein, variations from the blessed version will be highlighted, which can help the developer find errors.
Logged

Currently developing dot sneak - a minimalist stealth game
Lynx
Level 5
*****


Upstart Feline Miscreant


View Profile WWW
« Reply #19 on: February 25, 2009, 10:50:50 PM »

I have discovered wxLayoutConstraints!  These will allow me to place things where I need them to be, where wxBoxSizers won't allow any element to be overlaid on top of another element.

Code:
class TestPanel(wx.Panel):
    def __init__(self, parent, id=-1):
        wx.Panel.__init__(self, parent, id)
        self.SetAutoLayout(True)
       
        gamePanel = TestCanvas(self)
        lc = wx.LayoutConstraints()
        lc.left.SameAs(self, wx.Left, 0)
        lc.right.SameAs(self, wx.Right, 0)
        lc.top.SameAs(self, wx.Top, 0)
        lc.bottom.SameAs(self, wx.Bottom, 0)
        gamePanel.SetConstraints(lc)

        ulPanel = wx.Window(gamePanel , -1)
        ulText = wx.StaticText(ulPanel, -1, "Upper Left")
        width, height = ulText.GetSize()
        lc = wx.LayoutConstraints()
        lc.top.SameAs(gamePanel , wx.Top, 10)
        lc.left.SameAs(gamePanel , wx.Left, 10)
        lc.width.Absolute(width)
        lc.height.Absolute(height)
        ulPanel.SetConstraints(lc)
       
        lrPanel = wx.Window(gamePanel , -1)
        lrText = wx.StaticText(lrPanel, -1, "Lower Right")
        width, height = lrText.GetSize()
        lc = wx.LayoutConstraints()
        lc.bottom.SameAs(gamePanel , wx.Bottom, 10)
        lc.right.SameAs(gamePanel , wx.Right, 10)
        lc.width.Absolute(width)
        lc.height.Absolute(height)
        lrPanel.SetConstraints(lc)

As far as I can tell, LayoutConstraints won't poll their children to find out the best size, so you have to give them enough information that they can determine all 4 sides - hence, the code above that checks the width of the text so that they can be positioned at the extreme corners.  This code gives them a 10 pixel margin.
« Last Edit: February 25, 2009, 11:08:24 PM by Lynx » Logged

Currently developing dot sneak - a minimalist stealth game
Pages: [1] 2
Print
Jump to:  

Theme orange-lt created by panic