Game development HOWTO: Difference between revisions
(Reference to discussion on how we used mesh module) |
Crazy-chris (talk | contribs) m (16bpp) |
||
Line 17: | Line 17: | ||
def main(): |
def main(): |
||
# Create a window 400x225 with 16 bpp |
|||
window = pygame.display.set_mode((400, 225)) |
window = pygame.display.set_mode((400, 225), 16) |
||
# Block MouseMotion event - Remove that line if you want to capture it |
|||
pygame.event.set_blocked(MOUSEMOTION) |
pygame.event.set_blocked(MOUSEMOTION) |
||
⚫ | |||
# Get going |
|||
⚫ | |||
while True: |
while True: |
||
for event in [ pygame.event.wait() ] + pygame.event.get( ): |
for event in [ pygame.event.wait() ] + pygame.event.get( ): |
||
Line 108: | Line 113: | ||
<pre> |
<pre> |
||
for evt in pygame.event.get(): |
for evt in [ pygame.event.wait() ] + pygame.event.get( ): |
||
if evt.type == pygame.KEYDOWN: |
if evt.type == pygame.KEYDOWN: |
||
# ... |
# ... |
Revision as of 00:03, 10 December 2007
This HOWTO is current as of December 2007.
Note: The OLPCGames Pygame wrapper requires at least build 432 to work for version 1.0 and at least an Update.2 build (649) for version 1.1. See the reference manual at Pygame wrapper. See also Game development.
Crash Course on Pygame
The slides from Noah's lecture at the start of the game jam are online at http://dev.laptop.org/~coderanger/ (both PDF and PowerPoint form).
Development Environment
Start with Pygame. If you are running Mac OS X, check out the Mac setup instructions.
You don't need an XO laptop for simple Pygame development. When creating your Pygame game, use this new boilerplate:
import sys import pygame from pygame.locals import * def main(): # Create a window 400x225 with 16 bpp window = pygame.display.set_mode((400, 225), 16) # Block MouseMotion event - Remove that line if you want to capture it pygame.event.set_blocked(MOUSEMOTION) # Get going pygame.init() while True: for event in [ pygame.event.wait() ] + pygame.event.get( ): print event if event.type == KEYUP: # Quit on 'q' if event.key == 113: sys.exit(0) if __name__=="__main__": main()
The 'main' method will be called by the activity wrapper later on, so it must be called 'main'. Using pygame.event.wait() instead of pygame.event.get() reduces the cpu-load from 99% to 0.7 - 4%.
Wrapping and Testing
If you want to test using laptop software, but you don't have a real XO, you could set up an emulated environment.
To make your game run as an Activity, you will need the 'olpcgames' wrapper, otherwise known simply as "the wrapper". Eventually, the wrapper will be included as part of the standard laptop software distribution, but for now you must include it in your Activity.
git clone git://dev.laptop.org/projects/games-misc
This will download several games-related projects. There are a few game Activities checked in, as well as the wrapper.
First construct an activity development bundle as in Sugar Activity Tutorial.
The wrapper requires the following boilerplate as the main class of your activity as specified in activity.info. Generally this is called 'activity.py' and your Pygame app retains its original name:
import olpcgames # Class name must match 'class' property in activity/activity.info: class ExampleActivity(olpcgames.PyGameActivity): """An example of using a Pygame game as a Sugar activity.""" game_name = 'examplemodule:main' # game_name must match name of your Pygame module game_title = 'Example' game_size = (1200,825)
The game_name
parameter has the format "module:method". The module will be imported and the method called to start your Pygame application. Method is optional and defaults to main
. (FIXME: Use Gettext to localize the game_title parameter.)
The game_size is what sets the display mode in Pygame.
The last step: you need to copy or link the 'olpcgames' directory from the Git repository you checked out into the root of your Activity. (Eventually, 'olpcgames' will be part of the main laptop build, so you will no longer need to do this.)
Hardware
The Pygame page has some information on hardware.
Camera
OLPCGames provides you with a simple wrapper class that will use GStreamer to snap an image with the built-in camera on the XO. The camera module works by creating a GStreamer pipeline that starts with the camera and terminates in a png or jpeg file. Alternately the module can allow you to take a "picture" of the test source, for those testing on non-XO hardware.
You will need to import the module:
from olpcgames import camera
when you want to take a picture with the camera, call snap_async, like so:
camera.snap_async( 'picture 32', source='test' )
the gstreamer pipeline will be created and will iterate until complete. When the picture is available it will be read as a pygame image and returned via a camera.CAMERA_LOAD or camera.CAMERA_LOAD_FAIL event in your Pygame mainloop. These events have the following members:
- filename -- filename into which the file was saved
- success -- boolean indicating whether we succeeded/failed
- token -- the object passed in as the first argument to snap_async
- image -- the loaded image as a Pygame surface (image), or None on failure
- err -- if an error occurred, the Exception instance
There is a cameratest activity in GIT which demonstrates basic use of the snap_async function.
Note that the camera module exposes an older synchronous API for backwards compatibility. You likely should *not* use that api, as it can hang your entire activity waiting for the GStreamer stream to complete (which can take an arbitrary amount of time).
Sharing and the Mesh
Your activity can automatically be shared (through the user clicking "Share" on the Sugar toolbar). You should be using build >=530 (or so) for mesh related stuff. When the user does this, your activity will appear in the Neighborhood screen and others can join it.
In order to meaningfully communicate, you must
import olpcgames.mesh as mesh
Now, you can make use of events you receive that are mesh related. See Pygame_wrapper#Mesh for details.
Here is a simple example -- in your event loop, just add listening for certain mesh events:
for evt in [ pygame.event.wait() ] + pygame.event.get( ): if evt.type == pygame.KEYDOWN: # ... elif evt.type == mesh.PARTICIPANT_ADD: # Somebody joined. Add them to our list of people, and send them a message: self.participants.append(evt.handle) mesh.send_to(evt.handle, str(self.game_state)) elif evt.type == mesh.MESSAGE_UNI: # Received a message! Display it (and/or decode it): print "Got a message from %s: %s" % (evt.handle, evt.content) # Figure out the nick of whoever sent it: print "It was from buddy %s" % (mesh.get_buddy(evt.handle).props.nick)
See Also:
- Discussion of how Productive uses the mesh module and raw Telepathy
Troubleshooting
Ensure you are using at least an Update.2 (first manufacturing release) Sugar environment. Also ensure you are using a checkout of the wrapper from the Git repository.
Check your log files. On modern Sugar, use the Log Viewer activity to view the log for your activity. Open this activity and find your activity in the list of activity instances on the left. The numeric suffixes increase as you run your activity multiple times.
User:Mcfletch is the current maintainer of the wrapper. Contact him if you get stuck.