From 9b6de0eb9e4f09cddd12129a2547dd1ad07552f0 Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Wed, 27 Jan 2010 11:39:25 +0000 Subject: fixing turtle rotation --- diff --git a/constants.py b/constants.py index c1a0b9c..b6dbb9f 100644 --- a/constants.py +++ b/constants.py @@ -81,11 +81,11 @@ STANDARD_STROKE_WIDTH = 1.0 # # block style definitions # -BASIC_STYLE_HEAD = ['start', 'hat1', 'hat2'] +BASIC_STYLE_HEAD = ['start', 'hat1', 'hat2', 'restore'] BASIC_STYLE_HEAD_1ARG = ['hat'] BASIC_STYLE_TAIL = ['stopstack'] BASIC_STYLE = ['clean', 'penup', 'pendown', 'stack1', 'stack2', 'vspace', - 'hideblocks', 'clearheap', 'printheap', 'kbinput', 'restore'] + 'hideblocks', 'clearheap', 'printheap', 'kbinput'] BASIC_STYLE_1ARG = ['forward', 'back', 'left', 'right', 'setheading', 'show', 'setscale', 'setpensize', 'setcolor', 'setshade', 'print', 'settextsize', 'settextcolor', 'print', 'wait', 'storeinbox1', @@ -163,7 +163,7 @@ OLD_NAMES = {'product':'product2', # PRIMITIVES = {'clean':'clean', 'forward':'forward', 'back':'back', 'arc':'arc', - 'left':'left', 'right':'right', 'set heading':'seth', 'scale':'scale', + 'left':'left', 'right':'right', 'setheading':'seth', 'scale':'scale', 'show':'show', 'set scale':'setscale', 'xcor':'xcor', 'setxy':'setxy', 'ycor':'ycor', 'heading':'heading', 'penup':'penup', 'pendown':'pendown', 'setpensize':'setpensize', diff --git a/sprite_factory.py b/sprite_factory.py index 0537d86..69228ba 100755 --- a/sprite_factory.py +++ b/sprite_factory.py @@ -209,7 +209,7 @@ class SVG: svg += self._end_boolean() return self._header() + svg - def turtle(self): + def turtle(self, colors): self._fill, self._stroke = "#D0D000", "none" svg = self._rect(21, 21, 19.5, 18) self._fill = "#808000" @@ -234,9 +234,9 @@ class SVG: svg += self._rect(3, 3, 36, 30) svg += self._rect(3, 3, 36, 18) svg += self._rect(3, 3, 36, 36) - self._fill, self._stroke = "#008000", "#008000" + self._fill, self._stroke = colors[0], colors[0] svg += self._turtle_body() - self._fill, self._stroke = "#00A000", "#00A000" + self._fill, self._stroke = colors[1], colors[1] svg += self._turtle_shell() self._fill, self._stroke = "#000000", "#000000" svg += self._circle(1.25,32.5,8) diff --git a/tacanvas.py b/tacanvas.py new file mode 100644 index 0000000..5bf62a1 --- /dev/null +++ b/tacanvas.py @@ -0,0 +1,315 @@ +#Copyright (c) 2007-8, Playful Invention Company. +#Copyright (c) 2008-9, Walter Bender + +#Permission is hereby granted, free of charge, to any person obtaining a copy +#of this software and associated documentation files (the "Software"), to deal +#in the Software without restriction, including without limitation the rights +#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +#copies of the Software, and to permit persons to whom the Software is +#furnished to do so, subject to the following conditions: + +#The above copyright notice and this permission notice shall be included in +#all copies or substantial portions of the Software. + +#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +#THE SOFTWARE. + +import gtk +from math import sin,cos,pi +class taTurtle: pass + +from tasetup import load_image +import sprites +import taturtle +import pango + +from constants import * + +colors = {} +DEGTOR = 2*pi/360 + +color_table = ( + 0xFF0000,0xFF0D00,0xFF1A00,0xFF2600,0xFF3300, + 0xFF4000,0xFF4D00,0xFF5900,0xFF6600,0xFF7300, + 0xFF8000,0xFF8C00,0xFF9900,0xFFA600,0xFFB300, + 0xFFBF00,0xFFCC00,0xFFD900,0xFFE600,0xFFF200, + 0xFFFF00,0xE6FF00,0xCCFF00,0xB3FF00,0x99FF00, + 0x80FF00,0x66FF00,0x4DFF00,0x33FF00,0x1AFF00, + 0x00FF00,0x00FF0D,0x00FF1A,0x00FF26,0x00FF33, + 0x00FF40,0x00FF4D,0x00FF59,0x00FF66,0x00FF73, + 0x00FF80,0x00FF8C,0x00FF99,0x00FFA6,0x00FFB3, + 0x00FFBF,0x00FFCC,0x00FFD9,0x00FFE6,0x00FFF2, + 0x00FFFF,0x00F2FF,0x00E6FF,0x00D9FF,0x00CCFF, + 0x00BFFF,0x00B3FF,0x00A6FF,0x0099FF,0x008CFF, + 0x0080FF,0x0073FF,0x0066FF,0x0059FF,0x004DFF, + 0x0040FF,0x0033FF,0x0026FF,0x001AFF,0x000DFF, + 0x0000FF,0x0D00FF,0x1A00FF,0x2600FF,0x3300FF, + 0x4000FF,0x4D00FF,0x5900FF,0x6600FF,0x7300FF, + 0x8000FF,0x8C00FF,0x9900FF,0xA600FF,0xB300FF, + 0xBF00FF,0xCC00FF,0xD900FF,0xE600FF,0xF200FF, + 0xFF00FF,0xFF00E6,0xFF00CC,0xFF00B3,0xFF0099, + 0xFF0080,0xFF0066,0xFF004D,0xFF0033,0xFF001A) + +def tNew(tw,w,h): + t = taTurtle() + t.tw, t.width, t.height = tw, w, h + t.canvas = sprites.Sprite(tw.sprite_list, 0, 0, + gtk.gdk.Pixmap(tw.area,w,h,-1)) + (t.cx,t.cy) = t.canvas.get_xy() + t.canvas.type = 'canvas' + t.canvas.set_layer(CANVAS_LAYER) + t.shapelist = [] + t.t = taturtle.Turtle(tw.turtle_list, tw.sprite_list, ["#800000", "#A00000"]) + t.spr = t.t.spr + t.spr.type = 'turtle' + t.spr.set_layer(TURTLE_LAYER) + t.gc = t.canvas.image.new_gc() + t.shade = 0 + clearscreen(t) + return t + +def clearscreen(t): + t.xcor, t.ycor, t.heading = 0,0,0 + rect = gtk.gdk.Rectangle(0,0,t.width,t.height) + t.gc.set_foreground(t.tw.bgcolor) + t.canvas.image.draw_rectangle(t.gc, True, *rect) + invalt(t,0,0,t.width,t.height) + setpensize(t,5) + setcolor(t,0) + settextcolor(t,70) + settextsize(t,32) + setshade(t,50) + t.pendown = True + move_turtle(t) + turn_turtle(t) + return None + +def forward(t, n): + n *= t.tw.coord_scale + t.gc.set_foreground(t.tw.fgcolor) + oldx, oldy = t.xcor, t.ycor + try: + t.xcor += n*sin(t.heading*DEGTOR) + t.ycor += n*cos(t.heading*DEGTOR) + except: + pass + if t.pendown: + draw_line(t,oldx,oldy,t.xcor,t.ycor) + move_turtle(t) + return None + +def seth(t,n): + try: + t.heading=n + except: + pass + t.heading%=360 + turn_turtle(t) + return None + +def right(t,n): + try: + t.heading+=n + except: + pass + t.heading%=360 + turn_turtle(t) + return None + +def arc(t,a,r): + t.gc.set_foreground(t.tw.fgcolor) + r *= t.tw.coord_scale + try: + if a<0: larc(t,-a,r) + else: rarc(t,a,r) + except: + pass + move_turtle(t) + turn_turtle(t) + +def rarc(t,a,r): + if r<0: r=-r; a=-a + cx = t.xcor+r*cos(t.heading*DEGTOR) + cy = t.ycor-r*sin(t.heading*DEGTOR) + x,y,w,h=t.width/2+int(cx-r),t.height/2-int(cy+r),int(2*r),int(2*r) + if t.pendown: + t.canvas.image.draw_arc(t.gc,False,x,y,w,h, \ + int(180-t.heading-a)*64,int(a)*64) + invalt(t,x-t.pensize*t.tw.coord_scale/2-3,y-t.pensize*t.tw.coord_scale/2-3,\ + w+t.pensize*t.tw.coord_scale+6,h+t.pensize*t.tw.coord_scale+6) + right(t,a) + t.xcor=cx-r*cos(t.heading*DEGTOR) + t.ycor=cy+r*sin(t.heading*DEGTOR) + +def larc(t,a,r): + if r<0: r=-r; a=-a + cx = t.xcor-r*cos(t.heading*DEGTOR) + cy = t.ycor+r*sin(t.heading*DEGTOR) + x,y,w,h=t.width/2+int(cx-r),t.height/2-int(cy+r),int(2*r),int(2*r) + if t.pendown: + t.canvas.image.draw_arc(t.gc,False,x,y,w,h,int(360-t.heading)*64, \ + int(a)*64) + invalt(t,x-t.pensize*t.tw.coord_scale/2-3,y-t.pensize*t.tw.coord_scale/2-3,\ + w+t.pensize*t.tw.coord_scale+6,h+t.pensize*t.tw.coord_scale+6) + right(t,-a) + t.xcor=cx+r*cos(t.heading*DEGTOR) + t.ycor=cy-r*sin(t.heading*DEGTOR) + +def setxy(t,x,y): + x *= t.tw.coord_scale + y *= t.tw.coord_scale + try: + t.xcor,t.ycor = x,y + except: + pass + move_turtle(t) + +def setpensize(t,ps): + try: + if ps<0: + ps=0; + t.pensize = ps + except: + pass + t.gc.set_line_attributes(int(t.pensize*t.tw.coord_scale), \ + gtk.gdk.LINE_SOLID, \ + gtk.gdk.CAP_ROUND, gtk.gdk.JOIN_MITER) + return None + +def setcolor(t,c): + try: + t.color = c + t.tcolor = c + except: + pass + set_fgcolor(t) + set_textcolor(t) + return None + +def settextcolor(t,c): + try: + t.tcolor = c + except: + pass + set_textcolor(t) + return None + +def settextsize(t,c): + try: + t.tw.textsize = c + except: + pass + return None + +def setshade(t,s): + try: + t.shade = s + except: + pass + set_fgcolor(t) + set_textcolor(t) + return None + +def fillscreen(t,c,s): + oldc, olds = t.color,t.shade + try: + setcolor(t,c); setshade(t,s) + rect = gtk.gdk.Rectangle(0,0,t.width,t.height) + t.gc.set_foreground(t.tw.fgcolor) + t.canvas.image.draw_rectangle(t.gc, True, *rect) + invalt(t,0,0,t.width,t.height) + setcolor(t,oldc); setshade(t,olds) + except: + pass + return None + +def set_fgcolor(t): + sh = (wrap100(t.shade)-50)/50.0 + rgb = color_table[wrap100(t.color)] + r,g,b = (rgb>>8)&0xff00,rgb&0xff00,(rgb<<8)&0xff00 + r,g,b = calc_shade(r,sh),calc_shade(g,sh),calc_shade(b,sh) + t.tw.rgb = [r>>8,g>>8,b>>8] + t.tw.fgcolor = t.tw.cm.alloc_color(r,g,b) + +def set_textcolor(t): + sh = (wrap100(t.shade)-50)/50.0 + rgb = color_table[wrap100(t.tcolor)] + r,g,b = (rgb>>8)&0xff00,rgb&0xff00,(rgb<<8)&0xff00 + r,g,b = calc_shade(r,sh),calc_shade(g,sh),calc_shade(b,sh) + t.tw.textcolor = t.tw.cm.alloc_color(r,g,b) + +def wrap100(n): + n = int(n) + n %= 200 + if n>99: n=199-n + return n + +def calc_shade(c,s): + if s<0: return int(c*(1+s*.8)) + return int(c+(65536-c)*s*.9) + +def setpen(t,bool): + t.pendown = bool + +def draw_pixbuf(t,pixbuf,a,b,x,y,w,h): + w *= t.tw.coord_scale + h *= t.tw.coord_scale + t.canvas.image.draw_pixbuf(t.gc, pixbuf, a, b, x, y) + invalt(t,x,y,w,h) + +def draw_text(t, label, x, y, size, w): + w *= t.tw.coord_scale + t.gc.set_foreground(t.tw.textcolor) + fd = pango.FontDescription('Sans') + try: + fd.set_size(int(size*t.tw.coord_scale)*pango.SCALE) + except: + pass + if type(label) == str or type(label) == unicode: + pl = t.tw.window.create_pango_layout(label.replace("\0"," ")) + elif type(label) == float or type(label) == int: + pl = t.tw.window.create_pango_layout(str(label)) + else: + print "draw text: Type Error: %s" % (type(label)) + pl = t.tw.window.create_pango_layout(str(label)) + pl.set_font_description(fd) + pl.set_width(int(w)*pango.SCALE) + t.canvas.image.draw_layout(t.gc,int(x),int(y),pl) + w,h = pl.get_pixel_size() + invalt(t,x,y,w,h) + +def draw_line(t,x1,y1,x2,y2): + x1,y1 = t.width/2+int(x1), t.height/2-int(y1) + x2,y2 = t.width/2+int(x2), t.height/2-int(y2) + if x1>8)&0xff00,rgb&0xff00,(rgb<<8)&0xff00 - r,g,b = calc_shade(r,sh),calc_shade(g,sh),calc_shade(b,sh) - t.tw.rgb = [r>>8,g>>8,b>>8] - t.tw.fgcolor = t.tw.cm.alloc_color(r,g,b) - -def set_textcolor(t): - sh = (wrap100(t.shade)-50)/50.0 - rgb = color_table[wrap100(t.tcolor)] - r,g,b = (rgb>>8)&0xff00,rgb&0xff00,(rgb<<8)&0xff00 - r,g,b = calc_shade(r,sh),calc_shade(g,sh),calc_shade(b,sh) - t.tw.textcolor = t.tw.cm.alloc_color(r,g,b) - -def wrap100(n): - n = int(n) - n %= 200 - if n>99: n=199-n - return n - -def calc_shade(c,s): - if s<0: return int(c*(1+s*.8)) - return int(c+(65536-c)*s*.9) - -def setpen(t,bool): - t.pendown = bool - -def draw_pixbuf(t,pixbuf,a,b,x,y,w,h): - w *= t.tw.coord_scale - h *= t.tw.coord_scale - t.canvas.image.draw_pixbuf(t.gc, pixbuf, a, b, x, y) - invalt(t,x,y,w,h) - -def draw_text(t, label, x, y, size, w): - w *= t.tw.coord_scale - t.gc.set_foreground(t.tw.textcolor) - fd = pango.FontDescription('Sans') - try: - fd.set_size(int(size*t.tw.coord_scale)*pango.SCALE) - except: - pass - if type(label) == str or type(label) == unicode: - pl = t.tw.window.create_pango_layout(label.replace("\0"," ")) - elif type(label) == float or type(label) == int: - pl = t.tw.window.create_pango_layout(str(label)) - else: - print "draw text: Type Error: %s" % (type(label)) - pl = t.tw.window.create_pango_layout(str(label)) - pl.set_font_description(fd) - pl.set_width(int(w)*pango.SCALE) - t.canvas.image.draw_layout(t.gc,int(x),int(y),pl) - w,h = pl.get_pixel_size() - invalt(t,x,y,w,h) - -def draw_line(t,x1,y1,x2,y2): - x1,y1 = t.width/2+int(x1), t.height/2-int(y1) - x2,y2 = t.width/2+int(x2), t.height/2-int(y2) - if x1 len(self.list)-1: + return(None) + else: + return(self.list[i]) + + def length_of_list(self): + return(len(self.list)) + + def append_to_list(self, turtle): + self.list.append(turtle) + + def remove_from_list(self, turtle): + if block in self.list: + self.list.remove(turtle) + + # + # sprite utilities + # + def spr_to_turtle(self, spr): + for b in self.list: + if spr == b.spr: + return b + return None + +# +# A class for the individual turtles +# +class Turtle: + # The turtle is not a block, just a sprite with an orientation + def __init__(self, turtle_list, sprite_list, + colors=["#008000", "#00A000"], scale=1.0): + self.shapes = [] + self.type = 'turtle' + _svg = SVG() + _svg.set_scale(scale) + self.spr = sprites.Sprite(sprite_list, 0, 0, + svg_str_to_pixbuf(_svg.turtle(colors))) + turtle_list.append_to_list(self) + for i in range(36): + _svg.set_orientation(i*10) + self.shapes.append(svg_str_to_pixbuf(_svg.turtle(colors))) + + def rotate(self, orientation): + try: + self.spr.set_shape(self.shapes[orientation]) + except IndexError: + self.spr.set_shape(self.shapes[0]) + print "Turtle shape IndexError %d" % orientation diff --git a/tawindow.py b/tawindow.py index 4ca3c34..421f85c 100644 --- a/tawindow.py +++ b/tawindow.py @@ -42,7 +42,7 @@ from math import atan2, pi DEGTOR = 2*pi/360 from constants import * from talogo import * -from taturtle import * +from tacanvas import * from taproject import * import sprite_factory try: @@ -56,7 +56,7 @@ from gettext import gettext as _ import sprites import block -import turtlex +import taturtle """ TurtleArt Window class abstraction @@ -143,7 +143,7 @@ class TurtleArtWindow(): self.drag_group = None self.block_list = block.Blocks() self.sprite_list = sprites.Sprites(self.window, self.area, self.gc) - self.turtle_list = turtlex.Turtles() + self.turtle_list = taturtle.Turtles() self.selected_turtle = None self.turtle = tNew(self,self.width,self.height) self.lc = lcNew(self) @@ -290,12 +290,15 @@ class TurtleArtWindow(): self._load_sprite_from_file("%s/%s.svg" % (self.path, name))) self.media_shapes[i].set_layer(HIDE_LAYER) self.media_shapes[i].type = 'media' + for i, name in enumerate(STATUS_SHAPES): - self.status_shapes[i] = sprites.Sprite(self.sprite_list, - self.height-75, 0, - self._load_sprite_from_file("%s/%s.svg" % (self.path, name))) - self.status_shapes[i].set_layer(HIDE_LAYER) - self.status_shapes[i].type = 'status' + self.status_shapes[name] =\ + self._load_sprite_from_file("%s/%s.svg" % (self.path, name)) + self.status_spr = sprites.Sprite(self.sprite_list, self.height-75, 0, + self.status_shapes['status']) + self.status_spr.set_layer(HIDE_LAYER) + self.status_spr.type = 'status' + for i in enumerate(OVERLAY_SHAPES): self.overlay_shapes[i] = sprites.Sprite(self.sprite_list, 0, 0, self._load_sprite_from_file("%s/%s.svg" % (self.path, name))) diff --git a/turtlex.py b/turtlex.py deleted file mode 100644 index bcde9f9..0000000 --- a/turtlex.py +++ /dev/null @@ -1,77 +0,0 @@ -# -*- coding: utf-8 -*- -#Copyright (c) 2010 Walter Bender - -#Permission is hereby granted, free of charge, to any person obtaining a copy -#of this software and associated documentation files (the "Software"), to deal -#in the Software without restriction, including without limitation the rights -#to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -#copies of the Software, and to permit persons to whom the Software is -#furnished to do so, subject to the following conditions: - -#The above copyright notice and this permission notice shall be included in -#all copies or substantial portions of the Software. - -#THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -#IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -#FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -#AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -#LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -#OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -#THE SOFTWARE. - -from constants import * -import sprite_factory -import sprites -from gettext import gettext as _ - -# -# A class for the list of blocks and everything they share in common -# -class Turtles: - def __init__(self): - self.list = [] - - def get_turtle(self, i): - if i < 0 or i > len(self.list)-1: - return(None) - else: - return(self.list[i]) - - def length_of_list(self): - return(len(self.list)) - - def append_to_list(self, turtle): - self.list.append(turtle) - - def remove_from_list(self, turtle): - if block in self.list: - self.list.remove(turtle) - - # - # sprite utilities - # - def spr_to_turtle(self, spr): - for b in self.list: - if spr == b.spr: - return b - return None - -# -# A class for the individual turtles -# -class Turtle: - # The turtle is not a block, just a sprite with an orientation - def __init__(self, turtle_list, sprite_list, orientation=0, scale=1.0): - self.spr = None - self.orientation = orientation - svg = sprite_factory.SVG() - svg.set_scale(scale) - svg.set_orientation(orientation) - self.spr = sprites.Sprite(sprite_list, 0, 0, - sprite_factory.svg_str_to_pixbuf(svg.turtle())) - self.type = 'turtle' - turtle_list.append_to_list(self) - - # - # TODO: generate orientations - # -- cgit v0.9.1