ruby-processing 1.0.3 → 1.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. data/CHANGELOG +12 -0
  2. data/README +3 -0
  3. data/lib/core/core.jar +0 -0
  4. data/lib/core/jruby-complete.jar +0 -0
  5. data/lib/patches/JRubyApplet.diff +24 -0
  6. data/lib/patches/PATCHES.txt +3 -0
  7. data/lib/patches/PApplet.diff +27 -0
  8. data/lib/ruby-processing.rb +4 -1
  9. data/lib/ruby-processing/app.rb +121 -75
  10. data/lib/ruby-processing/exporters/applet_exporter.rb +1 -1
  11. data/lib/ruby-processing/exporters/base_exporter.rb +21 -16
  12. data/lib/ruby-processing/exporters/creator.rb +12 -6
  13. data/lib/ruby-processing/runner.rb +2 -2
  14. data/lib/ruby-processing/runners/base.rb +59 -0
  15. data/lib/ruby-processing/runners/live.rb +2 -2
  16. data/lib/ruby-processing/runners/run.rb +2 -1
  17. data/lib/ruby-processing/runners/watch.rb +47 -11
  18. data/lib/templates/applet/index.html.erb +6 -6
  19. data/lib/templates/create/bare_sketch.rb.erb +7 -0
  20. data/lib/templates/create/blank_sketch.rb.erb +2 -2
  21. data/library/control_panel/control_panel.rb +6 -2
  22. data/library/opengl/library/export.txt +0 -0
  23. data/library/opengl/library/opengl.jar +0 -0
  24. data/library/pdf/library/itext.jar +0 -0
  25. data/library/pdf/library/pdf.jar +0 -0
  26. data/library/pdf/notes.txt +3 -4
  27. data/samples/animator.rb +35 -39
  28. data/samples/bezier_playground.rb +2 -4
  29. data/samples/fern.rb +34 -42
  30. data/samples/flight_patterns.rb +48 -54
  31. data/samples/full_screen.rb +20 -25
  32. data/samples/getting_started.rb +19 -39
  33. data/samples/learning_processing/chapter_01/1_stroke_and_fill.rb +14 -30
  34. data/samples/learning_processing/chapter_01/2_nofill.rb +18 -23
  35. data/samples/learning_processing/chapter_01/3_rgb_color.rb +16 -28
  36. data/samples/learning_processing/chapter_01/4_alpha_transparency.rb +7 -1
  37. data/samples/learning_processing/chapter_01/5_zoog.rb +20 -33
  38. data/samples/learning_processing/chapter_02/1_zoog_again.rb +3 -1
  39. data/samples/learning_processing/chapter_03/6_interactive_zoog.rb +34 -42
  40. data/samples/learning_processing/chapter_16/03_adjust_video_brightness.rb +49 -0
  41. data/samples/learning_processing/chapter_17/01_simple_displaying_text.rb +14 -0
  42. data/samples/learning_processing/chapter_17/02_text_align.rb +21 -0
  43. data/samples/learning_processing/chapter_17/03_scrolling_headlines.rb +35 -0
  44. data/samples/learning_processing/chapter_17/04_text_mirror.rb +68 -0
  45. data/samples/learning_processing/chapter_17/05_rotating_text.rb +22 -0
  46. data/samples/learning_processing/chapter_17/06_text_breaking_up.rb +73 -0
  47. data/samples/learning_processing/chapter_17/07_boxes_along_a_curve.rb +49 -0
  48. data/samples/learning_processing/chapter_17/08_characters_along_a_curve.rb +51 -0
  49. data/samples/learning_processing/chapter_17/data/ArialMT-16.vlw +0 -0
  50. data/samples/learning_processing/chapter_17/data/Courier-Bold-20.vlw +0 -0
  51. data/samples/learning_processing/chapter_18/01_user_input.rb +39 -0
  52. data/samples/learning_processing/chapter_18/02_graphing_comma_separated_numbers_from_a_text_file.rb +28 -0
  53. data/samples/learning_processing/chapter_18/03_creating_object_from_a_text_file.rb +64 -0
  54. data/samples/learning_processing/chapter_18/data/data-1.txt +1 -0
  55. data/samples/learning_processing/chapter_18/data/data-2.txt +10 -0
  56. data/samples/orbit.rb +45 -0
  57. data/samples/processing_app/basics/image/pointillism.rb +1 -1
  58. data/samples/processing_app/topics/effects/lens.rb +1 -0
  59. metadata +30 -13
  60. data/library/opengl/bin/processing/opengl/PGraphicsOpenGL$ImageCache.class +0 -0
  61. data/library/opengl/bin/processing/opengl/PGraphicsOpenGL$TessCallback.class +0 -0
  62. data/library/opengl/bin/processing/opengl/PGraphicsOpenGL.class +0 -0
  63. data/library/pdf/bin/processing/pdf/PGraphicsPDF.class +0 -0
@@ -61,7 +61,7 @@ module Processing
61
61
 
62
62
  def calculate_substitutions
63
63
  file_list = Dir.glob(@dest + "{/**/*.{rb,jar},/data/*.*}").map {|f| f.sub(@dest+"/","")}
64
- @width_plus_14 = (@width.to_i + 14).to_s
64
+ @width = @width.to_i
65
65
  @file_list = file_list.join(",")
66
66
  end
67
67
 
@@ -8,12 +8,12 @@ module Processing
8
8
  class BaseExporter
9
9
  include FileUtils
10
10
 
11
- DEFAULT_TITLE = "Ruby-Processing Sketch"
12
- DEFAULT_DIMENSIONS = {'width' => '500', 'height' => '500'}
11
+ DEFAULT_DIMENSIONS = {'width' => '200', 'height' => '200'}
13
12
  DEFAULT_DESCRIPTION = ''
14
13
 
15
14
  # Returns the filepath, basename, and directory name of the sketch.
16
15
  def get_main_file(file)
16
+ @file = file
17
17
  return file, File.basename(file), File.dirname(file)
18
18
  end
19
19
 
@@ -37,40 +37,45 @@ module Processing
37
37
  # Searches the source for a class name.
38
38
  def extract_class_name(source)
39
39
  match = source.match(/(\w+)\s*<\s*Processing::App/)
40
- match ? match[1] : nil
40
+ match ? match[1] : 'Sketch'
41
41
  end
42
42
 
43
43
  # Searches the source for a title.
44
44
  def extract_title(source)
45
45
  match = source.match(/#{@info[:class_name]}\.new.*?:title\s=>\s["'](.+)["']/m)
46
- match ? match[1] : DEFAULT_TITLE
46
+ match ? match[1] : File.basename(@file, '.rb').titleize
47
47
  end
48
48
 
49
49
  # Searches the source for the width and height of the sketch.
50
50
  def extract_dimension(source, dimension)
51
- match = source.match(/#{@info[:class_name]}\.new.*?:#{dimension}\s=>\s(\d+)/m)
52
- match ? match[1] : DEFAULT_DIMENSIONS[dimension]
51
+ match = source.match(/#{@info[:class_name]}\.new.*?:#{dimension}\s?=>\s?(\d+)/m)
52
+ size_match = source.match(/^[^#]*size\(?\s*(\d+)\s*,\s*(\d+)\s*\)?/)
53
+ return match[1] if match
54
+ return (dimension == 'width' ? size_match[1] : size_match[2]) if size_match
55
+ DEFAULT_DIMENSIONS[dimension]
53
56
  end
54
57
 
55
58
  # Searches the source for a description of the sketch.
56
59
  def extract_description(source)
57
- match = source.match(/# Description:(.*?)\n[^#]/m)
58
- match ? match[1].gsub!(/\n(\s*)?#/, "") : DEFAULT_DESCRIPTION
60
+ match = source.match(/\A((\s*#(.*?)\n)+)[^#]/m)
61
+ match ? match[1].gsub(/\s*#\s*/, "\n") : DEFAULT_DESCRIPTION
59
62
  end
60
63
 
61
- # Searches the source any libraries that have been loaded.
64
+ # Searches the source for any libraries that have been loaded.
62
65
  def extract_libraries(source)
63
66
  libs = []
64
67
  code = source.dup
65
68
  loop do
66
- matchdata = code.match(/load\w+librar(y|ies).+?["':](\S+?)["'\s]/)
69
+ matchdata = code.match(/^[^#]*load_librar(y|ies)\s+(.+)\n/)
67
70
  break unless matchdata
68
- match = matchdata[2]
69
- @opengl = true if match.match(/opengl/i)
70
- local_path = "#{local_dir}/library/#{match}"
71
- rp5_path = "#{RP5_ROOT}/library/#{match}"
72
- File.exists?(local_path) ? libs << local_path :
73
- (libs << rp5_path if File.exists?(rp5_path))
71
+ candidates = matchdata[2].gsub(/[:"'\s]/, '').split(/,/)
72
+ candidates.each do |cand|
73
+ @opengl = true if cand.match(/opengl/i)
74
+ local_path = "#{local_dir}/library/#{cand}"
75
+ rp5_path = "#{RP5_ROOT}/library/#{cand}"
76
+ libs << rp5_path if File.exists?(rp5_path)
77
+ libs << local_path if File.exists?(local_path)
78
+ end
74
79
  code = matchdata.post_match
75
80
  end
76
81
  libs
@@ -3,6 +3,8 @@ module Processing
3
3
  # This class creates blank sketches, with the boilerplate filled in.
4
4
  class Creator < BaseExporter
5
5
 
6
+ ALL_DIGITS = /\A\d+\Z/
7
+
6
8
  # Create a blank sketch, given a path.
7
9
  def create!(path, args)
8
10
  usage path
@@ -15,16 +17,20 @@ module Processing
15
17
  end
16
18
 
17
19
  # Get the substitutions
18
- @name = main_file.camelize
19
- @file_name = main_file.underscore
20
- @title = main_file.titleize
21
- @width = args[0] || "500"
22
- @height = args[1] || "500"
20
+ @name = main_file.camelize
21
+ @file_name = main_file.underscore
22
+ @title = main_file.titleize
23
+
24
+ bare = !!args.delete('--bare')
25
+ @width, @height = args[0], args[1]
26
+ @with_size = @width && @width.match(ALL_DIGITS) &&
27
+ @height && @height.match(ALL_DIGITS)
23
28
 
24
29
  # Make the file
25
30
  dir = File.dirname path
26
31
  mkdir_p dir
27
- template = File.new("#{RP5_ROOT}/lib/templates/create/blank_sketch.rb.erb")
32
+ template_name = bare ? 'bare_sketch.rb.erb' : 'blank_sketch.rb.erb'
33
+ template = File.new("#{RP5_ROOT}/lib/templates/create/#{template_name}")
28
34
  rendered = render_erb_from_string_with_binding(template.read, binding)
29
35
  full_path = File.join(dir, "#{@file_name}.rb")
30
36
  File.open(full_path, "w") {|f| f.print(rendered) }
@@ -18,11 +18,11 @@ module Processing
18
18
  Examples:
19
19
  rp5 unpack samples
20
20
  rp5 run samples/jwishy.rb
21
- rp5 create some_new_sketch 640 480
21
+ rp5 create some_new_sketch --bare 640 480
22
22
  rp5 watch some_new_sketch.rb
23
23
  rp5 applet some_new_sketch.rb
24
24
 
25
- Further information:
25
+ Everything Else:
26
26
  http://wiki.github.com/jashkenas/ruby-processing
27
27
 
28
28
  EOS
@@ -1,5 +1,64 @@
1
1
  $LOAD_PATH << File.expand_path(File.dirname(__FILE__) + "/../../")
2
+ SKETCH_ROOT = File.dirname(ARGV[0]) unless defined? SKETCH_ROOT
3
+
4
+ require 'ruby-processing'
5
+ require 'ruby-processing/app'
6
+
2
7
 
3
8
  module Processing
9
+
4
10
  SKETCH_PATH = ARGV[0]
11
+
12
+ # For use with "bare" sketches that don't want to define a class or methods
13
+ SKETCH_TEMPLATE = <<-EOS
14
+ class Sketch < Processing::App
15
+ <% if has_methods %>
16
+ <%= source %>
17
+ <% else %>
18
+ def setup
19
+ size(DEFAULT_WIDTH, DEFAULT_HEIGHT, JAVA2D)
20
+ <%= source %>
21
+ no_loop
22
+ end
23
+ <% end %>
24
+ end
25
+ EOS
26
+
27
+ # This method is the common entry point to run a sketch, bare or complete.
28
+ def self.load_and_run_sketch
29
+ source = self.read_sketch_source
30
+ has_sketch = !!source.match(/^[^#]*< Processing::App/)
31
+ has_methods = !!source.match(/^[^#]*def setup/)
32
+
33
+ if has_sketch
34
+ load Processing::SKETCH_PATH
35
+ Processing::App.sketch_class.new if !$app
36
+ return
37
+ else
38
+ require 'erb'
39
+ code = ERB.new(SKETCH_TEMPLATE).result(binding)
40
+ Object.class_eval code, Processing::SKETCH_PATH, 0
41
+ Processing::App.sketch_class.new if !$app
42
+ end
43
+ end
44
+
45
+
46
+ # Read in the sketch source code. Needs to work both online and offline.
47
+ def self.read_sketch_source
48
+ if Processing::App.online?
49
+ # Fuck the following lines. Fucking Java can go sit on broken glass.
50
+ source = ''
51
+ url = java.net.URL.new(JRUBY_APPLET.get_code_base, Processing::SKETCH_PATH)
52
+ input = java.io.BufferedReader.new(java.io.InputStreamReader.new(url.open_stream))
53
+ while line = input.read_line do
54
+ source << (line + "\n") if line
55
+ end
56
+ input.close
57
+ else
58
+ # Ahhh, much better.
59
+ source = File.read(Processing::SKETCH_PATH)
60
+ end
61
+ source
62
+ end
63
+
5
64
  end
@@ -6,6 +6,6 @@ require "#{File.dirname(__FILE__)}/base.rb"
6
6
 
7
7
  require 'irb'
8
8
  ARGV[0] = nil # To keep IRB from trying to run it multiple times.
9
- require Processing::SKETCH_PATH
10
9
  IRB.setup(__FILE__)
11
- IRB.start()
10
+ Processing.load_and_run_sketch
11
+ IRB.start()
@@ -7,4 +7,5 @@ if ARGV[1] == '--windows-app'
7
7
  end
8
8
 
9
9
  require "#{File.dirname(__FILE__)}/base.rb"
10
- require Processing::SKETCH_PATH
10
+
11
+ Processing.load_and_run_sketch
@@ -6,12 +6,13 @@ module Processing
6
6
  # the feedback between code and effect.
7
7
  class Watcher
8
8
 
9
- # Sic a new Processing::Watcher on a given sketch.
10
- def initialize(sketch)
11
- @file = sketch
9
+ # Sic a new Processing::Watcher on the sketch
10
+ def initialize
11
+ @file = Processing::SKETCH_PATH
12
12
  @time = Time.now
13
- record_state_of_ruby
14
- load @file
13
+ # Doesn't work well enough for now.
14
+ # record_state_of_ruby
15
+ Processing.load_and_run_sketch unless $app
15
16
  start_watching
16
17
  end
17
18
 
@@ -24,22 +25,44 @@ module Processing
24
25
  file_mtime = File.stat(@file).mtime
25
26
  if file_mtime > @time
26
27
  @time = file_mtime
27
- Processing::App.wipe_out_current_app!
28
- rewind_to_recorded_state
28
+ wipe_out_current_app!
29
+ # Taking it out the reset until it can be made to work more reliably
30
+ # rewind_to_recorded_state
29
31
  GC.start
30
32
  begin
31
- load @file
33
+ Processing.load_and_run_sketch
32
34
  rescue SyntaxError
33
35
  print "Syntax Error in your sketch: ", $!, "\n"
34
36
  end
35
37
  end
36
- sleep 0.1
38
+ sleep 0.33
37
39
  end
38
40
  end
39
41
  thread.join
40
42
  end
41
43
 
42
44
 
45
+ # Used to completely remove all traces of the current sketch,
46
+ # so that it can be loaded afresh. Go down into modules to find it, even.
47
+ def wipe_out_current_app!
48
+ app = $app
49
+ return unless app
50
+ app.no_loop
51
+ # Wait for the animation thread to finish rendering
52
+ sleep 0.05
53
+ app.close
54
+ constant_names = app.class.to_s.split(/::/)
55
+ app_class_name = constant_names.pop
56
+ obj = constant_names.inject(Object) {|o, name| o.send(:const_get, name) }
57
+ obj.send(:remove_const, app_class_name)
58
+ end
59
+
60
+ # The following methods were intended to make the watcher clean up all code
61
+ # loaded in from the sketch, gems, etc, and have them be reloaded properly
62
+ # when the sketch is.... but it seems that this is neither a very good idea
63
+ # or a very possible one. If you can make the scheme work, please do,
64
+ # otherwise the following methods will probably be removed soonish.
65
+
43
66
  # Do the best we can to take a picture of the current Ruby interpreter.
44
67
  # For now, this means top-level constants and loaded .rb files.
45
68
  def record_state_of_ruby
@@ -57,7 +80,7 @@ module Processing
57
80
  new_features = $LOADED_FEATURES.reject {|f| @saved_features.include?(f) }
58
81
  new_globals = Kernel.global_variables.reject {|g| @saved_globals.include?(g) }
59
82
 
60
- new_constants.each {|c| Object.send(:remove_const, c) }
83
+ Processing::App.recursively_remove_constants(Object, new_constants)
61
84
  new_load_paths.each {|p| $LOAD_PATH.delete(p) }
62
85
  new_features.each {|f| $LOADED_FEATURES.delete(f) }
63
86
  new_globals.each do |g|
@@ -69,7 +92,20 @@ module Processing
69
92
  end
70
93
  end
71
94
 
95
+
96
+ # Used to clean up declared constants in code that needs to be reloaded.
97
+ def recursively_remove_constants(base, constant_names)
98
+ constants = constant_names.map {|name| base.const_get(name) }
99
+ constants.each_with_index do |c, i|
100
+ java_obj = Java::JavaLang::Object
101
+ constants[i] = constant_names[i] = nil if c.respond_to?(:ancestors) && c.ancestors.include?(java_obj)
102
+ constants[i] = nil if !c.is_a?(Class) && !c.is_a?(Module)
103
+ end
104
+ constants.each {|c| recursively_remove_constants(c, c.constants) if c }
105
+ constant_names.each {|name| base.send(:remove_const, name.to_sym) if name }
106
+ end
107
+
72
108
  end
73
109
  end
74
110
 
75
- Processing::Watcher.new(Processing::SKETCH_PATH)
111
+ Processing::Watcher.new
@@ -24,7 +24,7 @@
24
24
  padding: 0;
25
25
  }
26
26
  #container {
27
- width: <%= @width_plus_14 %>px;
27
+ width: <%= @width + 14 %>px;
28
28
  margin: 0 auto;
29
29
  margin-top: 20px;
30
30
  }
@@ -42,8 +42,8 @@
42
42
  }
43
43
  #description {
44
44
  font-size: 12px;
45
- width: <%= @width %>px;
46
- padding: 7px;
45
+ width: <%= @width - 16 %>px;
46
+ padding: 7px 15px 7px 15px;
47
47
  background: #111;
48
48
  text-align: justify;
49
49
  margin: 0 auto;
@@ -72,7 +72,7 @@
72
72
  width="<%= @width %>" height="<%= @height %>">
73
73
 
74
74
  <param name="archive" value="<%= @file_list %>" />
75
- <param name="jruby.script" value="<%= @main_file %>" />
75
+ <param name="jruby.eval" value="ARGV[0] = '<%= @main_file %>'; require 'ruby-processing/runners/run.rb'" />
76
76
  <param name="image" value="images/ruby.jpg" />
77
77
  <param name="boxbgcolor" value="#000000" />
78
78
  <param name="lang" value="en" />
@@ -92,14 +92,14 @@
92
92
  </div>
93
93
 
94
94
  <div id="built_with">
95
- <a href="http://the-shoebox.org/apps/44/">
95
+ <a href="http://wiki.github.com/jashkenas/ruby-processing">
96
96
  <img src="images/built_with.jpg" alt="Ruby-Processing" />
97
97
  </a>
98
98
  Via <a href="http://jruby.codehaus.org/">JRuby</a> and <a href="http://processing.org/">Processing</a><br />
99
99
  Source: <a href="<%= @main_file %>"><%= @main_file %></a>
100
100
  </div>
101
101
 
102
- <% unless @description.empty? %>
102
+ <% if @description && !@description.empty? %>
103
103
  <div id="description">
104
104
  <h1><%= @title %></h1>
105
105
  <p><%= @description %></p>
@@ -0,0 +1,7 @@
1
+ def setup
2
+ <%= "size #{@width}, #{@height}" if @with_size %>
3
+ end
4
+
5
+ def draw
6
+
7
+ end
@@ -1,4 +1,4 @@
1
- require 'ruby-processing'
1
+ # <%= @title %>
2
2
 
3
3
  class <%= @name %> < Processing::App
4
4
 
@@ -12,4 +12,4 @@ class <%= @name %> < Processing::App
12
12
 
13
13
  end
14
14
 
15
- <%= @name %>.new :title => "<%= @title %>", :width => <%= @width %>, :height => <%= @height %>
15
+ <%= @name %>.new :title => "<%= @title %>"<%= ", :width => #{@width}" if @with_size %><%= ", :height => #{@height}" if @with_size %>
@@ -97,8 +97,12 @@ module ControlPanel
97
97
  set_size 200, 30 + (64 * @elements.size)
98
98
  set_default_close_operation javax.swing.JFrame::DISPOSE_ON_CLOSE
99
99
  set_resizable false
100
- set_location($app.width + 10, 0)
101
- show
100
+ # Need to wait for the sketch to finish sizing...
101
+ Thread.new do
102
+ sleep 0.2 while $app.default_size? || !$app.done_displaying?
103
+ set_location($app.width + 10, 0)
104
+ show
105
+ end
102
106
  end
103
107
 
104
108
  def add_element(element, name, has_label=true, button=false)
File without changes
Binary file
Binary file
Binary file
@@ -1,9 +1,8 @@
1
1
  The majority of the work in this library is done by iText.
2
2
  http://www.lowagie.com/iText/
3
3
 
4
- The version bundled in this release is 2.1.2u.
4
+ The version bundled in this release is 2.1.4.
5
5
 
6
- The files in the library must be named itext.jar (not iText-2.1.2u.jar)
7
- because they're specifically included on the classpath as part of the
8
- build/platform/make.sh scripts.
6
+ The files in the library must be named itext.jar because they're specifically
7
+ included on the classpath as part of the build/platform/make.sh scripts.
9
8
 
data/samples/animator.rb CHANGED
@@ -1,47 +1,43 @@
1
1
  # From the Processing Examples
2
+ # Uses the "bare" style, where a Processing::App sketch is implicitly wrapped
3
+ # around the code.
2
4
  # -- omygawshkenas
3
5
 
4
- require 'ruby-processing'
6
+ FRAME_COUNT = 12
5
7
 
6
- class Animator < Processing::App
7
- FRAME_COUNT = 12
8
+ def setup
9
+ @frames = []
10
+ @last_time = 0
11
+ @current_frame = 0
12
+ @draw = false
13
+ @back_color = 204
14
+ size 350, 350
15
+ stroke_weight 4
16
+ smooth
17
+ background @back_color
18
+ FRAME_COUNT.times { @frames << get() }
19
+ end
8
20
 
9
- def setup
10
- @frames = []
11
- @last_time = 0
12
- @current_frame = 0
13
- @draw = false
14
- @back_color = 204
15
- stroke_weight 4
16
- smooth
17
- background @back_color
18
- FRAME_COUNT.times { @frames << get() }
19
- end
20
-
21
- def draw
22
- time = millis()
23
- if time > @last_time + 100
24
- next_frame
25
- @last_time = time
26
- end
27
- line(pmouse_x, pmouse_y, mouse_x, mouse_y) if @draw
28
- end
29
-
30
- def mouse_pressed; @draw = true; end
31
- def mouse_released; @draw = false; end
32
-
33
- def key_pressed
34
- background @back_color
35
- @frames.size.times {|i| @frames[i] = get()}
36
- end
37
-
38
- def next_frame
39
- @frames[@current_frame] = get()
40
- @current_frame += 1
41
- @current_frame = 0 if @current_frame >= @frames.size
42
- image(@frames[@current_frame], 0, 0)
21
+ def draw
22
+ time = millis()
23
+ if time > @last_time + 100
24
+ next_frame
25
+ @last_time = time
43
26
  end
44
-
27
+ line(pmouse_x, pmouse_y, mouse_x, mouse_y) if @draw
28
+ end
29
+
30
+ def mouse_pressed; @draw = true; end
31
+ def mouse_released; @draw = false; end
32
+
33
+ def key_pressed
34
+ background @back_color
35
+ @frames.size.times {|i| @frames[i] = get()}
45
36
  end
46
37
 
47
- Animator.new :title => "Animator", :width => 350, :height => 350
38
+ def next_frame
39
+ @frames[@current_frame] = get()
40
+ @current_frame += 1
41
+ @current_frame = 0 if @current_frame >= @frames.size
42
+ image(@frames[@current_frame], 0, 0)
43
+ end