Development Team/Sugargame/Examples

From Sugar Labs
Jump to navigation Jump to search

Bouncing Ball

This is a simple Sugargame example which bounces a red ball across the screen.

A Sugar toolbar provides Pause and Unpause functionality, demonstrating communication between Sugar and Pygame.

TestActivity.py

This file implements the TestActivity activity class. The constructor sets up the Pygame canvas and Sugar toolbar, and starts the game running.

   from gettext import gettext as _
   
   import sys
   import gtk
   import pygame
   
   import sugar.activity.activity
   import sugar.graphics.toolbutton
   
   sys.path.append('..') # Import sugargame package from top directory.
   import sugargame.canvas
   
   import TestGame
   
   class TestActivity(sugar.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._canvas = sugargame.canvas.PygameCanvas(self)
           # Note that set_canvas implicitly calls read_file when resuming from the Journal.
           self.set_canvas(self._canvas)
           
           # Start the game running.
           self._canvas.run_pygame(self.game.run)
           
       def build_toolbar(self):        
           stop_play = sugar.graphics.toolbutton.ToolButton('media-playback-stop')
           stop_play.set_tooltip(_("Stop"))
           stop_play.set_accelerator(_('<ctrl>space'))
           stop_play.connect('clicked', self._stop_play_cb)
   
           toolbar = gtk.Toolbar()
           toolbar.insert(stop_play, 0)
           toolbar.insert(gtk.SeparatorToolItem(), 1)
           
           toolbox = sugar.activity.activity.ActivityToolbox(self)
           toolbox.add_toolbar(_("Pygame"), toolbar)
           
           toolbox.show_all()
           self.set_toolbox(toolbox)
   
       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)

TestGame.py

This file implements the game (really just a bouncing ball animation). Note the main function at the end; this file can also be run as a standalone Pygame program.

   #!/usr/bin/python
   import pygame
   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
           
       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)

               # Move the ball
               if not self.paused:
                   self.x += self.vx
                   if self.x > screen.get_width() + 100:
                       self.x = -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()