=begin
RGSS3
★ 方向キー入力型選択肢 ★
選択肢の形式をコマンド選択型から方向キー入力型に変更します。
決定キーは使用せず、選択肢のある方向に対応した方向キーを入力することで、
選択肢を選びます。
あまり長い文字列がある選択肢には向かない・・
● 機能と使用法 ●==================================================
使用方法はデフォルトのイベントコマンド「選択肢の表示」とほぼ同じです。
--------------------------------------------------------------------
[デフォルトと異なる点]
デフォルトでは例えば2択の選択肢を作りたい場合、
イベントコマンド「選択肢の表示」で選択肢1と選択肢2の欄に文字列を設定します。
このスクリプトを導入して同じことを実現しようとした場合、
「選択肢1と選択肢3の欄を使う」「選択肢3と選択肢4の欄を使う」といったことが
可能になります。
選択肢の1~4の欄は、選択肢が表示される位置を意味するようになり、
何も入力されていない欄は選択肢として判定されません。
--------------------------------------------------------------------
選択肢1~4の位置関係は以下のとおりです。
選択肢 1 : 左に選択肢が表示されます。
選択肢 2 : 右に選択肢が表示されます。
選択肢 3 : 上に選択肢が表示されます。
選択肢 4 : 下に選択肢が表示されます。
--------------------------------------------------------------------
↓ 即席:設定例の図
[url]http://kaisou-ryouiki.sakura.ne.jp/material/manual/img/choice_manual.png[/url]
====================================================================
ver1.00
Last Update : 2014/01/07
01/07 : 新規
ろかん [url]http://kaisou-ryouiki.sakura.ne.jp/[/url]
=end
$rsi ||= {}
$rsi["方向キー入力型選択肢"] = true
class Sprite_ChoiceItem < Sprite
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize(index, parent)
super(nil)
@index = index
@parent = parent
setup
end
#--------------------------------------------------------------------------
# ● 初期設定
#--------------------------------------------------------------------------
def setup
create_basebitmep
self.z = 500
self.ox = @base_bitmap.width / 2
self.oy = @base_bitmap.height / 2
self.visible = false
case @index
when 0
self.x = Graphics.width / 4 - 10
self.y = Graphics.height / 2
when 1
self.x = Graphics.width / 4 * 3 + 10
self.y = Graphics.height / 2
when 2
self.x = Graphics.width / 2
self.y = Graphics.height / 4 - 10
when 3
self.x = Graphics.width / 2
self.y = Graphics.height / 4 * 3 + 10
end
end
#--------------------------------------------------------------------------
# ● ベースビットマップの作成
#--------------------------------------------------------------------------
def create_basebitmep
@base_bitmap = Bitmap.new(170, 22)
@base_bitmap.gradient_fill_rect(0, 0, 85, 22, gradient_color2, gradient_color1)
@base_bitmap.gradient_fill_rect(85, 0, 85, 22, gradient_color1, gradient_color2)
@base_bitmap.font.size = 20
end
#--------------------------------------------------------------------------
# ● 背景グラデーションカラーの取得1
#--------------------------------------------------------------------------
def gradient_color1
Color.new(0, 0, 80, 180)
end
#--------------------------------------------------------------------------
# ● 背景グラデーションカラーの取得2
#--------------------------------------------------------------------------
def gradient_color2
Color.new(0, 0, 80, 20)
end
#--------------------------------------------------------------------------
# ● リフレッシュ
#--------------------------------------------------------------------------
def refresh
self.bitmap.dispose if self.bitmap
self.bitmap = @base_bitmap.dup
if $game_message.choices[@index] && !$game_message.choices[@index].empty?
self.visible = true
draw_text_ex 0,0,$game_message.choices[@index]
#self.bitmap.draw_text(0, 1, 170, 22, convert_escape_characters($game_message.choices[@index]), 1)
else
self.visible = false
end
self.opacity = 0
self.zoom_x = 1
self.zoom_y = 1
end
#--------------------------------------------------------------------------
# ● 解放
#--------------------------------------------------------------------------
def dispose
@base_bitmap.dispose
self.bitmap.dispose if self.bitmap
super
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
super
if @parent.active
self.opacity += 28
else
unless self.opacity.zero?
if @parent.index == @index
self.zoom_x += 0.08
self.zoom_y += 0.03
self.opacity -= 13
else
self.opacity -= 28
end
end
end
end
def contents
self.bitmap
end
#--------------------------------------------------------------------------
# ● 获取文字颜色
# n : 文字颜色编号(0..31)
#--------------------------------------------------------------------------
def text_color(n)
windowskin = Cache.system("Window")
windowskin.get_pixel(64 + (n % 8) * 8, 96 + (n / 8) * 8)
end
#--------------------------------------------------------------------------
# ● 获取各种文字颜色
#--------------------------------------------------------------------------
def normal_color; text_color(0); end; # 普通
def system_color; text_color(16); end; # 系统
def crisis_color; text_color(17); end; # 危险
def knockout_color; text_color(18); end; # 无法战斗
def gauge_back_color; text_color(19); end; # 值槽背景
def hp_gauge_color1; text_color(20); end; # HP 值槽 1
def hp_gauge_color2; text_color(21); end; # HP 值槽 2
def mp_gauge_color1; text_color(22); end; # MP 值槽 1
def mp_gauge_color2; text_color(23); end; # MP 值槽 2
def mp_cost_color; text_color(23); end; # 消费 TP
def power_up_color; text_color(24); end; # 能力值提升(更换装备时)
def power_down_color; text_color(25); end; # 能力值降低(更换装备时)
def tp_gauge_color1; text_color(28); end; # TP 值槽 1
def tp_gauge_color2; text_color(29); end; # TP 值槽 2
def tp_cost_color; text_color(29); end; # 消费 TP
#--------------------------------------------------------------------------
# ● 获取保留项目的背景色
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
# ● 更改内容绘制颜色
# enabled : 有效的标志。false 的时候使用半透明效果绘制
#--------------------------------------------------------------------------
def change_color(color, enabled = true)
contents.font.color.set(color)
contents.font.color.alpha = translucent_alpha unless enabled
end
#--------------------------------------------------------------------------
# ● 绘制带有控制符的文本内容
#--------------------------------------------------------------------------
def draw_text_ex(x, y, text)
reset_font_settings
text = convert_escape_characters(text)
size = text.size * self.bitmap.font.size
if text.include?("\eI")
size -= (6 * self.bitmap.font.size - 32)
elsif text.include?("\e")
size -= 6 * self.bitmap.font.size
end
x += 85
x -= size / 2
pos = {:x => x, :y => y, :new_x => x, :height => calc_line_height(text)}
process_character(text.slice!(0, 1), text, pos) until text.empty?
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!(/\eV\[(\d+)\]/i) { $game_variables[$1.to_i] }
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) { Vocab::currency_unit }
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.members[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
#--------------------------------------------------------------------------
# ● 绘制内容
# args : 与 Bitmap#draw_text 相同
#--------------------------------------------------------------------------
def draw_text(*args)
contents.draw_text(*args)
end
#--------------------------------------------------------------------------
# ● 处理普通文字
#--------------------------------------------------------------------------
def process_normal_character(c, pos)
text_width = text_size(c).width
draw_text(pos[:x], pos[:y], text_width * 2, pos[:height], c)
pos[:x] += text_width
end
#--------------------------------------------------------------------------
# ● 获取内容尺寸
#--------------------------------------------------------------------------
def text_size(str)
contents.text_size(str)
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!(/^[\$\.\|\^!><\{\}\\]|^[A-Z]+/i)
end
#--------------------------------------------------------------------------
# ● 获取控制符的参数(这个方法会破坏原始数据)
#--------------------------------------------------------------------------
def obtain_escape_param(text)
text.slice!(/^\[\d+\]/)[/\d+/].to_i rescue 0
end
#--------------------------------------------------------------------------
# ● 控制符的处理
# code : 控制符的实际形式(比如“\C[1]”是“C”)
# text : 绘制处理中的字符串缓存(字符串可能会被修改)
# pos : 绘制位置 {:x, :y, :new_x, :height}
#--------------------------------------------------------------------------
def process_escape_character(code, text, pos)
case code.upcase
when 'C'
change_color(text_color(obtain_escape_param(text)))
when 'I'
process_draw_icon(obtain_escape_param(text), pos)
when '{'
make_font_bigger
when '}'
make_font_smaller
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
#--------------------------------------------------------------------------
# ● 获取行高
#--------------------------------------------------------------------------
def line_height
return 24
end
#--------------------------------------------------------------------------
# ● 获取标准的边距尺寸
#--------------------------------------------------------------------------
def standard_padding
return 12
end
#--------------------------------------------------------------------------
# ● 计算行高
# restore_font_size : 计算完成后是否恢复原本的字体尺寸?
#--------------------------------------------------------------------------
def calc_line_height(text, restore_font_size = true)
result = [line_height, 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
#--------------------------------------------------------------------------
# ● 绘制值槽
# rate : 比率(1.0 为满值)
# color1 : 渐变色的左端
# color2 : 渐变色的右端
#--------------------------------------------------------------------------
def draw_gauge(x, y, width, rate, color1, color2)
fill_w = (width * rate).to_i
gauge_y = y + line_height - 8
contents.fill_rect(x, gauge_y, width, 6, gauge_back_color)
contents.gradient_fill_rect(x, gauge_y, fill_w, 6, color1, color2)
end
#--------------------------------------------------------------------------
# ● 绘制图标
# enabled : 有效的标志。false 的时候使用半透明效果绘制
#--------------------------------------------------------------------------
def draw_icon(icon_index, x, y, enabled = true)
bitmap = Cache.system("Iconset")
rect = Rect.new(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24)
contents.blt(x, y, bitmap, rect, enabled ? 255 : translucent_alpha)
end
#--------------------------------------------------------------------------
# ● 绘制角色肖像图
# enabled : 有效的标志。false 的时候使用半透明效果绘制
#--------------------------------------------------------------------------
def draw_face(face_name, face_index, x, y, enabled = true)
bitmap = Cache.face(face_name)
rect = Rect.new(face_index % 4 * 96, face_index / 4 * 96, 96, 96)
contents.blt(x, y, bitmap, rect, enabled ? 255 : translucent_alpha)
bitmap.dispose
end
#--------------------------------------------------------------------------
# ● 绘制人物行走图
#--------------------------------------------------------------------------
def draw_character(character_name, character_index, x, y)
return unless character_name
bitmap = Cache.character(character_name)
sign = character_name[/^[\!\$]./]
if sign && sign.include?('$')
cw = bitmap.width / 3
ch = bitmap.height / 4
else
cw = bitmap.width / 12
ch = bitmap.height / 8
end
n = character_index
src_rect = Rect.new((n%4*3+1)*cw, (n/4*4)*ch, cw, ch)
contents.blt(x - cw / 2, y - ch, bitmap, src_rect)
end
#--------------------------------------------------------------------------
# ● 绘制名字
#--------------------------------------------------------------------------
def draw_actor_name(actor, x, y, width = 112)
change_color(hp_color(actor))
draw_text(x, y, width, line_height, actor.name)
end
#--------------------------------------------------------------------------
# ● 绘制职业
#--------------------------------------------------------------------------
def draw_actor_class(actor, x, y, width = 112)
change_color(normal_color)
draw_text(x, y, width, line_height, actor.class.name)
end
#--------------------------------------------------------------------------
# ● 绘制称号
#--------------------------------------------------------------------------
def draw_actor_nickname(actor, x, y, width = 180)
change_color(normal_color)
draw_text(x, y, width, line_height, actor.nickname)
end
#--------------------------------------------------------------------------
# ● 绘制等级
#--------------------------------------------------------------------------
def draw_actor_level(actor, x, y)
change_color(system_color)
draw_text(x, y, 32, line_height, Vocab::level_a)
change_color(normal_color)
draw_text(x + 32, y, 24, line_height, actor.level, 2)
end
#--------------------------------------------------------------------------
# ● 绘制强化/弱化状态的图标
#--------------------------------------------------------------------------
def draw_actor_icons(actor, x, y, width = 96)
icons = (actor.state_icons + actor.buff_icons)[0, width / 24]
icons.each_with_index {|n, i| draw_icon(n, x + 24 * i, y) }
end
end
class Spriteset_DirectionChoice
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_reader :active
attr_reader :index
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
@active = false
@index = -1
create_sprites
end
#--------------------------------------------------------------------------
# ● 選択肢スプライトの作成
#--------------------------------------------------------------------------
def create_sprites
@command_sprites = []
4.times{|i| @command_sprites << Sprite_ChoiceItem.new(i, self)}
end
#--------------------------------------------------------------------------
# ● 入力処理の開始
#--------------------------------------------------------------------------
def start
@active = true
@index = -1
@command_sprites.each{|sprite| sprite.refresh}
end
#--------------------------------------------------------------------------
# ● 入力処理の終了
#--------------------------------------------------------------------------
def terminate
@active = false
end
#--------------------------------------------------------------------------
# ● 選択肢が完全に閉じているか
#--------------------------------------------------------------------------
def close?
@command_sprites.all?{|sprite| sprite.opacity.zero?}
end
#--------------------------------------------------------------------------
# ● 解放
#--------------------------------------------------------------------------
def dispose
@command_sprites.each{|sprite| sprite.dispose}
end
#--------------------------------------------------------------------------
# ● キャンセル処理の有効状態を取得
#--------------------------------------------------------------------------
def cancel_enabled?
$game_message.choice_cancel_type > 0
end
#--------------------------------------------------------------------------
# ● 選択肢の有効判定
#--------------------------------------------------------------------------
def active_choice?(i)
$game_message.choices[i] && !$game_message.choices[i].empty?
end
#--------------------------------------------------------------------------
# ● 選択肢の選択後処理
#--------------------------------------------------------------------------
def choiced_process(index)
@index = index
$game_message.choice_proc.call(index)
@command_sprites[index].flash(Color.new(255, 255, 255, 200), 35)
Sound.play_ok
Input.update
terminate
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
@command_sprites.each{|sprite| sprite.update}
if @active
if cancel_enabled? && Input.trigger?(:B)
$game_message.choice_proc.call($game_message.choice_cancel_type - 1)
Sound.play_cancel
Input.update
terminate
else
if Input.trigger?(:DOWN)
choiced_process(3) if active_choice?(3)
elsif Input.trigger?(:LEFT)
choiced_process(0) if active_choice?(0)
elsif Input.trigger?(:RIGHT)
choiced_process(1) if active_choice?(1)
elsif Input.trigger?(:UP)
choiced_process(2) if active_choice?(2)
end
end
end
end
end
class Window_Message < Window_Base
#--------------------------------------------------------------------------
# ● 全ウィンドウの作成
#--------------------------------------------------------------------------
alias _create_all_windows_recreate_choice create_all_windows
def create_all_windows
_create_all_windows_recreate_choice
@choice_window.dispose
@choice_window = Spriteset_DirectionChoice.new
end
end