サイン曲線を動かす

関数の曲線を描く練習でサイン曲線を描いた。
後、サイン曲線に添って円をレイアウトした。
ついでだから、横に動かしてみた。

#!usr/bin/env ruby

require 'sdl'
require 'cairo'

class BackGround
def initialize(w, h)
@w, @h = w, h
end

def update(c)
c.set_source_color(Cairo::Color::X11::WHITE)
c.rectangle(0, 0, @w, @h)
c.fill
end
end

class SinCurve
def initialize(w, h)
@w, @h = w, h
@x, @y = @w / 2, @h / 3
@vx, @vy = 5, 35
@hz = 4
@vectors = []
pitch = 10
i = -180 * @hz / pitch
(-@hz * Math::PI .. @hz * Math::PI).step(pitch * Math::PI / 180) do |r|
@vectors << [i * @vx, Math::sin(r) * @vy]
i += 1
end
end

def update(c)
@x += 1
@x = @w / 2 if @x == @w / 2 + @vx * 36
c.matrix = Cairo::Matrix.translate(@x, @y)
c.set_source_color(Cairo::Color::X11::BLACK)
c.set_line_width(8)
c.set_dash([25, 10, 10, 10], 5)
@vectors.inject(true) do |b, v|
x, y = v
if b
c.move_to(x, y)
else
c.line_to(x, y)
end
b = false
end
c.stroke
end
end

class Barrage < SinCurve
def initialize(w, h)
super
@y = h / 3 * 2
end

def update(c)
@x -= 1
@x = @w / 2 if @x == @w / 2 - @vx * 36
c.matrix = Cairo::Matrix.translate(@x, @y)
c.set_source_color(Cairo::Color::X11::ORANGE)
@vectors.inject(0) do |i, v|
if i % 3 == 0
x, y = v
c.circle(x, y, 5)
c.fill
end
i += 1
end
end
end

class Phase
def initialize(screen)
@screen = screen
@w, @h = @screen.w, @screen.h
@image = Cairo::ImageSurface.new(@w, @h)
@bg = BackGround.new(@w, @h)
@wave = SinCurve.new(@w, @h)
@barrage = Barrage.new(@w, @h)
end

def update
context = Cairo::Context.new(@image)
@bg.update(context)
@wave.update(context)
@barrage.update(context)
surface = SDL::Surface.new_from(@image.data, @image.width, @image.height, 32, @image.stride, 0, 0, 0, 0)
@screen.put(surface, 0, 0)
end

def run
loop do
while e=SDL::Event.poll
exit if e.kind_of?(SDL::Event::Quit) || (e.kind_of?(SDL::Event::KeyDown) && e.sym == SDL::Key::ESCAPE)
end
self.update
@screen.flip
SDL.delay(20)
end
end
end

SDL.init(SDL::INIT_VIDEO)
@screen = SDL::Screen.open(300, 300, SDL::Screen.info.bpp, SDL::SWSURFACE)
Phase.new(@screen).run
[PR]
by gaziya | 2011-05-18 20:14