人気ブログランキング | 話題のタグを見る

部品をバウンドさせる 2

反転(鏡映)の行列は
y軸での反転 Cairo::Matrix.scale(-1, 1)
x軸での反転 Cairo::Matrix.scale(1, -1)
で、できる。
ネットをみていたら、見つけた。いける!!
思いつきもしなかった。
さっそく、試した。

#!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::BLACK)
c.rectangle(0, 0, @w, @h)
c.fill
end
end

class Ball
def initialize(w, h)
@x, @y = w / 2, h / 2
@r = 10
@color = Cairo::Color::ORANGE
@erx = @r .. w - @r
@ery = @r .. h - @r
@vx, @vy = rand(5) + 2, rand(5) + 2
@vx *= -1 if rand(9) < 5
@vy *= -1 if rand(9) < 5
end

def update(c)
@vx, @vy = Cairo::Matrix.scale(-1, 1).transform_point(@vx, @vy) if !@erx.include?(@x + @vx)
@vx, @vy = Cairo::Matrix.scale(1, -1).transform_point(@vx, @vy) if !@ery.include?(@y + @vy)
@x += @vx
@y += @vy
c.matrix = Cairo::Matrix.translate(@x, @y)
c.set_source_color(@color)
c.circle(0, 0, @r)
c.fill
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)
@ball = Ball.new(@w, @h)
end

def update
context = Cairo::Context.new(@image)
@bg.update(context)
@ball.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(350, 250, SDL::Screen.info.bpp, SDL::SWSURFACE)
Phase.new(@screen).run
by gaziya | 2011-05-20 17:21