GTK+ で落書き 11(Ruby)


スクリーンセーバーみたいなものを Ruby で描いてみました。円が大きくなったり小さくなったりしながら落下していきます。

自画自賛ですけれど、これ結構好きです。

描画には自作の Gem 'oekaki' を使っています。
oekaki | RubyGems.org | your community gem host
GTK+でお絵かきしてみた(Ruby) - Camera Obscura

require 'oekaki'

Width, Height = if ARGV.size == 2
  ARGV.map(&:to_i)
else
  [1000, 700]
end

Max_r, Min_r = 40, 10
ColorMax = 65535
MaxNum = 60

class Circle
  def initialize(ob)
    @slot = ob
    renewal
    @y = rand(Height)
  end
  
  def renewal
    @max_r = rand(Max_r - Min_r) + Min_r
    @x =  rand(Width)
    @y = -rand(@max_r)
    @color = [rand(ColorMax), rand(ColorMax), rand(ColorMax)]
    @fall_step = 1 + rand * 3
    @r = 1
    @r_step = rand * 0.2 + 0.8
  end

  def paint
    @slot.color(@color[0], @color[1], @color[2])
    @slot.circle(true, @x, @y, @r)
    @y += @fall_step
    @r += @r_step
    @r_step *= -1 if @r > @max_r or @r < 1
    renewal if @y > Height + Max_r
    true
  end
end


Oekaki.app width: Width, height: Height do
  circles = []
  MaxNum.times {circles << Circle.new(self)}

  draw do
    color(0, 0, 0)  
    rectangle(true, 0, 0, Width, Height)
  end

  timer(80) do
    color(0, 0, 0)  
    rectangle(true, 0, 0, Width, Height)
    circles.each(&:paint)
  end
end

円によって落下速度や点滅測度が微妙に変えてあります。円の総数はいつも同じで、定数 MaxNum に入っています。

Gem 'oekaki' のバージョンは最新の 0.0.11 が必要です。古いバージョンならば、上の @slot.circle(true, @x, @y, @r)@slot.arc(true, @x - @r, @y - @r, 2 * @r, 2 * @r, 0, 64 * 360) に代えて下さい。それで動きます。


※追記
以上は Linux Mint 18.2, Ruby 2.3.3 で確認しましたが、Windows 8.1, Ruby 2.2.2 [i386-mingw32] でもそのまま動くことを確認しました。ただ、Windows 版ではなぜか画面がちらつきますし、Linux Mint で実行したよりよりも動きがなめらかでないです。