
A bare-bones isometric map display working in Pyglet.
I’ve just submitted my final thesis packet, and have a few weeks to breathe before heading to San Francisco in July for the last part of my MFA program. So, obviously, I’ve been thinking about the new GearHead game. Most of the parts are going to be taken from Dungeon Monkey Eternal, plus some improvements since I know Python far better now than when I started three years ago.
Choosing a Graphics Package
The first big decision will be to choose a graphics package. DME uses PyGame, which I like. It’s based on SDL 1.2, the same graphics library as just about every other game I’ve ever made. It’s fast enough to draw a not-highly-optimized fullscreen isometric map at over 30 fps on my laptop, which IMO is fast enough for a game of this type. However, it does have limitations. It doesn’t play well with multi-monitor setups and certain operating systems. It doesn’t come with many bells and whistles; things like text formatting and widgets need to be built from scratch. So, I’m considering my options.
One option is Pyglet, which is based on OpenGL. Because of this it should be faster than PyGame; instead of the Python interpreter redrawing the screen manually, the instructions get sent to the graphics card which then handles the heavy lifting. It also comes with html text formatting and a text input widget built in. On the down side, it is an event-driven system, which means that I’d have to learn how that works and modify the game logic accordingly. You know, I’ve been using basically the same input-handling loop structure since the 90s and I’ve become quite fond of it.
Another option is Kivy, a full featured widget system. This one has several big advantages- first, I could use a whole toolkit of UI elements and even create my own. Second, it has utilities to compile distribution packages for Windows, Android, and other systems. On the minus side, it is also event-driven and based on OpenGL. After looking through the docs I couldn’t see an easy way to add an isometric map display; other open source projects working on this problem did not look promising.
I think, for now, that I’m going to stick with PyGame, but I will try to rework the main game loop so that if I need to change it to an event-based system later on I’ll be able to.
4 comments
Skip to comment form
Not sure if you’re open to starting over, or if you really want to salvage your existing systems,but:
Have you looked at the Godot engine? I’m a fulltime software dev who has spiked out various game projects in C#, C++, Rust, etc and often get hung up on doing API/infrastructure work instead of delivering/shipping.
I tried Godot recently after hitting some brick walls with other frameworks where I built from scratch and, I have to say, I have REALLY enjoyed the experience of using it.
The entire thing is MIT-licensed and the built-in scripting language is python-like. So [maybe?] you would have some luck bringing over some of your game logic, depending on how pythonic/API-dependent it is, although I wouldn’t count on it. It’s definitely a system/infrastructure that respects developers and patterns and is lower level than something like GameMaker:Studio. It’s more akin to Unity, but with a very polished 2D story.
In any event, best of luck with your decision!
I should add that it includes complete patterns for isometric tilemaps, 2d lighting, a complete set of skinnable GUI controls, a scene system, animation, etc etc etc.
I’ve really enjoyed it because I can spend time harnessing the library and editor tools instead of spinning my wheels reinventing the wheel (heh).
I have recently been porting a pygame RPG to kivy and came across the same issue. What I did was to use pygame w/TILED to blit the map to a surface. Then on every update you set a kivy image’s texture to that of the pygame surface.
def surface_to_kivy_texture(surface):
buffer = tostring(surface, ‘RGBA’, True)
imdata = ImageData(surface.get_width(), surface.get_height(), ‘rgba’, buffer)
tex = Texture.create_from_data(imdata)
return Image(texture=tex, size=tex.size).texture
Its a little bit of a hack but it is now a Kivy texture. Set it to an image in your UI and Kivy can autoscale it to the desired resolution so you no longer have to worry about scale factors w/ your pygame image loads. I like Kivy’s ability to rapidly make scaling GUI’s but I have to admit I miss the straight forward input/handle/draw loop sometimes.
Author
That’s one way to do it. Thanks!