Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/TurtleArt/taturtle.py
diff options
context:
space:
mode:
Diffstat (limited to 'TurtleArt/taturtle.py')
-rw-r--r--TurtleArt/taturtle.py339
1 files changed, 312 insertions, 27 deletions
diff --git a/TurtleArt/taturtle.py b/TurtleArt/taturtle.py
index 7db72e6..992af95 100644
--- a/TurtleArt/taturtle.py
+++ b/TurtleArt/taturtle.py
@@ -26,11 +26,13 @@ import cairo
from taconstants import (TURTLE_LAYER, DEFAULT_TURTLE_COLORS)
from tasprite_factory import (SVG, svg_str_to_pixbuf)
-from tacanvas import (wrap100, COLOR_TABLE)
+from tacanvas import (wrap100, COLOR_TABLE, COLORDICT)
from sprites import Sprite
-from tautils import debug_output
+from tautils import debug_output, data_to_string, round_int
SHAPES = 36
+DEGTOR = pi / 180.
+RTODEG = 180. / pi
def generate_turtle_pixbufs(colors):
@@ -109,8 +111,9 @@ class Turtles:
class Turtle:
- def __init__(self, turtles, key, turtle_colors=None):
+ def __init__(self, turtle_window, turtles, key, turtle_colors=None):
""" The turtle is not a block, just a sprite with an orientation """
+ self.tw = turtle_window
self.x = 0.0
self.y = 0.0
self.hidden = False
@@ -124,6 +127,8 @@ class Turtle:
self.pen_gray = 100
self.pen_size = 5
self.pen_state = True
+ self.pen_fill = False
+ self.pen_poly_points = []
self.label_block = None
self._prep_shapes(key, turtles, turtle_colors)
@@ -175,7 +180,7 @@ class Turtle:
if turtle_colors is not None:
self.colors = turtle_colors[:]
self.shapes = generate_turtle_pixbufs(self.colors)
- self.set_heading(self.heading)
+ self.set_heading(self.heading, share=False)
def set_shapes(self, shapes, i=0):
""" Reskin the turtle """
@@ -218,9 +223,16 @@ class Turtle:
self.shapes = generate_turtle_pixbufs(self.colors)
self.custom_shapes = False
- def set_heading(self, heading):
+ def set_heading(self, heading, share=True):
""" Set the turtle heading (one shape per 360/SHAPES degrees) """
- self.heading = heading
+ try:
+ self.heading = heading
+ except (TypeError, ValueError):
+ debug_output('bad value sent to %s' % (__name__),
+ self.tw.running_sugar)
+ return
+ self.heading %= 360
+
i = (int(self.heading + 5) % 360) / (360 / SHAPES)
if not self.hidden and self.spr is not None:
try:
@@ -228,28 +240,142 @@ class Turtle:
except IndexError:
self.spr.set_shape(self.shapes[0])
- def set_color(self, color):
+ if self.tw.sharing() and share:
+ event = 'r|%s' % (data_to_string([self.tw.nick,
+ round_int(self.heading)]))
+ self.tw.send_event(event)
+
+ def set_color(self, color=None, share=True):
""" Set the pen color for this turtle. """
- self.pen_color = color
+ # Special case for color blocks
+ if color is not None and color in COLORDICT:
+ self.set_shade(COLORDICT[color][1], share)
+ self.set_gray(COLORDICT[color][2], share)
+ if COLORDICT[color][0] is not None:
+ self.set_color(COLORDICT[color][0], share)
+ color = COLORDICT[color][0]
+ else:
+ color = self.pen_color
+
+ try:
+ self.pen_color = color
+ except (TypeError, ValueError):
+ debug_output('bad value sent to %s' % (__name__),
+ self.tw.running_sugar)
+ return
+
+ self.tw.canvas.set_fgcolor(shade=self.pen_shade,
+ gray=self.pen_gray,
+ color=self.pen_color)
+
+ if self.tw.sharing() and share:
+ event = 'c|%s' % (data_to_string([self.tw.nick,
+ round_int(self.pen_color)]))
+ self.tw.send_event(event)
- def set_gray(self, gray):
+ def set_gray(self, gray=None, share=True):
""" Set the pen gray level for this turtle. """
- self.pen_gray = gray
+ if gray is not None:
+ try:
+ self.pen_gray = gray
+ except (TypeError, ValueError):
+ debug_output('bad value sent to %s' % (__name__),
+ self.tw.running_sugar)
+ return
+
+ if self.pen_gray < 0:
+ self.pen_gray = 0
+ if self.pen_gray > 100:
+ self.pen_gray = 100
+
+ self.tw.canvas.set_fgcolor(shade=self.pen_shade,
+ gray=self.pen_gray,
+ color=self.pen_color)
- def set_shade(self, shade):
+ if self.tw.sharing() and share:
+ event = 'g|%s' % (data_to_string([self.tw.nick,
+ round_int(self.pen_gray)]))
+ self.tw.send_event(event)
+
+ def set_shade(self, shade=None, share=True):
""" Set the pen shade for this turtle. """
- self.pen_shade = shade
+ if shade is not None:
+ try:
+ self.pen_shade = shade
+ except (TypeError, ValueError):
+ debug_output('bad value sent to %s' % (__name__),
+ self.tw.running_sugar)
+ return
+
+ self.tw.canvas.set_fgcolor(shade=self.pen_shade,
+ gray=self.pen_gray,
+ color=self.pen_color)
- def set_pen_size(self, pen_size):
+ if self.tw.sharing() and share:
+ event = 's|%s' % (data_to_string([self.tw.nick,
+ round_int(self.pen_shade)]))
+ self.tw.send_event(event)
+
+ def set_pen_size(self, pen_size=None, share=True):
""" Set the pen size for this turtle. """
- self.pen_size = pen_size
+ if pen_size is not None:
+ try:
+ self.pen_size = max(0, pen_size)
+ except (TypeError, ValueError):
+ debug_output('bad value sent to %s' % (__name__),
+ self.tw.running_sugar)
+ return
+
+ self.tw.canvas.set_pen_size(self.pen_size)
- def set_pen_state(self, pen_state):
+ if self.tw.sharing() and share:
+ event = 'w|%s' % (data_to_string([self.tw.nick,
+ round_int(self.pen_size)]))
+ self.tw.send_event(event)
+
+ def set_pen_state(self, pen_state=None, share=True):
""" Set the pen state (down==True) for this turtle. """
- self.pen_state = pen_state
+ if pen_state is not None:
+ self.pen_state = pen_state
+
+ self.tw.canvas.set_pen(self.pen_state)
+
+ if self.tw.sharing() and share:
+ event = 'p|%s' % (data_to_string([self.tw.nick,
+ self._pen_state]))
+ self.tw.send_event(event)
+
+ def set_fill(self, state=False):
+ self.pen_fill = state
+ if not self.pen_fill:
+ self.poly_points = []
+
+ def set_poly_points(self, poly_points=None):
+ if poly_points is not None:
+ self.poly_points = poly_points[:]
+
+ def start_fill(self):
+ self.pen_fill = True
+ self.poly_points = []
+
+ def stop_fill(self, share=True):
+ self.pen_fill = False
+ if len(self.poly_points) == 0:
+ return
+
+ self.tw.canvas.fill_polygon(self.poly_points)
+
+ if self.tw.sharing() and share:
+ shared_poly_points = []
+ for p in self.poly_points:
+ shared_poly_points.append(
+ (self.tw.canvas.screen_to_turtle_coordinates(p[0], p[1])))
+ event = 'F|%s' % (data_to_string([self.tw.nick,
+ shared_poly_points]))
+ self.tw.send_event(event)
+ self.poly_points = []
def hide(self):
- """ Hide the turtle. """
if self.spr is not None:
self.spr.hide()
if self.label_block is not None:
@@ -257,7 +383,6 @@ class Turtle:
self.hidden = True
def show(self):
- """ Show the turtle. """
if self.spr is not None:
self.spr.set_layer(TURTLE_LAYER)
self.hidden = False
@@ -266,8 +391,18 @@ class Turtle:
if self.label_block is not None:
self.label_block.spr.set_layer(TURTLE_LAYER + 1)
+ def move_turtle(self, pos=None):
+ if pos is None:
+ x, y = self.tw.canvas.get_xy()
+ else:
+ x, y = self.tw.canvas.turtle_to_screen_coordinates(pos[0], pos[1])
+ if self.tw.interactive_mode:
+ self.move((self.tw.canvas.cx + x - self.spr.rect.width / 2.,
+ self.tw.canvas.cy + y - self.spr.rect.height / 2.))
+ else:
+ self.move((self.tw.canvas.cx + x, self.tw.canvas.cy + y))
+
def move(self, pos):
- """ Move the turtle. """
self.x, self.y = pos[0], pos[1]
if not self.hidden and self.spr is not None:
self.spr.move((int(pos[0]), int(pos[1])))
@@ -277,33 +412,183 @@ class Turtle:
return(self.x, self.y)
def get_name(self):
- ''' return turtle name (key) '''
return self.name
def get_xy(self):
- """ Return the turtle's x, y coordinates. """
return(self.x, self.y)
def get_heading(self):
- """ Return the turtle's heading. """
return(self.heading)
def get_color(self):
- """ Return the turtle's color. """
return(self.pen_color)
def get_gray(self):
- """ Return the turtle's gray level. """
return(self.pen_gray)
def get_shade(self):
- """ Return the turtle's shade. """
return(self.pen_shade)
def get_pen_size(self):
- """ Return the turtle's pen size. """
return(self.pen_size)
def get_pen_state(self):
- """ Return the turtle's pen state. """
return(self.pen_state)
+
+ def get_fill(self):
+ return(self.pen_fill)
+
+ def get_poly_points(self):
+ return(self.poly_points)
+
+ def right(self, degrees, share=True):
+ ''' Rotate turtle clockwise '''
+ try:
+ self.heading += degrees
+ except (TypeError, ValueError):
+ debug_output('bad value sent to %s' % (__name__),
+ self.tw.running_sugar)
+ return
+ self.heading %= 360
+
+ if self.tw.sharing() and share:
+ event = 'r|%s' % (data_to_string([self.tw.nick,
+ round_int(self.heading)]))
+ self.tw.send_event(event)
+
+ def forward(self, distance, share=True):
+ scaled_distance = distance * self.tw.coord_scale
+
+ self.tw.canvas.set_rgb(self.tw.canvas.fgrgb[0] / 255.,
+ self.tw.canvas.fgrgb[1] / 255.,
+ self.tw.canvas.fgrgb[2] / 255.)
+
+ oldx, oldy = self.tw.canvas.get_xy()
+ try:
+ xcor = oldx + scaled_distance * sin(self.heading * DEGTOR)
+ ycor = oldy + scaled_distance * cos(self.heading * DEGTOR)
+ except (TypeError, ValueError):
+ debug_output('bad value sent to %s' % (__name__),
+ self.tw.running_sugar)
+ return
+
+ self.tw.canvas.set_xy(xcor, ycor)
+ if self.pen_state:
+ self.tw.canvas.draw_line(oldx, oldy, xcor, ycor)
+ if self.pen_fill:
+ if self.poly_points == []:
+ x, y = self.tw.canvas.turtle_to_screen_coordinates(oldx, oldy)
+ self.poly_points.append(('move', x, y))
+ x, y = self.tw.canvas.turtle_to_screen_coordinates(xcor, ycor)
+ self.poly_points.append(('line', x, y))
+
+ self.move_turtle((xcor, ycor))
+
+ if self.tw.sharing() and share:
+ event = 'f|%s' % (data_to_string([self.tw.nick,
+ int(distance)]))
+ self.tw.send_event(event)
+
+ def set_xy(self, x, y, share=True, pendown=True):
+ oldx, oldy = self.tw.canvas.get_xy()
+ try:
+ xcor = x * self.tw.coord_scale
+ ycor = y * self.tw.coord_scale
+ self.tw.canvas.set_xy(x, y)
+ except (TypeError, ValueError):
+ debug_output('bad value sent to %s' % (__name__),
+ self.tw.running_sugar)
+ return
+
+ if self.pen_state and pendown:
+ self.tw.canvas.set_rgb(self.tw.canvas.fgrgb[0] / 255.,
+ self.tw.canvas.fgrgb[1] / 255.,
+ self.tw.canvas.fgrgb[2] / 255.)
+ self.tw.canvas.draw_line(oldx, oldy, xcor, ycor)
+ if self.pen_fill:
+ if self.poly_points == []:
+ x, y = self.tw.canvas.turtle_to_screen_coordinates(oldx, oldy)
+ self.poly_points.append(('move', x, y))
+ x, y = self.tw.canvas.turtle_to_screen_coordinates(xcor, ycor)
+ self.poly_points.append(('line', x, y))
+
+ self.move_turtle((xcor, ycor))
+
+ if self.tw.sharing() and share:
+ event = 'x|%s' % (data_to_string([self.tw.nick,
+ [round_int(x), round_int(y)]]))
+ self.tw.send_event(event)
+
+ def arc(self, a, r, share=True):
+ ''' Draw an arc '''
+ if self.pen_state:
+ self.tw.canvas.set_rgb(self.tw.canvas.fgrgb[0] / 255.,
+ self.tw.canvas.fgrgb[1] / 255.,
+ self.tw.canvas.fgrgb[2] / 255.)
+ try:
+ if a < 0:
+ self.larc(-a, r)
+ else:
+ self.rarc(a, r)
+ except (TypeError, ValueError):
+ debug_output('bad value sent to %s' % (__name__),
+ self.tw.running_sugar)
+ return
+
+ xcor, ycor = self.tw.canvas.get_xy()
+ self.move_turtle((xcor, ycor))
+
+ if self.tw.sharing() and share:
+ event = 'a|%s' % (data_to_string([self.tw.nick,
+ [round_int(a), round_int(r)]]))
+ self.tw.send_event(event)
+
+ def rarc(self, a, r):
+ ''' draw a clockwise arc '''
+ r *= self.tw.coord_scale
+ if r < 0:
+ r = -r
+ a = -a
+ xcor, ycor = self.tw.canvas.get_xy()
+ cx = xcor + r * cos(self.heading * DEGTOR)
+ cy = ycor - r * sin(self.heading * DEGTOR)
+ if self.pen_state:
+ x, y = self.tw.canvas.turtle_to_screen_coordinates(cx, cy)
+ self.tw.canvas.rarc(x, y, r, a, self.heading)
+
+ if self.pen_fill:
+ x, y = self.tw.canvas.turtle_to_screen_coordinates(x, y)
+ if self.poly_points == []:
+ self.poly_points.append(('move', x, y))
+ self.poly_points.append(('rarc', x, y, r,
+ (self.heading - 180) * DEGTOR,
+ (self.heading - 180 + a) * DEGTOR))
+
+ self.right(a, False)
+ self.tw.canvas.set_xy(cx - r * cos(self.heading * DEGTOR),
+ cy + r * sin(self.heading * DEGTOR))
+
+ def larc(self, a, r):
+ ''' draw a counter-clockwise arc '''
+ r *= self.tw.coord_scale
+ if r < 0:
+ r = -r
+ a = -a
+ xcor, ycor = self.tw.canvas.get_xy()
+ cx = xcor - r * cos(self.heading * DEGTOR)
+ cy = ycor + r * sin(self.heading * DEGTOR)
+ if self.pen_state:
+ x, y = self.tw.canvas.turtle_to_screen_coordinates(cx, cy)
+ self.tw.canvas.larc(x, y, r, a, self.heading)
+
+ if self.pen_fill:
+ x, y = self.tw.canvas.turtle_to_screen_coordinates(x, y)
+ if self.poly_points == []:
+ self.poly_points.append(('move', x, y))
+ self.poly_points.append(('larc', x, y, r,
+ (self.heading) * DEGTOR,
+ (self.heading - a) * DEGTOR))
+
+ self.right(-a, False)
+ self.tw.canvas.set_xy(cx + r * cos(self.heading * DEGTOR),
+ cy - r * sin(self.heading * DEGTOR))