てきとうなさいと べぇたばん

DXRubyでアナログ時計を作ってみる

下のスクリプトを実行すると、こんな時計になります。 時計。1秒進んでいます。 2秒進んだ。 4秒進んだ。 5秒たち、秒針が0をさした。

DXRubyでアナログ時計を作ってみる

アナログ時計を作ってみる。アナログ時計は、時針と分針、そして秒針とに別れる。よく見てみると、時針と分針は、秒針が動いている時に連動して動いている。

昔のバージョンなので、動くかどうかはわかりません。ご了承下さい

作ってみた

#!ruby -Ks

require "dxruby"

module Clock
  class Hari
    def initialize(width, height)
      @w = width
      @h = height

      @image = Image.new(@w, @h).boxFill(0, 0, @w, @h, [128,128,128])
    end

    def pos
      0
    end

    def forward
    end

    def draw(x, y)
      Window.drawRot(x, y, @image, ((360 / self.pos) * self.forward) - 180, @w / 2, 0)
    end
  end

  class Hour < Hari
    def pos
      12
    end

    def forward
      Time.now.hour + Time.now.min / 60.to_f
    end
  end

  class Min < Hari
    def pos
      60
    end

    def forward
      Time.now.min + Time.now.sec / 60.to_f
    end
  end

  class Sec < Hari
    def pos
      60
    end

    def forward
      Time.now.sec
    end
  end

  class Mark
    SMALLER = 10

    def initialize(width)
      @width = width + SMALLER

      @image = Image.new(@width * 2, @width * 2).circleFill(@width, @width, @width, [255, 255, 255])
      @color = [128,128,128] 

      self.mark
    end

    def mark
      60.times do |i|
        @image.circleFill(
          @width + Math.sin((6 * i) * (Math::PI / 180)) * (@width - SMALLER),
          @width + Math.cos((6 * i) * (Math::PI / 180)) * (@width - SMALLER),
          (i % 5 == 0 ? 4 : 2),
          @color
        )
      end
    end

    def draw(x, y)
      Window.draw(x - @width, y - @width, @image)
    end
  end

  class Clock
    def initialize(x, y)
      @hms = [Hour.new(5, 70), Min.new(3, 90), Sec.new(1, 90)]
      @mark = Mark.new(100)

      @x = x
      @y = y
    end

    def main
      @mark.draw(@x, @y)
      @hms.each do |hms|
        hms.draw(@x, @y)
      end
    end
  end
end


clock = Clock::Clock.new(320, 240)

Window.loop do
  clock.main
end

ちょっとマジックナンバーが多いけれど、まぁこんなものかなと。

Markクラスで時計のベースをImageクラスで作っておいて、Markクラスのdrawメソッドでそのベースを指定するってことにしといた。頻繁にというか、全く更新しない要素は、一度作っといてあとは表示させるだけとしといたほうがいいみたい。boxFillだと、左端の座標を指定することになってしまうので、実際の円と少しずれたりする。circleFillは、中心なのでずれることはなく、うまくいったのでこっちにした。

Hariクラスをベースにして、時針、分針、秒針を作る。時針は1分ごとに分を60で割っただけ進め、分針は1秒ごとに秒を60で割っただけ進むようにしている。動かしてみると、実際のアナログ時計よりもちょっとずつ動いているのが分かったりする。