require "../src/game" require "../src/controller" require "../src/sprite" require "../src/pixel" require "../src/vector" require "../src/pixel_text" class Wind property width : Int32 property height : Int32 property density : Int32 property gusts : Array(Gust) = [] of Gust @step : Float64? struct Gust property position : PF::Vector2(Float64) property strength : PF::Vector2(Float64) def initialize(@position, @strength) end end def initialize(@width, @height, @density = 20) setup_vectors end def step @step ||= (@width / @density) end def setup_vectors @gusts = [] of Gust y = step / 2 while y < @height x = step / 2 while x < @width @gusts << Gust.new(PF::Vector[x, y], PF::Vector[rand(-1.0..1.0), rand(-1.0..1.0)]) x += step end y += step end end end class Flake property shape : UInt8 property position : PF::Vector2(Float64) property z_pos : Float64 property velocity : PF::Vector2(Float64) def initialize(@position, @shape = rand(0_u8..2_u8), @z_pos = rand(0.0..1.0), velocity : PF::Vector2(Float64)? = nil) @velocity = velocity || PF::Vector[rand(-2.0..2.0), rand(0.0..20.0)] end def update(dt) @velocity.y = @velocity.y + 1.0 * dt @position += @velocity * dt end end class Snow < PF::Game @wind : Wind @last_flake : Float64 = 0.0 @flakes : Array(Flake) = [] of Flake def initialize(*args, **kwargs) super @wind = Wind.new(@width, @height) clear(0, 0, 15) end def update(dt, event) @last_flake += dt if @last_flake >= 0.025 @last_flake = 0.0 @flakes << Flake.new(position: PF::Vector[rand(0.0..@width.to_f64), 0.0]) end @flakes.reject! do |flake| @wind.gusts.each do |gust| size = @wind.step / 3 if flake.position > gust.position - size && flake.position < gust.position + size flake.velocity = flake.velocity + gust.strength * 3 * dt end end flake.update(dt) flake.position.y > @height end end def draw clear(0, 0, 15) @flakes.each do |flake| color = PF::Pixel.white * flake.z_pos if flake.shape == 0 draw_point(flake.position.to_i32, color) else fill_circle(flake.position.to_i32, flake.shape, color) end end end end engine = Snow.new(1200, 800, 1, window_flags: SDL::Window::Flags::RESIZABLE | SDL::Window::Flags::SHOWN) engine.run!