#!/usr/bin/python """ This file is part of the 'Physics' Project Physics is a 2D Physics Playground for Kids (supporting Box2D2) Physics Copyright (C) 2008, Alex Levenson, Brian Jordan Elements Copyright (C) 2008, The Elements Team, Wiki: http://wiki.laptop.org/wiki/Physics IRC: #olpc-physics on irc.freenode.org Code: http://dev.laptop.org/git?p=activities/physics git clone git://dev.laptop.org/activities/physics License: GPLv3 http://gplv3.fsf.org/ """ import sys import math import pygame from pygame.locals import * from pygame.color import * sys.path.append("lib/") import pkg_resources sys.path.append("lib/Elements-0.13-py2.5.egg") sys.path.append("lib/Box2D-2.0.2b1-py2.5-linux-i686.egg") import Box2D as box2d import elements import tools from helpers import * import gtk class PhysicsGame: def __init__(self,screen): self.screen = screen # get everything set up self.trace_screen = pygame.Surface(self.screen.get_size()) self.trace_screen.fill((255,255,255)) self.clock = pygame.time.Clock() self.font = pygame.font.Font(None, 24) # font object self.canvas = olpcgames.ACTIVITY.canvas # create the name --> instance map for components self.toolList = {} for c in tools.allTools: self.toolList[c.name] = c(self) self.currentTool = self.toolList[tools.allTools[0].name] def setup(self): self.screen = pygame.display.get_surface() # get everything set up self.clock = pygame.time.Clock() self.font = pygame.font.Font(None, 24) # font object # set up the world (instance of Elements) self.box2d = box2d self.world = elements.Elements(self.screen.get_size()) self.world.renderer.set_surface(self.screen) # set up static environment self.world.add.ground() def stop_start_toggle(self): self.world.run_physics = not self.world.run_physics def set_tool(self, tool): self.setTool(tool) def write_file(self, file_path): self.world.add.remove_mouseJoint() self.world.json_save(file_path) def read_file(self, file_path): self.world.json_load(file_path) def run(self): self.setup() self.running = True 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 self.currentTool.handleEvents(event) # Clear Display self.screen.fill((255,255,255)) #255 for white self.screen.blit(self.trace_screen, (0,0)) #blit on the traces #Loop trough objects to apply impulses if self.world.run_physics: for body in self.world.world.GetBodyList(): if type(body.userData) == type({}): if body.userData.has_key('rollMotor'): diff = body.userData['rollMotor']['targetVelocity']- body.GetAngularVelocity() body.ApplyTorque(body.userData['rollMotor']['strength']*diff*body.getMassData().I) # Update & Draw World self.world.update() self.world.draw() #Loop trough objects to draw extra stuff if self.world.run_physics: for body in self.world.world.GetBodyList(): if type(body.userData) == type({}): if body.userData.has_key('paint'): color = body.userData['paint']['color'] rel_pos = body.GetWorldVector(body.userData['paint']['pos']).tuple() x = (body.GetPosition().tuple()[0]+rel_pos[0])*self.world.ppm y = (body.GetPosition().tuple()[1]+rel_pos[1])*self.world.ppm pos = self.world.to_screen((x,y)) pygame.draw.circle(self.trace_screen, color, pos, 2, 0) pygame.draw.circle(self.screen, (255,208,0), pos, 2, 0) # draw output from tools self.currentTool.draw() # Flip Display pygame.display.flip() # Try to stay at 30 FPS self.clock.tick(30) # originally 50 def setTool(self,tool): self.currentTool.cancel() self.currentTool = self.toolList[tool] def main(): pygame.init() pygame.display.init() width, height = pygame.display.list_modes()[0] pygame.display.set_mode((width,height)) game = PhysicsGame() game.run() # make sure that main get's called if __name__ == '__main__': main()