気ままなタンス*プログラミングなどのノートブック

プログラミングやRPGツクール、DTM、VOCALOIDについてのんびり書きます。

【RGSS】メーター描画モジュールの作成

前回に引き続き、メーター関連のお話。
※自分用のメモみたいなものです。

下記(赤枠)のように、画像を利用したメーター描画を行うスクリプトを
moduleにまとめた。(※コーディング中のものであるため、バグあるかも)

meter_20111120     meter_20111120_02  


  1. module Meter
  2.   BAR_FRAME_200_20  = "frame_size_200_20.png"
  3.   BAR_BASE_200_20   = "base_size_200_20.png"
  4.   BAR_FLOAT_200_20  = "float_size_200_20.png" 
  5.   #--------------------------------------------------------------------------
  6.   # ▲ 画像ファイルを用いてメーター描画する
  7.   #--------------------------------------------------------------------------
  8.   #   x             : x座標
  9.   #   y             : y座標
  10.   #   value         : メーター現在値
  11.   #   max_value     : メーター最大値
  12.   #   frame         : 外枠ファイル名
  13.   #   base          : 下地ファイル名
  14.   #   float         : 浮動ファイル名
  15.   #   frm_size_list : 外枠幅の指定配列(指定は任意)
  16.   # 
  17.   # 戻り値
  18.   #  Bitmap及びRectを格納したハッシュ
  19.   #
  20.   # ["frame"]       : 外枠Bitmap
  21.   # ["f_rect"]      : 外枠Bitmap用の矩形
  22.   # ["base"]        : 下地Bitmap
  23.   # ["b_rect"]      : 下地Bitmap用の矩形
  24.   # ["float"]       : 浮動Bitmap
  25.   # ["fl_rect"]     : 浮動Bitmap用の矩形
  26.   # ["fb_x"]        : float,base表示用x座標
  27.   # ["fb_y"]        : float,base表示用y座標
  28.   #--------------------------------------------------------------------------
  29.   def draw_meter_bmp(x, y, value, max_value, frame, base, float,frm_size_list=nil)
  30.     # 画像ファイルをキャッシュにて読み込み
  31.     frame = RPG::Cache.picture(frame)
  32.     base = RPG::Cache.picture(base)
  33.     float = RPG::Cache.picture(float)
  34.  
  35.     # 外枠サイズのデフォルト値設定
  36.     frame_side_bold = 1
  37.     frame_height_bold = 1
  38.     
  39.     # 外枠サイズの指定があった場合、値を更新
  40.     if frm_size_list != nil && frm_size_list.size == 2
  41.       frame_side_bold = frm_size_list[0]
  42.       frame_height_bold = frm_size_list[1]
  43.     end    
  44.     
  45.     # 浮動メーターの現在値から、表示するメーター幅のRect値を算出
  46.     meter_value = *1.to_i
  47.     if value <= 0
  48.       meter_value = 1
  49.     end
  50.     
  51.     # frameのRectサイズ
  52.     f_rect_width = frame.width
  53.     f_rect_height = frame.height
  54.     
  55.     # baseのRectサイズ
  56.     b_rect_width = base.width - frame_height_bold
  57.     b_rect_height = base.height - frame_side_bold
  58.     
  59.     # floatのRectサイズ 算出したmeter_valueを利用
  60.     fl_rect_width = meter_value - frame_height_bold
  61.     fl_rect_height = float.height - frame_side_bold
  62.     
  63.     # frame用Rect
  64.     f_rect  = Rect.new(0, 0, f_rect_width, f_rect_height)
  65.     
  66.     # base用Rect
  67.     b_rect  = Rect.new(0, 0, b_rect_width, b_rect_height)
  68.     
  69.     # float用Rect
  70.     fl_rect = Rect.new(0, 0, fl_rect_width, fl_rect_height)
  71.     
  72.     # メーター外枠部分を考慮し、floatとbaseのx,y座標を算出
  73.     fb_x    = x + (frame_side_bold/2).round
  74.     fb_y    = y + (frame_height_bold/2).round
  75.     
  76.     
  77.     return {"frame" => frame, "f_rect" => f_rect, 
  78.             "base" => base,   "b_rect" => b_rect,
  79.             "float" => float, "fl_rect" => fl_rect,
  80.             "fb_x" => fb_x, "fb_y" => fb_y}        
  81.   end  
  82.   #--------------------------------------------------------------------------
  83.   # ▲ 色を指定し、RGBカラーでメーターを作成する
  84.   #--------------------------------------------------------------------------
  85.   #   x             : x座標
  86.   #   y             : y座標
  87.   #   width         : 横幅
  88.   #   height        : 縦幅
  89.   #   value         : メーター現在値
  90.   #   max_value     : メーター最大値
  91.   #   frame_c       : 外枠カラー
  92.   #   base_c        : 下地カラー
  93.   #   float_c       : 浮動カラー
  94.   #   frm_size_list : 外枠幅の指定配列(指定は任意)
  95.   # 
  96.   # 戻り値
  97.   #  Bitmap及びRectを格納したハッシュ
  98.   #
  99.   # ["frame"]       : 外枠Bitmap
  100.   # ["f_rect"]      : 外枠Bitmap用の矩形
  101.   # ["base"]        : 下地Bitmap
  102.   # ["b_rect"]      : 下地Bitmap用の矩形
  103.   # ["float"]       : 浮動Bitmap
  104.   # ["fl_rect"]     : 浮動Bitmap用の矩形
  105.   # ["fb_x"]        : float,base表示用x座標
  106.   # ["fb_y"]        : float,base表示用y座標
  107.   #--------------------------------------------------------------------------
  108.   def draw_meter_param(x, y, width, height, value, max_value, frame_c, base_c, float_c, frm_size_list=nil)
  109.     # 外枠サイズのデフォルト値設定
  110.     frame_side_bold = 1
  111.     frame_height_bold = 1
  112.     
  113.     # 外枠サイズの指定があった場合、値を更新
  114.     if frm_size_list != nil && frm_size_list.size == 2
  115.       frame_side_bold = frm_size_list[0] * 2
  116.       frame_height_bold = frm_size_list[1] * 2
  117.     end    
  118.     
  119.     # 外枠メーター
  120.     frame = Bitmap.new(width, height)
  121.     frame.fill_rect(0, 0, width, height, frame_c)
  122.     
  123.     # メーター下地
  124.     base = Bitmap.new(width-frame_height_bold, height-frame_side_bold)
  125.     base.fill_rect(0, 0, width, height, base_c)
  126.   
  127.     # 浮動メーターの現在値から、表示するメーター幅のRect値を算出
  128.     meter_value = *2.to_i
  129.     if value <= 0
  130.       meter_value = 1
  131.     end
  132.     
  133.     float = Bitmap.new(meter_value, height-frame_side_bold)
  134.     
  135.     float.fill_rect(0, 0,meter_value,height, float_c)
  136.     
  137.     # メーター外枠部分を考慮し、floatとbaseのx,y座標を算出
  138.     fb_x    = x + (frame_height_bold/2).round
  139.     fb_y    = y + (frame_side_bold/2).round
  140.  
  141.     # frameのRectサイズ
  142.     f_rect_width = frame.width
  143.     f_rect_height = frame.height
  144.     
  145.     # baseのRectサイズ
  146.     b_rect_width = base.width
  147.     b_rect_height = base.height
  148.     
  149.     # floatのRectサイズ 算出したmeter_valueを利用
  150.     fl_rect_width = meter_value
  151.     fl_rect_height = float.height
  152.     
  153.      # frame用Rect
  154.     f_rect  = Rect.new(0,0, f_rect_width, f_rect_height)
  155.     
  156.     # base用Rect
  157.     b_rect  = Rect.new(0,0, b_rect_width, b_rect_height)
  158.     
  159.     # float用Rect
  160.     fl_rect = Rect.new(0,0,fl_rect_width, fl_rect_height)
  161.     
  162.     return {"frame" => frame, "f_rect" => f_rect, 
  163.             "base" => base,   "b_rect" => b_rect,
  164.             "float" => float, "fl_rect" => fl_rect,
  165.             "fb_x" => fb_x, "fb_y" => fb_y}  
  166.   end        
  167.           
  168.   module_function :draw_meter_bmp
  169.   module_function :draw_meter_param
  170. end

使い方(Meter::draw_meter_bmp編)


@meters = Meter::draw_meter_bmp(x,y, value, max_value, frame, base, float)
self.contents.blt(@meters["fb_x"].to_i, @meters["fb_y"].to_i, @meters["base"], @meters["b_rect"])
self.contents.blt(@meters["fb_x"].to_i, @meters["fb_y"].to_i, @meters["float"], @meters["fl_rect"])
self.contents.blt(x, y, @meters["frame"], @meters["f_rect"])


1.Meter::draw_meter_bmpメソッドを呼び出す


 引数
 # x : x座標
# y : y座標
# value : メーター現在値
# max_value : メーター最大値
# frame : 外枠ファイル名
# base : 下地ファイル名
# float : 浮動ファイル名
# frm_size_list : 外枠幅の指定配列(指定は任意)

 →metersインスタンスにハッシュが格納される
  ハッシュの中身はこんな感じ
# 戻り値
# Bitmap及びRectを格納したハッシュ
#
# ["frame"] : 外枠Bitmap
# ["f_rect"] : 外枠Bitmap用の矩形
# ["base"] : 下地Bitmap
# ["b_rect"] : 下地Bitmap用の矩形
# ["float"] : 浮動Bitmap
# ["fl_rect"] : 浮動Bitmap用の矩形
# ["fb_x"] : float,base表示用x座標
# ["fb_y"] : float,base表示用y座標

2.戻り値を利用して、RectサイズのBitmapを画面に表示


self.contentsには事前にBitmapクラスが生成されているはず。

注意点として、draw_meter_bmpの場合下記の順序を守ること。
self.contents.blt(@meters["fb_x"].to_i, @meters["fb_y"].to_i, @meters["base"], @meters["b_rect"])
self.contents.blt(@meters["fb_x"].to_i, @meters["fb_y"].to_i, @meters["float"], @meters["fl_rect"])
self.contents.blt(x, y, @meters["frame"], @meters["f_rect"])

base→float→frameの順で画面に表示してあげないといけない(改善点?)

 

使い方(Meter::draw_meter_param編)


@meters = Meter::draw_meter_param(x, y, width, height, value, max_value, Color.new("任意の色"), Color.new("任意の色"), Color.new("任意の色"),[2,2])

self.contents.blt(x, sp_y, @meters["frame"], @meters["f_rect"])
self.contents.blt(@meters["fb_x"].to_i, @meters["fb_y"].to_i, @meters["base"], @meters["b_rect"])
self.contents.blt(@meters["fb_x"].to_i, @meters["fb_y"].to_i, @meters["float"], @meters["fl_rect"])

1.Meter::draw_meter_paramメソッドを呼び出す


 引数
# x : x座標
# y : y座標
# width : 横幅
# height : 縦幅
# value : メーター現在値
# max_value : メーター最大値
# frame_c : 外枠カラー
# base_c : 下地カラー
# float_c : 浮動カラー
# frm_size_list : 外枠幅の指定配列(指定は任意)

 戻り値はdraw_meter_bmpと同じ

2.戻り値を利用して、RectサイズのBitmapを画面に表示

ここでも注意
self.contents.blt(x, sp_y, @meters["frame"], @meters["f_rect"])
self.contents.blt(@meters["fb_x"].to_i, @meters["fb_y"].to_i, @meters["base"], @meters["b_rect"])
self.contents.blt(@meters["fb_x"].to_i, @meters["fb_y"].to_i, @meters["float"], @meters["fl_rect"])

frame→base→floatの順序を守ること


draw_meter_bmpを使う場合には、3つの画像が必要
1.外枠の画像
2.下地の画像(メーターが覆いかぶさっていない状態のカラー用)
3. 浮動の画像(主にメーター部分の画像)


・現状1
おそらく、画像ファイルのframeを初期値(=1)以外で描画しようとしたら
表示がおかしくなってしまうかも。

・現状2
このModuleでは、ある時点での value/MaxValueのパーセンテージを
メーター画像として画面に表示しているだけ。
時間経過によってメーターの増加をぬるぬる動かすようにするには
別途なんらかの仕組みを考えなければいけない。
→数秒ごとにvalueの値を加算し、Module::draw_meter_xxxを呼び出すことで、
 メーターが増加するように見せかけることはできるが、ちょっと動きが硬い。
 たぶん画像をある地点へ移動させるような仕組みにすればよさげ?
 つまり、毎回draw_meterを呼び出すのではなく、move_meterというようなものを実装すればいけるかも?
 机上の空論でしかないが。

*1:value.to_f / max_value.to_f) * (float.width

*2:value.to_f / max_value.to_f) * (width-frame_height_bold