Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/tools.py
diff options
context:
space:
mode:
authorAlex <alex@Tiresias.(none)>2008-07-08 21:11:48 (GMT)
committer Alex <alex@Tiresias.(none)>2008-07-08 21:11:48 (GMT)
commitd610e626c0f6085fa27de62a3113ef722a310f85 (patch)
tree8af609d2aceb9abca5f302b7bfdd7b3057445885 /tools.py
parente2e93519e067f526ff285db53921e900f259ad72 (diff)
Total Reorganization! Now a proper activity (I hope)
Diffstat (limited to 'tools.py')
-rw-r--r--tools.py306
1 files changed, 290 insertions, 16 deletions
diff --git a/tools.py b/tools.py
index 87dd4f7..65b27b6 100644
--- a/tools.py
+++ b/tools.py
@@ -1,22 +1,296 @@
#==================================================================
# Physics.activity
-# Helper classes and functions
+# Tool Classes
# By Alex Levenson
#==================================================================
-import math
-# distance calculator, pt1 and pt2 are ordred pairs
-def distance(pt1, pt2):
- return math.sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] -pt2[1]) ** 2)
+import pygame
+from pygame.locals import *
+from helpers import *
+# tools that can be used superlcass
+class Tool(object):
+ def __init__(self,gameInstance):
+ self.game = gameInstance
+ self.name = "Tool"
+ def handleEvents(self,event):
+ # default event handling
+ if event.type == MOUSEBUTTONDOWN:
+ if self.game.menu.click(event.pos): return True
+ if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
+ # bye bye! Hope you had fun!
+ self.game.running = False
+ elif event.type == KEYDOWN:
+ if event.key == K_SPACE:
+ #space pauses
+ self.game.world.run_physics = not self.game.world.run_physics
+ else:
+ # let the subclasses know that no events were handled yet
+ return False
+ return True
+ def draw(self):
+ # default drawing method is don't draw anything
+ pass
+ def cancel(self):
+ # default cancel doesn't do anything
+ pass
-# returns the angle between the line segment from pt1 --> pt2 and the x axis, from -pi to pi
-def getAngle(pt1,pt2):
- xcomp = pt2[0] - pt1[0]
- ycomp = pt1[1] - pt2[1]
- return math.atan2(ycomp,xcomp)
+# The circle creation tool
+class CircleTool(Tool):
+ def __init__(self,gameInstance):
+ self.game = gameInstance
+ self.name = "Circle"
+ self.pt1 = None
+ self.radius = None
+ def handleEvents(self,event):
+ #look for default events, and if none are handled then try the custom events
+ if not super(CircleTool,self).handleEvents(event):
+ if event.type == MOUSEBUTTONDOWN:
+ if event.button == 1:
+ self.pt1 = pygame.mouse.get_pos()
+ elif event.type == MOUSEBUTTONUP:
+ if event.button == 1:
+ 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
+ def draw(self):
+ # draw a circle from pt1 to mouse
+ if self.pt1 != None:
+ self.radius = distance(self.pt1,pygame.mouse.get_pos())
+ if self.radius > 3:
+ thick = 3
+ else:
+ thick = 0
+ pygame.draw.circle(self.game.screen, (100,180,255),self.pt1,self.radius,thick)
+ 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):
+ def __init__(self,gameInstance):
+ self.game = gameInstance
+ self.name = "Box"
+ self.pt1 = None
+ self.rect = None
+ def handleEvents(self,event):
+ #look for default events, and if none are handled then try the custom events
+ if not super(BoxTool,self).handleEvents(event):
+ if event.type == MOUSEBUTTONDOWN:
+ if event.button == 1:
+ self.pt1 = pygame.mouse.get_pos()
+ elif event.type == MOUSEBUTTONUP:
+ if event.button == 1 and self.pt1!=None:
+ 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
+
+ def draw(self):
+ # draw a box from pt1 to mouse
+ if self.pt1 != None:
+ width = pygame.mouse.get_pos()[0] - self.pt1[0]
+ height = pygame.mouse.get_pos()[1] - self.pt1[1]
+ self.rect = pygame.Rect(self.pt1, (width, height))
+ self.rect.normalize()
+ 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):
+ def __init__(self,gameInstance):
+ self.game = gameInstance
+ self.name = "Triangle"
+ self.pt1 = None
+ self.vertices = None
+ def handleEvents(self,event):
+ #look for default events, and if none are handled then try the custom events
+ if not super(TriangleTool,self).handleEvents(event):
+ if event.type == MOUSEBUTTONDOWN:
+ if event.button == 1:
+ self.pt1 = pygame.mouse.get_pos()
+ elif event.type == MOUSEBUTTONUP:
+ if event.button == 1 and self.pt1!= None:
+ 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
+ def draw(self):
+ # draw a triangle from pt1 to mouse
+ if self.pt1 != None:
+ self.vertices = constructTriangleFromLine(self.pt1,pygame.mouse.get_pos())
+ pygame.draw.polygon(self.game.screen, (100,180,255),self.vertices, 3)
+ pygame.draw.line(self.game.screen,(100,180,255),self.pt1,pygame.mouse.get_pos(),1)
+
+ def cancel(self):
+ self.pt1 = None
+ self.vertices = None
-# returns a list of ordered pairs that describe an equilteral triangle around the segment from pt1 --> pt2
-def constructTriangleFromLine(p1,p2):
- halfHeightVector = (0.57735*(p2[1] - p1[1]), 0.57735*(p2[0] - p1[0]))
- p3 = (p1[0] + halfHeightVector[0], p1[1] - halfHeightVector[1])
- p4 = (p1[0] - halfHeightVector[0], p1[1] + halfHeightVector[1])
- return [p2,p3,p4]
+# The Polygon creation tool
+class PolygonTool(Tool):
+ def __init__(self,gameInstance):
+ self.game = gameInstance
+ self.name = "Polygon"
+ self.vertices = 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):
+ if event.type == MOUSEBUTTONDOWN:
+ if event.button == 1:
+ if not self.vertices:
+ self.vertices=[event.pos]
+ elif distance(event.pos,self.vertices[0]) < 15:
+ 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.vertices = None
+ else:
+ self.vertices.append(event.pos)
+ if event.button == 3:
+ if self.vertices:
+ self.vertices.append(event.pos)
+ self.game.world.add.complexPoly(self.vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5)
+ self.vertices = None
+
+ def draw(self):
+ # draw the poly being created
+ if self.vertices:
+ for i in range(len(self.vertices)-1):
+ pygame.draw.line(self.game.screen,(100,180,255),self.vertices[i],self.vertices[i+1],3)
+ pygame.draw.line(self.game.screen,(100,180,255),self.vertices[-1],pygame.mouse.get_pos(),3)
+ pygame.draw.circle(self.game.screen,(100,180,255),self.vertices[0],15,3)
+
+ def cancel(self):
+ self.vertices = None
+
+# The magic pen tool
+class MagicPenTool(Tool):
+ def __init__(self,gameInstance):
+ self.game = gameInstance
+ self.name = "Magic Pen"
+ self.vertices = 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):
+ if event.type == MOUSEBUTTONDOWN:
+ if event.button == 1:
+ if not self.vertices:
+ self.vertices=[event.pos]
+ elif distance(event.pos,self.vertices[0]) < 15:
+ 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.vertices = None
+ else:
+ self.vertices.append(event.pos)
+ elif event.type == MOUSEBUTTONUP:
+ if event.button == 1:
+ if self.vertices:
+ self.game.world.add.complexPoly(self.vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5)
+ self.vertices = None
+ elif event.type == MOUSEMOTION:
+ if self.vertices:
+ self.vertices.append(event.pos)
+
+ def draw(self):
+ # draw the poly being created
+ if self.vertices:
+ for i in range(len(self.vertices)-1):
+ pygame.draw.line(self.game.screen,(100,180,255),self.vertices[i],self.vertices[i+1],3)
+ pygame.draw.line(self.game.screen,(100,180,255),self.vertices[-1],pygame.mouse.get_pos(),3)
+ pygame.draw.circle(self.game.screen,(100,180,255),self.vertices[0],15,3)
+
+ def cancel(self):
+ self.vertices = None
+
+# The grab tool
+class GrabTool(Tool):
+ def __init__(self,gameInstance):
+ self.game = gameInstance
+ self.name = "Grab"
+ def handleEvents(self,event):
+ #look for default events, and if none are handled then try the custom events
+ if not super(GrabTool,self).handleEvents(event):
+ if event.type == MOUSEBUTTONDOWN:
+ if event.button == 1:
+ # grab the first object at the mouse pointer
+ bodylist = self.game.world.get_bodies_at_pos(event.pos, include_static=False)
+ if bodylist and len(bodylist) > 0:
+ self.game.world.add.mouseJoint(bodylist[0], event.pos)
+ elif event.type == MOUSEBUTTONUP:
+ # let it go
+ if event.button == 1:
+ self.game.world.add.remove_mouseJoint()
+ # use box2D mouse motion
+ elif event.type == MOUSEMOTION and event.buttons[0]:
+ self.game.world.mouse_move(event.pos)
+
+ def cancel(self):
+ self.game.world.add.remove_mouseJoint()
+
+# The joint tool
+class JointTool(Tool):
+ def __init__(self,gameInstance):
+ self.game = gameInstance
+ self.name = "Joint"
+ self.jb1 = self.jb2 = self.jb1pos = self.jb2pos = None
+ def handleEvents(self,event):
+ #look for default events, and if none are handled then try the custom events
+ if not super(JointTool,self).handleEvents(event):
+ if event.type == MOUSEBUTTONDOWN:
+ if event.button == 1:
+ # grab the first body
+ self.jb1pos = event.pos
+ self.jb1 = self.game.world.get_bodies_at_pos(event.pos)
+ self.jb2 = self.jb2pos = None
+ elif event.type == MOUSEBUTTONUP:
+ if event.button == 1:
+ # grab the second body
+ self.jb2pos = event.pos
+ self.jb2 = self.game.world.get_bodies_at_pos(event.pos)
+ # if we have two distinct bodies, add a joint!
+ if self.jb1 and self.jb2 and str(self.jb1) != str(self.jb2):
+ self.game.world.add.joint(self.jb1[0],self.jb2[0],self.jb1pos,self.jb2pos)
+ # If there's only one body, add a fixed joint
+ elif self.jb2:
+ self.game.world.add.joint(self.jb2[0],self.jb2pos)
+ # regardless, clean everything up
+ self.jb1 = self.jb2 = self.jb1pos = self.jb2pos = None
+ if event.button == 3:
+ # add a centered fixed joint
+ self.jb2 = world.get_bodies_at_pos(event.pos)
+ if self.jb2:
+ self.game.world.add.joint(self.jb2[0])
+ def draw(self):
+ if self.jb1:
+ pygame.draw.line(self.game.screen,(100,180,255),self.jb1pos,pygame.mouse.get_pos(),3)
+
+ def cancel(self):
+ self.jb1 = self.jb2 = self.jb1pos = self.jb2pos = None
+
+# The destroy tool
+class DestroyTool(Tool):
+ def __init__(self,gameInstance):
+ self.game = gameInstance
+ self.name = "Destroy"
+ self.vertices = None
+ def handleEvents(self,event):
+ #look for default events, and if none are handled then try the custom events
+ if not super(DestroyTool,self).handleEvents(event):
+ if pygame.mouse.get_pressed()[0]:
+ if not self.vertices: self.vertices = []
+ self.vertices.append(pygame.mouse.get_pos())
+ if len(self.vertices) > 10:
+ self.vertices.pop(0)
+ tokill = self.game.world.get_bodies_at_pos(pygame.mouse.get_pos())
+ if tokill:
+ self.game.world.world.DestroyBody(tokill[0])
+ elif event.type == MOUSEBUTTONUP and event.button == 1:
+ self.cancel()
+ def draw(self):
+ # draw the trail
+ if self.vertices:
+ if len(self.vertices) > 1:
+ pygame.draw.lines(self.game.screen,(255,0,0),False,self.vertices,3)
+
+ def cancel(self):
+ self.vertices = None \ No newline at end of file