ruby

Another Ruby tweet…

Was browsing the new Popular Science archives, which led to an article from 1984, which had a picture of the book Creative Graphics for the BBC Microcomputer, which led me to an archived copy of the book online, which had a dirt-simple program to draw Lissajous curves, which led me to write this tweetable Ruby version. (Phew!)

ruby -rcurses -e"include Curses;i=0;loop{setpos 12*(Math.sin(i)+1),40*(Math.cos(i*0.2)+1);addstr'.';i+=0.01;refresh}" #ruby
****         *******                ********                ******           **
*  *        **     **              **      **              **     *         * **
*  **       *       **            **        **            **       *        *  *
*   *      *         **          *           **          **        **      *   *
*   *      *          *         **             *         *          **     *   *
*    *    *            *        *              **       *            *    *    *
*    *   **             *      *                **     **            **   *    *
*    **  *              **    *                  *     *              *   *    *
*     * **               *   **                  **   *               ** *     *
*     * *                ** **                    *  *                 * *     *
*     * *                 * *                      * *                 **      *
*      **                  **                      **                   *      *
*      *                   **                       *                   *      *
*      **                 * *                      * *                 ***     *
*     * *                **  *                    *   *                * *     *
*     *  *               *   **                  **   *               ** *     *
*    *   *              *     *                  *     *              *  **    *
*    *   **            *       *                *      *             *    *    *
*   **    *            *       *               *        *            *    *    *
*   *     **          **        **            **         *          *      *   *
*   *      *         *           **           *          **         *      *   *
*  *        *       **            **        **            **       *       **  *
** *         *     **              **      **              **     **        * **
 **           ******                 *******                *******         ***

development
ruby

Permalink

Ruby Tweets!

ruby -e "i=0;loop{puts ' '*(29*(Math.sin(i)/2+1))+'|'*(29*(Math.cos(i)/2+1)); i+=0.1}" #ruby

about 23 hours ago via web

ruby -rtk -e "w=TkCanvas.new(TkRoot.new{title:paint});w.pack.bind('B1-Motion',proc{|x,y|TkcOval.new(w,x,y,x+4,y+4)},'%x %y').mainloop" #ruby

about 3 hours ago via web

Almost got this one short enough to tweet:

ruby -rtk -e"v,w=0,0;a=[1]*9;c=TkCanvas.new;c.pack.bind('Motion',proc{|x,y|a<<TkcLine.new(c,v,w,v=x,w=y,:arrow=>'last');a.shift.delete rescue 1},'%x %y').mainloop"

Ruby Tk

development
ruby

Permalink

Jemini Tutorial (Part 2 of 2)

In Part 2 of our tutorial, we’ll create some enemies for our player to fight. We’ll set up collision detection, use timers to make a pretty fading effect, and set up a custom manager to coordinate enemy movements and shooting.

Be sure to visit jemini.org for help on starting your own game!

You can view part 1 here.

Jemini Tutorial (Part 2 of 2)

development
games
ruby

Permalink

Jemini Tutorial (Part 1 of 2)

Jemini is a Ruby-based framework for game development. In this screencast, we’ll create a shooter game from scratch.

Part 1 shows creating a project, setting up a game state, loading animations, music and sound effects, and setting up keyboard input and event handlers. (Not bad for 22 minutes, right?)

You can view part 2 here.

Jemini Tutorial (Part 1 of 2)

development
games
ruby

Permalink

SVG On Acid…

Everything so far has relied on some tricky-to-install GUI gem… Working in SVG lets Ruby On Acid make pretty graphics (viewable in any modern browser) by outputting plain text.

Here’s a few samples. I’m sure I could produce more consistently pretty results with more SVG expertise, but that’s something I’ll have to play with another time.

1
2
3
4
5

Continue Reading »

development
ruby

Permalink

RubyConf in 22 Minutes video just posted by @greggpollack, featuring my handsome mug! I give the elevator pitch version of our Jemini talk.

http://blog.envylabs.com/2009/12/rubyconf-videos/

development
ruby

Permalink

Processing on Acid…

Got Ruby-Processing working with external libraries, so I can finally try it out with Ruby On Acid! My problem was that I couldn’t (or didn’t know how to) set the ruby load path with ruby-processing’s included “rp5″ tool. But on Marc Chung’s advice, I tried loading it into vanilla JRuby (had to do a small hack, but it worked). From there I was able to set $RUBYLIB, include it from a gem, whatever.

It’s fast, too, at least compared to wxRuby on MRI 1.8.7. My dual-core MacBook can draw 3000 shapes a second without breaking a sweat.
picture-8.pngpicture-7.pngpicture-6.png

OK, so here’s how to try it out yourself:

Save to acid_sketch.rb:

require 'rubygems'
require 'ruby-processing'
require 'rubyonacid/factories/meta'
require 'rubyonacid/factories/combination'
require 'rubyonacid/factories/constant'
require 'rubyonacid/factories/flash'
require 'rubyonacid/factories/loop'
require 'rubyonacid/factories/random'
require 'rubyonacid/factories/repeat'
require 'rubyonacid/factories/sine'
require 'rubyonacid/factories/skip'

class Sketch < Processing::App

  def setup
    @f = create_factory
    @resetter = RubyOnAcid::SkipFactory.new(0.9999)
    background 0
    smooth
    ellipse_mode CENTER
    rect_mode CENTER
  end
  def draw
    10.times do
      fill(
        @f.get(:red, :max => 255),
        @f.get(:green, :max => 255),
        @f.get(:blue, :max => 255),
        @f.get(:alpha, :max => 255)
      )
      no_stroke
      ellipse(
        @f.get(:x, :max => width),
        @f.get(:y, :max => height),
        @f.get(:width, :max => 100),
        @f.get(:height, :max => 100)
      )
      @f.reset_assignments if @resetter.boolean(:reset)
    end
  end

  def create_factory

    random_factory = RubyOnAcid::RandomFactory.new

    source_factories = []
    #Loop factories loop from 0.0 to 1.0 (or 1.0 to 0.0 if the increment value is negative).
    source_factories << RubyOnAcid::LoopFactory.new(0.01)
    source_factories << RubyOnAcid::LoopFactory.new(-0.01)
    source_factories << RubyOnAcid::LoopFactory.new(0.001)
    source_factories << RubyOnAcid::LoopFactory.new(-0.001)
    #Constant factories always return the same value,
    source_factories << RubyOnAcid::ConstantFactory.new(rand)
    source_factories << RubyOnAcid::ConstantFactory.new(rand)
    source_factories << RubyOnAcid::FlashFactory.new(rand(100))
    #Sine factories produce a "wave" pattern.
    source_factories << RubyOnAcid::SineFactory.new(0.1)
    source_factories << RubyOnAcid::SineFactory.new(-0.1)
    source_factories << RubyOnAcid::SineFactory.new(0.01)
    source_factories << RubyOnAcid::SineFactory.new(-0.01)
    #A RepeatFactory wraps another factory, queries it, and repeats the same value a certain number of times.
    source_factories << RubyOnAcid::RepeatFactory.new(
      RubyOnAcid::LoopFactory.new(random_factory.within(:increment, -0.1, 0.1)),
      random_factory.get(:interval, :min => 2, :max => 100)
    )
    source_factories << RubyOnAcid::RepeatFactory.new(
      RubyOnAcid::SineFactory.new(random_factory.within(:increment, -0.1, 0.1)),
      random_factory.get(:interval, :min => 2, :max => 100)
    )
    #A CombinationFactory combines the values of two or more other factories.
    combination_factory = RubyOnAcid::CombinationFactory.new
    2.times do
      combination_factory.source_factories << source_factories[rand(source_factories.length)]
    end
    source_factories << combination_factory

    #The MetaFactory pulls requested value types from the other factories.
    meta_factory = RubyOnAcid::MetaFactory.new
    meta_factory.factory_pool = source_factories

    meta_factory

  end
end

Processing::SKETCH_PATH = ""

Sketch.new :title => “Ruby On Acid”, :width => 800, :height => 600, :full_screen => false
jay@dandelion:~/Projects/ruby-processing
$ sudo jruby -S gem install ruby-processing
jay@dandelion:~/Projects/ruby-processing
$ sudo jruby -S gem install rubyonacid
jay@dandelion:~/Projects/ruby-processing
$ jruby acid_sketch.rb

development
java
ruby

Permalink

RubyConf wrapup…

RubyConf was awesome, and I’d like to think we made our contribution. The Jemini talk generated a lot of interested questions, and I’m pretty happy with the approach of using a screencast instead of slides (though we’ll see how it turns out in the Confreaks video). Last night Logan and I set up in the lobby with Life-Tank and our collection of XBox controllers, which attracted quite a few players and comments of “I gotta try this library when I get home”.

Enjoyed the Bay Area Computer Music Technology meetup at Pier 38, too. Got to promote Ruby On Acid, too. I showed off the usual graphical stuff, then the 8-bit PCM/WAV (”drunk Atari 2600″) sound and MIDI demos that I hacked together for the meetup. The audio demos need some experimentation before they’re ready for prime time, but I’d say the same of most things shown that evening. The other presenters clearly had more music composition education and/or experience, but I got a surprisingly warm reception anyway.

Had a lot of fun in SF. Great conference, great city, great people. If the right company is hiring I will definitely consider moving here.

development
ruby

Permalink

Sound waves on acid…

Looks like I’ll be talking on using Ruby on Acid for audio at a meetup in San Francisco during RubyConf. So, time to make sure it can actually do audio. :)

This would probably horrify anyone with audio programming experience, but: I just write a bunch of bytes ranging 0-255 to a file, then import into audacity as raw 8-bit PCM data.

require 'rubygems'
require 'rubyonacid/factories/meta'
require 'rubyonacid/factories/constant'
require 'rubyonacid/factories/flash'
require 'rubyonacid/factories/loop'
require 'rubyonacid/factories/modulo'
require 'rubyonacid/factories/random'
require 'rubyonacid/factories/repeat'
require 'rubyonacid/factories/sine'
require 'rubyonacid/factories/skip'

def generate_factories

  random_factory = RubyOnAcid::RandomFactory.new

  factory_pool = []

  #Loop factories loop from 0.0 to 1.0 (or 1.0 to 0.0 if the increment value is negative).
  factory_pool << RubyOnAcid::LoopFactory.new(random_factory.within(:increment, -0.01, 0.01))
  #Constant factories always return the same value,
  factory_pool << RubyOnAcid::ConstantFactory.new(rand)
  factory_pool << RubyOnAcid::ConstantFactory.new(rand)
  factory_pool << RubyOnAcid::FlashFactory.new(rand(100))
  #Sine factories produce a "wave" pattern.
  factory_pool << RubyOnAcid::SineFactory.new(random_factory.within(:increment, -0.01, 0.01))
  factory_pool << RubyOnAcid::RepeatFactory.new(
    RubyOnAcid::LoopFactory.new(random_factory.within(:increment, -0.1, 0.1)),
    random_factory.within(:interval, 2, 100)
  )
  factory_pool << RubyOnAcid::RepeatFactory.new(
    RubyOnAcid::SineFactory.new(random_factory.within(:increment, -0.1, 0.1)),
    random_factory.within(:interval, 2, 100)
  )
  factory_pool << RubyOnAcid::ModuloFactory.new(RubyOnAcid::LoopFactory.new(0.00001))
  factory_pool
end

#A skip factory, in charge of randomly resetting the meta factory.
@resetter = RubyOnAcid::SkipFactory.new(0.99995)

factory = RubyOnAcid::MetaFactory.new
factory.factory_pool = generate_factories
File.open("raw_audio.dat", "w") do |file|
  loop do
    channel_count = factory.within(:chanel_count, 0, 3).to_i
    channel_count.times do |i|
      file.putc factory.within(i, 0, 255).to_i
    end
    if @resetter.boolean(:reset)
      factory.factory_pool = generate_factories
      factory.reset_assignments
    end
  end
end

The result is a tour of every sound ever emitted by an Atari 2600:

Ruby On Acid 8-bit raw sound…

I also have a MIDI experiment going. Neither is spectacular, but the nice part is that the programs needn’t change; I just need better generators.

ruby

Permalink

Hi-res Ruby On Acid wallpapers…

Went back and re-rendered some of my favorites at 1080p resolution (should scale down to widescreen monitors nicely).
007910006901237

development
ruby

Permalink