Built a screen saver with the help of a wonderful new gem called ruby-processing. I've been messing around with Processing in java for a little bit as friendly intro to opengl effects and shaders.
Was very happy to find such an advanced ruby gem that leverages both the power of jruby and processing.
Check out the java version on OpenProcessing.org
Compare with the JRuby Applet. (Can take a minute to load)
Here's the ruby code:
1
2
3
4 include Math
5 attr_reader :grains, :num_grains
6
7
8 srand Time.now.to_i
9 @dx, @dy = 0, 0
10 hint(ENABLE_OPENGL_4X_SMOOTH )
11 @num_grains = size
12 reset_all
13 end
14
15
16 count = 0
17 @grains.each {|grain| count += grain.move }
18 if count == @grains.size
19 sleep 3
20 reset_all
21 end
22 end
23
24
25 reset_all
26 end
27
28
29 @grains = []
30 @num_grains = ((rand 5)+2) *(10**((rand 2)+1))
31 #start with two source colors
32 @source_colors = [[rand(255), rand(255), rand(255), rand(30)+45],
33 [rand(255), rand(255), rand(255), rand(30)+45]]
34 #set the backgrond color to black
35 background 0
36 @num_grains.times do |i|
37 # initialize the sand grains with a
38 # random vector going in any direction
39 # starting from the center of the screen.
40 vx = (rand * 2) - 1 # random number between -1 and 1
41 vy = (rand * 2) - 1 # random number between -1 and 1
42 #magnitude multiplier based on the screen size
43 k = ((width+height)/2)/5.to_f
44 @grains[i] = Grain.new(width/2, height/2, k*vx, k*vy, i)
45 # vvt -= 0.00033
46 # vt += vvt
47 end
48 @grains.each {|grain| grain.find_target }
49 end
50
51
52 #randomly pick from one of the 2 source colors.
53 choice = @source_colors[rand(2)].dup
54 #boost the 4 elements of the color by upto 60
55 choice.map! {|c| c + rand * (60) }
56 # decrease the alpha by 30percent.
57 choice[3] = choice[3] * 0.7
58 #introduce random colors a 5th of the time
59 return choice
60 end
61 end
62
63 SandChaser.new :width => 500, :height => 258,
64 :title => "Sand Chaser", :full_screen => true
65
66
67 include Math
68 attr_reader :x, :y, :color, :index
69
70
71 @app = Processing::App.current
72 @x, @y = x, y
73 @vx, @vy = vx, vy
74 @index = index
75 @color = @app.some_color
76 end
77
78
79 #approach the target
80 if ( (@vx.abs + @vy.abs) > 0.001 &&
81 @x.between?(0, @app.width) &&
82 @y.between?(0, @app.height)
83 )
84 @vx += (@target.x - @x)
85 @vy += (@target.y - @y)
86 newX = @x + @vx*1/60.to_f; newY = @y + @vy*1/60.to_f
87 draw_from_point_to_point(@x, @y, newX, newY)
88 @x, @y = newX, newY
89 return 0
90 end
91 return 1
92 end
93
94
95 # draw points between the from and to coordinates
96 # to smooth out the effect.
97 smoothing_factor = 1
98 numberOfIncrements = @app.dist(fromX, fromY, toX, toY)
99 numberOfIncrements*=smoothing_factor.to_f
100
101 xDistance = ([fromX, toX].max - [fromX, toX].min)
102 xincrement = xDistance/numberOfIncrements.to_f
103 yDistance = ([fromY, toY].max - [fromY, toY].min)
104 yincrement = yDistance/numberOfIncrements.to_f
105
106 xDir, yDir = 1, 1
107 xDir = -1 if toX < fromX
108 yDir = -1 if toY < fromY
109
110 (numberOfIncrements.to_i+1).times do |i|
111 @app.stroke *@target.color
112 @app.point fromX+(i*xDir*xincrement), fromY+(i*yDir*yincrement)
113 end
114 end
115
116
117 #find another grain at random to follow.
118 @target = @app.grains[rand @app.grains.size]
119 end
120 end
No comments:
Post a Comment