Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--activity.py19
-rw-r--r--helpers.py74
-rw-r--r--physics.py4
-rw-r--r--tools.py105
4 files changed, 131 insertions, 71 deletions
diff --git a/activity.py b/activity.py
index 24eed3c..477303d 100644
--- a/activity.py
+++ b/activity.py
@@ -28,7 +28,7 @@ import gtk
try:
# >= 0.86 toolbars
- from sugar.graphics.toolbarbox import ToolbarButton, ToolbarBox
+ from sugar.graphics.toolbarbox import ToolbarBox
from sugar.activity.widgets import ActivityToolbarButton
from sugar.activity.widgets import StopButton
except ImportError:
@@ -51,7 +51,8 @@ class PhysicsActivity(olpcgames.PyGameActivity):
"""
surface = pygame.display.get_surface()
width, height = surface.get_width(), surface.get_height()
- pixbuf = gtk.gdk.pixbuf_new_from_data(pygame.image.tostring(surface, "RGB"),
+ pixbuf = gtk.gdk.pixbuf_new_from_data(pygame.image.tostring(surface,
+ "RGB"),
gtk.gdk.COLORSPACE_RGB, 0, 8,
width, height,
3 * width)
@@ -158,7 +159,8 @@ class PhysicsActivity(olpcgames.PyGameActivity):
self.radioList[button] = c.name
def stop_play_cb(self, button):
- pygame.event.post(olpcgames.eventwrap.Event(pygame.USEREVENT, action="stop_start_toggle"))
+ pygame.event.post(olpcgames.eventwrap.Event(pygame.USEREVENT,
+ action="stop_start_toggle"))
self.stop_play_state = not self.stop_play_state
# Update button
if self.stop_play_state:
@@ -169,12 +171,15 @@ class PhysicsActivity(olpcgames.PyGameActivity):
self.stop_play.set_tooltip(_("Start"))
def radioClicked(self, button):
- pygame.event.post(olpcgames.eventwrap.Event(pygame.USEREVENT, action=self.radioList[button]))
+ pygame.event.post(olpcgames.eventwrap.Event(pygame.USEREVENT,
+ action=self.radioList[button]))
def _focus_event(self, event, data=None):
- """Send focus events to pygame to allow it to more gracefully idle when in the background.
+ """Send focus events to pygame to allow it to idle when in background.
"""
if data.state == gtk.gdk.VISIBILITY_FULLY_OBSCURED:
- pygame.event.post(olpcgames.eventwrap.Event(pygame.USEREVENT, action="focus_out"))
+ pygame.event.post(olpcgames.eventwrap.Event(pygame.USEREVENT,
+ action="focus_out"))
else:
- pygame.event.post(olpcgames.eventwrap.Event(pygame.USEREVENT, action="focus_in"))
+ pygame.event.post(olpcgames.eventwrap.Event(pygame.USEREVENT,
+ action="focus_in"))
diff --git a/helpers.py b/helpers.py
index b0c5c84..335852c 100644
--- a/helpers.py
+++ b/helpers.py
@@ -22,52 +22,58 @@
# 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)
+ """Distance calculator, pt1 and pt2 are ordred pairs.
+ """
+ return math.sqrt((pt1[0] - pt2[0]) ** 2 + (pt1[1] - pt2[1]) ** 2)
-# returns the angle between the line segment from pt1 --> pt2 and the x axis, from -pi to pi
def getAngle(pt1, pt2):
+ """Returns angle between line segment pt1 -> pt2 and x axis, from -pi to pi.
+ """
xcomp = pt2[0] - pt1[0]
ycomp = pt1[1] - pt2[1]
return math.atan2(ycomp, xcomp)
-# returns a list of ordered pairs that describe an equilteral triangle around the segment from pt1 --> pt2
-def constructTriangleFromLine(p1,p2):
+def constructTriangleFromLine(p1, p2):
+ """Returns list of ordered pairs describing equilteral triangle around segment pt1 --> pt2.
+ """
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]
-# returns the area of a polygon
def polyArea(vertices):
+ """Returns the area of a polygon.
+ """
n = len(vertices)
A = 0
- p=n - 1
- q=0
+ p = n - 1
+ q = 0
while q < n:
- A+=vertices[p][0] * vertices[q][1] - vertices[q][0] * vertices[p][1]
- p=q
+ A += vertices[p][0] * vertices[q][1] - vertices[q][0] * vertices[p][1]
+ p = q
q += 1
return A / 2.0
-#Some polygon magic, thanks to John W. Ratcliff on www.flipcode.com
-# returns true if pt is in triangle
def insideTriangle(pt, triangle):
-
+ """Returns true if pt is in triangle.
+
+ Some polygon magic, thanks to John W. Ratcliff on www.flipcode.com
+ """
ax = triangle[2][0] - triangle[1][0]
ay = triangle[2][1] - triangle[1][1]
bx = triangle[0][0] - triangle[2][0]
by = triangle[0][1] - triangle[2][1]
cx = triangle[1][0] - triangle[0][0]
cy = triangle[1][1] - triangle[0][1]
- apx= pt[0] - triangle[0][0]
- apy= pt[1] - triangle[0][1]
- bpx= pt[0] - triangle[1][0]
- bpy= pt[1] - triangle[1][1]
- cpx= pt[0] - triangle[2][0]
- cpy= pt[1] - triangle[2][1]
+ apx = pt[0] - triangle[0][0]
+ apy = pt[1] - triangle[0][1]
+ bpx = pt[0] - triangle[1][0]
+ bpy = pt[1] - triangle[1][1]
+ cpx = pt[0] - triangle[2][0]
+ cpy = pt[1] - triangle[2][1]
aCROSSbp = ax * bpy - ay * bpx
cCROSSap = cx * apy - cy * apx
@@ -86,39 +92,42 @@ def polySnip(vertices, u, v, w, n):
Cx = vertices[w][0]
Cy = vertices[w][1]
- if EPSILON > (((Bx-Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax))): return False
+ if EPSILON > (((Bx-Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax))):
+ return False
for p in range(0, n):
- if p == u or p == v or p == w: continue
+ if p == u or p == v or p == w:
+ continue
Px = vertices[p][0]
Py = vertices[p][1]
- if insideTriangle((Px, Py), ((Ax, Ay), (Bx, By), (Cx, Cy))): return False
+ if insideTriangle((Px, Py), ((Ax, Ay), (Bx, By), (Cx, Cy))):
+ return False
return True
-# decomposes a polygon into its triangles
def decomposePoly(vertices):
+ """Decomposes a polygon into its triangles.
+ """
vertices = list(vertices)
n = len(vertices)
result = []
if(n < 3): return [] # not a poly!
- # force a counter-clockwise polygon
+ # Force counter-clockwise polygon
if 0 >= polyArea(vertices):
vertices.reverse()
- # remove nv-2 vertices, creating 1 triangle every time
+ # Remove nv-2 vertices, creating 1 triangle every time
nv = n
count = 2 * nv # error detection
- m = 0
v = nv - 1
while nv > 2:
count -= 1
if 0 >= count:
return [] # Error -- probably bad polygon
- # three consecutive vertices
+ # Three consecutive vertices
u = v
if nv <= u: u = 0 # previous
v = u + 1
@@ -128,18 +137,17 @@ def decomposePoly(vertices):
if(polySnip(vertices, u, v, w, nv)):
- # record this triangle
+ # Record this triangle
result.append((vertices[u], vertices[v], vertices[w]))
- m += 1
- # remove v from remaining polygon
+ # Remove v from remaining polygon
vertices.pop(v)
nv -= 1
- # reset error detection
+ # Reset error detection
count = 2 * nv
return result
-def cast_tuple_to_int(tuple):
+def cast_tuple_to_int(tuple_input):
"""Cast tuple values to ints to avoid gtk+ and pygame's dislike of floats.
"""
- return [int(i) for i in tuple]
+ return [int(i) for i in tuple_input]
diff --git a/physics.py b/physics.py
index 658f0b7..97119da 100644
--- a/physics.py
+++ b/physics.py
@@ -48,10 +48,11 @@ class PhysicsGame:
self.clock = pygame.time.Clock()
self.font = pygame.font.Font(None, 24) # font object
self.canvas = olpcgames.ACTIVITY.canvas
+ self.in_focus = True
# Create the name --> instance map for components
self.toolList = {}
for c in tools.allTools:
- self.toolList[c.name] = c(self)
+ self.toolList[c.name] = c(self)
self.currentTool = self.toolList[tools.allTools[0].name]
# Set up the world (instance of Elements)
self.box2d = box2d
@@ -78,7 +79,6 @@ class PhysicsGame:
self.show_fake_cursor = True
def run(self):
- self.in_focus = True
while True:
for event in pygame.event.get():
self.currentTool.handleEvents(event)
diff --git a/tools.py b/tools.py
index 9c498dc..594154c 100644
--- a/tools.py
+++ b/tools.py
@@ -104,21 +104,26 @@ class CircleTool(Tool):
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.game.world.add.ball(self.pt1, self.radius,
+ dynamic=True, density=1.0,
+ restitution=0.16, friction=0.5)
self.pt1 = None
def draw(self):
# Draw a circle from pt1 to mouse
if self.pt1 != None:
- delta = distance(self.pt1, cast_tuple_to_int(pygame.mouse.get_pos()))
+ delta = distance(self.pt1,
+ cast_tuple_to_int(pygame.mouse.get_pos()))
if delta > 0:
self.radius = delta
if self.radius > 3:
thick = 3
else:
thick = 0
- pygame.draw.circle(self.game.screen, (100, 180, 255), self.pt1, int(self.radius), thick)
- pygame.draw.line(self.game.screen, (100, 180, 255), self.pt1, cast_tuple_to_int(pygame.mouse.get_pos()), 1)
+ pygame.draw.circle(self.game.screen, (100, 180, 255),
+ self.pt1, int(self.radius), thick)
+ pygame.draw.line(self.game.screen, (100, 180, 255), self.pt1,
+ cast_tuple_to_int(pygame.mouse.get_pos()), 1)
def cancel(self):
self.pt1 = None
@@ -148,8 +153,15 @@ class BoxTool(Tool):
if mouse_x_y[0] == self.pt1[0] and mouse_x_y[1] == self.pt1[1]:
self.rect = pygame.Rect(self.pt1, (-self.width, -self.height))
self.rect.normalize()
- 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)
+ 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):
@@ -161,7 +173,8 @@ class BoxTool(Tool):
self.height = mouse_x_y[1] - self.pt1[1]
self.rect = pygame.Rect(self.pt1, (self.width, self.height))
self.rect.normalize()
- pygame.draw.rect(self.game.screen, (100, 180, 255), self.rect, 3)
+ pygame.draw.rect(self.game.screen, (100, 180, 255),
+ self.rect, 3)
def cancel(self):
self.pt1 = None
@@ -189,10 +202,17 @@ class TriangleTool(Tool):
if event.button == 1 and self.pt1 != None:
mouse_x_y = cast_tuple_to_int(pygame.mouse.get_pos())
if mouse_x_y[0] == self.pt1[0] and mouse_x_y[1] == self.pt1[1]:
- self.pt1 = [mouse_x_y[0] - self.line_delta[0], mouse_x_y[1] - self.line_delta[1]]
- self.vertices = constructTriangleFromLine(self.pt1, mouse_x_y)
- if distance(self.pt1, cast_tuple_to_int(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 = [mouse_x_y[0] - self.line_delta[0],
+ mouse_x_y[1] - self.line_delta[1]]
+ self.vertices = constructTriangleFromLine(self.pt1,
+ mouse_x_y)
+ if distance(self.pt1, cast_tuple_to_int(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
@@ -202,9 +222,12 @@ class TriangleTool(Tool):
mouse_x_y = cast_tuple_to_int(pygame.mouse.get_pos())
if mouse_x_y[0] != self.pt1[0] or mouse_x_y[1] != self.pt1[1]:
self.vertices = constructTriangleFromLine(self.pt1, mouse_x_y)
- self.line_delta = [mouse_x_y[0] - self.pt1[0], mouse_x_y[1] - self.pt1[1]]
- pygame.draw.polygon(self.game.screen, (100, 180, 255), self.vertices, 3)
- pygame.draw.line(self.game.screen, (100, 180, 255), self.pt1, mouse_x_y, 1)
+ self.line_delta = [mouse_x_y[0] - self.pt1[0],
+ mouse_x_y[1] - self.pt1[1]]
+ pygame.draw.polygon(self.game.screen, (100, 180, 255),
+ self.vertices, 3)
+ pygame.draw.line(self.game.screen, (100, 180, 255),
+ self.pt1, mouse_x_y, 1)
def cancel(self):
self.pt1 = None
@@ -222,6 +245,7 @@ class PolygonTool(Tool):
Tool.__init__(self, gameInstance)
self.vertices = None
self.previous_vertices = None
+ self.safe = False
def handleToolEvent(self, event):
if event.type == MOUSEBUTTONDOWN and event.button == 1 and self.vertices is None:
@@ -235,7 +259,10 @@ class PolygonTool(Tool):
self.vertices = [[i[0] - delta_x, i[1] - delta_y]
for i in self.previous_vertices]
self.safe = True
- self.game.world.add.complexPoly(self.vertices, dynamic=True, density=1.0, restitution=0.16, friction=0.5)
+ self.game.world.add.complexPoly(self.vertices, dynamic=True,
+ density=1.0,
+ restitution=0.16,
+ friction=0.5)
self.vertices = None
elif (event.type == MOUSEBUTTONUP or event.type == MOUSEBUTTONDOWN) and event.button == 1:
if self.vertices is None or (event.pos[0] == self.vertices[-1][0] and event.pos[1] == self.vertices[-1][1]):
@@ -243,7 +270,10 @@ class PolygonTool(Tool):
return
if 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.game.world.add.complexPoly(self.vertices, dynamic=True,
+ density=1.0,
+ restitution=0.16,
+ friction=0.5)
self.previous_vertices = self.vertices[:]
self.vertices = None
elif distance(event.pos, self.vertices[0]) < 15:
@@ -257,9 +287,13 @@ class PolygonTool(Tool):
# 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], cast_tuple_to_int(pygame.mouse.get_pos()), 3)
- pygame.draw.circle(self.game.screen, (100, 180, 255), self.vertices[0], 15, 3)
+ 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],
+ cast_tuple_to_int(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
@@ -276,6 +310,7 @@ class MagicPenTool(Tool):
Tool.__init__(self, gameInstance)
self.vertices = None
self.previous_vertices = None
+ self.safe = False
def handleToolEvent(self, event):
if event.type == MOUSEBUTTONDOWN and event.button == 1:
@@ -290,7 +325,10 @@ class MagicPenTool(Tool):
for i in self.previous_vertices]
self.safe = True
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.game.world.add.complexPoly(self.vertices, dynamic=True,
+ density=1.0,
+ restitution=0.16,
+ friction=0.5)
self.previous_vertices = self.vertices[:]
self.vertices = None
elif event.type == MOUSEMOTION and self.vertices:
@@ -303,9 +341,13 @@ class MagicPenTool(Tool):
if self.vertices:
if len(self.vertices) > 1:
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], cast_tuple_to_int(pygame.mouse.get_pos()), 3)
- pygame.draw.circle(self.game.screen, (100, 180, 255), self.vertices[0], 15, 3)
+ 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],
+ cast_tuple_to_int(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
@@ -327,7 +369,8 @@ class GrabTool(Tool):
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)
+ bodylist = self.game.world.get_bodies_at_pos(event.pos,
+ include_static=False)
if bodylist and len(bodylist) > 0:
if self.game.world.run_physics:
self.game.world.add.mouseJoint(bodylist[0], event.pos)
@@ -382,17 +425,20 @@ class JointTool(Tool):
self.jb2 = self.game.world.get_bodies_at_pos(event.pos)
# If we have two distinct bodies, add a distance 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)
+ self.game.world.add.joint(self.jb1[0], self.jb2[0],
+ self.jb1pos, self.jb2pos)
#add joint to ground body
#elif self.jb1:
# groundBody = self.game.world.world.GetGroundBody()
- # self.game.world.add.joint(self.jb1[0], groundBody, self.jb1pos, self.jb2pos)
+ # self.game.world.add.joint(self.jb1[0], groundBody,
+ # self.jb1pos, self.jb2pos)
# regardless, clean everything up
self.jb1 = self.jb2 = self.jb1pos = self.jb2pos = None
def draw(self):
if self.jb1:
- pygame.draw.line(self.game.screen, (100, 180, 255), self.jb1pos, cast_tuple_to_int(pygame.mouse.get_pos()), 3)
+ pygame.draw.line(self.game.screen, (100, 180, 255), self.jb1pos,
+ cast_tuple_to_int(pygame.mouse.get_pos()), 3)
def cancel(self):
self.jb1 = self.jb2 = self.jb1pos = self.jb2pos = None
@@ -414,7 +460,7 @@ class PinTool(Tool):
self.jb1pos = event.pos
self.jb1 = self.game.world.get_bodies_at_pos(event.pos)
if self.jb1:
- self.game.world.add.joint(self.jb1[0], self.jb1pos)
+ self.game.world.add.joint(self.jb1[0], self.jb1pos)
self.jb1 = self.jb1pos = None
def cancel(self):
@@ -506,7 +552,8 @@ class DestroyTool(Tool):
# Draw the trail
if self.vertices:
if len(self.vertices) > 1:
- pygame.draw.lines(self.game.screen, (255, 0, 0), False, self.vertices, 3)
+ pygame.draw.lines(self.game.screen, (255, 0, 0), False,
+ self.vertices, 3)
def cancel(self):
self.vertices = None