LNS020 Color拡張

Colorの機能を拡張し、HSV Color と HSL Color を追加します。





基本情報

前提スクリプト

なし

拡張タイプ

△ 開発用 (導入するだけでは特に変化しない)


説明

概要

 通常 (red, green, blue, alpha) で定義される Color クラスに対して、(hue, saturation, lightness) で定義される HSL_Color クラスと、(hue, saturation, value) で定義される HSV_Color クラスを追加します。

  • HSL_Color と HSV_Color は Color のサブクラスです。つまり、Bitmap#draw_text などの、Color を引数に取る RGSS3組み込みメソッドに対応しています。
  • HSL と HSV は、色の明るさ(Lightness, Value)をどう表すかで異なります。
    • HSL の場合、輝度(Lightness)が 0.5 のとき原色で、0 で黒、1.0 で白になります。
    • HSV の場合、彩度(Saturation)によって明度(Value)の意味が決まります。
      • 彩度が 1 の場合:明度が 1 のとき原色で、0 で黒になります。
      • 彩度が 0 の場合:明度が 1 のとき 白 で、0 で黒になります。
  • 詳しくはこのあたりをご参照ください。

使い方

HSL_Color.new(color)

HSV_Color.new(color)

color の RGB 値を HSL/HSV 形式に変換して生成します。
color = Color.new(255, 0, 0)
p color2 = HSL_Color.new(color)   #=> HSL(0.0, 1.0, 0.5, 255.0)

HSL_Color.new(hue, saturation, lightness[, alpha])

HSV_Color.new(hue, saturation, value[, alpha])

パラメータを直接指定して生成します。
c1 = HSV_Color.new(  0, 1, 1)  #=> RGB(255, 0, 0)
c2 = HSV_Color.new(240, 1, 1)  #=> RGB(0, 0, 255)

注意

  • HSL_Color と HSV_Color は、red=() などプロパティを直接設定するメソッドには追従しません。
color2.red = 0
p color2            #=> HSL(0.0, 1.0, 0.5, 255.0)
                    #   (HSL(0.0, 0.0, 0.0, 255.0) を期待するが……)

  • RGB値を指定して色相などを変更したい場合、その都度 Color を用意してください。
color1 = Color.new(color2)
color1.red = 0
p HSL_Color.new(color1)  #=> HSL(0.0, 0.0, 0.0, 255.0)

  • 色相(hue)の値はクリッピングしないため、360以上や負の値も指定可能です。
    • 実際の色(RGB値)を計算するときにのみ、内部的に 0 以上 360 未満に矯正されます。
  • == による比較では hue の値が異なれば異なる色として扱われます。
    • 例えば、HSV(0, 1, 1) と HSV(360, 1, 1) はどちらも「赤」ですが、両者を == で比較すると異なるもの(false)と判定されます。
c1 = HSV_Color.new(  0, 1, 1)  #=> RGB(255, 0, 0)
c2 = HSV_Color.new(360, 1, 1)  #=> RGB(255, 0, 0) (両者は同じ"色")
c1 == c2      #=> false (しかし hue が異なるため別の色と判定される)

  • これは、「赤と青の中間色」としての「紫」を指定可能にするための仕様です。(下記)

● Color.medium(color1, color2[, rate])

● HSV_Color.medium(color1, color2[, rate])

● HSL_Color.medium(color1, color2[, rate])

それぞれの色空間での中間色を生成して返します。
  • rate が省略された場合は各パラメータを平均した色になります。
  • rate に 0.0 以上 1.0 以下の数値が指定された場合は、color1 を基準に rate のぶんだけ color2 に寄った色になります。

具体例
a = Color.new(255,   0, 0)
b = Color.new(  0, 255, 0)

Color.medium(a, b)      #=> RGB(127.5, 127.5, 0)
Color.medium(a, b, 0.1) #=> RGB(229.5,  25.5, 0)
Color.medium(a, b, 0.7) #=> RGB( 76.5, 178.5, 0)

  • HS_Color の中間色を求める場合、色相(hue)も機械的な平均が求められるため、例えば「赤(hue=0)」と「青(hue=240)」の中間を求めると「緑(hue=120)」になります。
a = HSV_Color.new(  0, 1, 1) #=> RGB(255,   0,   0)
b = HSV_Color.new(240, 1, 1) #=> RGB(  0,   0, 255)
c = HSV_Color.medium(a, b)   #=> HSV(120, 1, 1) ( RGB(0, 255, 0) )

  • ここで「赤」の色相を 360 にしておくと、中間色が「紫(hue=300)」になります。
a = HSV_Color.new(360, 1, 1) #=> RGB(255,   0,   0)
b = HSV_Color.new(240, 1, 1) #=> RGB(  0,   0, 255)
c = HSV_Color.medium(a, b)   #=> HSV(300, 1, 1) ( RGB(255, 0, 255) )

用途

  • 例えばLNS031 Bitmap図形描画では、グラデーション描画時に HS Color を指定した場合、RGB値ではなくHSL(V)値を変化させて中間色を得ます。

  • すなわち、次のようにした場合、
Graph_Colors[:max] = Color.new(255, 255,   0)
Graph_Colors[:mid] = Color.new(  0,   0, 255)
:max と :mid のちょうど中間では両者の成分が平均化され完全な灰色になってしまいます。
RGB(127, 127, 127)

  • 次のように設定すれば、
Graph_Colors[:max] = HSL_Color.new( 60, 1.0, 0.5)
Graph_Colors[:mid] = HSL_Color.new(240, 1.0, 0.5)
中間色は「青緑」になります。
HSL(150, 1.0, 0.5) #=> RGB(   0, 255, 128)

  • なお、Bitmap#gradient_fill_rect は組み込みメソッドのためこの方法は意味がありません。


備考

再定義されるメソッド

  • Color#to_s
RGBカラーであることが分かりやすいように、"RGB(0.0, 0.0, 0.0)"の形式で出力されます。

設定項目

なし


更新履歴

  • 2020/12/28 新版公開(機能は旧版から変化なし)

  • こんにちは。不具合を発見したのでご報告いたします。 LNS000 組み込み拡張 LNS010 Input拡張 LNS100 プリセット拡張 LNS102 マウス操作 LNS140 マップ/キャラ拡張 の5つを導入した状態で、マップ画面でマウスカーソルをゲームウインドウの外側で大きく動かすなどすると、「 スクリプト 'LNS 140 マップ/キャラ拡張' の 980 行目で IndexError が発生しました。 index -1 too small for array; minimum: 0 」というエラーメッセージが表示され、ゲームが終了してしまいます。 スクリプトは全て最新で、内容は改変していません。 -- 2022-07-26 01:29:40
  • 確認が遅れましたが、対応修正しました。正確には「既に対応済みであったがアップロードを忘れていた」という状態でした…… -- 2022-11-01 15:39:07
  • 対応ありがとうございます!しかし LNS000, 010, 100, 102, 140 の5つを入れた状態で起動直後に「スクリプト 'LNS140 マップ/キャラ拡張' の 1719 行目で NameError が発生しました。 undefined method 'lns102_dash?' for class 'Game_Player'」と表示され、終了します。 -- 2022-12-24 16:39:35
コメント:

すべてのコメントを見る
最終更新:2020年12月28日 22:35