Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS5
-rw-r--r--activity.py13
-rwxr-xr-xactivity/activity.info2
-rw-r--r--tools.py114
4 files changed, 84 insertions, 50 deletions
diff --git a/NEWS b/NEWS
index da4aab9..4e4003d 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,8 @@
+17
+
+ENHANCEMENT:
+* Chain tool behaves like magic pen: you can make loops and closed paths
+
16
ENHANCEMENT:
diff --git a/activity.py b/activity.py
index f6e8909..446684d 100644
--- a/activity.py
+++ b/activity.py
@@ -567,20 +567,20 @@ class PhysicsActivity(activity.Activity):
def _construct_shared_polygon(self, data):
polygon_data = json.loads(data)
- verticies = polygon_data[0]
+ vertices = polygon_data[0]
density = polygon_data[1]
restitution = polygon_data[2]
friction = polygon_data[3]
- self._constructors['Polygon'](verticies, density, restitution,
+ self._constructors['Polygon'](vertices, density, restitution,
friction, share=False)
def _construct_shared_magicpen(self, data):
magicpen_data = json.loads(data)
- verticies = magicpen_data[0]
+ vertices = magicpen_data[0]
density = magicpen_data[1]
restitution = magicpen_data[2]
friction = magicpen_data[3]
- self._constructors['Magicpen'](verticies, density, restitution,
+ self._constructors['Magicpen'](vertices, density, restitution,
friction, share=False)
def _add_shared_joint(self, data):
@@ -608,11 +608,10 @@ class PhysicsActivity(activity.Activity):
def _add_shared_chain(self, data):
joint_data = json.loads(data)
- pos1 = joint_data[0]
- pos2 = joint_data[1]
+ vertices = joint_data[0]
link_length = joint_data[2]
radius = joint_data[3]
- self._constructors['Chain'](pos1, pos2, link_length, radius,
+ self._constructors['Chain'](vertices, link_length, radius,
share=False)
def send_event(self, text):
diff --git a/activity/activity.info b/activity/activity.info
index 2946b51..724a211 100755
--- a/activity/activity.info
+++ b/activity/activity.info
@@ -4,6 +4,6 @@ summary = Prove Sir Isaac Newton right! Create real life simulations using diffe
bundle_id = org.laptop.physics
exec = sugar-activity activity.PhysicsActivity
icon = activity-physics
-activity_version = 16
+activity_version = 17
show_launcher = yes
mime_types = application/x-physics-activity;
diff --git a/tools.py b/tools.py
index 0ba305d..78737f4 100644
--- a/tools.py
+++ b/tools.py
@@ -899,59 +899,92 @@ class ChainTool(Tool):
def __init__(self, gameInstance):
Tool.__init__(self, gameInstance)
- self._clear()
+ self.vertices = None
+ self.previous_vertices = None
+ self.safe = False
def handleToolEvent(self, event):
radius = int(self.palette_data[self.palette_data_type]['radius'])
+ link_length = \
+ self.palette_data[self.palette_data_type]['link_length']
Tool.handleToolEvent(self, event)
- if event.type == MOUSEBUTTONDOWN:
- self._body_1 = self._pos_1 = self._pos_2 = None
- if event.button >= 1:
- # Find body 1
- self._pos_1 = tuple_to_int(event.pos)
- self._body_1 = find_body(self.game.world, event.pos)
- if self._body_1 is None:
- self._clear()
- return
- elif event.type == MOUSEBUTTONUP:
- if self._body_1 is None or self._body_1 == []:
- return
- if event.button == 1:
- self._pos_2 = tuple_to_int(event.pos)
- link_length = \
- self.palette_data[self.palette_data_type]['link_length']
- radius = \
- int(self.palette_data[self.palette_data_type]['radius'])
- self.constructor(self._pos_1, self._pos_2, link_length, radius)
-
- def constructor(self, pos1, pos2, link_length, radius, share=True):
+ if event.type == MOUSEBUTTONDOWN and event.button == 1:
+ self.vertices = [tuple_to_int(event.pos)]
+ self.safe = False
+ elif event.type == MOUSEBUTTONUP and event.button == 1:
+ if len(self.vertices) == 1 and self.previous_vertices is not None:
+ last_x_y = self.previous_vertices[-1]
+ delta_x = last_x_y[0] - tuple_to_int(event.pos)[0]
+ delta_y = last_x_y[1] - tuple_to_int(event.pos)[1]
+ self.vertices = [[i[0] - delta_x, i[1] - delta_y]
+ for i in self.previous_vertices]
+ self.safe = True
+ if self.vertices and self.safe:
+ self.constructor(self.vertices, link_length, radius)
+ self.previous_vertices = self.vertices[:]
+ self.vertices = None
+ elif event.type == MOUSEMOTION and self.vertices:
+ last_x_y = self.vertices[-1]
+ if distance(tuple_to_int(event.pos), last_x_y) >= link_length:
+ self.vertices.append(tuple_to_int(event.pos))
+ if distance(tuple_to_int(event.pos),
+ self.vertices[0]) >= link_length * 5 and \
+ len(self.vertices) > 3:
+ self.safe = True
+
+ def constructor(self, vertices, link_length, radius, share=True):
+ logging.debug(vertices)
+ pos1 = vertices[0][:]
body1 = find_body(self.game.world, pos1)
if body1 is None:
- return
- body2 = find_body(self.game.world, pos2)
- if body2 is None:
- body2 = self.game.world.add.ball(
- pos2, radius, dynamic=True, density=1.0, restitution=0.16,
- friction=0.1)
- body2.userData['color'] = (0, 0, 0)
-
- self.make_chain(body1, body2, pos1, pos2, link_length, radius)
+ body1 = self.game.world.add.ball(
+ pos1, radius, dynamic=True, density=1.0, restitution=0.16,
+ friction=0.1)
+ body1.userData['color'] = (0, 0, 0)
+ for i, pos2 in enumerate(vertices):
+ if i == 0:
+ continue
+ logging.debug(pos2)
+ body2 = find_body(self.game.world, pos2)
+ if body2 is None:
+ body2 = self.game.world.add.ball(
+ pos2, radius, dynamic=True, density=1.0, restitution=0.16,
+ friction=0.1)
+ body2.userData['color'] = (0, 0, 0)
+
+ self.make_chain(body1, body2, pos1, pos2, link_length, radius)
+ body1 = body2
+ pos1 = pos2[:]
+
+ # Close the chain if the start and end were near each other
+ if distance(vertices[0], vertices[-1]) < link_length * 2:
+ pos1 = vertices[0][:]
+ body1 = find_body(self.game.world, pos1)
+ pos2 = vertices[-1][:]
+ body2 = find_body(self.game.world, pos2)
+ if body1 != body2:
+ self.make_chain(body1, body2, pos1, pos2, link_length, radius)
if share and self.game.activity.we_are_sharing:
- data = json.dumps([pos1, pos2, link_length, radius])
+ data = json.dumps([vertices, link_length, radius])
self.game.activity.send_event('c:' + data)
def draw(self):
Tool.draw(self)
- if self._body_1:
- pygame.draw.line(self.game.screen, (100, 180, 255), self._pos_1,
- tuple_to_int(pygame.mouse.get_pos()), 3)
-
- def _clear(self):
- self._body_1 = self._pos_1 = self._pos_2 = None
+ # Draw the poly being created
+ 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],
+ 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._clear()
+ self.vertices = None
def make_chain(self, body1, body2, pos1, pos2, link_length, radius):
dist = int(distance(pos1, pos2) + 0.5)
@@ -961,7 +994,6 @@ class ChainTool(Tool):
if dist < link_length: # Too short to make a chain
self.game.world.add.joint(body1, body2, pos1, pos2)
- self._clear()
return
# Draw circles along the path and join them together
@@ -984,8 +1016,6 @@ class ChainTool(Tool):
prev_circle = circle
prev_pos = tuple_to_int((x, y))
- self._clear()
-
def getAllTools():
return [MagicPenTool,