スクリーンセイバーに使えないかな?

弾幕のモデルを、いじっていたら、生き物っぽく見えてきた。
それで、ちょっと改造。
スクリーンセイバーになりそうな気がする。


#!usr/bin/env ruby

require 'sdl'
require 'cairo'

class BackGround
def initialize(info)
@w,@h = info.w,info.h
@color = Cairo::Color::BLACK
end

def update(c)
c.set_source_color(@color)
c.rectangle(0, 0, @w, @h)
c.fill
end
end

class Core
attr_reader :x,:y
attr_accessor :dx,:dy

def initialize(info)
@info = info
@color = Cairo::Color::ORANGE
@x = @info.w / 2
@y = @info.h / 2
@r = 6
@dx,@dy = 0,0
end

def update(c)
@x += @dx * 5
@x = @r if @x < @r
@x = @info.w - @r if @x >= @info.w - @r
@y += @dy * 5
@y = @r if @y < @r
@y = @info.h - @r if @y >= @info.h - @r
c.set_source_color(@color)
c.circle(@x, @y, @r)
c.fill
end
end

class Barrage
attr_reader :alive

def initialize(x,y,r,g,b)
@x,@y = x,y
@r,@g,@b = r,g,b
@br = 2
@pr = 8
@d = 10
angle_size = 60
step = 360 / angle_size
@vector = []
0.step(359, step) do |d|
r= d * Math::PI / 180
@vector << [Math::cos(r), Math::sin(r)]
end
@alive = true
@limit = 200
end

def update(c)
@pr += @d
return @alive = false if @pr > @limit
c.set_source_rgb(@r,@g,@b)
@vector.each do |x,y|
px,py = @pr * x + @x, @pr * y + @y
c.circle(px, py, @br)
c.fill
end
end
end

class Phase
def initialize(info)
@info = info
@surface = Cairo::ImageSurface.new(@info.w,@info.h)
@bg = BackGround.new(@info)
@core = []
3.times do
@core << Core.new(@info)
end
@barrages = []
@move_ticks = 0
end

def update
if @move_ticks % 10 == 0
@core .each do |obj|
obj.dx = [0, 1, -1][rand(30) % 3]
obj.dy = [0, 1, -1][rand(30) % 3]
end
end
@move_ticks += 1
@barrages.reject!{|obj| !obj.alive}
r,g,b = rand / 2 + 0.5, rand / 2 + 0.5, rand / 2 + 0.5
@core .each do |obj|
@barrages << Barrage.new(obj.x, obj.y, r, g, b)
end
context = Cairo::Context.new(@surface)
@bg.update(context)
@barrages.each {|obj| obj.update(context)}
@core.each {|obj| obj.update(context)}
@surface
end
end

class Game
def initialize(screen)
@screen = screen
info = Struct.new(:w,:h)
@info = info.new(@screen.w,@screen.h)
@phase = Phase.new(@info)
end

def update
cairo = @phase.update
suface = SDL::Surface.new_from(cairo.data,@info.w,@info.h,32,cairo.stride,0,0,0,0)
@screen.put(suface,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(10)
end
end
end

SDL.init(SDL::INIT_VIDEO)
w,h = 800,500
@screen = SDL::Screen.open(w,h,SDL::Screen.info.bpp,SDL::SWSURFACE)
Game.new(@screen).run
[PR]
by gaziya | 2011-05-08 22:13