Suporte ao desenvolvimento de jogos!


    Adições a classe Color

    Compartilhe

    Cidiomar
    Semi-Experiente
    Semi-Experiente

    Mensagens : 115
    Créditos : 51

    Adições a classe Color

    Mensagem por Cidiomar em Dom Jan 29, 2012 3:01 am

    Bem, passei algumas das funções da classe Color da minha engine para o RPGMaker VXAce

    Não devo mais precisar desde script, por tanto não devo mais atualiza-lo, então resolvi postar.

    Código:

    #--------------------------------------------------
    # Color class Helper
    #--------------------------------------------------
    # Created by Cidiomar
    #--------------------------------------------------
    class Color
      #----------
      include Comparable
      #----------
      alias :cidi_dk_initialize :initialize
      def initialize(*args)
        if args.length == 1 and args[0].is_a?(String)
          raise ArgumentError, "empty string passed as hex code", caller(1) if args[0].empty?
          #-----
          h_str = args[0].dup
          h_str[0 .. 1] = '' if h_str[0..1] =~ /0[xX]/
          case h_str.length
            when 6 # 24 bits RGB
              set_RGBA24(h_str.hex)
            when 8 # 32 bits RGBA
              set_RGBA32(h_str.hex)
            when 3 # 12 bits RGBA
              set_RGBA12(h_str.hex)
            when 4 # 16 bits RGBA
              set_RGBA16(h_str.hex)
            when 2 #  8 bits escala de cinza
              set_Gray8(h_str.hex)
            when 1 #  4 bits escala de cinza
              set_Gray4(h_str.hex)
            when 5 # 12 bits RGB + 8 bits alpha
              set_RGB12(h_str.hex & 0xFFF00)
              self.alpha = h_str.hex & 0xFF
            when 7 # 24 bits RGB + 4 bits alpha
              set_RGB24(h_str.hex & 0xFFFFFF0)
              self.alpha = (h_str.hex & 0xF) * 0xF
            else
              l    = h_str.length
              pixel = h_str.hex & 0xFFFFFFFF
              #----
              if l > 8
                r = (pixel >> 24) & 0xFF
                g = (pixel >> 16) & 0xFF
                b = (pixel >>  8) & 0xFF
                a = (pixel) & 0xFF
              end
          end
        else
          case args.length
            when 0
              cidi_dk_initialize(0, 0, 0, 0)
            when 1
              cidi_dk_initialize(args[0], 0, 0, 0xFF)
            when 2
              cidi_dk_initialize(args[0], args[1], 0, 0xFF)
            else
              cidi_dk_initialize(*args)
          end
        end
      end
      #----------
      def set_from_hex(h_str)
        raise ArgumentError, "empty string passed as hex code", caller(1) if s_str.empty?
        self.set(Color.new(h_str))
      end
      #----------
      def set_RGBA32(pixel)
        self.set((pixel >> 24) & 0xFF, (pixel >> 16) & 0xFF, (pixel >>  8) & 0xFF, (pixel) & 0xFF)
      end
      #----------
      def set_RGBA16(pixel)
        r, g, b, a = (pixel >> 12) & 0xF, (pixel >> 8) & 0xF, (pixel >>  4) & 0xF, (pixel) & 0xF
        self.set(r * 0xF, g * 0xF, b * 0xF, a * 0xF)
      end
      #----------
      def set_RGB24(pixel)
        self.set((pixel >> 16) & 0xFF, (pixel >> 8) & 0xFF, (pixel) & 0xFF)
      end
      #----------
      def set_RGB12(pixel)
        r, g, b, a = (pixel >> 8) & 0xF, (pixel >> 4) & 0xF, (pixel) & 0xF
        self.set(r * 0xF, g * 0xF, b * 0xF)
      end
      #----------
      def set_Gray8(g, alpha = 0xFF)
        self.set(g, g, g, alpha)
      end
      #----------
      def set_Gray4(g, alpha = 0xFF)
        self.set(g * 0xF, g * 0xF, g * 0xF)
      end
      #----------
      def to_RGBA32
        (self.red.to_i << 24) | (self.green.to_i << 16) | (self.blue.to_i <<  8) | (self.alpha.to_i)
      end
      #----------
      def to_RGBA16
        (self.red.to_i / 0xF << 12) | (self.green.to_i / 0xF << 8) | (self.blue.to_i / 0xF <<  4) | (self.alpha.to_i / 0xF)
      end
      #----------
      def to_RGB24
        (self.red.to_i << 16) | (self.green.to_i << 8) | (self.blue.to_i)
      end
      #----------
      def to_RGB12
        (self.red.to_i / 0xF << 8) | (self.green.to_i / 0xF << 4) | (self.blue.to_i)
      end
      #----------
      def to_Gray8
        ((self.red + self.green + self.blue) / 3).to_i & 0xFF
      end
      #----------
      def to_Gray4
        ((self.red + self.green + self.blue) / (3 * 0xF)).to_i & 0xF
      end
      #----------
      def blend(other)
        raise ArgumentError, "Can't convert #{other.class.to_s} in Color" unless other.is_a?(Color)
        #-----
        a1    = self.alpha  / 255.0
        a2    = other.alpha / 255.0
        result = Color.new
        result.red  = (a1 * self.red  + a2 * (1 - a1) * other.red)
        result.green = (a1 * self.green + a2 * (1 - a1) * other.green)
        result.blue  = (a1 * self.blue  + a2 * (1 - a1) * other.blue)
        result.alpha = (255 * (a1 + a2 * (1 - a1)));
        result
      end
      #----------
      def to_a
        [self.red, self.green, self.blue, self.alpha]
      end
      #----------
      def <=>(other)
        raise ArgumentError, "Can't convert #{other.class.to_s} in Color" unless other.is_a?(Color)
        return  0 if self.object_id == other.object_id
        return -1 if self.alpha < other.alpha
        return  1 if self.alpha > other.alpha
        #-----
        avg1 = ((self.red  + self.green  + self.blue) / 3)
        avg2 = ((other.red + other.green + other.blue) / 3)
        #-----
        return avg1 <=> avg2
      end
      #----------
      ['+', '-', '*', '/'].each {|op|
        class_eval "
      def #{op}(other);
        if other.is_a?(Color);
          s, o = self.to_a, other.to_a;
          s.each_index {|i| s[i] #{op}= o[i] };
          Color.new(*s);
        elsif other.is_a?(Numeric);
          s = self.to_a;
          s.each_index {|i| s[i] #{op}= other };
          Color.new(*s);
        else;
          raise ArgumentError, sprintf(\"Can't convert %s in Color\", other.class.to_s), caller(1);
        end;
      end;
      "}
      #-----
      [['add', '+'], ['subtract', '-'], ['mutiply', '*'], ['divide', '/']].each {|op|
        class_eval "
      def #{op[0]}(other);
        if other.is_a?(Color);
          s, o = self.to_a, other.to_a;
          s.each_index {|i| s[i] #{op[1]}= o[i] };
          self.set(*s);
        elsif other.is_a?(Numeric);
          s = self.to_a;
          s.each_index {|i| s[i] #{op[1]}= other };
          self.set(*s);
        else;
          raise ArgumentError, sprintf(\"Can't convert %s in Color\", other.class.to_s), caller(1);
        end;
      end
      "}
      #----------
      def invert
        self.set(self.to_a.collect! {|v| 255 - v})
      end
      alias :!@ :invert
      alias :~@ :invert
      #----------
      def distance(other)
        self.to_RGBA32 - other.to_RGBA32
      end
      #----------
      LUMINANCE_MOD_RED  = (0.2126 / 255.0)
      LUMINANCE_MOD_BLUE  = (0.7152 / 255.0)
      LUMINANCE_MOD_GREEN = (0.0722 / 255.0)
      def luminance
        lum = (LUMINANCE_MOD_RED * self.red) + (LUMINANCE_MOD_GREEN * self.green) +(LUMINANCE_MOD_BLUE * self.blue)
        return 0.0 if lum < 0.0
        return 1.0 if lum > 1.0
        return lum
      end
      #----------
      def opaque?
        self.alpha == 255
      end
      #----------
      def inspect
        sprintf("<(%s)  red: %d, green: %d, blue: %d, alpha: %d; pixel: 0x%08x>", self.class, self.red.to_i, self.green.to_i, self.blue.to_i, self.alpha.to_i, self.to_RGBA32)
      end
      #----------
      def self.RGBA32(pixel)
        Color.new((pixel >> 24) & 0xFF, (pixel >> 16) & 0xFF, (pixel >>  8) & 0xFF, (pixel) & 0xFF)
      end
      #----------
      def self.RGBA16(pixel)
        Color.new((pixel >> 12) & 0xF, (pixel >> 8) & 0xF, (pixel >>  4) & 0xF, (pixel) & 0xF)
      end
      #----------
      def self.RGB24(pixel)
        Color.new((pixel >> 16) & 0xFF, (pixel >> 8) & 0xFF, (pixel) & 0xFF)
      end
      #----------
      def self.RGB12(pixel)
        Color.new((pixel >> 8) & 0xF, (pixel >> 4) & 0xF, (pixel) & 0xF)
      end
      #----------
      def self.Gray8(g)
        Color.new(g, g, g)
      end
      #----------
      def self.Gray4(g)
        Color.new(g * 0xF, g * 0xF, g * 0xF)
      end
      #----------
    end




    Ele adiciona funcionalidades como:
    criar cores tendo códigos hexadecimais como argumento,
    converter entre hex color em integers pra Color e o inverso,
    funções de comparação,
    pixel blending,
    inversão de cor,
    calculo de luminosidade,
    operações matemáticas,
    cálculos de distancia,
    conversão de co em um Array

      Data/hora atual: Sex Out 19, 2018 2:04 am