[Sugar-devel] [PATCH] tool accelerator keys add objects to the world

Martin Dengler martin at martindengler.com
Tue Aug 11 20:27:43 EDT 2009


Make it easy to add lots of objects to the world quickly by drawing
one shape, then pressing the key of the shape tool a few times to add
a few copies of that object to the tool.  Erase objects by hovering
and pressing E (the erase tool key).

Reduces the need to click the mouse while moving it, which is
especially hard on the OLPC XO-1 touchpad.
---
 tools.py |  128 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 121 insertions(+), 7 deletions(-)

diff --git a/tools.py b/tools.py
index 963e2a8..27b035a 100644
--- a/tools.py
+++ b/tools.py
@@ -10,6 +10,30 @@ from helpers import *
 from inspect import getmro
 from gettext import gettext as _
 
+
+_polygon_examples = (
+    #square
+    ((0,0), (1, 0), (1, 1), (0, 1),    (0, 0)),
+
+    #irregular square-ish
+    ((0,0), (2, 0), (1, 2), (0, 1),    (0, 0)),
+
+    # star-ish
+    ((0,0),
+     (1, 2), (4, 2),
+     (2, 3), (3, 5),
+     (0, 4),
+     (-3, 5), (-2, 3),
+     (-4, 2), (-1, 2),
+     (0, 0)),
+
+    # two hills-ish
+    ((0, 0),
+     (2, 0), (1, 1),
+     (-2, -1), (-2, 0),
+     (0, 0)),
+    )
+
 # tools that can be used superlcass
 class Tool(object):
     name = 'Tool'
@@ -77,7 +101,15 @@ class CircleTool(Tool):
                     if self.radius > 1: # elements doesn't like tiny shapes :(
                         self.game.world.add.ball(self.pt1,self.radius, dynamic=True, density=1.0, restitution=0.16, friction=0.5)                    
                     self.pt1 = None        
-                    self.radius = None            
+            elif event.type == KEYUP and event.key == K_c:
+                if self.radius is None:
+                    self.radius = self.game.screen.get_width() / 33
+                self.game.world.add.ball(
+                    pygame.mouse.get_pos(),
+                    self.radius,
+                    dynamic=True,
+                    density=1.0,
+                    restitution=0.16, friction=0.5)
     def draw(self):
         # draw a circle from pt1 to mouse
         if self.pt1 != None:
@@ -90,7 +122,6 @@ class CircleTool(Tool):
             pygame.draw.line(self.game.screen,(100,180,255),self.pt1,pygame.mouse.get_pos(),1)  
     def cancel(self):
         self.pt1 = None  
-        self.radius = None
    
 # The box creation tool        
 class BoxTool(Tool):    
@@ -115,7 +146,21 @@ class BoxTool(Tool):
                     if self.rect.width > 10 and self.rect.height > 10: # elements doesn't like small shapes :(
                         self.game.world.add.rect(self.rect.center, self.rect.width/2, self.rect.height/2, dynamic=True, density=1.0, restitution=0.16, friction=0.5)                   
                     self.pt1 = None        
-                                
+            elif event.type == KEYUP and event.key == K_b:
+                mouse_position = pygame.mouse.get_pos()
+                if self.rect is None:
+                    unit = min(self.game.screen.get_width(),
+                                   self.game.screen.get_height())
+                    unit /= 15
+                    self.rect = pygame.Rect(mouse_position, (unit, unit))
+                self.game.world.add.rect(
+                    mouse_position,
+                    self.rect.width / 2,
+                    self.rect.height / 2,
+                    dynamic=True,
+                    density=1.0,
+                    restitution=0.16,
+                    friction=0.5)
     def draw(self):
         # draw a box from pt1 to mouse
         if self.pt1 != None:
@@ -126,7 +171,6 @@ class BoxTool(Tool):
             pygame.draw.rect(self.game.screen, (100,180,255),self.rect,3)   
     def cancel(self):
         self.pt1 = None  
-        self.rect = None      
            
 # The triangle creation tool        
 class TriangleTool(Tool): 
@@ -151,7 +195,26 @@ class TriangleTool(Tool):
                     if distance(self.pt1,pygame.mouse.get_pos()) > 15: # elements doesn't like tiny shapes :(
                         self.game.world.add.convexPoly(self.vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5)                    
                     self.pt1 = None
-                    self.vertices = None                    
+            elif event.type == KEYUP and event.key == K_t:
+                if self.vertices is None:
+                    unit = min(self.game.screen.get_width(),
+                                   self.game.screen.get_height())
+                    unit /= 20
+                    self.vertices = ((0 - unit, 0),
+                                     (0 + unit, 0),
+                                     (0, math.sqrt(2 * unit * unit)))
+                mouse_position = pygame.mouse.get_pos()
+                offsetx = mouse_position[0] - self.vertices[0][0]
+                offsety = mouse_position[1] - self.vertices[0][1]
+                def move(vertex):
+                    return (vertex[0] + offsetx, vertex[1] + offsety)
+                self.vertices = [move(vertex) for vertex in self.vertices]
+                self.game.world.add.convexPoly(
+                    self.vertices,
+                    dynamic=True,
+                    density=1.0,
+                    restitution=0.16,
+                    friction=0.5)
     def draw(self):
         # draw a triangle from pt1 to mouse
         if self.pt1 != None:
@@ -161,7 +224,6 @@ class TriangleTool(Tool):
     
     def cancel(self):
         self.pt1 = None        
-        self.vertices = None
 
 # The Polygon creation tool        
 class PolygonTool(Tool):  
@@ -174,6 +236,7 @@ class PolygonTool(Tool):
         self.game = gameInstance
         self.name = 'Polygon'
         self.vertices = None
+        self.lastpoly = None
     def handleEvents(self,event):
         #look for default events, and if none are handled then try the custom events 
         if not super(PolygonTool,self).handleEvents(event):
@@ -186,6 +249,7 @@ class PolygonTool(Tool):
                     elif distance(event.pos,self.vertices[0]) < 15 and self.safe:                     
                         self.vertices.append(self.vertices[0]) #connect the polygon
                         self.game.world.add.complexPoly(self.vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5)                    
+                        self.lastpoly = self.vertices
                         self.vertices = None
                     elif distance(event.pos,self.vertices[0]) < 15:
                         self.vertices = None
@@ -203,6 +267,7 @@ class PolygonTool(Tool):
                         gons = decomposePoly(self.vertices)
                         for g in gons:
                             self.game.world.add.convexPoly(g, dynamic=True, density=1.0, restitution=0.16, friction=0.5)
+                        self.lastpoly = self.vertices
                         self.vertices = None
                     elif distance(event.pos,self.vertices[0]) < 15:
                         self.vertices = None
@@ -210,6 +275,28 @@ class PolygonTool(Tool):
                         self.vertices.append(event.pos)
                         if distance(event.pos,self.vertices[0]) >= 55 and self.vertices:
                             self.safe = True
+
+            elif event.type == KEYUP and event.key == K_p:
+                if self.lastpoly is not None:
+                    poly_to_draw = self.lastpoly
+                else:
+                    import random
+                    poly_to_draw = random.choice(_polygon_examples)
+                    unit = min(self.game.screen.get_width(),
+                               self.game.screen.get_height())
+                    unit /= 20
+                    offsetx, offsety = pygame.mouse.get_pos()
+                    def move_and_scale(v):
+                        return (int(v[0] * unit) + offsetx,
+                                int(v[1] * unit) + offsety)
+                    poly_to_draw = [move_and_scale(vertex) for vertex
+                                    in random.choice(_polygon_examples)]
+                self.game.world.add.complexPoly(
+                    poly_to_draw,
+                    dynamic=True,
+                    density=1.0,
+                    restitution=0.16,
+                    friction=0.5)
                                 
     def draw(self):
         # draw the poly being created
@@ -233,6 +320,7 @@ class MagicPenTool(Tool):
         self.game = gameInstance
         self.name = 'Magicpen'
         self.vertices = None
+        self.lastpoly = None
     def handleEvents(self,event):
         #look for default events, and if none are handled then try the custom events 
         if not super(MagicPenTool,self).handleEvents(event):
@@ -242,6 +330,7 @@ class MagicPenTool(Tool):
             elif event.type == MOUSEBUTTONUP and event.button == 1:
                 if self.vertices and self.safe:
                     self.game.world.add.complexPoly(self.vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5)
+                    self.lastpoly = self.vertices
                     self.vertices = None
                 else:
                     self.vertices = None
@@ -249,7 +338,28 @@ class MagicPenTool(Tool):
                 self.vertices.append(event.pos)
                 if distance(event.pos,self.vertices[0]) >= 55 and len(self.vertices) > 3:
                     self.safe = True
-                                
+            elif event.type == KEYUP and event.key == K_d:
+                if self.lastpoly is not None:
+                    poly_to_draw = self.lastpoly
+                else:
+                    import random
+                    poly_to_draw = random.choice(_polygon_examples)
+                    unit = min(self.game.screen.get_width(),
+                               self.game.screen.get_height())
+                    unit /= 20
+                    offsetx, offsety = pygame.mouse.get_pos()
+                    def move_and_scale(v):
+                        return (int(v[0] * unit) + offsetx,
+                                int(v[1] * unit) + offsety)
+                    poly_to_draw = [move_and_scale(vertex) for vertex
+                                    in random.choice(_polygon_examples)]
+                self.game.world.add.complexPoly(
+                    poly_to_draw,
+                    dynamic=True,
+                    density=1.0,
+                    restitution=0.16,
+                    friction=0.5)
+                
     def draw(self):
         # draw the poly being created
         if self.vertices:
@@ -439,6 +549,10 @@ class DestroyTool(Tool):
                         self.game.world.world.DestroyBody(tokill[0])
             elif event.type == MOUSEBUTTONUP and event.button == 1:
                 self.cancel()
+            elif event.type == KEYUP and event.key == K_e:
+                tokill = self.game.world.get_bodies_at_pos(pygame.mouse.get_pos())
+                if tokill:
+                    self.game.world.world.DestroyBody(tokill[0])
     def draw(self):
         # draw the trail
         if self.vertices:
-- 
1.6.0.6



More information about the Sugar-devel mailing list