-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
awesome pygame wrapper for XO activities
- Loading branch information
Showing
10 changed files
with
668 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,137 @@ | ||
== Sugargame == | ||
|
||
Sugargame is a Python package which allows [http://www.pygame.org/ Pygame] | ||
programs to run well under Sugar. | ||
It is fork of the olcpgames framework, which is no longer maintained. | ||
|
||
http://git.sugarlabs.org/projects/sugargame | ||
|
||
What it does: | ||
|
||
* Wraps a Sugar activity around an existing Pygame program with few changes | ||
* Allows Sugar toolbars and other widgets to be added to the activity UI | ||
* Provides hooks for saving to and restoring from the Journal | ||
|
||
==== Differences between Sugargame and olpcgames ==== | ||
|
||
The olpcgames framework provides a wrapper around Pygame which attempts to | ||
allow a Pygame program to run mostly unmodified under Sugar. To this end, | ||
the Pygame program is run in a separate thread with its own Pygame message | ||
loop while the main thread runs the GTK message loop. Also, olpcgames wraps | ||
Sugar APIs such as the journal and mesh into a Pygame-like API. | ||
|
||
Sugargame takes a simpler approach; it provides a way to embed Pygame into a | ||
GTK widget. The Sugar APIs are used to interact with Sugar, the Pygame APIs | ||
are used for the game. | ||
|
||
Sugargame advantages: | ||
|
||
* Simpler code | ||
* More elegant interface between Pygame and GTK | ||
* Runs as a single thread: no thread related segfaults | ||
* Possible to use Sugar widgets with Pygame | ||
|
||
Sugargame limitations: | ||
|
||
* No support for Pango or SVG sprites (yet) | ||
|
||
== Using Sugargame == | ||
|
||
See also [[Development Team/Sugargame/Examples]]. | ||
|
||
==== Wrapping a Pygame program ==== | ||
|
||
To use Sugargame to Sugarize a Pygame program, set up an activity directory and | ||
copy the Sugargame package to it. | ||
|
||
The activity directory should look something like this: | ||
|
||
activity/ - Activity directory: activity.info, SVG icon, etc. | ||
sugargame/ - Sugargame package | ||
MyActivity.py - Activity class | ||
mygame.py - Pygame code | ||
setup.py - Install script | ||
|
||
To make the Activity class, start with test/TestActivity.py from the Sugargame | ||
distribution. | ||
|
||
The activity should create a single PygameCanvas widget and call run_pygame on it. | ||
Pass the main loop function of the Pygame program. | ||
|
||
self._canvas = sugargame.canvas.PygameCanvas(self) | ||
self.set_canvas(self._canvas) | ||
|
||
# Start the game running. | ||
self._canvas.run_pygame(self.game.run) | ||
|
||
In your Pygame main loop, pump the GTK message loop: | ||
|
||
while gtk.events_pending(): | ||
gtk.main_iteration() | ||
|
||
==== Adding Pygame to a PyGTK activity ==== | ||
|
||
To add Pygame to an existing Sugar activity, create a PygameCanvas widget and call | ||
run_pygame on it. | ||
|
||
widget = sugargame.canvas.PygameCanvas(self) | ||
vbox.pack_start(widget) | ||
|
||
widget.run_pygame(self.game.run) | ||
|
||
Due to limitations of Pygame and SDL, there can only be one PygameCanvas in the | ||
entire activity. | ||
|
||
The argument to run_pygame is a function structured like a Pygame program. In the | ||
main loop, remember to dispatch GTK messages using gtk.main_iteration(). | ||
|
||
def main_loop(): | ||
clock = pygame.time.Clock() | ||
screen = pygame.display.get_surface() | ||
|
||
while self.running: | ||
# Pump GTK messages. | ||
while gtk.events_pending(): | ||
gtk.main_iteration() | ||
|
||
# Pump PyGame messages. | ||
for event in pygame.event.get(): | ||
if event.type == pygame.QUIT: | ||
return | ||
elif event.type == pygame.VIDEORESIZE: | ||
pygame.display.set_mode(event.size, pygame.RESIZABLE) | ||
|
||
# Check the mouse position | ||
x, y = pygame.mouse.get_pos() | ||
|
||
# Clear Display | ||
screen.fill((255,255,255)) #255 for white | ||
|
||
# Draw stuff here | ||
................. | ||
|
||
# Flip Display | ||
pygame.display.flip() | ||
|
||
# Try to stay at 30 FPS | ||
self.clock.tick(30) | ||
|
||
== Support == | ||
|
||
For help with Sugargame, please email the Sugar Labs development list: | ||
|
||
: [email protected] | ||
|
||
Sugargame is developed by Wade Brainerd <[email protected]>. | ||
|
||
It is loosely based on the source code to the olpcgames framework, developed by | ||
the One Laptop Per Child project. | ||
|
||
=== Changelog === | ||
|
||
====v1.1==== | ||
* Fix bugs in event handling. (Pablo Moleri) | ||
* Remove reference to gtk.Socket.get_window() method, which is missing in older versions of PyGTK. | ||
|
||
====v1.0==== | ||
* Initial version of Sugargame |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
from gettext import gettext as _ | ||
|
||
import sys | ||
from gi.repository import Gtk | ||
import pygame | ||
|
||
import sugar3.activity.activity | ||
from sugar3.graphics.toolbarbox import ToolbarBox | ||
from sugar3.activity.widgets import ActivityToolbarButton | ||
from sugar3.graphics.toolbutton import ToolButton | ||
from sugar3.activity.widgets import StopButton | ||
|
||
|
||
sys.path.append('..') # Import sugargame package from top directory. | ||
import sugargame.canvas | ||
|
||
import TestGame | ||
|
||
|
||
class TestActivity(sugar3.activity.activity.Activity): | ||
def __init__(self, handle): | ||
super(TestActivity, self).__init__(handle) | ||
|
||
self.paused = False | ||
|
||
# Create the game instance. | ||
self.game = TestGame.TestGame() | ||
|
||
# Build the activity toolbar. | ||
self.build_toolbar() | ||
|
||
# Build the Pygame canvas. | ||
self._pygamecanvas = sugargame.canvas.PygameCanvas(self) | ||
|
||
# Note that set_canvas implicitly calls read_file when | ||
# resuming from the Journal. | ||
self.set_canvas(self._pygamecanvas) | ||
self._pygamecanvas.grab_focus() | ||
|
||
# Start the game running (self.game.run is called when the | ||
# activity constructor returns). | ||
self._pygamecanvas.run_pygame(self.game.run) | ||
|
||
def build_toolbar(self): | ||
toolbar_box = ToolbarBox() | ||
self.set_toolbar_box(toolbar_box) | ||
toolbar_box.show() | ||
|
||
activity_button = ActivityToolbarButton(self) | ||
toolbar_box.toolbar.insert(activity_button, -1) | ||
activity_button.show() | ||
|
||
# Pause/Play button: | ||
|
||
stop_play = ToolButton('media-playback-stop') | ||
stop_play.set_tooltip(_("Stop")) | ||
stop_play.set_accelerator(_('<ctrl>space')) | ||
stop_play.connect('clicked', self._stop_play_cb) | ||
stop_play.show() | ||
|
||
toolbar_box.toolbar.insert(stop_play, -1) | ||
|
||
# Blank space (separator) and Stop button at the end: | ||
|
||
separator = Gtk.SeparatorToolItem() | ||
separator.props.draw = False | ||
separator.set_expand(True) | ||
toolbar_box.toolbar.insert(separator, -1) | ||
separator.show() | ||
|
||
stop_button = StopButton(self) | ||
toolbar_box.toolbar.insert(stop_button, -1) | ||
stop_button.show() | ||
|
||
def _stop_play_cb(self, button): | ||
# Pause or unpause the game. | ||
self.paused = not self.paused | ||
self.game.set_paused(self.paused) | ||
|
||
# Update the button to show the next action. | ||
if self.paused: | ||
button.set_icon('media-playback-start') | ||
button.set_tooltip(_("Start")) | ||
else: | ||
button.set_icon('media-playback-stop') | ||
button.set_tooltip(_("Stop")) | ||
|
||
def read_file(self, file_path): | ||
self.game.read_file(file_path) | ||
|
||
def write_file(self, file_path): | ||
self.game.write_file(file_path) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
#!/usr/bin/python | ||
import pygame | ||
from gi.repository import Gtk | ||
|
||
|
||
class TestGame: | ||
def __init__(self): | ||
# Set up a clock for managing the frame rate. | ||
self.clock = pygame.time.Clock() | ||
|
||
self.x = -100 | ||
self.y = 100 | ||
|
||
self.vx = 10 | ||
self.vy = 0 | ||
|
||
self.paused = False | ||
self.direction = 1 | ||
|
||
def set_paused(self, paused): | ||
self.paused = paused | ||
|
||
# Called to save the state of the game to the Journal. | ||
def write_file(self, file_path): | ||
pass | ||
|
||
# Called to load the state of the game from the Journal. | ||
def read_file(self, file_path): | ||
pass | ||
|
||
# The main game loop. | ||
def run(self): | ||
self.running = True | ||
|
||
screen = pygame.display.get_surface() | ||
|
||
while self.running: | ||
# Pump GTK messages. | ||
while Gtk.events_pending(): | ||
Gtk.main_iteration() | ||
|
||
# Pump PyGame messages. | ||
for event in pygame.event.get(): | ||
if event.type == pygame.QUIT: | ||
return | ||
elif event.type == pygame.VIDEORESIZE: | ||
pygame.display.set_mode(event.size, pygame.RESIZABLE) | ||
elif event.type == pygame.KEYDOWN: | ||
if event.key == pygame.K_LEFT: | ||
self.direction = -1 | ||
elif event.key == pygame.K_RIGHT: | ||
self.direction = 1 | ||
|
||
# Move the ball | ||
if not self.paused: | ||
self.x += self.vx * self.direction | ||
if self.direction == 1 and self.x > screen.get_width() + 100: | ||
self.x = -100 | ||
elif self.direction == -1 and self.x < -100: | ||
self.x = screen.get_width() + 100 | ||
|
||
self.y += self.vy | ||
if self.y > screen.get_height() - 100: | ||
self.y = screen.get_height() - 100 | ||
self.vy = -self.vy | ||
|
||
self.vy += 5 | ||
|
||
# Clear Display | ||
screen.fill((255, 255, 255)) # 255 for white | ||
|
||
# Draw the ball | ||
pygame.draw.circle(screen, (255, 0, 0), (self.x, self.y), 100) | ||
|
||
# Flip Display | ||
pygame.display.flip() | ||
|
||
# Try to stay at 30 FPS | ||
self.clock.tick(30) | ||
|
||
|
||
# This function is called when the game is run directly from the command line: | ||
# ./TestGame.py | ||
def main(): | ||
pygame.init() | ||
pygame.display.set_mode((0, 0), pygame.RESIZABLE) | ||
game = TestGame() | ||
game.run() | ||
|
||
if __name__ == '__main__': | ||
main() |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[Activity] | ||
name = SugargameTest | ||
bundle_id = org.sugarlabs.SugargameTest | ||
exec = sugar-activity TestActivity.TestActivity | ||
icon = activity-generic | ||
activity_version = 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info"> | ||
<mime-type type="application/x-physics-activity"> | ||
<comment xml:lang="en">Physics Activity</comment> | ||
<glob pattern="*.physics"/> | ||
</mime-type> | ||
</mime-info> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
#!/usr/bin/env python | ||
from sugar3.activity import bundlebuilder | ||
bundlebuilder.start() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
__version__ = '1.1' |
Oops, something went wrong.