#============================================================================
# 更方便地在窗口中描绘文字:移植VA中的 draw_text_ex (for XP)
#----------------------------------------------------------------------------
# 移植 By :RyanBern
#============================================================================
#============================================================================
# 使用方法:
# 在Window_Base或者是其子类下,使用draw_text_ex(x, y, text)对文本进行绘制
# 注意这个和 RGSS1 的不一样,RGSS1的 draw_text 定义在 Bitmap 类上。
# 所以使用的方法为self.draw_text_ex(x, y, text)而非self.contents.draw_text_ex()
# text 中可以使用控制符,现在支持的控制符如下:
#----------------------------------------------------------------------------
# \n :换行
# \\v[n] : 第 n 号变量
# \\n[n] : ID为 n 的队员的名字
# \\p[n] : 队伍中 第 n 个队员(从上至下)的名字
# \\c[n] : 字体变为编号为 n 的颜色(参考默认对话框)
# \\ic[filename] : 描绘文件名为filename的图标
# \\g : 描绘当前队伍的金钱
# \\I : 斜体
# \\i : 取消斜体
# \\B : 粗体
# \\b : 取消粗体
# \\{ : 字号加大一些(+8,不能超过64号字)
# \\} : 字号变小一些(-8,不能小于16号字)
# \\\\ : '\'这个文字本身
#----------------------------------------------------------------------------
# 注:由于转义字符的缘故,字符串必须用双引号
#----------------------------------------------------------------------------
# 例:text = "\\I你好!\\i\n\\{I\\} am RyanBern!\n\\v[1]\\ic[001-Weapon01]\n\\g"
# self.draw_text_ex(0, 0, text)
# 实际描绘效果为:
# (斜体)你好!(取消斜体)
# (字号32)I(字号24) am RyanBern!
# (1号变量的值)(图标001-Weapon01)
# (金钱数量+货币单位)
#============================================================================
class Window_Base < Window
#--------------------------------------------------------------------------
# ● 绘制带有控制符的文本内容
#--------------------------------------------------------------------------
def draw_text_ex(x, y, text)
reset_font_settings
text = convert_escape_characters(text)
pos = {:x => x, :y => y, :new_x => x, :height => calc_line_height(text)}
process_character(text.slice!(/./m), text, pos) until text.empty?
end
#--------------------------------------------------------------------------
# ● 更改内容绘制颜色
# enabled : 有效的标志。false 的时候使用半透明效果绘制
#--------------------------------------------------------------------------
def change_color(color, enabled = true)
self.contents.font.color = color
self.contents.font.color.alpha = 128 unless enabled
end
#--------------------------------------------------------------------------
# ● 重置字体设置
#--------------------------------------------------------------------------
def reset_font_settings
change_color(normal_color)
contents.font.size = Font.default_size
contents.font.bold = false
contents.font.italic = false
end
#--------------------------------------------------------------------------
# ● 进行控制符的事前变换
# 在实际绘制前、将控制符替换为实际的内容。
# 为了减少歧异,文字「\」会被首先替换为转义符(\e)。
#--------------------------------------------------------------------------
def convert_escape_characters(text)
result = text.to_s.clone
result.gsub!(/\\/) { "\e" }
result.gsub!(/\e\e/) { "\\" }
result.gsub!(/\eC/i) { "\e\001" }
result.gsub!(/\eic/i) { "\e\002" }
result.gsub!(/\e\{/) { "\e\003" }
result.gsub!(/\e\}/) { "\e\004" }
result.gsub!(/\eI/) { "\e\005" }
result.gsub!(/\ei/) { "\e\006" }
result.gsub!(/\eB/) { "\e\007" }
result.gsub!(/\eb/) { "\e\008" }
result.gsub!(/\eV\[(\d+)\]/i) { $game_variables[$1.to_i] }
result.gsub!(/\eN\[(\d+)\]/i) { actor_name($1.to_i) }
result.gsub!(/\eP\[(\d+)\]/i) { party_member_name($1.to_i) }
result.gsub!(/\eG/i) { $game_party.gold.to_s + $data_system.words.gold }
result
end
#--------------------------------------------------------------------------
# ● 获取第 n 号角色的名字
#--------------------------------------------------------------------------
def actor_name(n)
actor = n >= 1 ? $game_actors[n] : nil
actor ? actor.name : ""
end
#--------------------------------------------------------------------------
# ● 获取第 n 号队伍成员的名字
#--------------------------------------------------------------------------
def party_member_name(n)
actor = n >= 1 ? $game_party.actors[n - 1] : nil
actor ? actor.name : ""
end
#--------------------------------------------------------------------------
# ● 文字的处理
# c : 文字
# text : 绘制处理中的字符串缓存(字符串可能会被修改)
# pos : 绘制位置 {:x, :y, :new_x, :height}
#--------------------------------------------------------------------------
def process_character(c, text, pos)
case c
when "\r" # 回车
return
when "\n" # 换行
process_new_line(text, pos)
when "\f" # 翻页
process_new_page(text, pos)
when "\e" # 控制符
process_escape_character(obtain_escape_code(text), text, pos)
else # 普通文字
process_normal_character(c, pos)
end
end
#--------------------------------------------------------------------------
# ● 处理普通文字
#--------------------------------------------------------------------------
def process_normal_character(c, pos)
text_width = self.contents.text_size(c).width
self.contents.draw_text(pos[:x], pos[:y], text_width * 2, pos[:height], c)
pos[:x] += text_width
end
#--------------------------------------------------------------------------
# ● 处理换行文字
#--------------------------------------------------------------------------
def process_new_line(text, pos)
pos[:x] = pos[:new_x]
pos[:y] += pos[:height]
pos[:height] = calc_line_height(text)
end
#--------------------------------------------------------------------------
# ● 处理翻页文字
#--------------------------------------------------------------------------
def process_new_page(text, pos)
end
#--------------------------------------------------------------------------
# ● 获取控制符的实际形式(这个方法会破坏原始数据)
#--------------------------------------------------------------------------
def obtain_escape_code(text)
text.slice!(/^[\001\002\003\004\005\006\007\008]/)
end
#--------------------------------------------------------------------------
# ● 获取控制符的参数(这个方法会破坏原始数据)
#--------------------------------------------------------------------------
def obtain_escape_param(text)
text.slice!(/^\[(.+?)\]/)
return $1 || ""
end
#--------------------------------------------------------------------------
# ● 控制符的处理
# code : 控制符的实际形式(比如“\C[1]”是“C”)
# text : 绘制处理中的字符串缓存(字符串可能会被修改)
# pos : 绘制位置 {:x, :y, :new_x, :height}
#--------------------------------------------------------------------------
def process_escape_character(code, text, pos)
case code
when "\001"
change_color(text_color(obtain_escape_param(text).to_i)) rescue change_color(0)
when "\002"
process_draw_icon(obtain_escape_param(text), pos)
when "\003"
make_font_bigger
when "\004"
make_font_smaller
when "\005"
self.contents.font.italic = true
when "\006"
self.contents.font.italic = false
when "\007"
self.contents.font.bold = true
when "\008"
self.contents.font.bold = false
end
end
#--------------------------------------------------------------------------
# ● 处理控制符指定的图标绘制
#--------------------------------------------------------------------------
def process_draw_icon(icon_index, pos)
draw_icon(icon_index, pos[:x], pos[:y])
pos[:x] += 24
end
#--------------------------------------------------------------------------
# ● 放大字体尺寸
#--------------------------------------------------------------------------
def make_font_bigger
contents.font.size += 8 if contents.font.size <= 64
end
#--------------------------------------------------------------------------
# ● 缩小字体尺寸
#--------------------------------------------------------------------------
def make_font_smaller
contents.font.size -= 8 if contents.font.size >= 16
end
#--------------------------------------------------------------------------
# ● 计算行高
# restore_font_size : 计算完成后是否恢复原本的字体尺寸?
#--------------------------------------------------------------------------
def calc_line_height(text, restore_font_size = true)
result = [32, contents.font.size].max
last_font_size = contents.font.size
text.slice(/^.*$/).scan(/\e[\{\}]/).each do |esc|
make_font_bigger if esc == "\e{"
make_font_smaller if esc == "\e}"
result = [result, contents.font.size].max
end
contents.font.size = last_font_size if restore_font_size
result
end
#--------------------------------------------------------------------------
# ● 绘制图标
# enabled : 有效的标志。false 的时候使用半透明效果绘制
#--------------------------------------------------------------------------
def draw_icon(icon_name, x, y, enabled = true)
bitmap = RPG::Cache.icon(icon_name)
rect = Rect.new(0, 0, 24, 24)
contents.blt(x, y+4, bitmap, rect, enabled ? 255 : 128)
end
end