Pygame wrapper: Difference between revisions

From OLPC
Jump to navigation Jump to search
No edit summary
(→‎Keyboard and Mouse: added "directional pad" to aid search. added note on d-pad diagonal input.)
Line 33: Line 33:
</pre>
</pre>


The D-pad mappings initially make sense. The gamepad mappings make sense when you realize that 9/3 are page-up/page-down and 7/1 are home/end.
The D-pad (directional pad) mappings initially make sense. The gamepad mappings make sense when you realize that 9/3 are page-up/page-down and 7/1 are home/end.

The d-pad has 8 directions of articulation. You detect the diagonals by looking for two keys pressed at the same time.


==In progress==
==In progress==

Revision as of 14:53, 17 July 2007

The Pygame wrapper is called olpcgames. For a tutorial on how to use it, see Game development HOWTO. This is the reference manual.

Getting the wrapper

Eventually, the wrapper will be a part of the standard build. Before then, you need to get it from Git:

git clone git://dev.laptop.org/projects/games-misc

The 'olpcgames' directory is the package in question. Submodules you can access are activity, canvas, camera, and pangofont. The wrapper also replaces certain Python modules (python.event) with 'eventwrap' (which can also be imported separately), so we document those here too.

Notes

Differences from Pygame

The SDL Pygame wrapper allows for nested Pygame windows using a separate thread. It forwards GTK events and converts them to Pygame events. Games under the wrapper may not work exactly the same way and porting is not completely seamless -- you should be aware of a few OLPC-specific caveats:

  • You cannot set the display mode using pygame.display.set_mode. You must set it in the wrapper boilerplate instead (see Game development HOWTO).
  • It is not recommended that you use the regular Pygame.font text drawing. You can use the wrapper to draw text using the 'olpcgames.pangofont' module instead which supports proper internationalization. See Pygame wrapper#Pangofont.
  • The event module is shadowed by Pygame wrapper#Eventwrap and some methods may not work exactly the same. Certain methods in pygame.mouse and pygame.key are also shadowed.
  • There's no CD-ROM, so the 'cdrom' module isn't useful.

Keyboard and Mouse

Keyboard and mouse work. The "gamepad" buttons on the left and right of the screen come in as Numpad number keys (i.e., pygame.K_KP1 through pygame.K_KP9):

D-Pad (left of screen)             Gamepad (right of screen)
  
      8                                    9
    4   6                                7   1
      2                                    3

The D-pad (directional pad) mappings initially make sense. The gamepad mappings make sense when you realize that 9/3 are page-up/page-down and 7/1 are home/end.

The d-pad has 8 directions of articulation. You detect the diagonals by looking for two keys pressed at the same time.

In progress

Window resizing probably doesn't work well yet (i.e., resizing windows via the screen rotate button), but we will try to get this working soon.

The cursor is the small X cursor at this time. We should consider changing it to a standard Sugar cursor.

Module Reference

Activity

The olpcgames.activity module encapsulates creation of a Pygame activity. Your Activity should inherit from this class. Simply setting some class attributes is all you need to do in a class inheriting from olpcgames.activity.PyGameActivity in order to get Pygame to work.

class PyGameActivity(activity.Activity):
        
    game_name = None
    game_title = 'PyGame Game'
    game_handler = None
    game_size = (units.grid_to_pixels(16),
                 units.grid_to_pixels(11))
    pygame_mode = 'SDL'

You need to set these:

game_name: This is a string containing the name of the module and, optionally a colon followed by the name of the main method (example: "tictactoe:main"). If there's no main method specified it defaults to "main". In this example, the wrapper code will import the module named "tictactoe" and call main() on it. That is expected to enter a Pygame main loop (which makes some call into pygame.event periodically, see Pygame wrapper#Eventwrap).

game_title: This is the string containing the title of the game, as it appears in the Sugar toolbar at the top of activities.

game_size: Pixel resolution of your game window. This is not changeable at runtime. This needs to match whatever you pass to pygame.display.set_mode(), and you cannot call set_mode() later with a different size.

These are optional:

pygame_mode can be set to 'Cairo' if you want experimental Cairo pygame support. In this case you need to include 'pygamecairo' module accessible from your game. This is not recommended as Cairo is quite slow.

game_handler is a deprecated synonym for game_mode.

Canvas

The canvas submodule handles wrapping events and initializing SDL inside the container.

class PyGameCanvas(gtk.EventBox):
    pass

There's nothing you probably need to interact with in the canvas submodule.

Eventwrap

The 'eventwrap' module is a replacement for pygame.event. It has much of the same interface (see [1]). See the doc-strings of these methods for full documentation; I'll point out the differences here:

There is an install() method which installs eventwrap in place of pygame.event, so that unaware Pygame applications will use this event queue rather than the native Pygame one. Performance is mostly unaffected, and this event queue is more versatile than Pygame's. Thus, we do this for all Pygame games as part of the Activity wrapper.

This event queue does not support getting events only of a certain type. You need to get all pending events at a time, or filter them yourself. You can, however, block and unblock events of certain types, so that may be useful to you. Set_grab doesn't do anything (you are not allowed to grab events). Sorry.

Camera

def snap():
    """Dump a snapshot from the camera to a pygame surface."""

What it says. This method takes approximately forever, so it's not that useful right now. It takes a snapshot, saves it to a temporary file, and then loads the file as an image.

Pangofont

The 'pangofont' module is a replacement for pygame.font. It has a similar interface (see [2]). See the doc-strings of these methods for full documentation; I'll point out the differences here:

There is an install() method which installs pangofont in place of pygame.font, so that unaware Pygame applications will draw with Pango rather than SDL_ttf (the default font backend in SDL). Unlike eventwrap, install() is not called automatically.

The main problem with SDL_ttf is that it doesn't handle internationalization nearly as well as Pango (in fact, pretty much nothing does). However, it is fairly fast and it has a rich interface. You should avoid fonts where possible, prerender using Pango for internationalizable text, and use Pango or SDL_ttf for text that really needs to be rerendered each frame. (Use SDL_ttf if profiling demonstrates that performance is poor with Pango.)

class PangoFont(object):
    """Base class for a pygame.font.Font-like object drawn by Pango."""
    def __init__(self, family=None, size=None, bold=False, italic=False, fd=None):
        """If you know what pango.FontDescription (fd) you want, pass it in as
        'fd'.  Otherwise, specify any number of family, size, bold, or italic,
        and we will try to match something up for you."""

    def render(self, text, antialias, color, background=None):
        """Render the font onto a new Surface and return it.
        We ignore 'antialias' and use system settings.
        NOTE: Due to a retarded implementation problem you cannot use 
        transparent colors. Alpha is ignored (set to 255)."""

class SysFont(PangoFont):
    """Construct a PangoFont from a font description (name), size in pixels,
    bold, and italic designation. Similar to SysFont from Pygame."""
    def __init__(self, name, size, bold=False, italic=False):

def fontByDesc(desc="",bold=False,italic=False):
    """Constructs a FontDescription from the given string representation."""

The format of the fontByDesc string representation is passed directly to the pango.FontDescription constructor and documented at [3]. Bold and italic are provided as a convenience. Example descriptions:

"sans bold 12"
"serif,monospace bold italic condensed 16"
"normal 10"

Note that PangoFont objects don't have any of the methods to mutate or examine the font (set_bold, get_line_height, etc.) that pygame.font.Font has. If you really need these methods, you can consider sticking with SDL_ttf.