The processing api
Unlike ruby-processing and JRubyArt, propane does not support bare sketches, all sketches must be class wrapped, and explicitly inherit from Propane::App. Further you must also require 'propane' in the sketch file, and initiate the sketch by creating a new instance. For convenience use propane --create fred 200 200 to create an outline sketch to edit, and thus avoid entering a lot of boiler-plate code.
The processing-api
Most of the processing methods, as explained in the Processing Language API, are available as instance methods on your Propane::App. (frame_rate, ellipse, and the 158 others.) This makes it easy as pie to use them within your sketch, but you should prefer snake case to camel case and there are some caveats. NB: you do need to explicitly create a settings method in propane.
#!/usr/bin/env jruby
require 'propane'
# Triangles gone wild
class MySketch < Propane::App
def settings
size 200, 200
smooth 8
end
def setup
sketch_title 'Triangles Gone Wild' # propane & JRubyArt
color_mode RGB, 1.0
frame_rate 30
fill 0.8, 0.6, 0.4
end
def draw
triangle(rand(width), rand(height), rand(width), rand(height), rand(width), rand(height))
end
end
MySketch.new
#!/usr/bin/env jruby allows the sketch to be run from atom with script plugin or chmod +x my_sketch.rb to create an executable script.
Caveats
We do not directly support use of many processing PApplet static methods, since there are better ruby or propane alternatives. If you absolutely must use these methods, define a constant eg Core to stand for PApplet as follows:-
Core = Java::ProcessingCore::PApplet
# allows you to use
val = Core.map(mouse_x, 0, width, 0, 10) # don't do it though
# use instead our custom propane method, that is more ruby like
val = map1d(mouse_x, 0..width, 0..10)
also if you absolutely must use PVector say a library demands it, define a const eg Vect as follows (avoid Vector):-
Vect = Java::ProcessingCore::PVector
# allows you to create an instance
pvector = Vect.new
# but in general you should prefer Vec2D or Vec3D as more ruby like alternatives to PVector
Here are some the main differences moving from vanilla processing to ruby-processing:-
-
You do not declare types in ruby, eg use
vec = Vect.newinstead ofPVector vec = new PVector()for example, however in this case you should use Vec2D and Vec3D, which are alternatives toPVector(but with methods that are much more ruby-like, and have extended functionality). -
There are no void methods (what’s evaluated gets returned without needing an explicit return)
- Everything is an object (this includes primitive types float, integer etc cf. java) see more
-
Confusing for beginners and especially pythonistas there is often more than one way to do it
-
Processing makes heavy use of java
innerclasses (to make methods and values somewhat globally available) ruby-processing provides thePropane::Proxymixin to somewhat mimic this behaviour see Ball. An alternative to consider is to use delegator methods usingextend Forwardable, requiresrequire 'forwardable'see JRubyArt example. - Use
mouse_pressed?andkey_pressed?to access mouse_pressed and key_pressed as variables (ruby can’t cope with overloading themouse_pressedandkey_pressedmethods like java) see example.
In general you should try and code in regular ruby (in propane), only using processing short-cuts / methods when you need to (ie when ruby alternatives don’t exist, many processing short-cuts just aren’t needed in ruby). From 3. above you should use:-
a**bforpow(a, b)theta.degreesfordegrees(theta)theta.radiansforradians(theta)x.absforabs(x)x.ceilforceil(x)x.roundforround(x)str.stripfortrim(str)str.hexforhex(str)string.to_i(base=16)forunhex(str)
Other ruby methods to prefer are:-
rand(x)torandom(x)rand(lo..hi)torandom(lo, hi)puts val(or even justp val) toprintln(val)map1d(val, (range1), (range2))tomap(value, start1, stop1, start2, stop2)(lo..hi).clip(amt)toconstrain(amt, lo, hi)it is how it is implemented
To avoid confusion use with ruby map use map1d for processing map function see example.