#!ruby -Ku # -*- mode: ruby; coding: utf-8 -*- # Last updated: <2017/04/11 21:40:08 +0900> # # generate pixelart test # # usage: ruby fillpixelrect.rb # # space key : new generate # # Runtime Dependencies # color >= 1.8 # dxruby >= 1.4.5 module FillPixelRect require 'color' # fill a rectangle with a gradient # # @param buf [Array] pixels array # @param left_x [Integer] left # @param top_y [Integer] top # @param width [Integer] width # @param height [Integer] height # @param hsla0 [Array] hue, saturation, luminosity, alpha # @param hsla1 [Array] hue, saturation, luminosity, alpha # @param horizontal [true, false] horizontal gradation # @return [Array] pixels def fill_pixel_rect(buf, left_x, top_y, width, height, hsla0, hsla1, horizontal) return if (width == 0 or height == 0) canvas_w, canvas_h = buf[0].size, buf.size x0 = left_x y0 = top_y x1 = x0 + width - 1 y1 = y0 + height - 1 h0, s0, l0, a0 = hsla0 h1, s1, l1, a1 = hsla1 if horizontal # horizontal gradation (x0..x1).each do |nx| next if (nx < 0 or nx >= canvas_w) if x0 == x1 hn = (h0 + h1) / 2.0 ln = (l0 + l1) / 2.0 sn = (s0 + s1) / 2.0 an = ((a0 + a1) / 2.0).to_i else ratio = (nx - x0).to_f / (x1 - x0) hn = h0 + (h1 - h0) * ratio ln = l0 + (l1 - l0) * ratio sn = s0 + (s1 - s0) * ratio an = (a0 + (a1 - a0) * ratio).to_i end rgb = Color::HSL.new(hn, sn, ln).to_rgb r, g, b = rgb.red.to_i, rgb.green.to_i, rgb.blue.to_i (y0..y1).each do |ny| next if (ny < 0 or ny >= canvas_w) buf[ny][nx] = [r, g, b, an] end end else # vertical gradation (y0..y1).each do |ny| next if (ny < 0 or ny >= canvas_h) if y0 == y1 hn = (h0 + h1) / 2.0 ln = (l0 + l1) / 2.0 sn = (s0 + s1) / 2.0 an = ((a0 + a1) / 2.0).to_i else ratio = (ny - y0).to_f / (y1 - y0) hn = h0 + (h1 - h0) * ratio ln = l0 + (l1 - l0) * ratio sn = s0 + (s1 - s0) * ratio an = (a0 + (a1 - a0) * ratio).to_i end rgb = Color::HSL.new(hn, sn, ln).to_rgb r, g, b = rgb.red.to_i, rgb.green.to_i, rgb.blue.to_i (x0..x1).each do |nx| next if (nx < 0 or nx >= canvas_w) buf[ny][nx] = [r, g, b, an] end end end return buf end # mirror x pixels # @param buf [Array] pixels # @return [Array] pixels def mirror_x(buf) w, h = buf[0].size, buf.size xx = (w / 2.0).round x = 0 x1 = w - 1 while x < xx h.times do |y| r, g, b, a = buf[y][x] buf[y][x1] = [r, g, b, a] end x += 1 x1 -= 1 end return buf end # mirror y pixels # @param buf [Array] pixels # @return [Array] pixels def mirror_y(buf) w, h = buf[0].size, buf.size yy = (h / 2.0).round y = 0 y1 = h - 1 while y < yy buf[y1] = buf[y] y += 1 y1 -= 1 end return buf end end if $0 == __FILE__ # ---------------------------------------- # usage sample require 'dxruby' include FillPixelRect # Array to DXRuby Image # @param buf [Array] pixels array # @return [Image] DXRuby Image def array_to_image(buf) w, h = buf[0].size, buf.size img = Image.new(w, h, [0, 0, 0, 0]) h.times do |y| w.times do |x| r, g, b, a = buf[y][x] img[x, y] = [a, r, g, b] end end return img end # generate pixelart # @param w [Integer] pixelart width # @param h [Integer] pixelart height # @param cnt [Integer] pixelart number # @param seed [Integer] random seed def generate_rect(w, h, cnt, seed) imgs = [] srand(seed) cnt.times do |i| buf = Array.new(h) { Array.new(w) { Array.new(4, 0) } } hue_base = rand * 360 32.times do |i| wh, hh = w / 2, h / 2 rx = (rand(wh) + rand(wh) + rand(wh)) / 3 ry = (rand(hh) + rand(hh) + rand(hh)) / 3 rw = rand((w - rx) / 2) + 1 rh = rand((h - ry) / 2) + 1 hue = (hue_base + rand(30)) % 360 sat = 10 + rand(90) l0 = 10 + rand(90) l1 = 10 + rand(90) hor = (rand > 0.5)? true : false hsla0 = [hue, sat, l0, 255] hsla1 = [hue, sat, l1, 255] fill_pixel_rect(buf, rx, ry, rw, rh, hsla0, hsla1, hor) end buf = mirror_x(buf) if rand > 0.5 buf = mirror_y(buf) if rand > 0.5 img = array_to_image(buf) imgs.push(img) end return imgs end w, h = 64, 64 seed = 0 cnt = 54 imgs = generate_rect(w, h, cnt, seed) seed += cnt Window.bgcolor = [32, 96, 128] # Window.scale = 2 Window.loop do break if Input.keyPush?(K_ESCAPE) if Input.keyPush?(K_SPACE) imgs = generate_rect(w, h, cnt, seed) seed += cnt end x, y = 0, 0 imgs.each do |img| Window.draw(x, y, img) x += img.width + 4 if x + img.width >= Window.width y += img.height + 4 x = 0 end end end end