Pastie now auto-senses if line-wrap is a bad or good idea. Feedback?
## mark a section (Learn more)
# Shoegoo: Logo in Shoes # Example: # right 180 # move 50 # left 90 # def square x # repeat 4 do # move x # right 90 # end # end # @x = 5 # repeat 20 do # right 18 # square @x # @x += 5 # end BOARD_WIDTH = 500 BOARD_HEIGHT = 500 CONTROLS_WIDTH = 150 class Logo class << self; attr_accessor :board; end def self.setup(board, turtle) self.board = board self.board.turtle = LogoSandbox.turtle = turtle @@buff = [] @@depth = 0 self.board.draw end def self.read(text) if text =~ /^(def |repeat )/ @@buff << text @@depth += 1 elsif @@depth == 0 LogoSandbox.instance_eval(text) else @@buff << text if text =~ /^end/ @@depth -= 1 if @@depth == 0 LogoSandbox.instance_eval(@@buff.join("\n")) @@buff = [] end end end self.board.draw text end end class LogoSandbox attr_accessor :turtle def self.repeat(times, &block) times.times {block.call} end def self.move(steps) self.turtle.move(steps) end def self.turn(degrees) self.turtle.turn(degrees / 180.0 * Math::PI) end def self.left(degrees) turn(-degrees.to_f) end def self.right(degrees) turn(degrees.to_f) end end class Turtle attr_accessor :x, :y, :points def initialize(x, y) @x, @y = x, y @dir = [0.0, 1.0] @points = [[@x, @y]] end def draw $app.stroke(rgb(0, 1.0, 0)) # π turn v = [-@dir[1], @dir[0]] # turn - 5 units p1 = [@x - 5 * v[0], @y - 5 * v[1]] # turn + 5 units p2 = [@x + 5 * v[0], @y + 5 * v[1]] # forward 10 units p3 = [@x + 10 * @dir[0], @y + 10 * @dir[1]] $app.line(p1[0], p1[1], p2[0], p2[1]) $app.line(p2[0], p2[1], p3[0], p3[1]) $app.line(p3[0], p3[1], p1[0], p1[1]) end def move(dist) @x += dist * @dir[0] @y += dist * @dir[1] @points << [@x, @y] end def turn(r) @dir = [@dir[0] * Math.cos(r) - @dir[1] * Math.sin(r), @dir[0] * Math.sin(r) + @dir[1] * Math.cos(r)] end def each_line for i in (0...@points.size-1) yield [@points[i][0], @points[i][1], @points[i+1][0], @points[i+1][1]] end end end class LogoBoard attr_accessor :turtle def initialize @canvas = $app.flow(:margin => 0, :top => 0, :left => 0, :width => BOARD_WIDTH, :height => BOARD_HEIGHT) end def draw @canvas.clear do $app.background("#333333") $app.stroke(rgb(0, 0.8, 0)) @turtle.each_line { |l| $app.line(*l) } @turtle.draw end end end class ControlPanel def self.setup $app.stack :top => 0, :left => BOARD_WIDTH, :width => CONTROLS_WIDTH + 20, :margin => 10 do @@log = $app.edit_box :width => CONTROLS_WIDTH, :height => CONTROLS_WIDTH, :editable => false $app.para "" # spacing ick! @@input = $app.edit_line :width => CONTROLS_WIDTH, :height => 25 $app.para "" # more spacing $app.button("go", :width => CONTROLS_WIDTH) do @@log.text += Logo.read(@@input.text) + "\n" @@input.text = '' end end end end Shoes.app :width => BOARD_WIDTH + CONTROLS_WIDTH + 20, :height => BOARD_HEIGHT do $app = self ControlPanel.setup Logo.setup(LogoBoard.new, Turtle.new(250,250)) keypress {|key| self.clear if key == '\n'} end
This paste will be private.
From the Design Piracy series on my blog: