diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1f92e51 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.*~ + diff --git a/README b/README deleted file mode 100644 index 5310528..0000000 --- a/README +++ /dev/null @@ -1,30 +0,0 @@ -___ / ___________ _________________(_)_____________ _ -__ / _ _ \ __ `/_ ___/_ __ \_ /__ __ \_ __ `/ -_ /___/ __/ /_/ /_ / _ / / / / _ / / / /_/ / -/_____/\___/\__,_/ /_/ /_/ /_//_/ /_/ /_/_\__, / - /____/ -________ _____ -___ __ \________________________________________(_)_____________ _ -__ /_/ /_ ___/ __ \ ___/ _ \_ ___/_ ___/_ /__ __ \_ __ `/ -_ ____/_ / / /_/ / /__ / __/(__ )_(__ )_ / _ / / / /_/ / -/_/ /_/ \____/\___/ \___//____/ /____/ /_/ /_/ /_/_\__, / - /____/ - ________________ ________ ______ -___ ____(_)_ /___ /_ ___ __ \___ ____ /______ __ -__ | /| / /_ /_ __/_ __ \ __ /_/ / / / /_ __ \_ / / / -__ |/ |/ /_ / / /_ _ / / / _ _, _// /_/ /_ /_/ / /_/ / -____/|__/ /_/ \__/ /_/ /_/ /_/ |_| \__,_/ /_.___/_\__, / - /____/ - - -"Learning Processing" is a 2008 book that serves as a gentle introduction to -the theory and practice of programming. It works by introducing code concepts -over the course of 23 chapters, and creating a series of examples that build -on them. The book was written by professor Daniel Shiffman of the ITP in -New York City. - -More information about the book can be found at: -http://www.learningprocessing.com/ - -These samples have been ported over to Ruby-Processing, which can be found here: -http://wiki.github.com/jashkenas/ruby-processing diff --git a/README.md b/README.md new file mode 100644 index 0000000..4ddc1ae --- /dev/null +++ b/README.md @@ -0,0 +1,37 @@ +## Learning Processing examples adapted to ruby-processing ## + +[Learning Processing][] by Daniel Shiffman is an book that serves as a gentle introduction to +the theory and practice of programming. It works by introducing code concepts +over the course of 23 chapters, and creating a series of examples that build +on them. Daniel Shiffman is a professor of the Interactive Telecommunications Program at New York University. + + + +These samples have been ported over to [ruby-processing][] here. Although the sketches stand on their own merit, you should remember that they were originally designed to illustrate the book (so to get the most from them you should [get the book][]). Since they have been translated to more idiomatic ruby, some of the sketches may no longer exactly illustrate the points made in the book. However such sketches serve to demonstrate the differences between processing and ruby-processing. However you might choose instead to get a more up to date book and, Daniel Shiffman, has written another book [The Nature of Code][] which has also been ported to ruby-processing [here][] the original examples can be found in the processing ide __File/Examples/Books/Nature of Code__. + +@todo port to JRubyArt see below:- + +```ruby +def setup # ruby-processing + size 200, 200 + smooth + .... +end + +def settings # JRubyArt + size 200, 200 + smooth +end + +def setup + sketch_title 'My Sketch' + .... +end +``` + +[Learning Processing]:http://www.learningprocessing.com/ +[ruby-processing]:http://wiki.github.com/jashkenas/ruby-processing +[The Nature of Code]:http://natureofcode.com/ +[here]:https://github.com/ruby-processing/The-Nature-of-Code-Examples + +[get the book]:http://www.amazon.com/gp/product/0123736021?ie=UTF8&tag=learniproces-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0123736021 diff --git a/chapter_01/1_stroke_and_fill.rb b/chapter_01/1_stroke_and_fill.rb index ab62383..06ab693 100644 --- a/chapter_01/1_stroke_and_fill.rb +++ b/chapter_01/1_stroke_and_fill.rb @@ -3,16 +3,12 @@ # Stretch the canvas to 200 pixels wide by 200 pixels tall. size 200, 200 - # Paint the background white. background 255 - # Set the color of strokes to black. stroke 0 - # Set the color of fills to middle gray. fill 150 - # Draw a rectangle 50 pixels over and 50 pixels down from the top left corner, # with a width of 75 pixels and a height of 100. -rect 50, 50, 75, 100 \ No newline at end of file +rect 50, 50, 75, 100 diff --git a/chapter_01/2_nofill.rb b/chapter_01/2_nofill.rb index 451a23b..2046ab0 100644 --- a/chapter_01/2_nofill.rb +++ b/chapter_01/2_nofill.rb @@ -1,20 +1,17 @@ # Here we introduce a slightly more sophisticated version of a Ruby-Processing # sketch. The code inside of the setup is run a single time, at the beginning. +# Note: parentheses are mostly optional, add them if you think it makes your code clearer def setup size 200, 200 - smooth + smooth 4 background 255 # In Ruby, methods and variables are under_scored instead of camelCased no_fill stroke 0 - # You might notice that there are no parenthesis or semicolons. - # That's because they're optional. ellipse 60, 60, 100, 100 - # This line works too: - ellipse(60, 60, 100, 100); end # And the code inside of draw, if there were any, would be drawn over and over. def draw - -end \ No newline at end of file + +end diff --git a/chapter_01/3_rgb_color.rb b/chapter_01/3_rgb_color.rb index 5815bf7..8ae3330 100644 --- a/chapter_01/3_rgb_color.rb +++ b/chapter_01/3_rgb_color.rb @@ -1,7 +1,7 @@ # RGB color is specified by intensity of red, then green, then blue. size 200, 200 -smooth +smooth 4 background 255 no_stroke diff --git a/chapter_01/4_alpha_transparency.rb b/chapter_01/4_alpha_transparency.rb index b781738..bcc252e 100644 --- a/chapter_01/4_alpha_transparency.rb +++ b/chapter_01/4_alpha_transparency.rb @@ -2,41 +2,30 @@ # and demonstrates what's really going on behind the scenes when you make # one of the simpler sketches, with just a setup method. -# A sketch is a class that inherits from the Processing::App, which works -# very much along the lines of a PApplet in Processing. -class AlphaTransparency < Processing::App - def setup - background 0 - no_stroke - - # No fourth argument means 100% opacity - fill 0, 0, 255 - rect 0, 0, 100, 200 - - # 255 means 100% opacity - fill 255, 0, 0, 255 - rect 0, 0, 200, 40 - - # 75% opacity - fill 255, 0, 0, 191 - rect 0, 50, 200, 40 - - # 55% opacity - fill 200, 0, 0, 127 - rect 0, 100, 200, 40 - - # 25% opacity - fill 255, 0, 0, 63 - rect 0, 150, 200, 40 - end - - def draw - - end - +def setup + size 200, 200 + background 0 + no_stroke + # No fourth argument means 100% opacity + fill 0, 0, 255 + rect 0, 0, 100, 200 + # 255 means 100% opacity + fill 255, 0, 0, 255 + rect 0, 0, 200, 40 + # 75% opacity + fill 255, 0, 0, 191 + rect 0, 50, 200, 40 + # 55% opacity + fill 200, 0, 0, 127 + rect 0, 100, 200, 40 + # 25% opacity + fill 255, 0, 0, 63 + rect 0, 150, 200, 40 end -# After defining your sketch, you create one. -# If you prefer, you may set the width, height, and title as you create it. -AlphaTransparency.new :title => "Alpha Transparency", :width => 200, :height => 200 \ No newline at end of file +def draw + +end + + diff --git a/chapter_01/5_zoog.rb b/chapter_01/5_zoog.rb index ee77a4e..d495cbd 100644 --- a/chapter_01/5_zoog.rb +++ b/chapter_01/5_zoog.rb @@ -1,24 +1,20 @@ size 200, 200 -background 255 -smooth -ellipse_mode CENTER -rect_mode CENTER - +background 255 +smooth 4 +ellipse_mode CENTER +rect_mode CENTER # Body -stroke 0 -fill 150 -rect 100, 100, 20, 100 - +stroke 0 +fill 150 +rect 100, 100, 20, 100 # Head -fill 255 -ellipse 100, 70, 60, 60 - +fill 255 +ellipse 100, 70, 60, 60 # Eyes -fill 0 -ellipse 81, 70, 16, 32 -ellipse 119, 70, 16, 32 - +fill 0 +ellipse 81, 70, 16, 32 +ellipse 119, 70, 16, 32 # Legs -stroke 0 -line 90, 150, 80, 160 -line 110, 150, 120, 160 \ No newline at end of file +stroke 0 +line 90, 150, 80, 160 +line 110, 150, 120, 160 diff --git a/chapter_01/Rakefile b/chapter_01/Rakefile new file mode 100644 index 0000000..9af2bd0 --- /dev/null +++ b/chapter_01/Rakefile @@ -0,0 +1,30 @@ +# Simple demo Rakefile to autorun samples in current directory +# adjust path to rp5 executable, and or opts as required + +SAMPLES_DIR = './' + +desc 'run demo' +task default: [:demo] + +desc 'demo' +task :demo do + samples_list.shuffle.each { |sample| run_sample sample } +end + +def samples_list + files = [] + Dir.chdir(SAMPLES_DIR) + Dir.glob('*.rb').each do |file| + files << File.join(SAMPLES_DIR, file) + end + files +end + +def run_sample(sample_name) + puts "Running #{sample_name}...quit to run next sample" + open("|rp5 run #{sample_name}", 'r') do |io| + while l = io.gets + puts(l.chop) + end + end +end diff --git a/chapter_02/1_zoog_again.rb b/chapter_02/1_zoog_again.rb index ce447c7..8e98904 100644 --- a/chapter_02/1_zoog_again.rb +++ b/chapter_02/1_zoog_again.rb @@ -1,41 +1,32 @@ -# Let's do Zoog again, as part of a complete sketch, showing the class for it, -# with setup and draw methods, and sketch creation at the bottom. - - -class ZoogAgain < Processing::App - - def setup - background 255 - smooth - - # Set ellipses and rects to CENTER mode - ellipse_mode CENTER - rect_mode CENTER +# with setup and draw methods. + +def setup + size 200, 200 + background 255 + smooth 4 + # Set ellipses and rects to CENTER mode + ellipse_mode CENTER + rect_mode CENTER + # Draw Zoog's body + stroke 0 + fill 150 + rect 100, 100, 20, 100 + # Draw Zoog's head + fill 255 + ellipse 100, 70, 60, 60 + # Draw Zoog's eyes + fill 0 + ellipse 81, 70, 16, 32 + ellipse 119, 70, 16, 32 + # Draw Zoog's legs + stroke 0 + line 90, 150, 80, 160 + line 110, 150, 120, 160 +end - # Draw Zoog's body - stroke 0 - fill 150 - rect 100, 100, 20, 100 +def draw - # Draw Zoog's head - fill 255 - ellipse 100, 70, 60, 60 +end - # Draw Zoog's eyes - fill 0 - ellipse 81, 70, 16, 32 - ellipse 119, 70, 16, 32 - # Draw Zoog's legs - stroke 0 - line 90, 150, 80, 160 - line 110, 150, 120, 160 - end - - def draw - - end - -end -ZoogAgain.new :title => "Zoog Again", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_03/1_zoog_as_dynamic_sketch.rb b/chapter_03/1_zoog_as_dynamic_sketch.rb index d5aa1da..6030005 100644 --- a/chapter_03/1_zoog_as_dynamic_sketch.rb +++ b/chapter_03/1_zoog_as_dynamic_sketch.rb @@ -1,44 +1,41 @@ -require 'ruby-processing' -class ZoogAsDynamicSketch < Processing::App - # Setup runs first one time. - # In Ruby-Processing, you never need to call size(), - # just set the width and height when you instantiate the sketch, - # at the bottom. - def setup - - end - - # Draw loops continuously until you close the sketch window. - def draw - # Draw a white background - background 255 - - # Set CENTER mode - ellipse_mode CENTER - rect_mode CENTER - - # Draw Zoog's body - stroke 0 - fill 150 - rect 100, 100, 20, 100 - - # Draw Zoog's head - fill 255 - ellipse 100, 70, 60, 60 - - # Draw Zoog's eyes - fill 0 - ellipse 81, 70, 16, 32 - ellipse 119, 70, 16, 32 - - # Draw Zoog's legs - stroke 0 - line 90, 150, 80, 160 - line 110, 150, 120, 160 - end +# Setup runs first one time. +# In Ruby-Processing, you never need to call size(), +# just set the width and height when you instantiate the sketch, +# at the bottom. +def setup + size 200, 200 + # Set CENTER mode + ellipse_mode CENTER + rect_mode CENTER +end + +# Draw loops continuously until you close the sketch window. +def draw + # Draw a white background + background 255 + + + # Draw Zoog's body + stroke 0 + fill 150 + rect 100, 100, 20, 100 + + # Draw Zoog's head + fill 255 + ellipse 100, 70, 60, 60 + + # Draw Zoog's eyes + fill 0 + ellipse 81, 70, 16, 32 + ellipse 119, 70, 16, 32 + + # Draw Zoog's legs + stroke 0 + line 90, 150, 80, 160 + line 110, 150, 120, 160 end -ZoogAsDynamicSketch.new :title => "Zoog As Dynamic Sketch", :width => 200, :height => 200 \ No newline at end of file + diff --git a/chapter_03/2_mouse_x_and_mouse_y.rb b/chapter_03/2_mouse_x_and_mouse_y.rb index d5139c5..699a025 100644 --- a/chapter_03/2_mouse_x_and_mouse_y.rb +++ b/chapter_03/2_mouse_x_and_mouse_y.rb @@ -1,26 +1,19 @@ -require 'ruby-processing' - -class MouseXAndMouseY < Processing::App - - def setup +def setup + size 200, 200 +end - end +def draw + # Try moving background to setup and see the difference! + background 255 - def draw - # Try moving background to setup and see the difference! - background 255 - - # Body - stroke 0 - fill 175 - rect_mode CENTER - - # mouse_x is a keyword that the sketch replaces with the - # horizontal position of the mouse. - # mouse_y gets the vertical position. - rect mouse_x, mouse_y, 50, 50 - end + # Body + stroke 0 + fill 175 + rect_mode CENTER + # mouse_x is a keyword that the sketch replaces with the + # horizontal position of the mouse. + # mouse_y gets the vertical position. + rect mouse_x, mouse_y, 50, 50 end -MouseXAndMouseY.new :title => "Mouse X And Mouse Y", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_03/3_zoog_as_dynamic_sketch_with_variation.rb b/chapter_03/3_zoog_as_dynamic_sketch_with_variation.rb index 0b3f295..8ddedcd 100644 --- a/chapter_03/3_zoog_as_dynamic_sketch_with_variation.rb +++ b/chapter_03/3_zoog_as_dynamic_sketch_with_variation.rb @@ -1,41 +1,35 @@ -require 'ruby-processing' - -class ZoogAsDynamicSketchWithVariation < Processing::App +def setup + size 200, 200 + smooth 4 +end - def setup - smooth - end +def draw + background 255 # Draw a white background - def draw - background 255 # Draw a white background - - # Set ellipses and rects to CENTER mode - ellipse_mode CENTER - rect_mode CENTER + # Set ellipses and rects to CENTER mode + ellipse_mode CENTER + rect_mode CENTER - # Draw Zoog's body - stroke 0 - fill 150 - # Zoog's body is drawn at the location (mouse_x, mouse_y) - rect mouse_x, mouse_y, 20, 100 + # Draw Zoog's body + stroke 0 + fill 150 + # Zoog's body is drawn at the location (mouse_x, mouse_y) + rect mouse_x, mouse_y, 20, 100 - # Draw Zoog's head - stroke 0 - fill 255 - # Zoog's head is drawn above the body at the location (mouse_x, mouse_y - 30) - ellipse mouse_x, mouse_y - 30, 60, 60 + # Draw Zoog's head + stroke 0 + fill 255 + # Zoog's head is drawn above the body at the location (mouse_x, mouse_y - 30) + ellipse mouse_x, mouse_y - 30, 60, 60 - # Draw Zoog's eyes - fill 0 - ellipse 81, 70, 16, 32 - ellipse 119, 70, 16, 32 + # Draw Zoog's eyes + fill 0 + ellipse 81, 70, 16, 32 + ellipse 119, 70, 16, 32 - # Draw Zoog's legs - stroke 0 - line 90, 150, 80, 160 - line 110, 150, 120, 160 - end - + # Draw Zoog's legs + stroke 0 + line 90, 150, 80, 160 + line 110, 150, 120, 160 end -ZoogAsDynamicSketchWithVariation.new :title => "Zoog As Dynamic Sketch With Variation", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_03/4_drawing_a_continuous_line.rb b/chapter_03/4_drawing_a_continuous_line.rb index 5a629eb..ba05e0e 100644 --- a/chapter_03/4_drawing_a_continuous_line.rb +++ b/chapter_03/4_drawing_a_continuous_line.rb @@ -1,18 +1,13 @@ -require 'ruby-processing' -class DrawingAContinuousLine < Processing::App - - def setup - background 255 - smooth - end - - def draw - stroke 0 - # Draw a line from the previous mouse location to the current location. - line pmouse_x, pmouse_y, mouse_x, mouse_y - end - +def setup + size 200, 200 + background 255 + smooth 4 + stroke 0 end -DrawingAContinuousLine.new :title => "Drawing A Continuous Line", :width => 200, :height => 200 \ No newline at end of file +def draw + # Draw a line from the previous mouse location to the current location. + line pmouse_x, pmouse_y, mouse_x, mouse_y +end + diff --git a/chapter_03/5_mouse_pressed_and_key_pressed.rb b/chapter_03/5_mouse_pressed_and_key_pressed.rb index d75ed97..805d439 100644 --- a/chapter_03/5_mouse_pressed_and_key_pressed.rb +++ b/chapter_03/5_mouse_pressed_and_key_pressed.rb @@ -1,29 +1,26 @@ -require 'ruby-processing' # Click the mouse to draw a square. Hit the space bar to clear the window. -class MousePressedAndKeyPressed < Processing::App - def setup - background 255 - end - - def draw - # Nothing happens in draw in this example! - end - - # Whenever the mouse is clicked, the code inside mouse_pressed runs. - def mouse_pressed - stroke 0 - fill 175 - rect_mode CENTER - rect mouse_x, mouse_y, 16, 16 - end - - # Whenever a key is pressed, the code inside key_pressed runs. - def key_pressed - background 255 - end - +def setup + size 200, 200 + background 255 + stroke 0 + fill 175 + rect_mode CENTER end -MousePressedAndKeyPressed.new :title => "Mouse Pressed And Key Pressed", :width => 200, :height => 200 \ No newline at end of file +def draw + # empty draw loop +end + +# Whenever the mouse is clicked, the code inside mouse_pressed runs. +def mouse_pressed + rect mouse_x, mouse_y, 16, 16 +end + +# Whenever a key is pressed, the code inside key_pressed runs. +def key_pressed + background 255 +end + + diff --git a/chapter_03/6_interactive_zoog.rb b/chapter_03/6_interactive_zoog.rb index cb816a3..13290ac 100644 --- a/chapter_03/6_interactive_zoog.rb +++ b/chapter_03/6_interactive_zoog.rb @@ -1,16 +1,16 @@ def setup - smooth + size 200, 200 + smooth 4 # The frame rate (like a movie) is set to 30 frames per second frame_rate 30 + # Set ellipses and rects to CENTER mode + ellipse_mode CENTER + rect_mode CENTER end def draw # draw a white background background 255 - - # Set ellipses and rects to CENTER mode - ellipse_mode CENTER - rect_mode CENTER # Draw Zoog's body stroke 0 @@ -39,4 +39,4 @@ def mouse_pressed # In Ruby, you can call 'puts' to print to the console. # 'print' also works (but doesn't make a new line). puts 'Take me to your leader!' -end \ No newline at end of file +end diff --git a/chapter_03/Rakefile b/chapter_03/Rakefile new file mode 100644 index 0000000..9af2bd0 --- /dev/null +++ b/chapter_03/Rakefile @@ -0,0 +1,30 @@ +# Simple demo Rakefile to autorun samples in current directory +# adjust path to rp5 executable, and or opts as required + +SAMPLES_DIR = './' + +desc 'run demo' +task default: [:demo] + +desc 'demo' +task :demo do + samples_list.shuffle.each { |sample| run_sample sample } +end + +def samples_list + files = [] + Dir.chdir(SAMPLES_DIR) + Dir.glob('*.rb').each do |file| + files << File.join(SAMPLES_DIR, file) + end + files +end + +def run_sample(sample_name) + puts "Running #{sample_name}...quit to run next sample" + open("|rp5 run #{sample_name}", 'r') do |io| + while l = io.gets + puts(l.chop) + end + end +end diff --git a/chapter_04/1_variable_declaration.rb b/chapter_04/1_variable_declaration.rb index 377cd9b..27ed416 100644 --- a/chapter_04/1_variable_declaration.rb +++ b/chapter_04/1_variable_declaration.rb @@ -1,24 +1,20 @@ -require 'ruby-processing' - # Ruby has dynamic typing, so you don't have to say # what kind of thing a variable is before using it. -class VariableDeclaration < Processing::App - def setup - count = 0 # count gets assigned 0, an integer (Fixnum) - letter = 'a' # letter gets the letter 'a', a String - d = 132.32 # d gets the decimal 132.32, a Float (floating-point number) - happy = false # happy gets false, a Boolean (true or false) - x = 4.0 # x gets 4.0, another Float - y = nil # y gets nil, which stands for nothing - y = x + 5.2 # assign the value of x plus 5.2 to y - z = x * y + 15.0 # z gets the value of x times y plus 15.0 (or 51.8) - end - - def draw - - end - +def setup + size 200, 200 + count = 0 # count gets assigned 0, an integer (Fixnum) + letter = 'a' # letter gets the letter 'a', a String + d = 132.32 # d gets the decimal 132.32, a Float (floating-point number) + happy = false # happy gets false, a Boolean (true or false) + x = 4.0 # x gets 4.0, another Float + y = nil # y gets nil, which stands for nothing + y = x + 5.2 # assign the value of x plus 5.2 to y + z = x * y + 15.0 # z gets the value of x times y plus 15.0 (or 51.8) end -VariableDeclaration.new :title => "Variable Declaration and Initialization Examples", :width => 200, :height => 200 \ No newline at end of file +def draw + +end + + diff --git a/chapter_04/2_using_variables.rb b/chapter_04/2_using_variables.rb index 995cd68..d402a8f 100644 --- a/chapter_04/2_using_variables.rb +++ b/chapter_04/2_using_variables.rb @@ -1,27 +1,27 @@ -require 'ruby-processing' +# Note since processing-2.0 the bare sketch is preferred, however at runtime +# this code will be wrapped in a "Sketch" class -class UsingVariables < Processing::App +def setup + # Create two variables, holding integers. + # These will be instance variables, meaning that you can + # get at them from any method within the 'Sketch class'. + # object variables in Ruby begin with '@' sigil. + size 200, 200 + @circle_x = 100 + @circle_y = 100 + smooth 4 +end - def setup - # Create two variables, holding integers. - # These will be instance variables, meaning that you can - # get at them from any method within this class. - # Instance variables in Ruby begin with '@'. - - @circle_x = 100 - @circle_y = 100 - smooth - end - - def draw - background 255 - stroke 0 - fill 175 - # We use the instance variables from setup for the circle. - # They are available in this method too. - ellipse @circle_x, @circle_y, 50, 50 - end - +def draw + background 255 + stroke 0 + fill 175 + # We use the object (instance) variables from setup for the circle. + # They are available in this method too. + ellipse @circle_x, @circle_y, 50, 50 end -UsingVariables.new :title => "Using Variables", :width => 200, :height => 200 \ No newline at end of file +# However with ruby you should explore attr_reader, and attr_accessor which +# allow the easy creation and use of getters and setters. Which can also be +# be used within the class, and yes it also works in ruby-processing. +# See following examples! diff --git a/chapter_04/3_varying_variables.rb b/chapter_04/3_varying_variables.rb index a576956..1c2436b 100644 --- a/chapter_04/3_varying_variables.rb +++ b/chapter_04/3_varying_variables.rb @@ -1,27 +1,28 @@ -require 'ruby-processing' +# using attr_reader to create a getter for object variables +# you can use attr_accessor, but it is probably best reserved to +# create a getter and setter that will be used from outside the class -class VaryingVariables < Processing::App +attr_reader :circle_x, :circle_y - def setup - # Declare and initialize two integer instance variables. - @circle_x = 0 - @circle_y = 100 - - smooth - end +def setup + size 200, 200 + # initialize two integer object variables. + @circle_x = 0 + @circle_y = 100 + smooth 4 +end + +def draw + background 255 + stroke 0 + fill 175 - def draw - background 255 - stroke 0 - fill 175 - - # Use the variables to specify the location of the circle - ellipse @circle_x, @circle_y, 50, 50 - - # An assignment operation that increments the value of circle_x by 1. - @circle_x += 1 - end + # Using getters to access the object variables to specify the location of the circle + ellipse circle_x, circle_y, 50, 50 + # An assignment operation that increments the value of circle_x by 1. + # note we need to use the '@' sigil prefix when assigning to the object variable + @circle_x += 1 end + -VaryingVariables.new :title => "Varying Variables", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_04/4_many_variables.rb b/chapter_04/4_many_variables.rb index f40aea4..93c2d3f 100644 --- a/chapter_04/4_many_variables.rb +++ b/chapter_04/4_many_variables.rb @@ -1,38 +1,38 @@ -require 'ruby-processing' +# we create a change getter, so we can access it in the draw loop +# using attr_reader can be a convenient way to separate variables that get +# assigned again from the variables that are not changed -class ManyVariables < Processing::App +attr_reader :change - def setup - # We've got 8 variables now! They're all Floats. - @circle_x, @circle_y = 0.0, 0.0 - @circle_w, @circle_h = 50.0, 100.0 - @circle_stroke = 255.0 - @circle_fill = 0.0 - @background_color = 255.0 - @change = 0.5 - - smooth - end - - def draw - # Draw the background and the ellipse. - # Variables are used for everything: - # background, stroke, fill, location and size. - background @background_color - stroke @circle_stroke - fill @circle_fill - ellipse @circle_x, @circle_y, @circle_w, @circle_h - - # Change the values of all variables. - # The variable change is used to update the others. - @circle_x += @change - @circle_y += @change - @circle_w += @change - @circle_h -= @change - @circle_stroke -= @change - @circle_fill += @change - end +def setup + size 200, 200 + # We've got 8 variables now! They're all Floats. + @circle_x, @circle_y = 0.0, 0.0 + @circle_w, @circle_h = 50.0, 100.0 + @circle_stroke = 255.0 + @circle_fill = 0.0 + @background_color = 255.0 + @change = 0.5 + smooth 4 +end + +def draw + # Draw the background and the ellipse. + # Variables are used for everything: + # background, stroke, fill, location and size. + background @background_color + stroke @circle_stroke + fill @circle_fill + ellipse @circle_x, @circle_y, @circle_w, @circle_h + # Change the values of all variables. The variable change is used to + # update the others (however in this case it could have been a constant). + @circle_x += change + @circle_y += change + @circle_w += change + @circle_h -= change + @circle_stroke -= change + @circle_fill += change end + -ManyVariables.new :title => "Many Variables", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_04/5_using_system_variables.rb b/chapter_04/5_using_system_variables.rb index d567fb8..baf158d 100644 --- a/chapter_04/5_using_system_variables.rb +++ b/chapter_04/5_using_system_variables.rb @@ -1,28 +1,24 @@ -require 'ruby-processing' -class UsingSystemVariables < Processing::App +def setup + size 200, 200 + smooth 4 +end - def setup - smooth - end - - def draw - background 100 - stroke 255 - - # frame_count is used to color a rectangle - fill(frame_count / 2) - rect_mode CENTER - - # The rectangle will always be in the middle of the window - # if it is located at (width/2, height/2) - rect(width/2, height/2, mouse_x + 10, mouse_y + 10) - end +def draw + background 100 + stroke 255 - def key_pressed - puts key - end + # frame_count is used to color a rectangle + fill(frame_count / 2) + rect_mode CENTER + # The rectangle will always be in the middle of the window + # if it is located at (width/2, height/2) + rect(width / 2, height / 2, mouse_x + 10, mouse_y + 10) end -UsingSystemVariables.new :title => "Using System Variables", :width => 200, :height => 200 \ No newline at end of file +def key_pressed + puts "You pressed the '#{key}' key." +end + + diff --git a/chapter_04/6_ellipse_with_variables.rb b/chapter_04/6_ellipse_with_variables.rb index 4bdcc9f..6a53bd6 100644 --- a/chapter_04/6_ellipse_with_variables.rb +++ b/chapter_04/6_ellipse_with_variables.rb @@ -1,24 +1,20 @@ -require 'ruby-processing' +attr_reader :r, :g, :b, :a, :x, :y, :diam -class EllipseWithVariables < Processing::App - - def setup - # Initialize your variables (you don't have to declare 'em) - @r, @g, @b, @a = 100, 150, 200, 200 - @x, @y = 100, 100 - @diam = 20 - - background 255 - smooth - end - - def draw - # Use the variables to draw an ellipse - stroke 0 - fill @r, @g, @b, @a # Remember, the fourth argument for a color means opacity. - ellipse @x, @y, @diam, @diam - end +def setup + size 200, 200 + @r, @g, @b, @a = 100, 150, 200, 200 + @x, @y = 100, 100 + @diam = 50 + background 255 + smooth 4 end -EllipseWithVariables.new :title => "Ellipse With Variables", :width => 200, :height => 200 \ No newline at end of file +def draw + # Use the variables to draw an ellipse + stroke 0 + fill r, g, b, a # Remember, the fourth argument for a color means opacity. + ellipse x, y, diam, diam +end + + diff --git a/chapter_04/7_filling_variables_with_random_values.rb b/chapter_04/7_filling_variables_with_random_values.rb index 401e384..5cd152f 100644 --- a/chapter_04/7_filling_variables_with_random_values.rb +++ b/chapter_04/7_filling_variables_with_random_values.rb @@ -1,27 +1,22 @@ -require 'ruby-processing' - -class FillingVariablesWithRandomValues < Processing::App +def setup + size 200, 200 + background 255 + smooth 4 +end - def setup - background 255 - smooth - end - - def draw - # Each time through draw, new random numbers - # are picked for a new ellipse. - # We're using local variables here, not instance variables, - # because we only need them in the draw method. - r, g, b, a = random(255), random(255), random(255), random(255) - diam = random(20) - x, y = random(width), random(height) - - # Use the values to draw an ellipse - no_stroke - fill r, g, b, a - ellipse x, y, diam, diam - end +def draw + # Each time through draw, new random numbers + # are picked for a new ellipse. + # We're using local variables here, not instance variables, + # because we only need them in the draw method. + r, g, b, a = rand(255), rand(255), rand(255), rand(255) + diam = rand(20) + x, y = rand(width), rand(height) + # Use the values to draw an ellipse + no_stroke + fill r, g, b, a + ellipse x, y, diam, diam end -FillingVariablesWithRandomValues.new :title => "Filling Variables With Random Values", :width => 200, :height => 200 \ No newline at end of file + diff --git a/chapter_04/8_variable_zoog.rb b/chapter_04/8_variable_zoog.rb index 76ea34b..7f75015 100644 --- a/chapter_04/8_variable_zoog.rb +++ b/chapter_04/8_variable_zoog.rb @@ -1,50 +1,45 @@ -require 'ruby-processing' # NEW FEATURE #1: Zoog will rise from below the screen and fly off into space. # NEW FEATURE #2: Zoog's eyes will be colored randomly as Zoog moves. -class VariableZoog < Processing::App - def setup - # Since in Ruby-Processing you don't ever call the size method, - # you can initialize zoog_x and zoog_y straight off. - @zoog_x, @zoog_y = width/2, height+100 - smooth - end +def setup + size 200, 200 + @zoog_x, @zoog_y = width / 2, height + 100 + smooth 4 +end + +def draw + background 255 # Draw a white background + + # Set ellipses and rects to CENTER mode + ellipse_mode CENTER + rect_mode CENTER + + # Draw Zoog's body + stroke 0 + fill 150 + # Feature #1: zoog_x and zoog_y are used for the location + rect @zoog_x, @zoog_y, 20, 100 - def draw - background 255 # Draw a white background - - # Set ellipses and rects to CENTER mode - ellipse_mode CENTER - rect_mode CENTER - - # Draw Zoog's body - stroke 0 - fill 150 - # Feature #1: zoog_x and zoog_y are used for the location - rect @zoog_x, @zoog_y, 20, 100 - - # Draw Zoog's head - stroke 0 - fill 255 - ellipse @zoog_x, @zoog_y-30, 60, 60 - - # Draw Zoog's eyes - # Feature #2: Zoog's eyes are colored with random values. - fill random(255), random(255), random(255) - ellipse @zoog_x-19, @zoog_y-30, 16, 32 - ellipse @zoog_x+19, @zoog_y-30, 16, 32 - - # Draw Zoog's legs - stroke 150 - line @zoog_x-10, @zoog_y+50, @zoog_x-10, height - line @zoog_x+10, @zoog_y+50, @zoog_x+10, height - - # Zoog moves up - @zoog_y -= 1 - - end + # Draw Zoog's head + stroke 0 + fill 255 + ellipse @zoog_x, @zoog_y - 30, 60, 60 + + # Draw Zoog's eyes + # Feature #2: Zoog's eyes are colored with random values. + fill rand(255), rand(255), rand(255) + ellipse @zoog_x - 19, @zoog_y - 30, 16, 32 + ellipse @zoog_x + 19, @zoog_y - 30, 16, 32 + + # Draw Zoog's legs + stroke 150 + line @zoog_x - 10, @zoog_y + 50, @zoog_x - 10, height + line @zoog_x + 10, @zoog_y + 50, @zoog_x + 10, height + + # Zoog moves up + @zoog_y -= 1 end -VariableZoog.new :title => "Variable Zoog", :width => 200, :height => 200 \ No newline at end of file + diff --git a/chapter_04/Rakefile b/chapter_04/Rakefile new file mode 100644 index 0000000..9af2bd0 --- /dev/null +++ b/chapter_04/Rakefile @@ -0,0 +1,30 @@ +# Simple demo Rakefile to autorun samples in current directory +# adjust path to rp5 executable, and or opts as required + +SAMPLES_DIR = './' + +desc 'run demo' +task default: [:demo] + +desc 'demo' +task :demo do + samples_list.shuffle.each { |sample| run_sample sample } +end + +def samples_list + files = [] + Dir.chdir(SAMPLES_DIR) + Dir.glob('*.rb').each do |file| + files << File.join(SAMPLES_DIR, file) + end + files +end + +def run_sample(sample_name) + puts "Running #{sample_name}...quit to run next sample" + open("|rp5 run #{sample_name}", 'r') do |io| + while l = io.gets + puts(l.chop) + end + end +end diff --git a/chapter_05/01_conditionals.rb b/chapter_05/01_conditionals.rb index 06c5bc5..8be46da 100644 --- a/chapter_05/01_conditionals.rb +++ b/chapter_05/01_conditionals.rb @@ -1,31 +1,27 @@ -require 'ruby-processing' -class Conditionals < Processing::App - - def setup - # Variables - @r, @g, @b = 150, 0, 0 - end +def setup + size 200, 200 + # Variables + @r, @g, @b = 150, 0, 0 +end - def draw - #Draw stuff - background @r, @g, @b - stroke 255 - line width/2, 0, width/2, height - - # The following checks use the "ternary operator" which is a compact way - # of saying, "if this is true ? do this : otherwise this" +def draw + #Draw stuff + background @r, @g, @b + stroke 255 + line width / 2, 0, width / 2, height + + # The following checks use the "ternary operator" which is a compact way + # of saying, "if this is true ? do this : otherwise this" - # If the mouse is on the right side of the screen is equivalent to - # "if mouse_x is greater than width divided by 2." - (mouse_x > width/2) ? @r += 1 : @r -=1 + # If the mouse is on the right side of the screen is equivalent to + # "if mouse_x is greater than width divided by 2." + (mouse_x > width / 2) ? @r += 1 : @r -=1 - # If r is greater than 255, set it back to 255. - # If r is less than 0, set it back to 0. - @r = 255 if @r > 255 - @r = 0 if @r < 0 - end - -end + # If r is greater than 255, set it back to 255. + # If r is less than 0, set it back to 0. + @r = 255 if @r > 255 + @r = 0 if @r < 0 + end + -Conditionals.new :title => "Conditionals", :width => 200, :height => 200 diff --git a/chapter_05/02_more_conditionals.rb b/chapter_05/02_more_conditionals.rb index ac83b29..7d567b5 100644 --- a/chapter_05/02_more_conditionals.rb +++ b/chapter_05/02_more_conditionals.rb @@ -1,38 +1,35 @@ -require 'ruby-processing' -class MoreConditionals < Processing::App - - def setup - # Three variables for the background color. - @r, @g, @b = 0, 0, 0 - end +def setup + size 200, 200 + # Three variables for the background color. + @r, @g, @b = 0, 0, 0 +end - def draw - # Color the background and draw lines to divide the window in quadrants. - background @r, @g, @b - stroke 0 - line width/2, 0, width/2, height - line 0, height/2, width, height/2 - - # The following checks use the "ternary operator" which is a compact way - # of saying, "if this is true ? do this : otherwise this" - - # If the mouse is on the right hand side of the window, increase red. - # Otherwise, it is on the left hand side and decrease red. - (mouse_x > width / 2) ? @r += 1 : @r -= 1 - - # If the mouse is on the bottom of the window, increase blue. - # Otherwise, it is on the top and decrease blue. - (mouse_y > height/2) ? @b += 1 : @b -= 1 - - # If the mouse is pressed. (for green) - mouse_pressed? ? @g += 1 : @g -= 1 - - # Constrain all color values to between 0 and 255. - @r = constrain(@r, 0, 255) - @g = constrain(@g, 0, 255) - @b = constrain(@b, 0, 255) - end +def draw + size 200, 200 + # Color the background and draw lines to divide the window in quadrants. + background @r, @g, @b + stroke 0 + line width/2, 0, width/2, height + line 0, height/2, width, height/2 + + # The following checks use the "ternary operator" which is a compact way + # of saying, "if this is true ? do this : otherwise this" + + # If the mouse is on the right hand side of the window, increase red. + # Otherwise, it is on the left hand side and decrease red. + (mouse_x > width / 2) ? @r += 1 : @r -= 1 + + # If the mouse is on the bottom of the window, increase blue. + # Otherwise, it is on the top and decrease blue. + (mouse_y > height/2) ? @b += 1 : @b -= 1 + + # If the mouse is pressed. (for green) + mouse_pressed? ? @g += 1 : @g -= 1 + + # Constrain all color values to between 0 and 255. + @r = constrain(@r, 0, 255) + @g = constrain(@g, 0, 255) + @b = constrain(@b, 0, 255) end -MoreConditionals.new :title => "More Conditionals", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_05/03_rollovers.rb b/chapter_05/03_rollovers.rb index 746cabe..d8aa3bc 100644 --- a/chapter_05/03_rollovers.rb +++ b/chapter_05/03_rollovers.rb @@ -1,34 +1,30 @@ -require 'ruby-processing' -class Rollovers < Processing::App - def setup +def setup + size 200, 200 +end + +def draw + background 255 + stroke 0 + line 100, 0, 100, 200 + line 0, 100, 200, 100 - end + # Fill a black color + no_stroke + fill 0 - def draw - background 255 - stroke 0 - line 100, 0, 100, 200 - line 0, 100, 200, 100 - - # Fill a black color - no_stroke - fill 0 - - # Depending on the mouse location, a different rectangle is displayed. - if mouse_x < 100 && mouse_y < 100 - rect 0, 0, 100, 100 - elsif mouse_x > 100 && mouse_y < 100 - rect 100, 0, 100, 100 - elsif mouse_x < 100 && mouse_y > 100 - rect 0, 100, 100, 100 - elsif mouse_x > 100 && mouse_y > 100 - rect 100, 100, 100, 100 - end - + # Depending on the mouse location, a different rectangle is displayed. + if mouse_x < 100 && mouse_y < 100 + rect 0, 0, 100, 100 + elsif mouse_x > 100 && mouse_y < 100 + rect 100, 0, 100, 100 + elsif mouse_x < 100 && mouse_y > 100 + rect 0, 100, 100, 100 + elsif mouse_x > 100 && mouse_y > 100 + rect 100, 100, 100, 100 end end -Rollovers.new :title => "Rollovers", :width => 200, :height => 200 \ No newline at end of file + diff --git a/chapter_05/04_hold_down_the_button.rb b/chapter_05/04_hold_down_the_button.rb index 83c315f..a3953ad 100644 --- a/chapter_05/04_hold_down_the_button.rb +++ b/chapter_05/04_hold_down_the_button.rb @@ -1,33 +1,28 @@ -require 'ruby-processing' -class HoldDownTheButton < Processing::App +def setup + size 200, 200 + @x, @y = 50, 50 + @w, @h = 100, 75 +end - def setup - @x, @y = 50, 50 - @w, @h = 100, 75 +def draw + # The button is pressed if (mouse_x, mouse_y) is inside + # the rectangle and mouse_pressed? is true. + if mouse_x > @x && mouse_x < @x+@w && mouse_y > @y && mouse_y < @y+@h && mouse_pressed? + button = true + else + button = false end - def draw - # The button is pressed if (mouse_x, mouse_y) is inside - # the rectangle and mouse_pressed? is true. - if mouse_x > @x && mouse_x < @x+@w && mouse_y > @y && mouse_y < @y+@h && mouse_pressed? - button = true - else - button = false - end - - if button - background 255 - stroke 0 - else - background 0 - stroke 255 - end - - fill 175 - rect @x, @y, @w, @h + if button + background 255 + stroke 0 + else + background 0 + stroke 255 end - + + fill 175 + rect @x, @y, @w, @h end - -HoldDownTheButton.new :title => "Hold Down The Button", :width => 200, :height => 200 \ No newline at end of file + diff --git a/chapter_05/05_button_as_switch.rb b/chapter_05/05_button_as_switch.rb index 3d0d008..1efca06 100644 --- a/chapter_05/05_button_as_switch.rb +++ b/chapter_05/05_button_as_switch.rb @@ -1,39 +1,35 @@ -require 'ruby-processing' -class ButtonAsSwitch < Processing::App - def setup - @x, @y = 50, 50 - @w, @h = 100, 75 - @button = false - end - - def draw - if @button - background 255 - stroke 0 - else - background 0 - stroke 255 - end - - fill 175 - rect @x, @y, @w, @h +def setup + size 200, 200 + @x, @y = 50, 50 + @w, @h = 100, 75 + @button = false +end + +def draw + if @button + background 255 + stroke 0 + else + background 0 + stroke 255 end - # When the mouse is pressed, the state of the button is toggled. - # Try moving this code to draw() like in the rollover example. What goes wrong? - - # The following method uses Ruby ranges, which look like 1..10, and - # stand for the range of things between the start and end element. - # You can ask a range if it includes a value, in this case whether - # or not mouse_x is between @x and @x+@w. - def mouse_pressed - if (@x..@x+@w).include?(mouse_x) && (@y..@y+@h).include?(mouse_y) - @button = !@button - end - end + fill 175 + rect @x, @y, @w, @h +end +# When the mouse is pressed, the state of the button is toggled. +# Try moving this code to draw() like in the rollover example. What goes wrong? + +# The following method uses Ruby ranges, which look like 1..10, and +# stand for the range of things between the start and end element. +# You can ask a range if it includes a value, in this case whether +# or not mouse_x is between @x and @x+@w. +def mouse_pressed + if (@x..@x+@w).include?(mouse_x) && (@y..@y+@h).include?(mouse_y) + @button = !@button + end end -ButtonAsSwitch.new :title => "Button As Switch", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_05/06_bouncing_ball.rb b/chapter_05/06_bouncing_ball.rb index 240a35f..2fc350c 100644 --- a/chapter_05/06_bouncing_ball.rb +++ b/chapter_05/06_bouncing_ball.rb @@ -1,33 +1,29 @@ -require 'ruby-processing' -class BouncingBall < Processing::App - def setup - @x = 0 - @speed = 1 - smooth - end +def setup + size 200, 200 + @x = 0 + @speed = 1 + smooth +end + +def draw + background 255 - def draw - background 255 - - # Add the current speed to the x location. - # += means x = x + speed - @x += @speed - - # Remember, || means "or" and && means "and". - # speed *= -1 means (speed = speed * -1) - # this one line if statement works the way it looks - # (do this thing) if (this thing is true) - @speed *= -1 if @x > width || @x < 0 - - # Draw a circle at @x location. - stroke 0 - fill 175 - ellipse @x, 100, 32, 32 + # Add the current speed to the x location. + # += means x = x + speed + @x += @speed - end + # Remember, || means "or" and && means "and". + # speed *= -1 means (speed = speed * -1) + # this one line if statement works the way it looks + # (do this thing) if (this thing is true) + @speed *= -1 if @x > width || @x < 0 + # Draw a circle at @x location. + stroke 0 + fill 175 + ellipse @x, 100, 32, 32 + end -BouncingBall.new :title => "Bouncing Ball", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_05/07_bouncing_color.rb b/chapter_05/07_bouncing_color.rb index 7dacea9..9ff5ba3 100644 --- a/chapter_05/07_bouncing_color.rb +++ b/chapter_05/07_bouncing_color.rb @@ -1,37 +1,33 @@ -require 'ruby-processing' -class BouncingColor < Processing::App - def setup - @c1, @c2 = 1.0, 255.0 - # Start by incrementing c1 and decrementing c2. - @c1_dir, @c2_dir = 0.1, -0.1 - end +def setup + size 200, 200 + @c1, @c2 = 1.0, 255.0 + # Start by incrementing c1 and decrementing c2. + @c1_dir, @c2_dir = 0.1, -0.1 +end + +def draw + no_stroke + + # Draw rectangle on left + fill @c1, 0, @c2 + rect 0, 0, 100, 200 + + # Draw rectangle on right + fill @c2, 0, @c1 + rect 100, 0, 100, 200 - def draw - no_stroke - - # Draw rectangle on left - fill @c1, 0, @c2 - rect 0, 0, 100, 200 - - # Draw rectangle on right - fill @c2, 0, @c1 - rect 100, 0, 100, 200 - - # Adjust color values - @c1 += @c1_dir - @c2 += @c2_dir - - # Instead of reaching the edge of a window, these variables reach the "edge" of color: - # 0 for no color and 255 for full color. - # When this happens, just like with the bouncing ball, the direction is reversed. - # - # The following lines use Ranges and "unless" (which is the opposite of if). - @c1_dir *= -1 unless (0..255).include?(@c1) - @c2_dir *= -1 unless (0..255).include?(@c1) - end + # Adjust color values + @c1 += @c1_dir + @c2 += @c2_dir + # Instead of reaching the edge of a window, these variables reach the "edge" of color: + # 0 for no color and 255 for full color. + # When this happens, just like with the bouncing ball, the direction is reversed. + # + # The following lines use Ranges and "unless" (which is the opposite of if). + @c1_dir *= -1 unless (0..255).include?(@c1) + @c2_dir *= -1 unless (0..255).include?(@c1) end -BouncingColor.new :title => "Bouncing Color", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_05/08_square_following_edge.rb b/chapter_05/08_square_following_edge.rb index 08d016b..ca1cb31 100644 --- a/chapter_05/08_square_following_edge.rb +++ b/chapter_05/08_square_following_edge.rb @@ -1,59 +1,56 @@ -require 'ruby-processing' +attr_reader :square, :speed -class SquareFollowingEdge < Processing::App +def setup + size 200, 200 + @square = State.new(0, 0, 0) + @speed = 5 +end - def setup - @x, @y = 0, 0 # x and y locations of the square - @speed = 5 # speed of square - - # A variable to keep track of the square's "state." - # Depending on the value of its state, it will either move right, down, left, or up. - @state = 0 - end +def draw + background 255 - def draw - background 255 - - # Display the square. - stroke 0 - fill 175 - rect @x, @y, 9, 9 - - # The following section uses a "case" statement. Cases let you - # set up different blocks of code for specific values of variables, - # as an alternative to a long if, elsif, else, kind of structure. - - # If the state is 0, move to the right. - case @state - when 0 - @x = @x + @speed - # If, while the state is 0, it reaches the right side of the window, change the state to 1 - # Repeat this same logic for all states!? - if @x > width-10 - @x = width-10 - @state = 1 - end - when 1 - @y = @y + @speed - if @y > height-10 - @y = height-10 - @state = 2 - end - when 2 - @x = @x - @speed - if @x < 0 - @x = 0 - @state = 3 - end - when 3 - @y = @y - @speed; - if @y < 0 - @y = 0 - @state = 0 - end - end + # Display the square. + stroke 0 + fill 175 + rect square.x, square.y, 9, 9 + # The following section uses a "case" statement. Cases let you + # set up different blocks of code for specific values of variables, + # as an alternative to a long if, elsif, else, kind of structure. + + # If the state is 0, move to the right. + case square.state + when 0 + square.x += speed + # If, while the state is 0, it reaches the right side of the window, change the state to 1 + # Repeat this same logic for all states!? + if square.x > width - 10 + square.x = width - 10 + square.state = 1 + end + when 1 + square.y += speed + if square.y > height - 10 + square.y = height - 10 + square.state = 2 + end + when 2 + square.x -= speed + if square.x < 0 + square.x = 0 + square.state = 3 + end + when 3 + square.y -= speed + if square.y < 0 + square.y = 0 + square.state = 0 + end end + end -SquareFollowingEdge.new :title => "Square Following Edge", :width => 200, :height => 200 \ No newline at end of file +# A ruby Struct is a convenient way to bundle a number of attributes together, +# using accessor methods, without having to write an explicit class. + +State = Struct.new(:state, :x, :y) diff --git a/chapter_05/09_simple_gravity.rb b/chapter_05/09_simple_gravity.rb index 37a3767..b5f6379 100644 --- a/chapter_05/09_simple_gravity.rb +++ b/chapter_05/09_simple_gravity.rb @@ -1,43 +1,38 @@ -require 'ruby-processing' +attr_reader :gravity, :speed -class SimpleGravity < Processing::App +def setup + size 200, 200 + @x, @y = 100, 0 # x and y locations of square + @speed = 0.0 # speed of square + + # A new variable, for gravity (i.e. acceleration). + # We use a relatively small number (0.1) because this + # accelerations accumulates over time, increasing the speed. + # Try changing this number to 2.0 and see what happens. + @gravity = 0.1 +end - def setup - @x, @y = 100, 0 # x and y locations of square - @speed = 0.0 # speed of square - - # A new variable, for gravity (i.e. acceleration). - # We use a relatively small number (0.1) because this - # accelerations accumulates over time, increasing the speed. - # Try changing this number to 2.0 and see what happens. - @gravity = 0.1 - end +def draw + background 255 - def draw - background 255 - - # Display the square - fill 175 - stroke 0 - rect_mode CENTER - rect @x, @y, 10, 10 - - # Add speed to location - @y += @speed - - # Add gravity to speed - @speed += @gravity - - # If square reaches the bottom - # Reverse speed - @speed *= -0.95 if @y > @height - # Multiplying by -0.95 instead of -1 slows the square down - # each time it bounces (by decreasing speed). - # This is known as a "dampening" effect and is a more realistic - # simulation of the real world (without it, a ball would bounce forever). + # Display the square + fill 175 + stroke 0 + rect_mode CENTER + rect @x, @y, 10, 10 - end + # Add speed to location + @y += speed -end + # Add gravity to speed + @speed += gravity + + # If square reaches the bottom + # Reverse speed + @speed *= -0.95 if @y > height + # Multiplying by -0.95 instead of -1 slows the square down + # each time it bounces (by decreasing speed). + # This is known as a "dampening" effect and is a more realistic + # simulation of the real world (without it, a ball would bounce forever). -SimpleGravity.new :title => "Simple Gravity", :width => 200, :height => 200 \ No newline at end of file +end diff --git a/chapter_05/10_zoog_and_conditionals.rb b/chapter_05/10_zoog_and_conditionals.rb index 1f5af52..e01a93d 100644 --- a/chapter_05/10_zoog_and_conditionals.rb +++ b/chapter_05/10_zoog_and_conditionals.rb @@ -1,53 +1,49 @@ -require 'ruby-processing' +attr_reader :x_speed, :y_speed, :eye_size -class ZoogAndConditionals < Processing::App +def setup + size 200, 200 + @x, @y, @w, @h = 100.0, 100.0, 60.0, 60.0 + @eye_size = 16.0 + + # Zoog has variables for speed in the horizontal and vertical direction. + @x_speed, @y_speed = 3.0, 1.0 + smooth 4 +end - def setup - @x, @y, @w, @h = 100.0, 100.0, 60.0, 60.0 - @eye_size = 16.0 - - # Zoog has variables for speed in the horizontal and vertical direction. - @x_speed, @y_speed = 3.0, 1.0 - smooth - end +def draw + # Change the location of Zoog by speed + @x += x_speed + @y += y_speed + + # An IF statement with a logical OR determines if Zoog has reached either + # the right or left edge of the screen. + # When this is true, we multiply speed by -1, reversing Zoog's direction! + # Identical logic is applied to the y direction as well. + @x_speed *= -1 if @x > width || @x < 0 + @y_speed *= -1 if @y > height || @y < 0 + + background 255 + ellipse_mode CENTER + rect_mode CENTER + + # Draw Zoog's body + stroke 0 + fill 150 + rect @x, @y, @w / 6, @h * 2 + + # Draw Zoog's head + # added () to make order of operations a bit more clear + fill 255 + ellipse @x, @y - @h / 2, @w, @h - def draw - # Change the location of Zoog by speed - @x += @x_speed - @y += @y_speed - - # An IF statement with a logical OR determines if Zoog has reached either - # the right or left edge of the screen. - # When this is true, we multiply speed by -1, reversing Zoog's direction! - # Identical logic is applied to the y direction as well. - @x_speed *= -1 if @x > width || @x < 0 - @y_speed *= -1 if @y > height || @y < 0 - - background 255 - ellipse_mode CENTER - rect_mode CENTER - - # Draw Zoog's body - stroke 0 - fill 150 - rect @x, @y, @w/6, @h*2 - - # Draw Zoog's head - # added () to make order of operations a bit more clear - fill 255 - ellipse @x, @y-@h/2, @w, @h - - # Draw Zoog's eyes - fill 0 - ellipse @x-@w/3+1, @y-@h/2, @eye_size, @eye_size*2 - ellipse @x+@w/3-1, @y-@h/2, @eye_size, @eye_size*2 - - # Draw Zoog's legs - stroke 0 - line @x-@w/12, @y+@h, @x-@w/4, @y+@h+10 - line @x+@w/12, @y+@h, @x+@w/4, @y+@h+10 - end + # Draw Zoog's eyes + fill 0 + ellipse @x - @w / 3 + 1, @y - @h / 2, eye_size, eye_size * 2 + ellipse @x + @w / 3 - 1, @y - @h / 2, eye_size, eye_size * 2 + # Draw Zoog's legs + stroke 0 + line @x - @w / 12, @y + @h, @x - @w / 4, @y + @h + 10 + line @x + @w / 12, @y + @h, @x + @w / 4, @y + @h + 10 end -ZoogAndConditionals.new :title => "Zoog And Conditionals", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_05/Rakefile b/chapter_05/Rakefile new file mode 100644 index 0000000..254cf8f --- /dev/null +++ b/chapter_05/Rakefile @@ -0,0 +1,30 @@ +# Simple demo Rakefile to autorun samples in current directory +# adjust path to rp5 executable, and or opts as required + +SAMPLES_DIR="./" + +desc 'run demo' +task :default => [:demo] + +desc 'demo' +task :demo do + samples_list.shuffle.each{|sample| run_sample sample} +end + +def samples_list + files = [] + Dir.chdir(SAMPLES_DIR) + Dir.glob("*.rb").each do |file| + files << File.join(SAMPLES_DIR, file) + end + return files +end + +def run_sample(sample_name) + puts "Running #{sample_name}...quit to run next sample" + open("|rp5 run #{sample_name}", "r") do |io| + while l = io.gets + puts(l.chop) + end + end +end diff --git a/chapter_06/01_many_lines.rb b/chapter_06/01_many_lines.rb index 78949c1..32d8956 100644 --- a/chapter_06/01_many_lines.rb +++ b/chapter_06/01_many_lines.rb @@ -1,29 +1,24 @@ -require 'ruby-processing' -class ManyLines < Processing::App - - def setup - background 255 - - # Legs - stroke 0 - line 50, 60, 50, 80 - line 60, 60, 60, 80 - line 70, 60, 70, 80 - line 80, 60, 80, 80 - line 90, 60, 90, 80 - line 100, 60, 100, 80 - line 110, 60, 110, 80 - line 120, 60, 120, 80 - line 130, 60, 130, 80 - line 140, 60, 140, 80 - line 150, 60, 150, 80 - end - - def draw - - end +def setup + size 200, 200 + background 255 + # Legs + stroke 0 + line 50, 60, 50, 80 + line 60, 60, 60, 80 + line 70, 60, 70, 80 + line 80, 60, 80, 80 + line 90, 60, 90, 80 + line 100, 60, 100, 80 + line 110, 60, 110, 80 + line 120, 60, 120, 80 + line 130, 60, 130, 80 + line 140, 60, 140, 80 + line 150, 60, 150, 80 +end + +def draw + end -ManyLines.new :title => "Many Lines", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_06/02_many_lines_with_variables.rb b/chapter_06/02_many_lines_with_variables.rb index 635e3f9..24673d5 100644 --- a/chapter_06/02_many_lines_with_variables.rb +++ b/chapter_06/02_many_lines_with_variables.rb @@ -1,53 +1,48 @@ -require 'ruby-processing' -class ManyLinesWithVariables < Processing::App - - def setup - background 255 - - # Legs - stroke 0 - y = 80 # Vertical location of each line - x = 50 # Initial horizontal location for first line - spacing = 10 # How far apart is each line - len = 20 # Length of each line +def setup + size 200, 200 + background 255 + + # Legs + stroke 0 + y = 80 # Vertical location of each line + x = 50 # Initial horizontal location for first line + spacing = 10 # How far apart is each line + len = 20 # Length of each line - # Draw the first leg. - line x, y, x, y + len - # Add spacing so the next leg appears 10 pixels to the right. - x = x + spacing + # Draw the first leg. + line x, y, x, y + len + # Add spacing so the next leg appears 10 pixels to the right. + x += spacing - # You could continue this process for each leg, like in the original - # example, but it's pretty silly to repeat any chunk of code so many times: - - line x, y, x, y + len - x = x + spacing - line x, y, x, y + len - x = x + spacing - line x, y, x, y + len - x = x + spacing - line x, y, x, y + len - x = x + spacing - line x, y, x, y + len - x = x + spacing - line x, y, x, y + len - x = x + spacing - line x, y, x, y + len - x = x + spacing - line x, y, x, y + len - x = x + spacing - line x, y, x, y + len - x = x + spacing - line x, y, x, y + len - - # A nicer way is to repeat that chunk of code with a block, - # you can see how in example 06. - end - - def draw + # You could continue this process for each leg, like in the original + # example, but it's pretty silly to repeat any chunk of code so many times: - end + line x, y, x, y + len + x += spacing + line x, y, x, y + len + x += spacing + line x, y, x, y + len + x += spacing + line x, y, x, y + len + x += spacing + line x, y, x, y + len + x += spacing + line x, y, x, y + len + x += spacing + line x, y, x, y + len + x += spacing + line x, y, x, y + len + x += spacing + line x, y, x, y + len + x += spacing + line x, y, x, y + len + # A nicer way is to repeat that chunk of code with a block, + # you can see how in example 06. +end + +def draw + end -ManyLinesWithVariables.new :title => "Many Lines With Variables", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_06/03_while_loop.rb b/chapter_06/03_while_loop.rb index 970e487..c993969 100644 --- a/chapter_06/03_while_loop.rb +++ b/chapter_06/03_while_loop.rb @@ -1,30 +1,26 @@ -require 'ruby-processing' -class WhileLoop < Processing::App - def setup - background 255 +def setup + size 200, 200 + background 255 - y = 80 # Vertical location of each line - x = 50 # Initial horizontal location for first line - spacing = 10 # How far apart is each line - len = 20 # Length of each line + y = 80 # Vertical location of each line + x = 50 # Initial horizontal location for first line + spacing = 10 # How far apart is each line + len = 20 # Length of each line - # A variable to mark where the legs end. - end_legs = 150 - stroke 0 + # A variable to mark where the legs end. + end_legs = 150 + stroke 0 - # Draw each leg inside a while loop. - while x <= end_legs - line x, y, x, y + len - x = x + spacing - end + # Draw each leg inside a while loop. + while x <= end_legs + line x, y, x, y + len + x = x + spacing end - - def draw - - end - end -WhileLoop.new :title => "While Loop", :width => 200, :height => 200 \ No newline at end of file +def draw + +end + diff --git a/chapter_06/04_infinite_loop.rb b/chapter_06/04_infinite_loop.rb index f6593f2..dd468b5 100644 --- a/chapter_06/04_infinite_loop.rb +++ b/chapter_06/04_infinite_loop.rb @@ -1,25 +1,17 @@ -require 'ruby-processing' - -class InfiniteLoop < Processing::App - - def setup - - end - - def draw - - x = 0 - while x < 10 - puts x - # Decrementing x results in an infinite loop here because the value of x will never be 10 or greater. - # Be careful! - x = x - 1 - end +def setup + size 200, 200 +end - # This example does not include the break function. - # To stop the runaway loop, close the window or use control-c in the terminal. +def draw + x = 0 + while x < 10 + puts x + # Decrementing x results in an infinite loop here because the value of x will never be 10 or greater. + # Be careful! + x -= 1 end + # This example does not include the break function. + # To stop the runaway loop, close the window or use control-c in the terminal. end -InfiniteLoop.new :title => "Infinite Loop (Don't do this)", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_06/05_another_infinite_loop.rb b/chapter_06/05_another_infinite_loop.rb index 2310600..0b45300 100644 --- a/chapter_06/05_another_infinite_loop.rb +++ b/chapter_06/05_another_infinite_loop.rb @@ -1,33 +1,28 @@ -require 'ruby-processing' +attr_reader :spacing, :len, :end_legs -class AnotherInfiniteLoop < Processing::App +def setup + size 200, 200 + @y = 80 # Vertical location of each line + @x = 0 # Horizontal location of first line + @spacing = 10 # How far apart is each line + @len = 20 # Length of each line + @end_legs = 150 # Where should the lines stop? +end - def setup - @y = 80 # Vertical location of each line - @x = 0 # Horizontal location of first line - @spacing = 10 # How far apart is each line - @len = 20 # Length of each line - @end_legs = 150 # Where should the lines stop? - end - - def draw - # The spacing variable, which sets the distance in between each line, - # is assigned a value equal to mouseX divided by two. - # THIS LINE IS COMMENTED OUT SO THAT THE SKETCH DOES NOT CRASH - # IF YOU PUT IT BACK IN THIS SKETCH WILL CRASH! - # @spacing = mouse_x / 2 +def draw + # The spacing variable, which sets the distance in between each line, + # is assigned a value equal to mouseX divided by two. + # THIS LINE IS COMMENTED OUT SO THAT THE SKETCH DOES NOT CRASH + # IF YOU PUT IT BACK IN THIS SKETCH WILL CRASH! + # @spacing = mouse_x / 2 - # Exit Condition: when x is greater than endlegs. - while @x <= @end_legs - line @x, @y, @x, @y + @len - # Incrementation of x. - # x always increases by the value of spacing. - # What is the range of possible values for spacing? - @x = @x + @spacing - end - + # Exit Condition: when x is greater than endlegs. + while @x <= end_legs + line @x, @y, @x, @y + len + # Incrementation of x. + # x always increases by the value of spacing. + # What is the range of possible values for spacing? + @x += spacing end - -end -AnotherInfiniteLoop.new :title => "Another Infinite Loop", :width => 200, :height => 200 \ No newline at end of file +end diff --git a/chapter_06/06_legs_with_a_for_loop.rb b/chapter_06/06_legs_with_a_for_loop.rb index 14a37a3..a953243 100644 --- a/chapter_06/06_legs_with_a_for_loop.rb +++ b/chapter_06/06_legs_with_a_for_loop.rb @@ -1,41 +1,37 @@ -require 'ruby-processing' +attr_reader :spacing, :len -class LegsWithAForLoop < Processing::App +def setup + size 200, 200 + background 255 +end - def setup - background 255 - end +def reset_values + @x = 50 # Horizontal location of first line + @y = 80 # Vertical location of each line + @spacing = 10 # How far apart is each line + @len = 20 # Length of each line +end + +def draw + reset_values - def reset_values - @x = 50 # Horizontal location of first line - @y = 80 # Vertical location of each line - @spacing = 10 # How far apart is each line - @len = 20 # Length of each line - end + # In ruby numbers also have methods. + # The times method allows you to run a given block of code + # a certain number of times: - def draw - reset_values - - # In ruby numbers also have methods. - # The times method allows you to run a given block of code - # a certain number of times: - - 10.times do - line @x, @y, @x, @y + @len - @x += @spacing - end - - # There's also an alternative method called step, - # You call it on the number you'd like to start with, - # passing it the end number, and the size of the steps to take: - # start_num.step(stop_num, step_size) { |value| do_something_with value ... - - 50.step(150, @spacing) { |x| line x, @y, x, @y + @len } - - # The curly braces are an alternative form for writing do ... end. - # So, I guess this isn't much of a demonstration of the for loop... + 10.times do + line @x, @y, @x, @y + len + @x += spacing end + # There's also an alternative method called step, + # You call it on the number you'd like to start with, + # passing it the end number, and the size of the steps to take: + # start_num.step(stop_num, step_size) { |value| do_something_with value ... + + 50.step(150, spacing) { |x| line x, @y, x, @y + len } + + # The curly braces are an alternative form for writing do ... end. + # So, I guess this isn't much of a demonstration of the for loop... end -LegsWithAForLoop.new :title => "Legs With A For Loop", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_06/07_local_variables.rb b/chapter_06/07_local_variables.rb index 53294da..02b85e0 100644 --- a/chapter_06/07_local_variables.rb +++ b/chapter_06/07_local_variables.rb @@ -1,39 +1,30 @@ -require 'ruby-processing' +# To fix this add 'attr_reader :ted' +# and use '@' sigil prefix version of ted to assign -class LocalVariables < Processing::App +# attr_reader :ted - def setup - # x is not available! It is local to the draw block of code. - end - - def draw - background 0 - x = 0 - # x is available! Since it is declared within the draw - # block of code, it is available here. - # Notice, however, that it is not available inside draw - # above where it is declared. - # Also, it is available inside the while block of code - # because while is inside of draw. - - while x < width - stroke 255 - line x, 0, x, height - x += 5 - end - - # This could also be written with until: - # until x > width ... - # Or it could be written with step: - # 0.step(width, 5) do ... - +def setup + size 200, 200 + ted = 2000 + no_loop +end + +def draw + background 0 + # x is not available! Since it is declared within the setup + begin + puts "in draw:\n#{ted.inspect}" + rescue => detail + puts "in draw:\nrescue" end - - def mouse_pressed - # x is not available! It is local to the draw block of code. - puts "The mouse was pressed!" +end + +def mouse_pressed + # x is not available! It is local to the setup block of code. + begin + puts "in mouse_pressed:\n#{ted.inspect}" + rescue => detail + puts "in mouse_pressed:\nrescue" end - end -LocalVariables.new :title => "Local Variables", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_06/08_lines_one_at_a_time.rb b/chapter_06/08_lines_one_at_a_time.rb index bd36098..d6cfe33 100644 --- a/chapter_06/08_lines_one_at_a_time.rb +++ b/chapter_06/08_lines_one_at_a_time.rb @@ -1,30 +1,30 @@ -require 'ruby-processing' +# No for loop here. Instead, a global variable. +# In ruby, global variables start with '$' sigil. +# Not that it makes any sense here, more useful is $app +# which can be used anywhere to call the sketch object. +# see previous sketch for a more ruby like solution to +# access sketch variables. -class LinesOneAtATime < Processing::App - - # No for loop here. Instead, a global variable. - # In ruby, global variables start with $. - $y = 0 - - def setup - background 255 - # Slowing down the frame rate so we can easily see the effect. - frame_rate 5 - end - - def draw - # Draw a line - stroke 0 - # Only one line is drawn each time through draw. - line 0, $y, width, $y - # Increment y - $y += 10 - # Reset y back to 0 when it gets to the bottom of window - # In ruby, you can put if statements at the end, like speaking. - $y = 0 if $y > height - end +$y = 0 + +def setup + size 255, 255 + background 255 + # Slowing down the frame rate so we can easily see the effect. + frame_rate 5 +end + +def draw + # Draw a line + stroke 0 + # Only one line is drawn each time through draw. + line 0, $y, width, $y + # Increment y + $y += 10 + # Reset y back to 0 when it gets to the bottom of window + # In ruby, you can put if statements at the end, like speaking. + $y = 0 if $y > height end -LinesOneAtATime.new :title => "Lines One At A Time", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_06/09_simple_while_loop_with_interactivity.rb b/chapter_06/09_simple_while_loop_with_interactivity.rb index 0922e36..d880898 100644 --- a/chapter_06/09_simple_while_loop_with_interactivity.rb +++ b/chapter_06/09_simple_while_loop_with_interactivity.rb @@ -1,41 +1,37 @@ -require 'ruby-processing' -class SimpleWhileLoopWithInteractivity < Processing::App - def setup - # no_stroke can go inside setup, because it only needs to be called once. - no_stroke - end - - def draw - background 0 +def setup + size 255, 255 + # no_stroke can go inside setup, because it only needs to be called once. + no_stroke +end - # Start with i as 0 - i = 0 +def draw + background 0 - # While i is less than the width of the window - while i < width - # The distance between the current rectangle and the mouse - # is equal to the absolute value of the difference between i and mouseX. - distance = (mouse_x - i).abs - # That distance is used to fill the color of a rectangle at horizontal location i. - fill distance - rect i, 0, 10, height - # Increase i by 10 - i += 10 - end - - # Un-comment the following lines to perform the same procedure - # for the height of the sketch, at half opacity. - # Uses a slightly different technique: - - # (height/10).times do |j| - # distance = (mouse_y - j*10).abs - # fill distance, 128 - # rect 0, j*10, width, 10 - # end + # Start with i as 0 + i = 0 + + # While i is less than the width of the window + while i < width + # The distance between the current rectangle and the mouse + # is equal to the absolute value of the difference between i and mouseX. + distance = (mouse_x - i).abs + # That distance is used to fill the color of a rectangle at horizontal location i. + fill distance + rect i, 0, 10, height + # Increase i by 10 + i += 10 end + # Un-comment the following lines to perform the same procedure + # for the height of the sketch, at half opacity. + # Uses a slightly different technique: + + # (height/10).times do |j| + # distance = (mouse_y - j*10).abs + # fill distance, 128 + # rect 0, j*10, width, 10 + # end end -SimpleWhileLoopWithInteractivity.new :title => "Simple While Loop With Interactivity", :width => 255, :height => 255 \ No newline at end of file diff --git a/chapter_06/10_zoog_with_arms.rb b/chapter_06/10_zoog_with_arms.rb index 1f3eb89..0449551 100644 --- a/chapter_06/10_zoog_with_arms.rb +++ b/chapter_06/10_zoog_with_arms.rb @@ -1,56 +1,52 @@ -require 'ruby-processing' - -class ZoogwithArms < Processing::App - - def setup - @x, @y = 100, 100 - @w, @h = 60, 60 - @eye_size = 16 - @speed = 1 - smooth - - # Set ellipses and rects to CENTER mode - # We can do this in setup because we only need to do it once - ellipseMode CENTER - rectMode CENTER - end + + +def setup + size 200, 200 + @x, @y = 100, 100 + @w, @h = 60, 60 + @eye_size = 16 + @speed = 1 + smooth 4 - def draw - # Change the x location of Zoog by speed - @x += @speed - - # If we've reached an edge, reverse speed i.e. multiply it by -1 - # Note if speed is a + number, square moves to the right, - to the left - @speed *= -1 if @x > @width || @x < 0 - - background 255 # Draw a white background - stroke 0 # Set the stroke color to black - - # Arms are incorporated into Zoog's design with a times loop. - 6.times do |i| - y = i * 10 + @y + 5 - line @x-@w/3, y, @x+@w/3, y - end - - # Draw Zoog's body - fill 175 - rect @x, @y, @w/6, @h*2 - - # Draw Zoog's head - fill 255 - ellipse @x, @y-@h/2, @w, @h - - # Draw Zoog's eyes - fill 0 - ellipse @x-@w/3+1, @y-@h/2, @eye_size, @eye_size*2 - ellipse @x+@w/3-1, @y-@h/2, @eye_size, @eye_size*2 - - # Draw Zoog's legs - line @x-@w/12, @y+@h, @x-@w/4, @y+@h+10 - line @x+@w/12, @y+@h, @x+@w/4, @y+@h+10 - + # Set ellipses and rects to CENTER mode + # We can do this in setup because we only need to do it once + ellipseMode CENTER + rectMode CENTER +end + +def draw + # Change the x location of Zoog by speed + @x += @speed + + # If we've reached an edge, reverse speed i.e. multiply it by -1 + # Note if speed is a + number, square moves to the right, - to the left + @speed *= -1 if @x > @width || @x < 0 + + background 255 # Draw a white background + stroke 0 # Set the stroke color to black + + # Arms are incorporated into Zoog's design with a times loop. + 6.times do |i| + y = i * 10 + @y + 5 + line @x-@w/3, y, @x+@w/3, y end + + # Draw Zoog's body + fill 175 + rect @x, @y, @w/6, @h*2 + + # Draw Zoog's head + fill 255 + ellipse @x, @y-@h/2, @w, @h + + # Draw Zoog's eyes + fill 0 + ellipse @x-@w/3+1, @y-@h/2, @eye_size, @eye_size*2 + ellipse @x+@w/3-1, @y-@h/2, @eye_size, @eye_size*2 + + # Draw Zoog's legs + line @x-@w/12, @y+@h, @x-@w/4, @y+@h+10 + line @x+@w/12, @y+@h, @x+@w/4, @y+@h+10 end -ZoogwithArms.new :title => "Zoog with Arms", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_06/11_multiple_zoogs.rb b/chapter_06/11_multiple_zoogs.rb index 975c80f..80d4e16 100644 --- a/chapter_06/11_multiple_zoogs.rb +++ b/chapter_06/11_multiple_zoogs.rb @@ -1,46 +1,42 @@ -require 'ruby-processing' +attr_reader :eye_size -class MultipleZoogs < Processing::App +def setup + size 400, 200 + @w, @h = 60, 60 + @eye_size = 16 + @y = height / 2 + smooth 4 + ellipse_mode CENTER + rect_mode CENTER +end - def setup - @w, @h = 60, 60 - @eye_size = 16 - @y = height/2 - smooth - ellipseMode CENTER - rectMode CENTER - end +def draw + background 255 + stroke 0 - def draw - background 255 - stroke 0 - - # Multiple versions of Zoog - # If we want to show four Zoogs, let's draw it four times: - - 4.times do |i| - x = i * 80 + 80 + # Multiple versions of Zoog + # If we want to show four Zoogs, let's draw it four times: + + 4.times do |i| + x = i * 80 + 80 - # Draw Zoog's body - fill 175 - rect x, @y, @w/6, @h*2 + # Draw Zoog's body + fill 175 + rect x, @y, @w / 6, @h * 2 - # Draw Zoog's head - fill 255 - ellipse x, @y-@h/2, @w, @h + # Draw Zoog's head + fill 255 + ellipse x, @y - @h / 2, @w, @h - # Draw Zoog's eyes - fill 0 - ellipse x-@w/3+1, @y-@h/2, @eye_size, @eye_size*2 - ellipse x+@w/3-1, @y-@h/2, @eye_size, @eye_size*2 + # Draw Zoog's eyes + fill 0 + ellipse x - @w / 3 + 1, @y - @h / 2, eye_size, eye_size * 2 + ellipse x + @w / 3 - 1, @y - @h / 2, eye_size, eye_size * 2 - # Draw Zoog's legs - line x-@w/12, @y+@h, x-@w/4, @y+@h+10 - line x+@w/12, @y+@h, x+@w/4, @y+@h+10 - end - + # Draw Zoog's legs + line x - @w / 12, @y + @h, x - @w / 4, @y + @h + 10 + line x + @w / 12, @y + @h, x + @w / 4, @y + @h + 10 end - + end -MultipleZoogs.new :title => "Multiple Zoogs", :width => 400, :height => 200 diff --git a/chapter_06/Rakefile b/chapter_06/Rakefile new file mode 100644 index 0000000..da182ca --- /dev/null +++ b/chapter_06/Rakefile @@ -0,0 +1,31 @@ +# Simple demo Rakefile to autorun samples in current directory +# adjust path to rp5 executable, and or opts as required +# here we exclude file with infinite loops + +SAMPLES_DIR="./" + +desc 'run demo' +task :default => [:demo] + +desc 'demo' +task :demo do + samples_list.shuffle.each{|sample| run_sample sample} +end + +def samples_list + files = [] + Dir.chdir(SAMPLES_DIR) + Dir.glob("*.rb").each do |file| + files << File.join(SAMPLES_DIR, file) unless file =~ /infinite/ + end + return files +end + +def run_sample(sample_name) + puts "Running #{sample_name}...quit to run next sample" + open("|rp5 run #{sample_name}", "r") do |io| + while l = io.gets + puts(l.chop) + end + end +end diff --git a/chapter_07/01_defining_a_function.rb b/chapter_07/01_defining_a_function.rb index 0e649a7..4e26feb 100644 --- a/chapter_07/01_defining_a_function.rb +++ b/chapter_07/01_defining_a_function.rb @@ -1,22 +1,17 @@ -require 'ruby-processing' +# Strictly there are only bound and unbound methods in ruby +# "setup, draw and draw_black_circle" are all bound to a Sketch object -class DefiningAFunction < Processing::App +def setup + size 200, 200 +end + +def draw - def setup - - end - - def draw - - end - - # This example defines a function, but it is - # not called. So nothing happens. - def draw_black_circle - fill 0 - ellipse 50, 50, 20, 20 - end - end -DefiningAFunction.new :title => "Defining A Function", :width => 200, :height => 200 \ No newline at end of file +# This example defines a function, but it is +# not called. So nothing happens. +def draw_black_circle + fill 0 + ellipse 50, 50, 20, 20 +end diff --git a/chapter_07/02_calling_a_function.rb b/chapter_07/02_calling_a_function.rb index 1e7aa6f..f0f17be 100644 --- a/chapter_07/02_calling_a_function.rb +++ b/chapter_07/02_calling_a_function.rb @@ -1,22 +1,20 @@ -require 'ruby-processing' +# Many languages distinguish between functions, which have no associated object, +# and methods, which are invoked on a receiver object. Strictly in ruby there are +# no functions, they are either bound or unbound methods. +# all the below are bound methods (bound to an object of the Sketch class) -class CallingAFunction < Processing::App +def setup + size 100, 100 + smooth 4 +end + +def draw + background 255 + draw_black_circle +end - def setup - smooth - draw_black_circle - end - - def draw - background 255 - draw_black_circle - end - - def draw_black_circle - fill 0 - ellipse 50, 50, 20, 20 - end - +def draw_black_circle + fill 0 + ellipse 50, 50, 20, 20 end -CallingAFunction.new :title => "Calling A Function", :width => 100, :height => 100 \ No newline at end of file diff --git a/chapter_07/03_bouncing_ball_with_functions.rb b/chapter_07/03_bouncing_ball_with_functions.rb index 996c477..2496d1f 100644 --- a/chapter_07/03_bouncing_ball_with_functions.rb +++ b/chapter_07/03_bouncing_ball_with_functions.rb @@ -1,49 +1,45 @@ -require 'ruby-processing' - -class BouncingBallWithFunctions < Processing::App - - def setup - # Declare variables - @x = 1 - @speed = 1 - smooth - end - - def draw - background 255 - # Instead of writing out all the code about the ball - # in draw, we simply call three functions. How do - # we know the names of these functions? We made them up! - move - bounce - display - end - - # Where should functions be placed? - # You can define your functions anywhere in the code outside of setup and draw. - # However, the convention is to place your function definitions below draw. - - # A function to move the ball - def move - # Change the x location by speed - @x += @speed - end - - # A function to bounce the ball - def bounce - # If we’ve reached an edge, reverse speed - # (0..width) is a Ruby range, representing the numbers from 0 to width (aka 200). - # You can ask a range if it includes another number or not. - @speed *= -1 unless (0..width).include? @x - end - - # A function to display the ball - def display - stroke 0 - fill 175 - ellipse @x, 100, 32, 32 - end - + + +def setup + size 200, 200 + @x = 1 + @speed = 1 + smooth +end + +def draw + background 255 + # Instead of writing out all the code about the ball + # in draw, we simply call three methods. How do + # we know the names of these methods? We made them up! + move + bounce + display +end + +# Where should methods be placed? +# You can define your methods anywhere in the code outside of setup and draw. +# However, the convention is to place your method definitions below draw. +# These methods all get wrapped in the Sketch class at runtime. + +# A method to move the ball +def move + # Change the x location by speed + @x += @speed +end + +# A method to bounce the ball +def bounce + # If we’ve reached an edge, reverse speed + # (0..width) is a Ruby range, representing the numbers from 0 to width (aka 200). + # You can ask a range if it includes another number or not. + @speed *= -1 unless (0..width).include? @x +end + +# A method to display the ball +def display + stroke 0 + fill 175 + ellipse @x, 100, 32, 32 end -BouncingBallWithFunctions.new :title => "Bouncing Ball With Functions", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_07/04_function_returns_distance.rb b/chapter_07/04_function_returns_distance.rb index f355e19..5871356 100644 --- a/chapter_07/04_function_returns_distance.rb +++ b/chapter_07/04_function_returns_distance.rb @@ -1,48 +1,43 @@ -require 'ruby-processing' -class FunctionReturnsDistance < Processing::App - def setup +def setup + size 200, 200 +end + +def draw + background 0 + stroke 0 - end + # Set up width/2-1 and height/2-1 variables, for convenience. + w1, h1 = width/2-1, height/2-1 - def draw - background 0 - stroke 0 - - # Set up width/2-1 and height/2-1 variables, for convenience. - w1, h1 = width/2-1, height/2-1 - - # Top left square - # Our distance function is used to calculate a brightness value - # for each quadrant. We could use the built-in function dist - # instead, but we are learning how to write our own functions. - fill distance(0, 0, mouse_x ,mouse_y) - rect 0, 0, w1, h1 - - # Top right square - fill distance(width, 0, mouse_x, mouse_y) - rect width/2, 0, w1, h1 - - # Bottom left square - fill distance(0, height, mouse_x, mouse_y) - rect 0, height/2, w1, h1 - - # Bottom right square - fill distance(width, height, mouse_x, mouse_y) - rect width/2, height/2, w1, h1 + # Top left square + # Our distance method is used to calculate a brightness value + # for each quadrant. We could use the built-in method dist + # instead, but we are learning how to write our own methods. + fill distance(0, 0, mouse_x ,mouse_y) + rect 0, 0, w1, h1 - end + # Top right square + fill distance(width, 0, mouse_x, mouse_y) + rect width/2, 0, w1, h1 - # Defining the distance method. - # In Ruby we don't have to write "return", because Ruby implicitly - # returns the last thing that was evaluated from any method. - def distance x1, y1, x2, y2 - dx = x1 - x2 - dy = y1 - y2 - sqrt(dx*dx + dy*dy) - end + # Bottom left square + fill distance(0, height, mouse_x, mouse_y) + rect 0, height/2, w1, h1 + # Bottom right square + fill distance(width, height, mouse_x, mouse_y) + rect width/2, height/2, w1, h1 + +end + +# Defining the distance method. +# In Ruby we don't have to write "return", because Ruby implicitly +# returns the last thing that was evaluated from any method. +def distance x1, y1, x2, y2 + dx = x1 - x2 + dy = y1 - y2 + sqrt(dx*dx + dy*dy) end -FunctionReturnsDistance.new :title => "Function Returns Distance", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_07/05_zoog_with_functions.rb b/chapter_07/05_zoog_with_functions.rb index 6202060..794aedc 100644 --- a/chapter_07/05_zoog_with_functions.rb +++ b/chapter_07/05_zoog_with_functions.rb @@ -1,71 +1,66 @@ -require 'ruby-processing' -class ZoogWithFunctions < Processing::App +def setup + size 200, 200 + @x, @y = 100, 100 + @w, @h = 60, 60 + @eye_size = 16 + @speed = 1 + ellipse_mode CENTER + rect_mode CENTER + stroke 0 + smooth 4 +end - def setup - @x, @y = 100, 100 - @w, @h = 60, 60 - @eye_size = 16 - @speed = 1 - ellipse_mode CENTER - rect_mode CENTER - stroke 0 - smooth - end +def draw + background 255 # Draw a black background - def draw - background 255 # Draw a black background - - # mouse_x position determines speed factor for moveZoog function - factor = constrain mouse_x/10, 0, 5 - - # The code for changing the variables associated with Zoog and - # displaying Zoog is moved outside of draw and into functions - # called here. The functions are given arguments, such as - # "Jiggle Zoog by the following factor" and "draw Zoog with - # the following eye color". - jiggle_zoog factor - - # pass in a color to the draw_zoog function for eye color - d = dist(@x, @y, mouse_x, mouse_y) - c = color(d) - draw_zoog c - end + # mouse_x position determines speed factor for moveZoog function + factor = constrain(mouse_x/10, 0, 5) - def jiggle_zoog speed - # Change the x and y location of Zoog randomly - @x = @x + random(-1, 1) * speed - @y = @y + random(-1, 1) * speed - # Constrain Zoog to window - @x = constrain @x, 0, width - @y = constrain @y, 0, height - end + # The code for changing the variables associated with Zoog and + # displaying Zoog is moved outside of draw and into methods + # called here. The methods are given arguments, such as + # "Jiggle Zoog by the following factor" and "draw Zoog with + # the following eye color". + jiggle_zoog factor - def draw_zoog eye_color - # Arms are incorporated into Zoog's design with a times loop. - 6.times do |i| - y = i * 10 + @y + 5 - line @x-@w/3, y, @x+@w/3, y - end - - # Draw Zoog's body - fill 175 - rect @x, @y, @w/6, @h*2 - - # Draw Zoog's head - fill 255 - ellipse @x, @y-@h/2, @w, @h + # pass in a color to the draw_zoog function for eye color + d = dist(@x, @y, mouse_x, mouse_y) + c = color(d) + draw_zoog c +end - # Draw Zoog's eyes - fill eye_color - ellipse @x-@w/3+1, @y-@h/2, @eye_size, @eye_size*2 - ellipse @x+@w/3-1, @y-@h/2, @eye_size, @eye_size*2 +def jiggle_zoog(speed) + # Change the x and y location of Zoog randomly + @x = @x + rand(-1.0 .. 1) * speed + @y = @y + rand(-1.0 .. 1) * speed + # Constrain Zoog to window + @x = constrain @x, 0, width + @y = constrain @y, 0, height +end - # Draw Zoog's legs - line @x-@w/12, @y+@h, @x-@w/4, @y+@h+10 - line @x+@w/12, @y+@h, @x+@w/4, @y+@h+10 +def draw_zoog(eye_color) + # Arms are incorporated into Zoog's design with a times loop. + 6.times do |i| + y = i * 10 + @y + 5 + line @x - @w / 3, y, @x + @w / 3, y end + # Draw Zoog's body + fill 175 + rect @x, @y, @w/6, @h*2 + + # Draw Zoog's head + fill 255 + ellipse @x, @y - @h / 2, @w, @h + + # Draw Zoog's eyes + fill eye_color + ellipse @x-@w / 3 + 1, @y - @h / 2, @eye_size, @eye_size * 2 + ellipse @x+@w / 3 - 1, @y - @h / 2, @eye_size, @eye_size * 2 + + # Draw Zoog's legs + line @x - @w / 12, @y + @h, @x - @w / 4, @y + @h + 10 + line @x + @w / 12, @y + @h, @x+@w / 4, @y + @h + 10 end -ZoogWithFunctions.new :title => "Zoog With Functions", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_07/Rakefile b/chapter_07/Rakefile new file mode 100644 index 0000000..254cf8f --- /dev/null +++ b/chapter_07/Rakefile @@ -0,0 +1,30 @@ +# Simple demo Rakefile to autorun samples in current directory +# adjust path to rp5 executable, and or opts as required + +SAMPLES_DIR="./" + +desc 'run demo' +task :default => [:demo] + +desc 'demo' +task :demo do + samples_list.shuffle.each{|sample| run_sample sample} +end + +def samples_list + files = [] + Dir.chdir(SAMPLES_DIR) + Dir.glob("*.rb").each do |file| + files << File.join(SAMPLES_DIR, file) + end + return files +end + +def run_sample(sample_name) + puts "Running #{sample_name}...quit to run next sample" + open("|rp5 run #{sample_name}", "r") do |io| + while l = io.gets + puts(l.chop) + end + end +end diff --git a/chapter_08/01_car_class_and_car_variable.rb b/chapter_08/01_car_class_and_car_variable.rb index b103395..b531951 100644 --- a/chapter_08/01_car_class_and_car_variable.rb +++ b/chapter_08/01_car_class_and_car_variable.rb @@ -1,45 +1,60 @@ -require 'ruby-processing' +# Introducing the Processing::Proxy module +# Here we mixin this module, to provide access to sketch methods/variables +# within the Car class (similar to vanilla processings inner class access) +# except width and height variables are deliberately excluded -class CarClassAndCarVariable < Processing::App +# require 'car' - def setup - # Initialize a car object - @my_car = Car.new(self) - rect_mode CENTER - end + +def setup + size 200, 200 + # Initialize a car object + @my_car = Car.new + rect_mode CENTER +end + +def draw + background 255 - def draw - background 255 - - # Operate the car object in draw - # by calling object methods using the dots syntax. - @my_car.move - @my_car.display_car - end - + # Operate the car object in draw + # by calling object methods using the dots syntax. + @my_car.move + @my_car.display_car end + + -class Car # Define a class below the rest of the program. +# Define a class below the rest of the program. +# Or in another file eg car.rb then use require 'car' to include in the sketch +# +# 'include Processing::Proxy' makes methods and variables available +# to the Car (similar to processings java inner class) except that +# width and height are excluded, hence global $app is reqd to access them - def initialize(app) - @app = app - @c = @app.color 175 - @xpos = @app.width/2 - @ypos = @app.height/2 +class Car + include Processing::Proxy + + attr_reader :width, :height + + def initialize + @width, @height = $app.width, $app.height + @c = color 175 + @xpos = width / 2 + @ypos = height / 2 @xspeed = 1 end def display_car # A new function of class Car - @app.stroke 0 - @app.fill @c - @app.rect @xpos, @ypos, 20, 10 + stroke 0 + fill @c + rect @xpos, @ypos, 20, 10 end def move @xpos = @xpos + @xspeed - @xpos = 0 if @xpos > @app.width + @xpos = 0 if @xpos > width end end -CarClassAndCarVariable.new :title => "Car Class And Car Variable", :width => 200, :height => 200 + diff --git a/chapter_08/02_two_car_objects.rb b/chapter_08/02_two_car_objects.rb index 03db3b7..00a86d7 100644 --- a/chapter_08/02_two_car_objects.rb +++ b/chapter_08/02_two_car_objects.rb @@ -1,60 +1,69 @@ -require 'ruby-processing' - -class TwoCarObjects < Processing::App - load_library :control_panel - - def setup - control_panel do |c| - c.slider :red_car_speed, -5..15 - c.slider :blue_car_speed, -5..15 - end - - # Initialize car objects - @red_car = Car.new(self, color(255,0,0), 0, 100) - @blue_car = Car.new(self, color(0,0,255), 0, 10) - @red_car_speed = 1 - @blue_car_speed = 2 - rect_mode CENTER +# Introducing the ruby-processing control panel + +load_library :control_panel +attr_reader :panel, :hide + +def setup + size 200, 200 + @hide = false + control_panel do |c| + c.look_feel "Metal" + c.slider :red_car_speed, -5..15 + c.slider :blue_car_speed, -5..15 + @panel = c end - def draw - background 255 - - # Operate the car object in draw - # by calling object methods using the dots syntax. - @red_car.move(@red_car_speed) - @red_car.display_car - @blue_car.move(@blue_car_speed) - @blue_car.display_car + # Initialize car objects + @red_car = Car.new(color(255,0,0), 0, 100) + @blue_car = Car.new(color(0,0,255), 0, 10) + @red_car_speed = 1 + @blue_car_speed = 2 + rect_mode CENTER +end + +def draw + if !hide # only set once + panel.visible = true + @hide = true end - + + background 255 + + # Operate the car object in draw + # by calling object methods using the dots syntax. + @red_car.move(@red_car_speed) + @red_car.display_car + @blue_car.move(@blue_car_speed) + @blue_car.display_car end + class Car # Define a class below the rest of the program. - attr_accessor :temp_color, :temp_x_position, :temp_y_position, :temp_x_speed + include Processing::Proxy + + attr_accessor :width, :temp_color, :temp_x_position, :temp_y_position, :temp_x_speed LENGTH = 20 - HEIGHT = 10 + CHEIGHT = 10 - def initialize(app, temp_color, temp_x_position, temp_y_position) - @app = app + def initialize(temp_color, temp_x_position, temp_y_position) + @width = $app.width @c = temp_color @xpos = temp_x_position @ypos = temp_y_position end def display_car # A new function of class Car - @app.stroke 0 - @app.fill @c - @app.rect @xpos, @ypos, LENGTH, HEIGHT + stroke 0 + fill @c + rect @xpos, @ypos, LENGTH, CHEIGHT end def move(speed) @xpos += speed - @xpos = 0 if @xpos > @app.width + LENGTH/2 - @xpos = @app.width if @xpos < -LENGTH/2 + @xpos = 0 if @xpos > width + LENGTH/2 + @xpos = width if @xpos < -LENGTH/2 end end -TwoCarObjects.new :title => "Car Class And Car Variable", :width => 200, :height => 200 diff --git a/chapter_08/03_object_oriented_zoog.rb b/chapter_08/03_object_oriented_zoog.rb index 21fdff9..8047b8a 100644 --- a/chapter_08/03_object_oriented_zoog.rb +++ b/chapter_08/03_object_oriented_zoog.rb @@ -1,81 +1,35 @@ -require 'ruby-processing' +require 'zoog' # zoog class is defined in zoog.rb -class ObjectOrientedZoog < Processing::App - load_library "control_panel" +load_library :control_panel +attr_reader :panel, :hide - def setup - smooth - control_panel do |c| - c.slider :zoog_jiggle_factor, 0..width/10 - end - - # Initalize zoog - @zoog = Zoog.new(self, 100, 125, 60, 60, 16) - @zoog_jiggle_factor = 10 - - rect_mode CENTER - ellipse_mode CENTER +def setup + size 200, 200 + smooth 4 + control_panel do |c| + c.look_feel "Metal" + c.slider :zoog_jiggle_factor, 0..width / 10, 5.0 + @panel = c end - def draw - background 255 - - # mouse_x position determines speed factor - # factor = constrain(mouse_x/10, 0, 5) - - @zoog.jiggle(@zoog_jiggle_factor) - @zoog.display - end + # Initalize zoog + @zoog = Zoog.new(100, 125, 60, 60, 16) + + rect_mode CENTER + ellipse_mode CENTER end -class Zoog - attr_accessor :temp_x_position, :temp_y_position, :temp_width, :temp_height, :temp_eye_size - - def initialize(app, temp_x_position, temp_y_position, temp_zoog_width, temp_zoog_height, temp_eye_size) - @app = app - @x, @y = temp_x_position, temp_y_position - @w, @h = temp_zoog_width, temp_zoog_height - @eye_size = temp_eye_size +def draw + if !hide # only set once + panel.visible = true + @hide = true end + background 255 - # Move zoog - def jiggle(speed) - @x = @x + speed * @app.random(-1,1) - @y = @y + speed * @app.random(-1,1) - - @x = @app.constrain(@x, 0, @app.width) - @y = @app.constrain(@y, 0, @app.height) - end + # mouse_x position determines speed factor + # factor = constrain(mouse_x / 10, 0, 5) - def display - # Draw zoog's arms - (@y - @h/3).step((@y + @h/2), 10) do |i| - @app.stroke 0 - @app.line @x-@w/4, i, @x+@w/4, i - end - - # Draw zoog's body - @app.stroke 0 - @app.fill 255 - @app.rect @x, @y, @w/6, @h - - # Draw zoog's head - @app.stroke 0 - @app.fill 255 - @app.ellipse @x, @y-@h, @w, @h - - # Draw zoog's eyes - @app.fill 0 - @app.ellipse @x-@w/3, @y-@h, @eye_size, @eye_size*2 - @app.ellipse @x+@w/3, @y-@h, @eye_size, @eye_size*2 - - # Draw zoog's legs - @app.stroke 0 - @app.line @x-@w/12, @y+@h/2, @x-@w/4, @y+@h/2+10 - @app.line @x+@w/12, @y+@h/2, @x+@w/4, @y+@h/2+10 - end - -end - -ObjectOrientedZoog.new :title => "Object Oriented Zoog", :width => 200, :height => 200 \ No newline at end of file + @zoog.jiggle(@zoog_jiggle_factor) + @zoog.display +end \ No newline at end of file diff --git a/chapter_08/zoog.rb b/chapter_08/zoog.rb new file mode 100644 index 0000000..889695b --- /dev/null +++ b/chapter_08/zoog.rb @@ -0,0 +1,51 @@ +class Zoog + include Processing::Proxy + attr_accessor :width, :height + attr_accessor :temp_x_position, :temp_y_position, :temp_width, :temp_height, :temp_eye_size + + def initialize(temp_x_position, temp_y_position, temp_zoog_width, temp_zoog_height, temp_eye_size) + @width, @height = $app.width, $app.height + @x, @y = temp_x_position, temp_y_position + @w, @h = temp_zoog_width, temp_zoog_height + @eye_size = temp_eye_size + end + + # Move zoog + def jiggle(speed) + @x = @x + speed * rand(-1.0 .. 1) + @y = @y + speed * rand(-1.0 .. 1) + + @x = constrain(@x, 0, width) + @y = constrain(@y, 0, height) + end + + def display + # Draw zoog's arms + (@y - @h/3).step((@y + @h/2), 10) do |i| + stroke 0 + line @x-@w/4, i, @x+@w/4, i + end + + # Draw zoog's body + stroke 0 + fill 255 + rect @x, @y, @w/6, @h + + # Draw zoog's head + stroke 0 + fill 255 + ellipse @x, @y-@h, @w, @h + + # Draw zoog's eyes + fill 0 + ellipse @x-@w/3, @y-@h, @eye_size, @eye_size*2 + ellipse @x+@w/3, @y-@h, @eye_size, @eye_size*2 + + # Draw zoog's legs + stroke 0 + line @x-@w/12, @y+@h/2, @x-@w/4, @y+@h/2+10 + line @x+@w/12, @y+@h/2, @x+@w/4, @y+@h/2+10 + end + +end + diff --git a/chapter_10/01_catcher.rb b/chapter_10/01_catcher.rb index 97ae2b9..478222d 100644 --- a/chapter_10/01_catcher.rb +++ b/chapter_10/01_catcher.rb @@ -1,35 +1,34 @@ -require 'ruby-processing' -class CatcherSketch < Processing::App - def setup - @catcher = Catcher.new(32) - smooth - end - - def draw - background 255 - @catcher.set_location mouse_x, mouse_y - @catcher.display - end +def setup + size 400, 400 + @catcher = Catcher.new(32) + smooth 4 end +def draw + background 255 + @catcher.set_location + @catcher.display +end + + class Catcher + include Processing::Proxy + def initialize(temp_r) @r = temp_r @x, @y = 0, 0 end - def set_location(temp_x, temp_y) - @x, @y = temp_x, temp_y + def set_location + @x, @y = mouse_x, mouse_y end - # In Ruby-Processing, you can always find the sketch in $app. def display - $app.stroke 0 - $app.fill 175 - $app.ellipse @x, @y, @r*2, @r*2 + stroke 0 + fill 175 + ellipse @x, @y, @r*2, @r*2 end end -CatcherSketch.new :title => "CatcherSketch", :width => 400, :height => 400 \ No newline at end of file diff --git a/chapter_10/02_bouncing_ball.rb b/chapter_10/02_bouncing_ball.rb index 493f13a..95d87e1 100644 --- a/chapter_10/02_bouncing_ball.rb +++ b/chapter_10/02_bouncing_ball.rb @@ -1,28 +1,30 @@ -require 'ruby-processing' -class BouncingBallSketch < Processing::App - def setup - smooth - - # Create two balls. - @ball_1, @ball_2 = Ball.new(64), Ball.new(32) - end - - def draw - background 255 - @ball_1.move - @ball_2.move - @ball_1.display - @ball_2.display - end +def setup + size 400, 400 + smooth 4 + # Create two balls, one with a default radius, one with a hash argument + @ball_1, @ball_2 = Ball.new(radius: 64), Ball.new +end + +def draw + background 255 + @ball_1.move + @ball_2.move + @ball_1.display + @ball_2.display end + class Ball - def initialize(temp_r) - @r = temp_r - @x, @y = rand($app.width), rand($app.height) - @x_speed, @y_speed = (rand * 10 - 5), (rand * 10 - 5) + include Processing::Proxy + attr_reader :width, :height, :r + + def initialize(radius: 32) # a hash argument with a default value + @width, @height = $app.width, $app.height + @r = radius + @x, @y = rand(r .. width - r), rand(r .. height - r) + @x_speed, @y_speed = rand(-5.0 .. 5), rand(-5.0 .. 5) end def move @@ -30,15 +32,14 @@ def move @y += @y_speed # Move the ball vertically # Check for the edges of the sketch - @x_speed *= -1 unless (0..$app.width).include?(@x) - @y_speed *= -1 unless (0..$app.height).include?(@y) + @x_speed *= -1 unless (r ... width - r).include?(@x) + @y_speed *= -1 unless (r ... height - r).include?(@y) end def display - $app.stroke 0 - $app.fill 0, 50 - $app.ellipse @x, @y, @r*2, @r*2 + stroke 0 + fill 0, 50 + ellipse @x, @y, @r*2, @r*2 end end -BouncingBallSketch.new :title => "Bouncing Ball", :width => 400, :height => 400 \ No newline at end of file diff --git a/chapter_10/03_bouncing_balls_with_intersection.rb b/chapter_10/03_bouncing_balls_with_intersection.rb index 3d15829..6b9164a 100644 --- a/chapter_10/03_bouncing_balls_with_intersection.rb +++ b/chapter_10/03_bouncing_balls_with_intersection.rb @@ -1,69 +1,69 @@ -require 'ruby-processing' -class BouncingBallsWithIntersection < Processing::App - def setup - smooth - # Create two balls. - @ball_1, @ball_2 = Ball.new(64), Ball.new(32) - end +def setup + size 400, 400 + smooth 4 + # Create two balls, one with the default radius. + @ball_1, @ball_2 = Ball.new(radius: 64), Ball.new +end + +def draw + background 255 + @ball_1.move + @ball_2.move - def draw - background 255 - @ball_1.move - @ball_2.move - - # New! Methods on objects that you define can take each other as arguments. - # This is one way to have objects communicate. - # In this case they're checking to see if they intersect. - if @ball_1.intersect(@ball_2) - @ball_1.highlight - @ball_2.highlight - end - - @ball_1.display - @ball_2.display + # New! Methods on objects that you define can take each other as arguments. + # This is one way to have objects communicate. + # In this case they're checking to see if they intersect. + if @ball_1.intersect(@ball_2) + @ball_1.highlight + @ball_2.highlight end + + @ball_1.display + @ball_2.display end + class Ball + include Processing::Proxy # We use attr_reader to make the @x, @y and @r instance variables readable by other objects. - attr_reader :x, :y, :r + attr_reader :x, :y, :r, :width, :height, :x_speed, :y_speed - def initialize(temp_r) - @r = temp_r - @x, @y = rand($app.width), rand($app.height) - @x_speed, @y_speed = (rand * 10 - 5), (rand * 10 - 5) - @color = $app.color(100, 50) + def initialize(radius: 32) # a hash parameter for constructor + @width, @height = $app.width, $app.height + @r = radius + @x, @y = rand(r .. width - r), rand(r .. height - r) + @x_speed, @y_speed = rand(-5.0 .. 5), rand(-5.0 .. 5) + @color = color(100, 50) end def move - @x += @x_speed # Move the ball horizontally - @y += @y_speed # Move the ball vertically - - @x_speed *= -1 unless (0..$app.width).include?(@x) - @y_speed *= -1 unless (0..$app.height).include?(@y) + @x += x_speed # Move the ball horizontally + @y += y_speed # Move the ball vertically + # boundary check + @x_speed *= -1 unless (r .. width - r).include?(@x) + @y_speed *= -1 unless (r .. height - r).include?(@y) end def highlight - @color = $app.color(0, 150) + @color = color(0, 150) end def display - $app.stroke 0 - $app.fill @color - $app.ellipse @x, @y, @r*2, @r*2 + stroke 0 + fill @color + ellipse @x, @y, @r*2, @r*2 # After the ball is displayed, the color is reset back to a dark gray. - @color = $app.color(100, 50) + @color = color(100, 50) end # A function that returns true or false based on whether or not two circles intersect. # If distance is less than the sum of the radii, the circles touch. # Objects that you define can be passed as arguments too! def intersect(other_ball) - distance = $app.dist(@x, @y, other_ball.x, other_ball.y) + distance = dist(@x, @y, other_ball.x, other_ball.y) distance < @r + other_ball.r end end -BouncingBallsWithIntersection.new :title => "Bouncing Balls with Intersection", :width => 400, :height => 400 \ No newline at end of file diff --git a/chapter_10/04_a_timer.rb b/chapter_10/04_a_timer.rb index bd8f204..ce7b2df 100644 --- a/chapter_10/04_a_timer.rb +++ b/chapter_10/04_a_timer.rb @@ -1,24 +1,19 @@ -require 'ruby-processing' -class Timer < Processing::App - def setup - background 0 - @total_time = 5000 - @saved_time = millis - end - - def draw - passed_time = millis - @saved_time - # Has 5 seconds passed? - if passed_time > @total_time - puts "5 seconds have passed!" - # Color a new background, and let's give it some color. - background rand(255), rand(255), rand(255) - @saved_time = millis # Save the current time to restart the timer! - end - end - +def setup + size 200, 200 + background 0 + @total_time = 5000 + @saved_time = millis end -Timer.new :title => "04 A Timer", :width => 200, :height => 200 \ No newline at end of file +def draw + passed_time = millis - @saved_time + # Has 5 seconds passed? + if passed_time > @total_time + puts "5 seconds have elapsed!" + # Color a new background, and let's give it some color. + background rand(255), rand(255), rand(255) + @saved_time = millis # Save the current time to restart the timer! + end +end diff --git a/chapter_10/05_object_oriented_timer.rb b/chapter_10/05_object_oriented_timer.rb index 5910986..4565ffa 100644 --- a/chapter_10/05_object_oriented_timer.rb +++ b/chapter_10/05_object_oriented_timer.rb @@ -1,23 +1,19 @@ -require 'ruby-processing' -class ObjectOrientedTimer < Processing::App - def setup - background 0 - @timer = Timer.new(5000) +def setup + size 200, 200 + background 0 + @timer = Timer.new(5000) + @timer.start +end + +def draw + if @timer.finished? + background rand(255) @timer.start end - - def draw - if @timer.is_finished? - background rand(255) - @timer.start - end - end - end - class Timer def initialize(total_time) @saved_time = nil # When it started @@ -26,17 +22,15 @@ def initialize(total_time) # When the timer starts it stores the current time in milliseconds def start - @saved_time = $app.millis + @saved_time = millis end - # The method is_finished? returns true if 5 seconds have passed. + # The method finished? returns true if 5 seconds have passed. # Most of the work of the timer is farmed out to this method. - def is_finished? - passed_time = $app.millis - @saved_time + def finished? + passed_time = millis - @saved_time passed_time > @total_time end end - -ObjectOrientedTimer.new :title => "Object Oriented Timer", :width => 200, :height => 200 \ No newline at end of file diff --git a/chapter_10/06_simple_raindrop.rb b/chapter_10/06_simple_raindrop.rb index 9f413f3..0097053 100644 --- a/chapter_10/06_simple_raindrop.rb +++ b/chapter_10/06_simple_raindrop.rb @@ -1,23 +1,18 @@ -require 'ruby-processing' -class SimpleRaindrop < Processing::App - def setup - background 0 - @x, @y = width / 2, 0 - smooth - no_stroke - end - - def draw - background 255 - # Show the drop - fill 50, 100, 150 - ellipse @x, @y, 16, 16 - # Move the drop - @y += 1 - end - +def setup + size 200, 200 + background 0 + @x, @y = width / 2, 0 + smooth + no_stroke end -SimpleRaindrop.new :title => "Simple Raindrop", :width => 400, :height => 400 \ No newline at end of file +def draw + background 255 + # Show the drop + fill 50, 100, 150 + ellipse @x, @y, 16, 16 + # Move the drop + @y += 1 +end diff --git a/chapter_10/07_drops_one_at_a_time.rb b/chapter_10/07_drops_one_at_a_time.rb index 74a4670..2a4cde0 100644 --- a/chapter_10/07_drops_one_at_a_time.rb +++ b/chapter_10/07_drops_one_at_a_time.rb @@ -1,56 +1,60 @@ -require 'ruby-processing' +attr_reader :drops, :max_drops -class DropsOneAtATime < Processing::App +def setup + size 400, 400 + @max_drops = 1000 # The most drops we're going to have at once. + @drops = [] # An array to hold the drops + no_stroke + smooth 4 +end - def setup - @max_drops = 1000 # The most drops we're going to have at once. - @drops = [] # An array to hold the drops - no_stroke - smooth - end +def draw + background 255 + drops << Drop.new # Create one drop + # Start over when we have too many. + drops.clear if drops.size > max_drops - def draw - background 255 - @drops << Drop.new # Create one drop - # Start over when we have too many. - @drops = [] if @drops.size > @max_drops - - # Move and display all the drops. - # New! We no longer move and display all the drops, but rather, - # only the ones that are still present in the @drops array. - @drops.each do |drop| - drop.move - drop.display - end + # Move and display all the drops. + # New! We no longer move and display all the drops, but rather, + # only the ones that are still present in the @drops array. + drops.each do |drop| + drop.move + drop.display end - end + class Drop + include Processing::Proxy + + attr_reader :width, :height, :speed + def initialize + @width, @height = $app.width, $app.height @r = 8 # All raindrops are the same size - @x = rand($app.width) # Start with a random x location + @x = rand(width) # Start with a random x location @y = -@r * 4 # Start a little above the window - @speed = rand * 4 + 1 # Pick a random speed - @color = $app.color(50, 100, 150) + @speed = rand(1 .. 4.0) + # Pick a random speed + @color = color(50, 100, 150) end # Move the raindrop down def move - @y += @speed # Increment y by speed + @y += speed # Increment y by speed end # Check to see if it hit the bottom def reached_bottom? - @y > $app.height + @r*4 # If we go a little beyond the bottom + @y > height + @r*4 # If we go a little beyond the bottom end # Display the raindrop def display - $app.fill @color + fill @color # For each number between 2 and the radius, draw an ellipse. - (2...@r).each { |i| $app.ellipse(@x, @y+i*4, i*2, i*2) } + (2...@r).each { |i| ellipse(@x, @y+i*4, i*2, i*2) } end # If the drop is caught @@ -60,4 +64,3 @@ def caught end end -DropsOneAtATime.new :title => "Drops One At A Time", :width => 400, :height => 400 \ No newline at end of file diff --git a/chapter_10/Rakefile b/chapter_10/Rakefile new file mode 100644 index 0000000..254cf8f --- /dev/null +++ b/chapter_10/Rakefile @@ -0,0 +1,30 @@ +# Simple demo Rakefile to autorun samples in current directory +# adjust path to rp5 executable, and or opts as required + +SAMPLES_DIR="./" + +desc 'run demo' +task :default => [:demo] + +desc 'demo' +task :demo do + samples_list.shuffle.each{|sample| run_sample sample} +end + +def samples_list + files = [] + Dir.chdir(SAMPLES_DIR) + Dir.glob("*.rb").each do |file| + files << File.join(SAMPLES_DIR, file) + end + return files +end + +def run_sample(sample_name) + puts "Running #{sample_name}...quit to run next sample" + open("|rp5 run #{sample_name}", "r") do |io| + while l = io.gets + puts(l.chop) + end + end +end diff --git a/chapter_13/02_random_number_distribution.rb b/chapter_13/02_random_number_distribution.rb index 54f157d..bb8a5a7 100644 --- a/chapter_13/02_random_number_distribution.rb +++ b/chapter_13/02_random_number_distribution.rb @@ -1,24 +1,22 @@ -require 'ruby-processing' +attr_reader :sz -class RandomNumberDistributionSketch < Processing::App - def setup - # An array to keep track of how often numbers are picked. - @random_counts = Array.new(20, 0) - end +def setup + size 200, 200 + # An array to keep track of how often numbers are picked. + @sz = 20 + @random_counts = Array.new(20, 0) +end - def draw - size = @random_counts.size - # Pick a random number and increase the count. - @random_counts[rand(size)] += 1 - background 255 - stroke 0 - fill 175 - # Draw a rectangle to graph results - @random_counts.each_with_index do |count, i| - rect i * width/size, 0, (width/size)-1, count - end +def draw + # Pick a random number and increase the count. + @random_counts[rand(0 ... sz)] += 1 + background 255 + stroke 0 + fill 175 + # Draw a rectangle to graph results + @random_counts.each_with_index do |count, i| + rect i * width / sz, height - count, (width / sz) - 1, height end - end -RandomNumberDistributionSketch.new :title => "Random Number Distribution", :width => 200, :height => 200 + diff --git a/chapter_13/03_probabilities.rb b/chapter_13/03_probabilities.rb index eff182a..115536a 100644 --- a/chapter_13/03_probabilities.rb +++ b/chapter_13/03_probabilities.rb @@ -1,33 +1,31 @@ -require 'ruby-processing' -class ProbabilitiesSketch < Processing::App - def setup - background 255 - smooth - no_stroke - end - - def draw - # Probabilities for 3 different cases - # These need to add up to 100%! - red_prob = 0.60 # 60% chance of red color - green_prob = 0.70 # 10% chance of green color - blue_prob = 1.00 # 30% chance of blue color - - # Pick a random number between 0 and 1 - num = rand - - case num - when (0.0..red_prob): fill(255, 53, 2, 150) - when (red_prob..green_prob): fill(156, 255, 28, 150) - when (green_prob..blue_prob): fill(10, 52, 178, 150) - end +def setup + size 400, 400 + background 255 + smooth 4 + no_stroke +end - # Draw ellipse - ellipse rand(width), rand(height), 64, 64 +def draw + # Probabilities for 3 different cases + red_prob = 0.60 # 60% chance of red color + green_prob = 0.70 # 10% chance of green color + blue_prob = 1.00 # 30% chance of blue color + + # Pick a random number between 0 and 1 + num = rand + # with ruby we can switch on a range + case num + when (0.0..red_prob) + fill(255, 53, 2, 150) + when (red_prob..green_prob) + fill(156, 255, 28, 150) + when (green_prob..blue_prob) + fill(10, 52, 178, 150) end + # Draw ellipse + ellipse rand(width), rand(height), 64, 64 end -ProbabilitiesSketch.new :title => "Probabilities", :width => 400, :height => 400 diff --git a/chapter_13/04_perlin_noise.rb b/chapter_13/04_perlin_noise.rb index c873e6c..54a3a94 100644 --- a/chapter_13/04_perlin_noise.rb +++ b/chapter_13/04_perlin_noise.rb @@ -1,22 +1,17 @@ -require 'ruby-processing' -class PerlinNoiseSketch < Processing::App - def setup - smooth - @time = 0.0 - @increment = 0.01 - end - - def draw - background 255 +def setup + size 200, 200 + smooth 4 + @time = 0.0 + @increment = 0.01 +end - n = noise(@time) * width - @time += @increment - fill 0 - ellipse width/2, height/2, n, n - end +def draw + background 255 + n = noise(@time) * width + @time += @increment + fill 0 + ellipse width / 2, height / 2, n, n end - -PerlinNoiseSketch.new :title => "Perlin Noise", :width => 400, :height => 400 diff --git a/chapter_13/06_oscillation.rb b/chapter_13/06_oscillation.rb index eb7a7a1..957934c 100644 --- a/chapter_13/06_oscillation.rb +++ b/chapter_13/06_oscillation.rb @@ -1,29 +1,21 @@ -require 'ruby-processing' - -class OscillationSketch < Processing::App - - def setup - @theta = 0.0 - smooth - end - - def draw - background 255 - # The output of the sin() function oscillates smoothly between 1 and 1. - # By adding 1 we get values between 0 and 2. - # By multiplying by 100, we get values between 0 and 200 which can be used as the ellipse's x location. - x = (sin(@theta) + 1) * width/2 - - # with each cycle, increment theta - @theta += 0.05 - fill 0 - stroke 0 - - # draw the ellipse at the value produce by the sin - line width/2, 0, x, height/2 - ellipse x, height/2, 16, 16 - end +# Get to grips with ruby lambda, then write more functional code when it makes sense +def setup + size 200, 200 + # The output of the sin() function oscillates smoothly between -1 and 1. + # By adding 1 we get values between 0 and 2. + # By multiplying by width / 2, we get values between 0 and width, + # that can be used as the ellipse's x location. + + @sine = ->(angle){(sin(angle) + 1) * width / 2} + fill 0 + stroke 0 end -OscillationSketch.new :title => "Oscillation", :width => 200, :height => 200 +def draw + background 255 + x = @sine.call(frame_count * 0.05) + # draw the ellipse at the value produce by the sin + line width / 2, 0, x, height / 2 + ellipse x, height / 2, 16, 16 +end diff --git a/chapter_13/07_wave.rb b/chapter_13/07_wave.rb index 3ece9c2..c56c139 100644 --- a/chapter_13/07_wave.rb +++ b/chapter_13/07_wave.rb @@ -1,31 +1,22 @@ -require 'ruby-processing' +# demonstrate use of lamba and possibility of a more functional style +# of programming available to ruby users (cf vanilla processing) -class WaveSketch < Processing::App - - def setup - @theta = 0 - smooth - end - - def draw - background 255 - # Increment theta (try different values for " angular velocity " here) - @theta += 0.02 - no_stroke - fill 0 - x = @theta +def setup + size 200, 200 + @sine = ->(angle, offset){sin(angle + offset) * height / 2} + smooth 4 +end - # times is used to draw all the points along a sine wave (scaled to the pixel dimension of the window). - 20.times do |i| - # Calculate y value based off of sine function - y = sin(x) * height/2 - # Draw an ellipse - ellipse i*10, y+height/2, 16, 16 - # Move along x-axis - x += 0.2 - end +def draw + background 255 + # Increment theta (try different values for " angular velocity " here) + no_stroke + fill 0 + # times is used to draw all the points along a sine wave (scaled to the pixel dimension of the window). + 20.times do |i| + # Calculate y value based off of sine function + + # Draw an ellipse + ellipse(i * 10, @sine.call(i * 0.2, frame_count * 0.02) + height/2, 16, 16) end - end - -WaveSketch.new :title => "Oscillation", :width => 200, :height => 200 diff --git a/chapter_13/08_recursion.rb b/chapter_13/08_recursion.rb index 1e19cbd..a299d06 100644 --- a/chapter_13/08_recursion.rb +++ b/chapter_13/08_recursion.rb @@ -1,30 +1,27 @@ -require 'ruby-processing' -class RecursionSketch < Processing::App - def setup - smooth - end - - def draw - background 255 - stroke 0 - no_fill +def setup + size 200, 200 + smooth 4 +end - draw_circle width/2, height/2, width/2 - end +def draw + background 255 + stroke 0 + no_fill - def draw_circle(x, y, radius) - ellipse x, y, radius, radius - # It's important to establish an end-point to recursion, or else it - # would go forever. Comment out the following line to break the sketch. - return if radius < 2 - # draw_circle calls itself twice, creating a branching effect. - # For every circle, a smaller circle is drawn to the left and right. - draw_circle x+radius/2, y, radius/2 - draw_circle x-radius/2, y, radius/2 - end + draw_circle width/2, height/2, width/2 +end +def draw_circle(x, y, radius) + ellipse x, y, radius, radius + # It's important to establish an end-point to recursion, or else it + # would go forever. Comment out the following line to break the sketch. + return if radius < 2.0 + # draw_circle calls itself twice, creating a branching effect. + # For every circle, a smaller circle is drawn to the left and right. + draw_circle x + radius / 2, y, radius / 2.0 + draw_circle x - radius / 2, y, radius / 2.0 end -RecursionSketch.new :title => "Recursion", :width => 200, :height => 200 + diff --git a/chapter_13/09_two_dimensional_array.rb b/chapter_13/09_two_dimensional_array.rb index d6e9689..db39956 100644 --- a/chapter_13/09_two_dimensional_array.rb +++ b/chapter_13/09_two_dimensional_array.rb @@ -1,21 +1,16 @@ -require 'ruby-processing' -class TwoDimensionalArraySketch < Processing::App - - def setup - smooth - # initialize array with random values - @my_array = Array.new(width) { Array.new(height) { rand 255 }} - - # draw the points - width.times do |i| - height.times do |j| - stroke @my_array[i][j] - point i, j - end +def setup + size 200, 200 + no_smooth + # initialize array with random values + my_array = Array.new(width) { Array.new(height) { rand 255 }} + # render my_array + my_array.each_with_index do |row, i| + row.each_with_index do |cell, j| + stroke cell + point i, j end end - end -TwoDimensionalArraySketch.new :title => "Two Dimensional Array", :width => 200, :height => 200 + diff --git a/chapter_13/10_two_dimensional_array_with_objects.rb b/chapter_13/10_two_dimensional_array_with_objects.rb index 26ca7f3..e17d055 100644 --- a/chapter_13/10_two_dimensional_array_with_objects.rb +++ b/chapter_13/10_two_dimensional_array_with_objects.rb @@ -1,12 +1,15 @@ -require 'ruby-processing' +# Let's start by defining the cell class, we use Processing::Proxy mixin to +# access variable/methods of processing within Cell class (similar to vanilla +# processings inner class access) -# Let's start by defining the cell class. class Cell - - def initialize(x, y, w, h, angle) - @x, @y = x, y - @w, @h = w, h - @angle = angle + include Processing::Proxy + attr_reader :x, :y, :w, :h, :angle + + def initialize(x, y, sz) + @x, @y = x * sz, y * sz + @w, @h = sz, sz + @angle = x + y end # we oscillate by increasing the angle, here. @@ -15,10 +18,10 @@ def oscillate end def display - $app.stroke 255 + stroke 255 # calculate color using sine wave - $app.fill 127 + 127 * Math.sin(@angle) - $app.rect @x, @y, @w, @h + fill 127 + 127 * sin(angle) + rect x, y, w, h end def oscillate_and_display @@ -28,27 +31,19 @@ def oscillate_and_display end +def setup + size 200, 200 + no_smooth + sz = 20 -# And then the sketch that holds many cells. -class ArrayWithObjectsSketch < Processing::App - - def setup - smooth - @cols = @rows = 20 - - # initialize array with random values - @grid = Array.new(@cols) do |i| - Array.new(@rows) do |j| - Cell.new(i*20, j*20, 20, 20, i+j) - end - end - end - - def draw - background 0 - @grid.each { |array| array.each { |cell| cell.oscillate_and_display } } - end + # initialize array with random values + @grid = (0 .. sz).map{|i| (0 .. sz).map {|j| Cell.new(i, j, sz) } } + +end +def draw + background 0 + @grid.map { |array| array.map { |cell| cell.oscillate_and_display } } end -ArrayWithObjectsSketch.new :title => "Two Dimensional Array with Objects", :width => 200, :height => 200 + diff --git a/chapter_13/Rakefile b/chapter_13/Rakefile new file mode 100644 index 0000000..254cf8f --- /dev/null +++ b/chapter_13/Rakefile @@ -0,0 +1,30 @@ +# Simple demo Rakefile to autorun samples in current directory +# adjust path to rp5 executable, and or opts as required + +SAMPLES_DIR="./" + +desc 'run demo' +task :default => [:demo] + +desc 'demo' +task :demo do + samples_list.shuffle.each{|sample| run_sample sample} +end + +def samples_list + files = [] + Dir.chdir(SAMPLES_DIR) + Dir.glob("*.rb").each do |file| + files << File.join(SAMPLES_DIR, file) + end + return files +end + +def run_sample(sample_name) + puts "Running #{sample_name}...quit to run next sample" + open("|rp5 run #{sample_name}", "r") do |io| + while l = io.gets + puts(l.chop) + end + end +end diff --git a/chapter_14/01_growing_rectangle.rb b/chapter_14/01_growing_rectangle.rb index c2ac2db..b411e03 100644 --- a/chapter_14/01_growing_rectangle.rb +++ b/chapter_14/01_growing_rectangle.rb @@ -1,26 +1,24 @@ -require 'ruby-processing' -class GrowingRectangleSketch < Processing::App - def setup - rect_mode CENTER - @r = 8 - end - - def draw - background 255 - # Display a rectangle in the middle of the screen - stroke 0 - fill 175 - rect width/2, height/2, @r, @r +def setup + size 200, 200 + rect_mode CENTER + @r = 8 +end - # Increase the rectangle size - @r += 1 +def draw + size 200, 200 + background 255 + # Display a rectangle in the middle of the screen + stroke 0 + fill 175 + rect width/2, height/2, @r, @r - # Start rectangle over - @r = 0 if @r > width - end + # Increase the rectangle size + @r += 1 + # Start rectangle over + @r = 0 if @r > width end -GrowingRectangleSketch.new :title => "Growing Rectangle", :width => 200, :height => 200 + diff --git a/chapter_14/02_multiple_translations.rb b/chapter_14/02_multiple_translations.rb index 0b53c49..66c9366 100644 --- a/chapter_14/02_multiple_translations.rb +++ b/chapter_14/02_multiple_translations.rb @@ -1,37 +1,34 @@ -require 'ruby-processing' -class MultipleTranslationsSketch < Processing::App - def setup - smooth - end - - def draw - background 255 - stroke 0 - fill 175 +def setup + size 200, 200 + smooth 4 +end - # Grab mouse coordinates, constrained to window - mx = constrain(mouse_x, 0, width) - my = constrain(mouse_y, 0, height) +def draw + background 255 + stroke 0 + fill 175 - # Translate to the mouse location - translate mx, my - ellipse 0, 0, 8, 8 + # Grab mouse coordinates, constrained to window + mx = constrain(mouse_x, 0, width) + my = constrain(mouse_y, 0, height) - # Translate 100 pixels to the right - translate 100, 0 - ellipse 0, 0, 8, 8 + # Translate to the mouse location + translate mx, my + ellipse 0, 0, 8, 8 - # Translate 100 pixels down - translate 0, 100 - ellipse 0, 0, 8, 8 + # Translate 100 pixels to the right + translate 100, 0 + ellipse 0, 0, 8, 8 - # Translate 100 pixels left - translate -100, 0 - ellipse 0, 0, 8, 8 - end + # Translate 100 pixels down + translate 0, 100 + ellipse 0, 0, 8, 8 + # Translate 100 pixels left + translate -100, 0 + ellipse 0, 0, 8, 8 end -MultipleTranslationsSketch.new :title => "Multiple Translations", :width => 200, :height => 200 + diff --git a/chapter_14/03_depth_rectangle.rb b/chapter_14/03_depth_rectangle.rb index 4fec660..64da517 100644 --- a/chapter_14/03_depth_rectangle.rb +++ b/chapter_14/03_depth_rectangle.rb @@ -1,29 +1,26 @@ -require 'ruby-processing' -class DepthRectangleSketch < Processing::App - def setup - @z = 0 # A variable for the z (depth) coordinate - rect_mode CENTER - render_mode P3D - end - - def draw - background 255 - stroke 0 - fill 175 - - # Translate to a point before displaying a shape there - translate width/2, height/2, @z - rect 0, 0, 8, 8 +def setup + size 200, 200, P3D + @z = 0 # A variable for the z (depth) coordinate + rect_mode CENTER +end - # Increment z (i.e. move the shape toward the viewer) - @z += 1 +def draw + background 255 + stroke 0 + fill 175 + + # Translate to a point before displaying a shape there + translate width/2, height/2, @z + rect 0, 0, 8, 8 - # Start rectangle over - @z = 0 if @z > 200 - end + # Increment z (i.e. move the shape toward the viewer) + @z += 1 + # Start rectangle over + @z = 0 if @z > 200 end -DepthRectangleSketch.new :title => "Depth Rectangle", :width => 200, :height => 200 + + diff --git a/chapter_14/04_pyramid_using_beingshape.rb b/chapter_14/04_pyramid_using_beingshape.rb index d3f5827..4fa1f3a 100644 --- a/chapter_14/04_pyramid_using_beingshape.rb +++ b/chapter_14/04_pyramid_using_beingshape.rb @@ -1,55 +1,52 @@ -require 'ruby-processing' +load_library :vecmath -class PyramidUsingBeginshape < Processing::App - - def setup - render_mode P3D - end - - def draw - background 255 - stroke 0 - - # The pyramid's vertices are drawn relative to a centerpoint. - # Therefore, we call translate to place the pyramid properly in the window. - # A slightly better option might be to include the translate in the draw_pyramid function and pass in x,y,z as arguments - translate 100, 100, 0 - draw_pyramid 150 - end +def setup + size 200, 200, P3D + ArcBall.new(self) +end +def draw + background 255 + stroke 0 + lights + # The pyramid's vertices are drawn relative to a centerpoint. + # Therefore, we call translate to place the pyramid properly in the window. + # A slightly better option might be to include the translate in the draw_pyramid function and pass in x,y,z as arguments + #translate 100, 100, 0 + draw_pyramid 150 +end - # The function sets the vertices for the pyramid around the centerpoint at a flexible distance, - # depending on the number passed in as an argument. - def draw_pyramid(t) - # this pyramid has 4 sides, each drawn as a separate triangle - # each side has 3 vertices, making up a triangle shape - # the parameter " t " determines the size of the pyramid - begin_shape TRIANGLES - fill 255, 150 # Note that each polygon can have its own color. - vertex -t,-t,-t - vertex t,-t,-t - vertex 0, 0, t +# The function sets the vertices for the pyramid around the centerpoint at a flexible distance, +# depending on the number passed in as an argument. +def draw_pyramid(t) + # this pyramid has 4 sides, each drawn as a separate triangle + # each side has 3 vertices, making up a triangle shape + # the parameter " t " determines the size of the pyramid + begin_shape TRIANGLES - fill 150, 150 - vertex t,-t,-t - vertex t, t,-t - vertex 0, 0, t + fill 255, 150 # Note that each polygon can have its own color. + vertex -t,-t,-t + vertex t,-t,-t + vertex 0, 0, t - fill 255, 150 - vertex t, t,-t - vertex -t, t,-t - vertex 0, 0, t + fill 150, 150 + vertex t,-t,-t + vertex t, t,-t + vertex 0, 0, t - fill 150, 150 - vertex -t, t,-t - vertex -t,-t,-t - vertex 0, 0, t + fill 255, 150 + vertex t, t,-t + vertex -t, t,-t + vertex 0, 0, t - end_shape - end + fill 150, 150 + vertex -t, t,-t + vertex -t,-t,-t + vertex 0, 0, t + end_shape end -PyramidUsingBeginshape.new :title => "Draw Pyramid Using BeginShape", :width => 200, :height => 200 + diff --git a/chapter_14/05_rotate_rectangle_around_center.rb b/chapter_14/05_rotate_rectangle_around_center.rb index 9407e7b..62a6bb0 100644 --- a/chapter_14/05_rotate_rectangle_around_center.rb +++ b/chapter_14/05_rotate_rectangle_around_center.rb @@ -1,28 +1,24 @@ -require 'ruby-processing' -class RotateRectangleAroundCenterSketch < Processing::App - def setup - render_mode P3D - rect_mode CENTER - end - - def draw - background 255 - stroke 0 - fill 175 +def setup + size 200, 200 + rect_mode CENTER +end - # translate to center - translate width/2, height/2 - # The greek letter "theta" is often used as the name of a variable to store an angle - # The angle ranges from 0 to PI, based on the ratio of mouse_x location to the sketch's width. - theta = PI * mouse_x / width +def draw + background 255 + stroke 0 + fill 175 - rotate theta - rect 0, 0, 100, 100 - end + # translate to center + translate width/2, height/2 + # The greek letter "theta" is often used as the name of a variable to store an angle + # The angle ranges from 0 to PI, based on the ratio of mouse_x location to the sketch's width. + theta = PI * mouse_x / width + rotate theta + rect 0, 0, 100, 100 end -RotateRectangleAroundCenterSketch.new :title => "Rotate Rectangle Around Center", :width => 200, :height => 200 + diff --git a/chapter_14/06_rotate_z.rb b/chapter_14/06_rotate_z.rb index 66a4c92..960194c 100644 --- a/chapter_14/06_rotate_z.rb +++ b/chapter_14/06_rotate_z.rb @@ -1,24 +1,21 @@ -require 'ruby-processing' -class RotateZSketch < Processing::App - def setup - rect_mode CENTER - render_mode P3D - @theta = 0 - end - - def draw - background 255 - stroke 0 - fill 175 +def setup + size 200, 200, P3D + rect_mode CENTER + @theta = 0 +end - translate width/2, height/2 - rotate_z @theta - rect 0, 0, 100, 100 - @theta += 0.02 - end +def draw + background 255 + lights + stroke 0 + fill 175 + translate width/2, height/2 + rotate_z @theta + rect 0, 0, 100, 100 + @theta += 0.02 end -RotateZSketch.new :title => "Rotate Z", :width => 200, :height => 200 + diff --git a/chapter_14/07_rotate_x.rb b/chapter_14/07_rotate_x.rb index 0caabc9..593d68b 100644 --- a/chapter_14/07_rotate_x.rb +++ b/chapter_14/07_rotate_x.rb @@ -1,24 +1,20 @@ -require 'ruby-processing' -class RotateXSketch < Processing::App - def setup - render_mode P3D - rect_mode CENTER - @theta = 0 - end - - def draw - background 255 - stroke 0 - fill 175 +def setup + size 200, 200, P3D + rect_mode CENTER + @theta = 0 +end - translate width/2, height/2 - rotate_x @theta - rect 0, 0, 100, 100 - @theta += 0.02 - end +def draw + background 255 + stroke 0 + fill 175 + translate width / 2, height / 2 + rotate_x @theta + rect 0, 0, 100, 100 + @theta += 0.02 end -RotateXSketch.new :title => "Rotate X", :width => 200, :height => 200 + diff --git a/chapter_14/08_rotate_y.rb b/chapter_14/08_rotate_y.rb index 519e842..10ed5bf 100644 --- a/chapter_14/08_rotate_y.rb +++ b/chapter_14/08_rotate_y.rb @@ -1,24 +1,20 @@ -require 'ruby-processing' -class RotateYSketch < Processing::App - def setup - render_mode P3D - rect_mode CENTER - @theta = 0 - end - - def draw - background 255 - stroke 0 - fill 175 +def setup + size 200, 200, P3D + rect_mode CENTER + @theta = 0 +end - translate width/2, height/2 - rotate_y @theta - rect 0, 0, 100, 100 - @theta += 0.02 - end +def draw + background 255 + stroke 0 + fill 175 + translate width/2, height/2 + rotate_y @theta + rect 0, 0, 100, 100 + @theta += 0.02 end -RotateYSketch.new :title => "Rotate Y", :width => 200, :height => 200 + diff --git a/chapter_14/09_rotate_all.rb b/chapter_14/09_rotate_all.rb index 694ebf1..45bee6a 100644 --- a/chapter_14/09_rotate_all.rb +++ b/chapter_14/09_rotate_all.rb @@ -1,24 +1,21 @@ -require 'ruby-processing' -class RotateAllSketch < Processing::App - def setup - render_mode P3D - rect_mode CENTER - end - - def draw - background 255 - stroke 0 - fill 175 +def setup + size 200, 200, P3D + smooth 4 + rect_mode CENTER +end - translate width/2, height/2 - rotate_x PI * mouse_x / height - rotate_y PI * mouse_x / height - rect 0, 0, 100, 100 - end +def draw + background 255 + stroke 0 + fill 175 + translate width/2, height/2 + rotate_x PI * (height - mouse_y) / height + rotate_y PI * mouse_x / width + rect 0, 0, 100, 100 end -RotateAllSketch.new :title => "Rotate All", :width => 200, :height => 200 + diff --git a/chapter_14/10_draw_pyramid.rb b/chapter_14/10_draw_pyramid.rb index 68616b0..181cb4c 100644 --- a/chapter_14/10_draw_pyramid.rb +++ b/chapter_14/10_draw_pyramid.rb @@ -1,59 +1,54 @@ -require 'ruby-processing' -class DrawPyramidSketch < Processing::App - - def setup - render_mode P3D - @theta = 0.0 - end - - def draw - background 255 - @theta += 0.01 +def setup + size 200, 200, P3D + @theta = 0.0 +end - translate 100, 100, 0 - rotate_x @theta - rotate_y @theta - draw_pyramid 50 +def draw + background 255 + lights + @theta += 0.01 - # translate the scene again - translate 50, 50, 20 - # call the pyramid drawing function - draw_pyramid 10 - end + translate 100, 100, 0 + rotate_x @theta + rotate_y @theta + draw_pyramid 50 - def draw_pyramid(t) - stroke 0 + # translate the scene again + translate 50, 50, 20 + # call the pyramid drawing function + draw_pyramid 10 +end - # this pyramid has 4 sides, each drawn as a separate triangle - # each side has 3 vertices, making up a triangle shape - # the parameter "t" determines the size of the pyramid - begin_shape TRIANGLES +def draw_pyramid(t) + stroke 0 - fill 150, 0, 0, 127 - vertex -t, -t, -t - vertex t, -t, -t - vertex 0, 0, t + # this pyramid has 4 sides, each drawn as a separate triangle + # each side has 3 vertices, making up a triangle shape + # the parameter "t" determines the size of the pyramid + begin_shape TRIANGLES - fill 0, 150, 0, 127 - vertex t, -t, -t - vertex t, t, -t - vertex 0, 0, t + fill 150, 0, 0, 127 + vertex -t, -t, -t + vertex t, -t, -t + vertex 0, 0, t - fill 0, 0, 150, 127 - vertex t, t, -t - vertex -t, t, -t - vertex 0, 0, t + fill 0, 150, 0, 127 + vertex t, -t, -t + vertex t, t, -t + vertex 0, 0, t - fill 150, 0, 150, 127 - vertex -t, t, -t - vertex -t, -t, -t - vertex 0, 0, t + fill 0, 0, 150, 127 + vertex t, t, -t + vertex -t, t, -t + vertex 0, 0, t - end_shape - end + fill 150, 0, 150, 127 + vertex -t, t, -t + vertex -t, -t, -t + vertex 0, 0, t + end_shape end -DrawPyramidSketch.new :title => "Draw Pyramid", :width => 200, :height => 200 diff --git a/chapter_14/12_rotating_one_square.rb b/chapter_14/12_rotating_one_square.rb index 986a4b8..f41cce3 100644 --- a/chapter_14/12_rotating_one_square.rb +++ b/chapter_14/12_rotating_one_square.rb @@ -1,25 +1,21 @@ -require 'ruby-processing' -class RotatingOneSquareSketch < Processing::App - def setup - render_mode P3D - rect_mode CENTER - @theta1 = 0 - end - - def draw - background 255 - stroke 0 - fill 175 +def setup + size 200, 200, P3D + rect_mode CENTER + @theta1 = 0 +end - translate 50, 50 - rotate_z @theta1 - rect 0, 0, 60, 60 - @theta1 += 0.02 - end +def draw + background 255 + stroke 0 + fill 175 + translate 50, 50 + rotate_z @theta1 + rect 0, 0, 60, 60 + @theta1 += 0.02 end -RotatingOneSquareSketch.new :title => "Rotating One Square", :width => 200, :height => 200 + diff --git a/chapter_14/13_rotating_another_square.rb b/chapter_14/13_rotating_another_square.rb index 5882d43..2d8752c 100644 --- a/chapter_14/13_rotating_another_square.rb +++ b/chapter_14/13_rotating_another_square.rb @@ -1,25 +1,21 @@ -require 'ruby-processing' -class RotatingAnotherSquareSketch < Processing::App - def setup - render_mode P3D - rect_mode CENTER - @theta2 = 0 - end - - def draw - background 255 - stroke 0 - fill 175 +def setup + size 200, 200, P3D + rect_mode CENTER + @theta2 = 0 +end - translate 150, 150 - rotate_y @theta2 - rect 0, 0, 60, 60 - @theta2 += 0.02 - end +def draw + background 255 + stroke 0 + fill 175 + translate 150, 150 + rotate_y @theta2 + rect 0, 0, 60, 60 + @theta2 += 0.02 end -RotatingAnotherSquareSketch.new :title => "Rotating Another Square", :width => 200, :height => 200 + diff --git a/chapter_14/14_rotating_both_squares.rb b/chapter_14/14_rotating_both_squares.rb index d89bae3..216e19c 100644 --- a/chapter_14/14_rotating_both_squares.rb +++ b/chapter_14/14_rotating_both_squares.rb @@ -1,43 +1,39 @@ -require 'ruby-processing' - -class RotatingBothSquaresSketch < Processing::App - - def setup - render_mode P3D - rect_mode CENTER - @theta1 = @theta2 = 0 - end - - def draw - background 255 - stroke 0 - fill 175 - - # Save the current transformation matrix. - # This is where we started, with (0,0) in the top left corner of the window and no rotation. - push_matrix - - # Translate and rotate the first rectangle. - translate 50, 50 - rotate_z @theta1 - # Display the first rectangle. - rect 0, 0, 60, 60 - # Restore matrix from Step 1 so that it isn't affected by Steps 2 and 3! - pop_matrix - - push_matrix - # Translate and rotate the second rectangle. - translate 150, 150 - rotate_y @theta2 - # Display the second rectangle. - rect 0, 0, 60, 60 - pop_matrix - - @theta1 += 0.02 - @theta2 += 0.02 - end + +def setup + size 200, 200, P3D + rect_mode CENTER + @theta1 = @theta2 = 0 +end + +def draw + background 255 + stroke 0 + fill 175 + + # Save the current transformation matrix. + # This is where we started, with (0,0) in the top left corner of the window and no rotation. + push_matrix + + # Translate and rotate the first rectangle. + translate 50, 50 + rotate_z @theta1 + # Display the first rectangle. + rect 0, 0, 60, 60 + # Restore matrix from Step 1 so that it isn't affected by Steps 2 and 3! + pop_matrix + + push_matrix + # Translate and rotate the second rectangle. + translate 150, 150 + rotate_y @theta2 + # Display the second rectangle. + rect 0, 0, 60, 60 + pop_matrix + + @theta1 += 0.02 + @theta2 += 0.02 end -RotatingBothSquaresSketch.new :title => "Rotating Both Squares", :width => 200, :height => 200 + diff --git a/chapter_14/15_rotating_many_things.rb b/chapter_14/15_rotating_many_things.rb index 752c751..0293f97 100644 --- a/chapter_14/15_rotating_many_things.rb +++ b/chapter_14/15_rotating_many_things.rb @@ -1,8 +1,10 @@ -require 'ruby-processing' # A Rotater class class Rotater - + include Processing::Proxy + + attr_reader :speed, :theta + def initialize(x, y, speed, width) @x, @y = x, y # Angle is always initialized to 0 @@ -13,44 +15,43 @@ def initialize(x, y, speed, width) # Increment angle def spin - @theta += @speed + @theta += speed end # Display rectangle def display # push_matrix and pop_matrix are called inside the class' display method. # This way, every Rotater object is rendered with its own independent translation and rotation! - $app.push_matrix - $app.translate @x, @y - $app.rotate @theta - $app.rect 0, 0, @w, @w - $app.pop_matrix + push_matrix + translate @x, @y + rotate theta + rect 0, 0, @w, @w + pop_matrix end end -class RotatingManyThingsSketch < Processing::App - def setup - rect_mode CENTER - stroke 0 - fill 0, 100 - @rotaters = Array.new(20) do - Rotater.new(rand(width), rand(height), random(-0.1, 0.1), rand(48)) - end + +def setup + size 200, 200 + rect_mode CENTER + stroke 0 + fill 0, 100 + @rotaters = Array.new(20) do + Rotater.new(rand(width), rand(height), rand(-0.1 .. 0.1), rand(48)) end +end - def draw - background 255 +def draw + background 255 - # All Rotaters spin and are displayed - @rotaters.each do |r| - r.spin - r.display - end + # All Rotaters spin and are displayed + @rotaters.each do |r| + r.spin + r.display end - end -RotatingManyThingsSketch.new :title => "Rotating Many Things", :width => 200, :height => 200 + diff --git a/chapter_14/16_simple_solar_system.rb b/chapter_14/16_simple_solar_system.rb index c44fe11..ef8e42c 100644 --- a/chapter_14/16_simple_solar_system.rb +++ b/chapter_14/16_simple_solar_system.rb @@ -1,53 +1,50 @@ -require 'ruby-processing' - -class SimpleSolarSystemSketch < Processing::App - - def setup - smooth - @theta = 0 # Angle of rotation around sun and planets - end - - def draw - background 255 - stroke 0 - - # Translate to center of window to draw the sun. - translate width/2, height/2 - fill 255, 200, 50 - ellipse 0, 0, 20, 20 - - # The earth rotates around the sun - push_matrix - rotate @theta - translate 50, 0 - fill 50, 200, 255 - ellipse 0, 0, 10, 10 - - # Moon #1 rotates around the earth - # push_matrix is called to save the transformation state before drawing moon #1. - # This way we can pop and return to earth before drawing moon #2. - # Both moons rotate around the earth which itself is rotating around the sun). - push_matrix - rotate -@theta*4 - translate 15, 0 - fill 50, 255, 200 - ellipse 0, 0, 6, 6 - pop_matrix - - # Moon #2 also rotates around the earth - push_matrix - rotate @theta*2 - translate 25, 0 - fill 50, 255, 200 - ellipse 0, 0, 6, 6 - pop_matrix - - pop_matrix - - @theta += 0.01; - end +attr_reader :theta +def setup + size 200, 200 + smooth 4 + @theta = 0 # Angle of rotation around sun and planets end -SimpleSolarSystemSketch.new :title => "Simple Solar System", :width => 200, :height => 200 +def draw + background 15, 15, 25 + stroke 0 + + # Translate to center of window to draw the sun. + translate width/2, height/2 + fill 255, 200, 50 + ellipse 0, 0, 20, 20 + + # The earth rotates around the sun + push_matrix + rotate theta + translate 50, 0 + fill 50, 200, 255 + ellipse 0, 0, 10, 10 + + # Moon #1 rotates around the earth + # push_matrix is called to save the transformation state before drawing moon #1. + # This way we can pop and return to earth before drawing moon #2. + # Both moons rotate around the earth which itself is rotating around the sun). + push_matrix + rotate -theta * 4 + translate 15, 0 + fill 50, 255, 200 + ellipse 0, 0, 6, 6 + pop_matrix + + # Moon #2 also rotates around the earth + push_matrix + rotate theta * 2 + translate 25, 0 + fill 50, 255, 200 + ellipse 0, 0, 6, 6 + pop_matrix + + pop_matrix + + @theta += 0.01 +end + + diff --git a/chapter_14/17_nested_push_and_pop.rb b/chapter_14/17_nested_push_and_pop.rb index 691d8c9..a6c7853 100644 --- a/chapter_14/17_nested_push_and_pop.rb +++ b/chapter_14/17_nested_push_and_pop.rb @@ -1,50 +1,47 @@ -require 'ruby-processing' +attr_reader :theta -class NestedPushAndPopSketch < Processing::App +def setup + size 200, 200 + smooth 4 + @theta = 0 # angle for rotation +end - def setup - smooth - @theta = 0 # angle for rotation - end +def draw + background 255 + stroke 0 - def draw - background 255 - stroke 0 + # Translate to center of window + translate width/2, height/2 - # Translate to center of window - translate width/2, height/2 + # Loop from 0 to 360 degrees (2*PI radians) + 0.step(TAU, 0.2) do |i| + + # Push, rotate and draw a line! + # The transformation state is saved at the beginning of each cycle through the for loop and restored at the end. + # Try commenting out these lines to see the difference! + push_matrix + rotate theta + i + line 0, 0, 100, 0 # Loop from 0 to 360 degrees (2*PI radians) - 0.step(TWO_PI, 0.2) do |i| - - # Push, rotate and draw a line! - # The transformation state is saved at the beginning of each cycle through the for loop and restored at the end. - # Try commenting out these lines to see the difference! - push_matrix - rotate @theta + i - line 0, 0, 100, 0 - - # Loop from 0 to 360 degrees (2*PI radians) - 0.step(TWO_PI, 0.5) do |j| - # Push, translate, rotate and draw a line! - push_matrix - translate 100, 0 - rotate -@theta - j - line 0, 0, 50, 0 - # We're done with the inside loop,pop! - pop_matrix - end - - # We're done with the outside loop, pop! + 0.step(TAU, 0.5) do |j| + # Push, translate, rotate and draw a line! + push_matrix + translate 100, 0 + rotate -theta - j + line 0, 0, 50, 0 + # We're done with the inside loop,pop! pop_matrix end - end_shape - # Increment @theta - @theta += 0.01 + # We're done with the outside loop, pop! + pop_matrix end + end_shape + # Increment @theta + @theta += 0.01 end -NestedPushAndPopSketch.new :title => "Nested Push and Pop", :width => 200, :height => 200 + diff --git a/chapter_14/18_object_oriented_solar_system.rb b/chapter_14/18_object_oriented_solar_system.rb index f2c73a7..0f55e02 100644 --- a/chapter_14/18_object_oriented_solar_system.rb +++ b/chapter_14/18_object_oriented_solar_system.rb @@ -1,7 +1,6 @@ -require 'ruby-processing' class Planet - + include Processing::Proxy # Each planet object keeps track of its own angle of rotation. # @theta Rotation around sun # @diameter Size of planet @@ -11,7 +10,7 @@ def initialize(distance, diameter) @distance = distance @diameter = diameter @theta = 0 - @orbit_speed = rand * 0.02 + 0.01 + @orbit_speed = rand(-0.01 .. 0.01) end def update @@ -21,49 +20,46 @@ def update def display # Before rotation and translation, the state of the matrix is saved with push_matrix. - $app.push_matrix + push_matrix # Rotate orbit - $app.rotate @theta + rotate @theta # translate out @distance - $app.translate @distance, 0 - $app.stroke 0 - $app.fill 175 - $app.ellipse 0, 0, @diameter, @diameter + translate @distance, 0 + stroke 0 + fill 175 + ellipse 0, 0, @diameter, @diameter # Once the planet is drawn, the matrix is restored with pop_matrix so that the next planet is not affected. - $app.pop_matrix + pop_matrix end end -class ObjectOrientedSolarSystemSketch < Processing::App - - def setup - smooth - @planets = Array.new(8) { |i| Planet.new(20+i*10, i+8) } - end - - def draw - background 255 +def setup + size 200, 200 + smooth 4 + @planets = (0 .. 8).map{ |i| Planet.new(20 + i * 10, i + 8) } +end - # Drawing the Sun - push_matrix - # Translate to center of window - translate width/2, height/2 - stroke 0 - fill 255 - ellipse 0, 0, 20, 20 +def draw + background 50, 50, 100 - # Drawing all Planets - @planets.each do |p| - p.update - p.display - end + # Drawing the Sun + push_matrix + # Translate to center of window + translate width / 2, height / 2 + stroke 0 + fill 255 + ellipse 0, 0, 20, 20 - pop_matrix + # Drawing all Planets + @planets.each do |p| + p.update + p.display end + pop_matrix end - ObjectOrientedSolarSystemSketch.new :title => "Object Oriented Solar System", :width => 200, :height => 200 + diff --git a/chapter_14/Rakefile b/chapter_14/Rakefile new file mode 100644 index 0000000..254cf8f --- /dev/null +++ b/chapter_14/Rakefile @@ -0,0 +1,30 @@ +# Simple demo Rakefile to autorun samples in current directory +# adjust path to rp5 executable, and or opts as required + +SAMPLES_DIR="./" + +desc 'run demo' +task :default => [:demo] + +desc 'demo' +task :demo do + samples_list.shuffle.each{|sample| run_sample sample} +end + +def samples_list + files = [] + Dir.chdir(SAMPLES_DIR) + Dir.glob("*.rb").each do |file| + files << File.join(SAMPLES_DIR, file) + end + return files +end + +def run_sample(sample_name) + puts "Running #{sample_name}...quit to run next sample" + open("|rp5 run #{sample_name}", "r") do |io| + while l = io.gets + puts(l.chop) + end + end +end diff --git a/chapter_15/01_hello_world_image.rb b/chapter_15/01_hello_world_image.rb index 5e6de7c..7bd0530 100644 --- a/chapter_15/01_hello_world_image.rb +++ b/chapter_15/01_hello_world_image.rb @@ -1,20 +1,16 @@ -require 'ruby-processing' +# For some reason this sketch needs to be run using --nojava flag -class HelloWorldImageSketch < Processing::App - - def setup - # the image file must be in the data directory - @img = load_image("mysummervacation.jpg") - end - - def draw - background 0 - - #The image function displays the image at a location-in this case the point (0,0). - image @img, 0, 0 - end +def setup + size 200, 200 + # the image file must be in the data directory + @img = load_image("mysummervacation.jpg") +end +def draw + background 0 + #The image function displays the image at a location-in this case the point (0,0). + image @img, 0, 0 end -HelloWorldImageSketch.new :title => "Hello World Image", :width => 320, :height => 240 + diff --git a/chapter_15/02_image_sprite.rb b/chapter_15/02_image_sprite.rb index bba1208..b41ba19 100644 --- a/chapter_15/02_image_sprite.rb +++ b/chapter_15/02_image_sprite.rb @@ -1,29 +1,26 @@ -require 'ruby-processing' +# this sketch requires --nojruby flag (load_image) -class ImageSpriteSketch < Processing::App - - def setup - @head = load_image("face.jpg") # variable for the image file - @x, @y = 0, width/2 # variables for image location - @rot = 0.0 # variable for image rotation - end - - def draw - background 255 +def setup + size 200, 200 + @head = load_image("face.jpg") # variable for the image file + @x, @y = 0, width/2 # variables for image location + @rot = 0.0 # variable for image rotation +end - translate @x, @y - rotate @rot +def draw + background 255 - # Images can be animated just like regular shapes using variables, translate, rotate, and so on. - image @head, 0, 0 - # Adjust variables for animation - @x += 1.0 - @rot += 0.02 - @x = -@head.width if @x > width + @head.width - end + translate @x, @y + rotate @rot + # Images can be animated just like regular shapes using variables, translate, rotate, and so on. + image @head, 0, 0 + # Adjust variables for animation + @x += 1.0 + @rot += 0.02 + @x = -@head.width if @x > width + @head.width end -ImageSpriteSketch.new :title => "Image Sprite", :width => 200, :height => 200 + diff --git a/chapter_15/03_swapping_images.rb b/chapter_15/03_swapping_images.rb index b32bb2f..3d75d87 100644 --- a/chapter_15/03_swapping_images.rb +++ b/chapter_15/03_swapping_images.rb @@ -1,25 +1,21 @@ -require 'ruby-processing' +# this sketch requires --nojruby flag (load_image) -class SwappingImagesSketch < Processing::App - - def setup - @index = 0 - @count = 7 - # loading the images into the array - @images = (0...@count).map { |i| load_image("animal#{i}.jpg") } - end - - def draw - # displaying one images - image @images[@index], 0, 0 - end +def setup + size 200, 200 + @index = 0 + @count = 7 + # loading the images into the array + @images = (0...@count).map { |i| load_image("animal#{i}.jpg") } +end - def mouse_pressed - # A new image is picked randomly when the mouse is clicked - @index = rand(@images.size) - end +def draw + # displaying one images + image @images[@index], 0, 0 +end +def mouse_pressed + # A new image is picked randomly when the mouse is clicked + @index = rand(@images.size) end -SwappingImagesSketch.new :title => "Swapping Images", :width => 200, :height => 200 diff --git a/chapter_15/04_image_sequence.rb b/chapter_15/04_image_sequence.rb index cdd3cdf..12a4313 100644 --- a/chapter_15/04_image_sequence.rb +++ b/chapter_15/04_image_sequence.rb @@ -1,22 +1,19 @@ -require 'ruby-processing' +# this sketch requires --nojruby flag (load_image) -class ImageSequence < Processing::App - - def setup - @index = 0 - @count = 7 - # loading the images into the array - @images = (0...@count).map { |i| load_image("animal#{i}.jpg") } - frame_rate 5 - end - - def draw - # displaying one images - image @images[@index], 0, 0 - @index = (@index + 1) % @images.size - end +def setup + size 200, 200 + @index = 0 + @count = 7 + # loading the images into the array + @images = (0...@count).map { |i| load_image("animal#{i}.jpg") } + frame_rate 5 +end +def draw + # displaying one images + image @images[@index], 0, 0 + @index = (@index + 1) % @images.size end -ImageSequence.new :title => "Image Sequence", :width => 200, :height => 200 + diff --git a/chapter_15/05_setting_pixels.rb b/chapter_15/05_setting_pixels.rb index 6b294ae..82134e1 100644 --- a/chapter_15/05_setting_pixels.rb +++ b/chapter_15/05_setting_pixels.rb @@ -1,19 +1,16 @@ -require 'ruby-processing' - -class SettingPixelsSketch < Processing::App - - def setup - # load the pixels array - load_pixels - background 0 - # loop through the pixels and set each one to a random greyscale color - pixels.size.times { |i| pixels[i] = color(rand 255) } - # update the pixels on screen - update_pixels - end - +# introducing lambda +def setup + size 200, 200 + # load the pixels array + load_pixels + background 0 + # loop through the pixels and set each one to a random greyscale color + col = ->{color(rand 255)} + pixels.size.times { |i| pixels[i] = col.call } + # update the pixels on screen + update_pixels end -SettingPixelsSketch.new :title => "Setting Pixels", :width => 200, :height => 200 + diff --git a/chapter_15/06_pixels_2d.rb b/chapter_15/06_pixels_2d.rb index 06b8a11..11b1c19 100644 --- a/chapter_15/06_pixels_2d.rb +++ b/chapter_15/06_pixels_2d.rb @@ -1,29 +1,24 @@ -require 'ruby-processing' -class Pixels2dSketch < Processing::App - - def setup - # load the pixels array - load_pixels - # Two loops allow us to visit every column (x) and every row (y). - # Loop through every pixel column - width.times do |x| - # Loop through every pixel row - height.times do |y| - # Use the formula to find the 1D location - # The location in the pixel array is calculated via our formula: 1D pixel location = x + y * width - loc = x + y * width - # We use the even-or-odd-ness of the column number (x) to determine whether the color should be black or white. - pixels[loc] = (x % 2 == 0) ? color(255) : color(0) - end +def setup + size 200, 200 + # load the pixels array + load_pixels + # Two loops allow us to visit every column (x) and every row (y). + # Loop through every pixel column + width.times do |x| + # Loop through every pixel row + height.times do |y| + # Use the formula to find the 1D location + # The location in the pixel array is calculated via our formula: 1D pixel location = x + y * width + loc = x + y * width + # We use the even-or-odd-ness of the column number (x) to determine whether the color should be black or white. + pixels[loc] = (x.even? ) ? color(255) : color(0) end - # update the pixels on screen - update_pixels end - - + # update the pixels on screen + update_pixels end -Pixels2dSketch.new :title => "Pixels 2d", :width => 200, :height => 200 + diff --git a/chapter_15/07_image_pixels.rb b/chapter_15/07_image_pixels.rb index 746d280..19fc62f 100644 --- a/chapter_15/07_image_pixels.rb +++ b/chapter_15/07_image_pixels.rb @@ -1,40 +1,37 @@ -require 'ruby-processing' +# requires jruby-complete to run, ie use --nojruby flag -class ImagePixelsSketch < Processing::App - - def setup - @image = load_image 'sunflower.jpg' - end +def setup + size 200, 200 + @image = load_image 'sunflower.jpg' +end - def draw - # load the pixels array - load_pixels - # Two loops allow us to visit every column (x) and every row (y). - # Loop through every pixel column - width.times do |x| - # Loop through every pixel row - height.times do |y| - # Use the formula to find the 1D location - loc = x + y * width # The location in the pixel array is calculated via our formula: 1D pixel location = x + y * width - - # The functions red, green, and blue pull out the three color components from a pixel. - r = red(@image.pixels[loc]) - g = green(@image.pixels[loc]) - b = blue(@image.pixels[loc]) - - # Image Processing would go here - # If we were to change the RGB values, we would do it here, before setting the pixel in the display window. - - # Set the display pixel to the image pixel - pixels[loc] = color(r,g,b) - end +def draw + # load the pixels array + load_pixels + # Two loops allow us to visit every column (x) and every row (y). + # Loop through every pixel column + width.times do |x| + # Loop through every pixel row + height.times do |y| + # Use the formula to find the 1D location + loc = x + y * width # The location in the pixel array is calculated via our formula: 1D pixel location = x + y * width + + # The functions red, green, and blue pull out the three color components from a pixel. + r = red(@image.pixels[loc]) + g = green(@image.pixels[loc]) + b = blue(@image.pixels[loc]) + + # Image Processing would go here + # If we were to change the RGB values, we would do it here, before setting the pixel in the display window. + + # Set the display pixel to the image pixel + pixels[loc] = color(r,g,b) end - # update the pixels on screen - update_pixels end - + # update the pixels on screen + update_pixels end -ImagePixelsSketch.new :title => "Image Pixels", :width => 200, :height => 200 + diff --git a/chapter_15/08_image_brightness.rb b/chapter_15/08_image_brightness.rb index 5437081..d89f2e0 100644 --- a/chapter_15/08_image_brightness.rb +++ b/chapter_15/08_image_brightness.rb @@ -1,29 +1,26 @@ -require 'ruby-processing' -class ImageBrightnessSketch < Processing::App - def setup - @image = load_image 'sunflower.jpg' - # Let's grab the red, green and blue component of each pixel of the image to start with. - @image_pixels = @image.pixels.map {|p| [red(p), green(p), blue(p)]} - end +def setup + size 200, 200, P2D + @image = load_image 'sunflower.jpg' + # Let's grab the red, green and blue component of each pixel of the image to start with. + @image_pixels = @image.pixels.map {|p| [red(p), green(p), blue(p)]} +end - def draw - # We calculate a multiplier ranging from 0.0 to 8.0 based on mouseX position. - # That multiplier changes the RGB value of each pixel. - adjustment = (mouse_x.to_f / width) * 8.0 - load_pixels # load the pixels array - - # And here's a modified Ruby way to do the Java equivalent - pixels.size.times do |i| - pixels[i] = color(*@image_pixels[i].map {|rgb| rgb * adjustment }) - end - - update_pixels +def draw + # We calculate a multiplier ranging from 0.0 to 8.0 based on mouseX position. + # That multiplier changes the RGB value of each pixel. + adjustment = (mouse_x.to_f / width) * 8.0 + load_pixels # load the pixels array + + # And here's a modified Ruby way to do the Java equivalent + pixels.size.times do |i| + pixels[i] = color(*@image_pixels[i].map {|rgb| rgb * adjustment }) end - + + update_pixels end -ImageBrightnessSketch.new :title => "Image Brightness", :width => 200, :height => 200 + diff --git a/chapter_15/09_flashlight_effect.rb b/chapter_15/09_flashlight_effect.rb index 25dfbf3..17b014e 100644 --- a/chapter_15/09_flashlight_effect.rb +++ b/chapter_15/09_flashlight_effect.rb @@ -1,42 +1,39 @@ -require 'ruby-processing' -class FlashlightEffectSketch < Processing::App - def setup - @image = load_image 'sunflower.jpg' - # Let's grab the red, green and blue component of each pixel of the image to start with. - @image_pixels = @image.pixels.map {|p| [red(p), green(p), blue(p)]} - end +def setup + size 200, 200, P2D + @image = load_image 'sunflower.jpg' + # Let's grab the red, green and blue component of each pixel of the image to start with. + @image_pixels = @image.pixels.map {|p| [red(p), green(p), blue(p)]} +end - def draw - load_pixels # Load the pixels array - # Two loops allow us to visit every column (x) and every row (y). - # Loop through every pixel column - width.times do |x| - # Loop through every pixel row - height.times do |y| - # Use the formula to find the 1D location - loc = x + y * width # The location in the pixel array is calculated via our formula: 1D pixel location = x + y * width - - # Calculate an amount to change brightness - # based on proximity to the mouse - distance = dist(x, y, mouseX, mouseY) - - # The closer the pixel is to the mouse, the lower the value of "distance" - # We want closer pixels to be brighter, however, so we invert the value with the formula: adjustment = (50-distance)/50 - # Pixels with a distance of 50 (or greater) have a brightness of 0.0 (or negative which is equivalent to 0 here) - # Pixels with a distance of 0 have a brightness of 1.0. - adjustment = (50 - distance) / 50 - - # Set the display pixel to the image pixel - pixels[loc] = color(*@image_pixels[loc].map {|rgb| rgb * adjustment }) - end +def draw + load_pixels # Load the pixels array + # Two loops allow us to visit every column (x) and every row (y). + # Loop through every pixel column + width.times do |x| + # Loop through every pixel row + height.times do |y| + # Use the formula to find the 1D location + loc = x + y * width # The location in the pixel array is calculated via our formula: 1D pixel location = x + y * width + + # Calculate an amount to change brightness + # based on proximity to the mouse + distance = dist(x, y, mouseX, mouseY) + + # The closer the pixel is to the mouse, the lower the value of "distance" + # We want closer pixels to be brighter, however, so we invert the value with the formula: adjustment = (50-distance)/50 + # Pixels with a distance of 50 (or greater) have a brightness of 0.0 (or negative which is equivalent to 0 here) + # Pixels with a distance of 0 have a brightness of 1.0. + adjustment = (50 - distance) / 50 + + # Set the display pixel to the image pixel + pixels[loc] = color(*@image_pixels[loc].map {|rgb| rgb * adjustment }) end - update_pixels end - + update_pixels end -FlashlightEffectSketch.new :title => "Flashlight Effect", :width => 200, :height => 200 + diff --git a/chapter_15/10_brightness_threshold.rb b/chapter_15/10_brightness_threshold.rb index bba88c3..de3a388 100644 --- a/chapter_15/10_brightness_threshold.rb +++ b/chapter_15/10_brightness_threshold.rb @@ -1,33 +1,30 @@ -require 'ruby-processing' -class BrightnessThresholdSketch < Processing::App - def setup - @source = load_image 'sunflower.jpg' - @destination = create_image @source.width, @source.height, RGB - end +def setup + size 200, 200, P2D + @source = load_image 'sunflower.jpg' + @destination = create_image @source.width, @source.height, RGB +end - def draw - threshold = 127 - # We are going to look at both image's pixels - @source.load_pixels - @destination.load_pixels - - @source.width.times do |x| - @source.height.times do |y| - loc = x + y*@source.width; - # Test the brightness against the threshold - @destination.pixels[loc] = (brightness(@source.pixels[loc]) > threshold) ? color(255) : color(0) - end +def draw + threshold = 127 + # We are going to look at both image's pixels + @source.load_pixels + @destination.load_pixels + + @source.width.times do |x| + @source.height.times do |y| + loc = x + y * @source.width + # Test the brightness against the threshold + @destination.pixels[loc] = (brightness(@source.pixels[loc]) > threshold) ? color(255) : color(0) end - - # We changed the pixels in @destination - @destination.update_pixels - # Display the @destination - image @destination, 0, 0 end + # We changed the pixels in @destination + @destination.update_pixels + # Display the @destination + image @destination, 0, 0 end -BrightnessThresholdSketch.new :title => "Brightness Threshold", :width => 200, :height => 200 + diff --git a/chapter_15/11_brightness_threshold_with_filter.rb b/chapter_15/11_brightness_threshold_with_filter.rb index 9b828f2..cc504a4 100644 --- a/chapter_15/11_brightness_threshold_with_filter.rb +++ b/chapter_15/11_brightness_threshold_with_filter.rb @@ -1,20 +1,16 @@ -require 'ruby-processing' -class BrightnessThresholdWithFilterSketch < Processing::App - def setup - @img = load_image 'sunflower.jpg' - end - - def draw - # Draw the image - image @img, 0, 0 - # Filter the window with a threshold effect - # 0.5 means threshold is 50% brightness - filter THRESHOLD, 0.5 - end +def setup + size 200, 200 + @img = load_image 'sunflower.jpg' +end +def draw + # Draw the image + image @img, 0, 0 + # Filter the window with a threshold effect + # 0.5 means threshold is 50% brightness + filter THRESHOLD, 0.5 end -BrightnessThresholdWithFilterSketch.new :title => "Brightness Threshold With Filter", :width => 200, :height => 200 diff --git a/chapter_15/12_pixel_neighbour_differences.rb b/chapter_15/12_pixel_neighbour_differences.rb index a8080c4..bb54bec 100644 --- a/chapter_15/12_pixel_neighbour_differences.rb +++ b/chapter_15/12_pixel_neighbour_differences.rb @@ -1,43 +1,40 @@ -require 'ruby-processing' -class PixelNeighbourDifferencesSketch < Processing::App - def setup - @img = load_image 'sunflower.jpg' - @destination = create_image @img.width, @img.height, RGB - end +def setup + size 200, 200 + @img = load_image 'sunflower.jpg' + @destination = create_image @img.width, @img.height, RGB +end - def draw - # We are going to look at both image's pixels - @img.load_pixels - @destination.load_pixels - - # Since we are looking at left neighbors - # We skip the first column - (1...width).each do |x| - (0...height).each do |y| - # Pixel location and color - loc = x + y * @img.width - pix = @img.pixels[loc] - - # Pixel to the left location and color - left_loc = (x - 1) + y * @img.width - left_pix = @img.pixels[left_loc] - - # New color is difference between pixel and left neighbor - diff = (brightness(pix) - brightness(left_pix)).abs - @destination.pixels[loc] = color(diff) - end +def draw + # We are going to look at both image's pixels + @img.load_pixels + @destination.load_pixels + + # Since we are looking at left neighbors + # We skip the first column + (1...width).each do |x| + (0...height).each do |y| + # Pixel location and color + loc = x + y * @img.width + pix = @img.pixels[loc] + + # Pixel to the left location and color + left_loc = (x - 1) + y * @img.width + left_pix = @img.pixels[left_loc] + + # New color is difference between pixel and left neighbor + diff = (brightness(pix) - brightness(left_pix)).abs + @destination.pixels[loc] = color(diff) end - - # We changed the pixels in @destination - @destination.update_pixels - # Display the @destination - image @destination, 0, 0 end + # We changed the pixels in @destination + @destination.update_pixels + # Display the @destination + image @destination, 0, 0 end -PixelNeighbourDifferencesSketch.new :title => "Pixel Neighbour Differences", :width => 200, :height => 200 + diff --git a/chapter_15/14_pointillism.rb b/chapter_15/14_pointillism.rb index 22e4f70..fde6ad5 100644 --- a/chapter_15/14_pointillism.rb +++ b/chapter_15/14_pointillism.rb @@ -1,34 +1,31 @@ -require 'ruby-processing' - -class PointillismSketch < Processing::App - - def setup - @pointillize = 10 - @img = load_image 'sunflower.jpg' - background 255 - frame_rate 200 # Let's run this one as fast as we can. - no_stroke - smooth - end - - def draw - # Pick a random point - x, y = rand(width), rand(height) - loc = x + y * width - - # Look up the RGB color in the source image - load_pixels - pixel = @img.pixels[loc] - r, g, b = red(pixel), green(pixel), blue(pixel) - - # Draw an ellipse at that location with that color - fill r, g, b, 100 - # Back to shapes! Instead of setting a pixel, we use the color from a pixel to draw a circle. - ellipse x, y, @pointillize, @pointillize - end +# this sketch requires --nojruby flag (load_image) + +def setup + size 200, 200 + @pointillize = 10 + @img = load_image 'sunflower.jpg' + background 255 + frame_rate 200 # Let's run this one as fast as we can. + no_stroke +end + +def draw + # Pick a random point + x, y = rand(width), rand(height) + loc = x + y * width + + # Look up the RGB color in the source image + load_pixels + pixel = @img.pixels[loc] + r, g, b = red(pixel), green(pixel), blue(pixel) + + # Draw an ellipse at that location with that color + fill r, g, b, 100 + # Back to shapes! Instead of setting a pixel, we use the color from a pixel to draw a circle. + ellipse x, y, @pointillize, @pointillize end -PointillismSketch.new :title => "Pointillism", :width => 200, :height => 200 + diff --git a/chapter_15/15_2d_image_mapped_to_3d.rb b/chapter_15/15_2d_image_mapped_to_3d.rb index dc9d372..47a7b1d 100644 --- a/chapter_15/15_2d_image_mapped_to_3d.rb +++ b/chapter_15/15_2d_image_mapped_to_3d.rb @@ -1,43 +1,37 @@ -require 'ruby-processing' -class TwoDMappedTo3dSketch < Processing::App - - def setup - @cellsize = 2 - @img = load_image 'sunflower.jpg' # Load the image - @img.load_pixels - @pixels = @img.pixels - @cols = width / @cellsize # Calculate number of columns - @rows = height / @cellsize # Calculate number of rows - render_mode P3D - no_stroke - rect_mode CENTER - end - - def draw - background 255 - @cols.times do |i| # Begin loop for columns - x = i * @cellsize + @cellsize / 2 # x position - @rows.times do |j| # Begin loop for rows - y = j * @cellsize + @cellsize / 2 # y position - loc = x + y * width # Pixel array location - c = @pixels[loc] # Grab the color - - # Calculate a z position as a function of mouse_x and pixel brightness - z = (mouse_x/width.to_f) * brightness(@pixels[loc]) - 100.0 +def setup + size 200, 200, P3D + @cellsize = 2 + @img = load_image 'sunflower.jpg' # Load the image + @img.load_pixels + @pixels = @img.pixels + @cols = width / @cellsize # Calculate number of columns + @rows = height / @cellsize # Calculate number of rows + no_stroke + rect_mode CENTER +end - # Translate to the location, set fill and stroke, and draw the rect - push_matrix - translate x, y, z - fill c - rect 0, 0, @cellsize, @cellsize - pop_matrix - end +def draw + background 255 + @cols.times do |i| # Begin loop for columns + x = i * @cellsize + @cellsize / 2 # x position + @rows.times do |j| # Begin loop for rows + y = j * @cellsize + @cellsize / 2 # y position + loc = x + y * width # Pixel array location + c = @pixels[loc] # Grab the color + + # Calculate a z position as a function of mouse_x and pixel brightness + z = (mouse_x/width.to_f) * brightness(@pixels[loc]) - 100.0 + + # Translate to the location, set fill and stroke, and draw the rect + push_matrix + translate x, y, z + fill c + rect 0, 0, @cellsize, @cellsize + pop_matrix end end - end -TwoDMappedTo3dSketch.new :title => "2d Mapped To 3d", :width => 200, :height => 200 diff --git a/chapter_15/Rakefile b/chapter_15/Rakefile new file mode 100644 index 0000000..027b172 --- /dev/null +++ b/chapter_15/Rakefile @@ -0,0 +1,30 @@ +# Simple demo Rakefile to autorun samples in current directory +# adjust path to rp5 executable, and or opts as required + +SAMPLES_DIR="./" + +desc 'run demo' +task :default => [:demo] + +desc 'demo' +task :demo do + samples_list.shuffle.each{|sample| run_sample sample} +end + +def samples_list + files = [] + Dir.chdir(SAMPLES_DIR) + Dir.glob("*.rb").each do |file| + files << File.join(SAMPLES_DIR, file) + end + return files +end + +def run_sample(sample_name) + puts "Running #{sample_name}...quit to run next sample" + open("|rp5 --nojruby run #{sample_name}", "r") do |io| + while l = io.gets + puts(l.chop) + end + end +end diff --git a/chapter_16/01_display_video.rb b/chapter_16/01_display_video.rb index 3f7d44e..fc0c3ed 100644 --- a/chapter_16/01_display_video.rb +++ b/chapter_16/01_display_video.rb @@ -1,25 +1,22 @@ -require 'ruby-processing' -class CaptureVideoSketch < Processing::App - # Step 1. Import the video library - load_library "video" - # We need the video classes to be included here. - import "processing.video" +# Step 1. Import the video library +load_library :video +# We need the video classes to be included here. +include_package "processing.video" - def setup - # Step 2. Declare a Capture object - @video = Capture.new(self, width, height, 30) - end - - def draw - # Step 3 and 4: Read from the camera if it's available. - @video.read if @video.available +def setup + size 320, 240 + # Step 2. Declare a Capture object + @video = Capture.new(self, width, height, 30) +end - # Step 5. Display the video image. - image @video, 0, 0 - end +def draw + # Step 3 and 4: Read from the camera if it's available. + @video.read if @video.available + # Step 5. Display the video image. + image @video, 0, 0 end -CaptureVideoSketch.new :title => "Capture Video", :width => 320, :height => 240 + diff --git a/chapter_16/02_manipulate_video_image.rb b/chapter_16/02_manipulate_video_image.rb index 09c93e0..28106b9 100644 --- a/chapter_16/02_manipulate_video_image.rb +++ b/chapter_16/02_manipulate_video_image.rb @@ -1,24 +1,21 @@ -require 'ruby-processing' - -class ManipulateVideoImageSketch < Processing::App - - load_library "video" - import "processing.video" - - def setup - @video = Capture.new(self, width, height, 30) - end - - def draw - @video.read if @video.available - - # Tinting using mouse location - tint mouse_x, mouse_y, 255 - - # A video image can also be tinted and resized just as with a PImage. - image @video, 0, 0, mouse_x, mouse_y - end +# Step 1. Import the video library +load_library :video +# We need the video classes to be included here. +include_package "processing.video" + +def setup + size 320, 240 + @video = Capture.new(self, width, height, 30) +end +def draw + @video.read if @video.available + + # Tinting using mouse location + tint mouse_x, mouse_y, 255 + + # A video image can also be tinted and resized just as with a PImage. + image @video, 0, 0, mouse_x, mouse_y end -ManipulateVideoImageSketch.new :title => "Manipulate Video Image", :width => 320, :height => 240 + diff --git a/chapter_16/03_adjust_video_brightness.rb b/chapter_16/03_adjust_video_brightness.rb index 6c9ae0f..a836ef6 100644 --- a/chapter_16/03_adjust_video_brightness.rb +++ b/chapter_16/03_adjust_video_brightness.rb @@ -1,49 +1,45 @@ # Example 16-3: Adjust video brightness -require 'ruby-processing' - -class AdjustVideoBrightness < Processing::App - load_library "video" - import "processing.video" - - def setup - size 240, 180, P3D - - # Initialize Capture object via Constructor - # video is 320 x 240, @15 fps - @video = Capture.new self, 240, 180, 15 - background 0 - end - - def draw - # Check to see if a new frame is available - # If so, read it. - @video.read if @video.available? - - load_pixels - @video.load_pixels - pixs = @video.pixels - mx, my = mouse_x, mouse_y - max_dist = 100 - vid_width, vid_height = @video.width, @video.height - - vid_width.times do |x| - vid_height.times do |y| - # Calculate the 1D location from a 2D grid - loc = x + y * vid_width - pix = pixs[loc] - - # Calculate an amount to change brightness based on proximity to the mouse - d = dist(x, y, mx, my) - fudge = (max_dist - d) / max_dist - r, g, b = red(pix) * fudge, green(pix) * fudge, blue(pix) * fudge +# Step 1. Import the video library +load_library :video +# We need the video classes to be included here. +package_include "processing.video" + +def setup + size 240, 180, P3D + + # Initialize Capture object via Constructor + # video is 320 x 240, @15 fps + @video = Capture.new self, 240, 180, 15 + background 0 +end - # Make a new color and set pixel in the window - pixels[loc] = color(r, g, b) - end +def draw + # Check to see if a new frame is available + # If so, read it. + @video.read if @video.available? + + load_pixels + @video.load_pixels + pixs = @video.pixels + mx, my = mouse_x, mouse_y + max_dist = 100 + vid_width, vid_height = @video.width, @video.height + + vid_width.times do |x| + vid_height.times do |y| + # Calculate the 1D location from a 2D grid + loc = x + y * vid_width + pix = pixs[loc] + + # Calculate an amount to change brightness based on proximity to the mouse + d = dist(x, y, mx, my) + fudge = (max_dist - d) / max_dist + r, g, b = red(pix) * fudge, green(pix) * fudge, blue(pix) * fudge + + # Make a new color and set pixel in the window + pixels[loc] = color(r, g, b) end - update_pixels end - + update_pixels end -AdjustVideoBrightness.new :title => "Adjust Video Brightness" \ No newline at end of file diff --git a/chapter_17/02_text_align.rb b/chapter_17/02_text_align.rb index 60b0d82..6c96972 100644 --- a/chapter_17/02_text_align.rb +++ b/chapter_17/02_text_align.rb @@ -15,7 +15,7 @@ def draw text_align CENTER text "This text is centered.", width / 2, 60 text_align LEFT - text "This text is left aligned.", width/2, 100 + text "This text is left aligned.", width / 2, 100 text_align RIGHT text "This text is right aligned.", width / 2, 140 end diff --git a/chapter_17/04_text_mirror.rb b/chapter_17/04_text_mirror.rb index d57c940..8c93903 100644 --- a/chapter_17/04_text_mirror.rb +++ b/chapter_17/04_text_mirror.rb @@ -1,68 +1,65 @@ # This example demonstrates how to use the video library. You'll need a # video camera hooked in to your computer. -class TextMirror < Processing::App - load_library "video" - import "processing.video" - # Size of each cell in the grid, ratio of window size to video size - VIDEOSCALE = 14 +load_library :video +include_package "processing.video" - # The source text used in the mosaic pattern. - # A longer String might produce more interesting results. - CHARS = "thetextmirror" +# Size of each cell in the grid, ratio of window size to video size +VIDEOSCALE = 14 - def setup - size 640, 480 - smooth - # Set up columns and rows - @cols = width / VIDEOSCALE # Number of columns and... - @rows = height / VIDEOSCALE # rows in our system - @video = Capture.new(self, @cols, @rows, 15) +# The source text used in the mosaic pattern. +# A longer String might produce more interesting results. +CHARS = "thetextmirror" - # Load the font - # Using a fixed-width font. In most fonts, individual characters have different widths. - # In a fixed-width font, all characters have the same width. - # This is useful here since we intend to display the letters one at a time spaced out evenly. - # See Section 17.7 for how to display text character by character with a nonfixed width font. - @f = load_font "Courier-Bold-20.vlw" - end - - def draw - background 0 - - # Read image from the camera - @video.read if @video.available? - @video.load_pixels - - # Use a variable to count through chars in String - charcount = 0 - # Begin loop for rows - @rows.times do |j| - # Begin loop for columns - @cols.times do |i| - - # Where are we, pixel-wise? - x = i * VIDEOSCALE - y = j * VIDEOSCALE - - # Looking up the appropriate color in the pixel array - c = @video.pixels[i + j * @video.width] - - # Displaying an individual character from the String instead of a rectangle - text_font @f - fill c - - # One character from the source text is displayed colored accordingly to the pixel location. - # A counter variableâ charcountâ is used to walk through the source String one character at a time. - text CHARS[charcount].chr, x, y - - # Go on to the next character - charcount = (charcount + 1) % CHARS.length - end - end - end +def setup + size 640, 480 + smooth + # Set up columns and rows + @cols = width / VIDEOSCALE # Number of columns and... + @rows = height / VIDEOSCALE # rows in our system + @video = Capture.new(self, @cols, @rows, 15) + + # Load the font + # Using a fixed-width font. In most fonts, individual characters have different widths. + # In a fixed-width font, all characters have the same width. + # This is useful here since we intend to display the letters one at a time spaced out evenly. + # See Section 17.7 for how to display text character by character with a nonfixed width font. + @f = load_font "Courier-Bold-20.vlw" +end +def draw + background 0 + + # Read image from the camera + @video.read if @video.available? + @video.load_pixels + + # Use a variable to count through chars in String + charcount = 0 + # Begin loop for rows + @rows.times do |j| + # Begin loop for columns + @cols.times do |i| + + # Where are we, pixel-wise? + x = i * VIDEOSCALE + y = j * VIDEOSCALE + + # Looking up the appropriate color in the pixel array + c = @video.pixels[i + j * @video.width] + + # Displaying an individual character from the String instead of a rectangle + text_font @f + fill c + + # One character from the source text is displayed colored accordingly to the pixel location. + # A counter variableâ charcountâ is used to walk through the source String one character at a time. + text CHARS[charcount].chr, x, y + + # Go on to the next character + charcount = (charcount + 1) % CHARS.length + end + end end -TextMirror.new :title => "Text Mirror" \ No newline at end of file diff --git a/chapter_17/05_rotating_text.rb b/chapter_17/05_rotating_text.rb index 8119ac5..12c0147 100644 --- a/chapter_17/05_rotating_text.rb +++ b/chapter_17/05_rotating_text.rb @@ -18,5 +18,5 @@ def draw text @message, 0, 0 # Increase rotation - @theta += 0.05; + @theta += 0.05 end \ No newline at end of file diff --git a/chapter_17/06_text_breaking_up.rb b/chapter_17/06_text_breaking_up.rb index 25f55a7..45599f8 100644 --- a/chapter_17/06_text_breaking_up.rb +++ b/chapter_17/06_text_breaking_up.rb @@ -1,41 +1,39 @@ -require 'ruby-processing' -class TextBreakingUp < Processing::App +def setup + size 260, 200 + fill 0 + text_align LEFT + text_font create_font("Arial", 20, true) + @message = "click mouse to shake it up".split - def setup - size 260, 200 - fill 0 - text_align LEFT - text_font create_font("Arial", 20, true) - @message = "click mouse to shake it up" + # Create the array + @letters = [] - # Create the array - @letters = [] - - # Initialize Letters at the correct x location - x = 16 - @message.each do |letter| - # Letter objects are initialized with their location within - # the String as well as what character they should display. - @letters << Letter.new(x, 100, letter) - x += text_width(letter) - end + # Initialize Letters at the correct x location + x = 16 + @message.each do |letter| + # Letter objects are initialized with their location within + # the String as well as what character they should display. + @letters << Letter.new(x, 100, letter) + x += text_width(letter) end +end - def draw - background 255 - @letters.each do |letter| - letter.display - # If the mouse is pressed the letters shake - # If not, they return to their original location - mouse_pressed? ? letter.shake : letter.home - end +def draw + background 255 + @letters.each do |letter| + letter.display + # If the mouse is pressed the letters shake + # If not, they return to their original location + mouse_pressed? ? letter.shake : letter.home end - end + + # A class to describe a single Letter class Letter + include Processing::Proxy # The letter that this instance represents attr_reader :letter @@ -53,13 +51,13 @@ def initialize(x, y, letter) # Display the letter def display - $app.text @letter, @x, @y + text @letter, @x, @y end # Move the letter randomly def shake - @x += rand * 4 - 2 - @y += rand * 4 - 2 + @x += rand(-2.0 .. 2) + @y += rand(-2.0 .. 2) end # At any point, the current location can be set back to @@ -68,6 +66,4 @@ def home @x = @home_x @y = @home_y end -end - -TextBreakingUp.new :title => "Text Breaking Up" \ No newline at end of file +end \ No newline at end of file diff --git a/chapter_17/07_boxes_along_a_curve.rb b/chapter_17/07_boxes_along_a_curve.rb index 8b6e8b2..17cea65 100644 --- a/chapter_17/07_boxes_along_a_curve.rb +++ b/chapter_17/07_boxes_along_a_curve.rb @@ -10,7 +10,7 @@ def draw background 255 # Start in the center and draw the circle - translate width/2, height/2 + translate width / 2, height / 2 no_fill stroke 0 diff --git a/chapter_17/08_characters_along_a_curve.rb b/chapter_17/08_characters_along_a_curve.rb index 82f4b12..30bb1af 100644 --- a/chapter_17/08_characters_along_a_curve.rb +++ b/chapter_17/08_characters_along_a_curve.rb @@ -4,7 +4,6 @@ def setup @r = 100 # The radius of a circle text_font create_font("Georgia", 40, true) text_align CENTER # The text must be centered! - smooth end def draw diff --git a/chapter_18/01_user_input.rb b/chapter_18/01_user_input.rb index 70de1ff..1c5d773 100644 --- a/chapter_18/01_user_input.rb +++ b/chapter_18/01_user_input.rb @@ -18,7 +18,7 @@ def draw text @saved, indent, 130 end -def keyPressed +def key_pressed # If the return key is pressed, save the String and clear it if key == "\n" @saved = @typing diff --git a/chapter_18/02_graphing_comma_separated_numbers_from_a_text_file.rb b/chapter_18/02_graphing_comma_separated_numbers_from_a_text_file.rb index ce10348..fc446d1 100644 --- a/chapter_18/02_graphing_comma_separated_numbers_from_a_text_file.rb +++ b/chapter_18/02_graphing_comma_separated_numbers_from_a_text_file.rb @@ -9,7 +9,7 @@ def setup # This array has one element because the file only has one line. # Convert String into an array of integers using ',' as a delimiter @data = stuff.first.split(',') - @data.map! {|num| num.to_i } + @data.map! { |num| num.to_i } end def draw @@ -18,6 +18,7 @@ def draw @data.each_with_index do |data, i| # The array of ints is used to set the color and height of each rectangle. fill data - rect i * 20, 0, 20, data + # counter intuitive y values owing to processings poxy coordinate convention + rect i * 20, height - data, 20, height end end diff --git a/chapter_18/03_creating_object_from_a_text_file.rb b/chapter_18/03_creating_object_from_a_text_file.rb index 0607e20..a6b6ecd 100644 --- a/chapter_18/03_creating_object_from_a_text_file.rb +++ b/chapter_18/03_creating_object_from_a_text_file.rb @@ -32,25 +32,29 @@ def draw # A Class to describe a "Bubble" # class Bubble + include Processing::Proxy + + attr_reader :width, :height # The constructor initializes color and size # Location is filled randomly def initialize(r, g, diameter) - @x, @y = $app.random($app.width), $app.height + @width, @height = $app.width, $app.height + @x, @y = rand(width), height @r, @g = r, g @diameter = diameter end # Display the Bubble def display - $app.stroke 0 - $app.fill @r, @g, 255, 150 - $app.ellipse @x, @y, @diameter, @diameter + stroke 0 + fill @r, @g, 255, 150 + ellipse @x, @y, @diameter, @diameter end # Move the bubble def drift - @y += $app.random(-3, -0.1) - @x += $app.random(-1, 1) - @y = $app.height + @diameter * 2 if @y < -@diameter * 2 + @y += rand(-3 .. -0.1) + @x += rand(-1 .. 1.0) + @y = height + @diameter * 2 if @y < -@diameter * 2 end end diff --git a/chapter_18/04_loading_and_saving_data_to_text_file.rb b/chapter_18/04_loading_and_saving_data_to_text_file.rb index dea2855..9941148 100644 --- a/chapter_18/04_loading_and_saving_data_to_text_file.rb +++ b/chapter_18/04_loading_and_saving_data_to_text_file.rb @@ -49,20 +49,23 @@ def save_data # Save to File # The same file is overwritten by adding the data folder path to saveStrings(). - File.open(@file_path, 'w') {|file| file.write(data.join("\n")) } + File.open(@file_path, 'w') { |file| file.write(data.join("\n")) } end # # A Class to describe a "Bubble" # class Bubble - attr_reader :r, :g, :diameter + include Processing::Proxy + + attr_reader :width, :height, :r, :g, :diameter # The constructor initializes color and size # Location is filled randomly def initialize(r, g, diameter) - @x = $app.random($app.width) - @y = $app.height + @width, @height = $app.width, $app.height + @x = rand(width) + @y = height @r = r @g = g @diameter = diameter @@ -70,29 +73,29 @@ def initialize(r, g, diameter) # True or False if point is inside circle def rollover(mx, my) - $app.dist(mx, my, @x, @y) < diameter / 2 + dist(mx, my, @x, @y) < diameter / 2 end # Change Bubble variables def change - @r = $app.constrain(@r + $app.random(-10, 10), 0, 255) - @g = $app.constrain(@g + $app.random(-10, 10), 0, 255) - @diameter = $app.constrain(@diameter + $app.random(-2, 4), 4, 72) + @r = constrain(@r + rand(-10 .. 10), 0, 255) + @g = constrain(@g + rand(-10 .. 10), 0, 255) + @diameter = constrain(@diameter + rand(-2 .. 4), 4, 72) end # Display the Bubble def display - $app.stroke 0 - $app.fill @r, @g, 255, 150 - $app.ellipse @x, @y, @diameter, @diameter + stroke 0 + fill @r, @g, 255, 150 + ellipse @x, @y, @diameter, @diameter end # Move the bubble def drift - @y += $app.random(-3, -0.1) - @x += $app.random(-1, 1) + @y += rand(-3 .. -0.1) + @x += rand(-1 .. 1.0) if @y < -@diameter * 2 - @y = $app.height + @diameter * 2 + @y = height + @diameter * 2 end end end diff --git a/chapter_18/05_parsing_yahoos_xml_weather_feed_manually.rb b/chapter_18/05_parsing_yahoos_xml_weather_feed_manually.rb index 5bc69a1..463867b 100644 --- a/chapter_18/05_parsing_yahoos_xml_weather_feed_manually.rb +++ b/chapter_18/05_parsing_yahoos_xml_weather_feed_manually.rb @@ -47,6 +47,7 @@ def mouse_pressed # A WeatherGrabber class # class WeatherGrabber + include Processing::Proxy attr_reader :temperature, :weather, :zip attr_writer :zip @@ -61,7 +62,7 @@ def request_weather # Get all the HTML/XML source code into an array of strings # (each line is one element in the array) url = "http://xml.weather.yahoo.com/forecastrss?p=" + @zip - lines = $app.load_strings(url) + lines = load_strings(url) # Turn array into one long String xml = lines.join # join(lines, ""); diff --git a/chapter_18/06_analyzing_king_lear.rb b/chapter_18/06_analyzing_king_lear.rb index 6eaec42..ec004a9 100644 --- a/chapter_18/06_analyzing_king_lear.rb +++ b/chapter_18/06_analyzing_king_lear.rb @@ -1,22 +1,24 @@ # # Example 18-6: Analyzing King Lear # +require 'open-uri' + def setup size 200, 200 # Load the font - text_font load_font("Georgia-Bold-16.vlw") + text_font(load_font("#{sketch_path}/data/Georgia-Bold-16.vlw")) # Where are we in the text (start later b/c Project Gutenberg has # licensing info at beginning) - @counter = 1509 + @counter = 0 #1509 - # Load King Lear into an array of strings - url = "http://www.gutenberg.org/dirs/etext97/1ws3310.txt" - rawtext = load_strings(url) + # Load King Lear into an array of strings + url = 'http://www.gutenberg.org/ebooks/1128.txt' + everything = open(url) {|f| f.read } # Join the big array together as one long string - everything = rawtext.join + puts everything # All the lines in King Lear are first joined as one big String and # then split up into an array of individual words. @@ -32,13 +34,11 @@ def draw background 255 # Pick one word from King Lear - theword = @kinglear[@counter] + theword = @kinglear[@counter].chomp # Count how many times that word appears in King Lear - total = 0 - @kinglear.length.times do |i| - total += 1 if theword == @kinglear[i] - end + + total = @kinglear.select{|word| theword == word}.length unless theword == ' ' # Display the text and total times the word appears fill 0 diff --git a/chapter_18/07_loading_a_url_with_simpleml.rb b/chapter_18/07_loading_a_url_with_simpleml.rb deleted file mode 100644 index 966d305..0000000 --- a/chapter_18/07_loading_a_url_with_simpleml.rb +++ /dev/null @@ -1,90 +0,0 @@ -# -# Example 18-7: Loading a URL with simpleML -# -load_library "simpleML" -import "simpleML" - -def setup - size 200, 200 - @html = "" # String to hold data from request - @counter = 0 # Counter to animate rectangle across window - @back = 255 # Background brightness - - # Create and make an asynchronous request using - # the Request object from the library - @request = HTMLRequest.new(self, "http://www.yahoo.com") - @request.makeRequest - @timer = Timer.new(5000) - @timer.start - background 0 -end - -def draw - background @back - - # A request is made every 5s. - # The data is not received here, however, this is only the request. - if @timer.finished? - @request.make_request - # XXX: was println("Making request!"); - puts "Making request!" - @timer.start - end - - # XXX: There are still issues related to events from imported library - # so we call the net_event method ourselves - # When a request is finished the data the available flag is set to true - # and we get a chance to read the data returned by the request - if @request.available? - net_event(@request) - end - - # Draw some lines with colors based on characters from data retrieved - width.times do |i| - if i < @html.length - c = @html[i] - stroke c, 150 - line i, 0, i, height - end - end - - # Animate rectangle and dim rectangle - fill 255 - noStroke - rect @counter, 0, 10, height - @counter = (@counter + 1) % width - @back = constrain(@back - 1, 0, 255) -end - -# When a request is finished the data is received in the netEvent() -# function which is automatically called whenever data is ready. -def net_event(ml) - @html = ml.readRawSource # Read the raw data - @back = 255 # Reset background - puts "Request completed!" # Print message -end - -# -# Timer Class from Chapter 10 -# -class Timer - def initialize(total_time) - @total_time = total_time - @running = false - end - - def start - @running = true - @saved_time = $app.millis - end - - def finished? - finished = $app.millis - @saved_time > @total_time - if @running && finished - @running = false - return true - else - return false - end - end -end diff --git a/chapter_18/08_loading_xml_with_simpleml.rb b/chapter_18/08_loading_xml_with_simpleml.rb deleted file mode 100644 index 3738988..0000000 --- a/chapter_18/08_loading_xml_with_simpleml.rb +++ /dev/null @@ -1,36 +0,0 @@ -# -# Example 18-8: Loading XML with simpleML -# -load_library "simpleML" -import "simpleML" - -def setup - size 200, 200 - - # Creating and starting the request - # An array of XML elements can be retrieved using getElementArray. - # This only works for elements with the same name that appear multiple times in the XML document. - @request = XMLRequest.new(self, "http://rss.news.yahoo.com/rss/topstories") - @request.makeRequest -end - -def draw - # XXX: There are still issues related to events from imported library - # so we call the net_event method ourselves - # When a request is finished the data the available flag is set to true - # and we get a chance to read the data returned by the request - if @request.available? - net_event(@request) - no_loop - end -end - -# When a request is finished the data is received in the netEvent() -# function which is automatically called whenever data is ready. -def net_event(ml) - # Retrieving an array of all XML elements inside " title* " tags - headlines = ml.getElementArray("title") - headlines.each do |headline| - puts headline # XXX: was println(headlines[i]); - end -end \ No newline at end of file diff --git a/chapter_18/09_using_processings_xml_library.rb b/chapter_18/09_using_processings_xml_library.rb index 1210e36..c7af6a9 100644 --- a/chapter_18/09_using_processings_xml_library.rb +++ b/chapter_18/09_using_processings_xml_library.rb @@ -1,32 +1,27 @@ # # Example 18-9: Using Processing's XML library # -import "processing.xml" + def setup size 200, 200 smooth # Load an XML document - xml = XMLElement.new(self, "bubbles.xml") + xml = loadXML("bubbles.xml") # Getting the total number of Bubble objects with getChildCount(). totalBubbles = xml.get_child_count @bubbles = [] # Get all the child elements - children = xml.get_children + children = xml.get_children("bubble") children.each do |child| - # The diameter is child 0 - diameterElement = child.get_child(0) - - # The diameter is the content of the first element while red and green are attributes of the second. + diameterElement = child.get_child("diameter") diameter = diameterElement.get_content.to_i - - # Color is child 1 - colorElement = child.get_child(1) - r = colorElement.get_int_attribute("red") - g = colorElement.get_int_attribute("green") + colorElement = child.get_child("color") + r = colorElement.get_int("red") + g = colorElement.get_int("green") # Make a new Bubble object with values from XML document @bubbles << Bubble.new(r, g, diameter) @@ -47,9 +42,13 @@ def draw # A Bubble class # class Bubble + include Processing::Proxy + attr_reader :width, :height + def initialize(r, g, diameter) - @x = $app.random($app.width) - @y = $app.height + @width, @height = $app.width, $app.height + @x = random(width) + @y = height @r = r @g = g @diameter = diameter @@ -57,17 +56,17 @@ def initialize(r, g, diameter) # Display Bubble def display - $app.stroke 0 - $app.fill @r, @g, 255, 150 - $app.ellipse @x, @y, @diameter, @diameter + stroke 0 + fill @r, @g, 255, 150 + ellipse @x, @y, @diameter, @diameter end # Bubble drifts upwards def drift - @y += $app.random(-3, -0.1) - @x += $app.random(-1, 1) + @y += rand(-3 .. -0.1) + @x += rand(-1 .. 1.0) if @y < -@diameter * 2 - @y = $app.height + @diameter * 2 + @y = height + @diameter * 2 end end end diff --git a/chapter_18/11_yahoo_search_visualization.rb b/chapter_18/11_yahoo_search_visualization.rb index 44da881..11394f7 100644 --- a/chapter_18/11_yahoo_search_visualization.rb +++ b/chapter_18/11_yahoo_search_visualization.rb @@ -1,8 +1,8 @@ # # Example 18-11: Yahoo search visualization # -load_library "pyahoo" -import "pyahoo" +load_library :pyahoo +java_import "pyahoo" # The names to search NAMES = %w{ Aliki Cleopatra Penelope Daniel Peter }