#==============================================================================
# ■ Balloon
#------------------------------------------------------------------------------
# 複数のメッセージを表示するクラスです。
#==============================================================================
#
# ■吹き出しメッセージ Ver 1.01 2012/11/7
#
# 使い方:イベントコマンド『文章の表示』内に吹き出しウィンドウの
# 対象イベントのIDを入力するだけ
#
# 例:
#
# \w[8]村人
# 「ここは***の村です。
#
# ↑8は対象のイベントID
#
# その他の操作
#・\w[0] … 主人公に表示
#・\w[-1] … 通常ウィンドウで表示
#・\w[-2] … 実行中のイベントに表示
#・記述なし … 記述なしだとふきだしウィンドウの切り替えを行わず
# 最後のウィンドウに文章の表示が継続されます。
# いちいち\w[~]と入力しなくても大丈夫です。
#
# また、記述なしで対象イベントを設定しないまま
# いきなり文章の表示を実行しても、自動的に実行中のイベントが
# 吹き出しウィンドウの対象となります。
#
#・バグの報告や質問、要望がありましたらこちらへお願いします。
#
# Gossum magazine [url]http://gossum.blog.fc2.com/[/url]
#
#==============================================================================
# 【使用フォントを変更する場合】
# 文字のサイズがウィンドウの大きさに合わず、
# 正しく表示されない場合は以下の数値で補正してみてください。
# 文字の横幅を補正
GOSS_BALL_WIDTH = 2
# 文字の高さを補正
GOSS_BALL_HEIGHT = 4
class Balloon
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
@index = nil
@balloons = {}
end
#--------------------------------------------------------------------------
# ● アクティブなウィンドウの取得
#--------------------------------------------------------------------------
def active_window
@balloons[@index]
end
#--------------------------------------------------------------------------
# ● アクティブなウィンドウの変更
#--------------------------------------------------------------------------
def change_balloon(index)
@index = index
if @index == -2
@index = $game_map.interpreter.event_id
end
if @balloons[@index] != nil
@balloons[@index].dispose
end
@balloons[@index] = Window_Balloon.new(@index)
@balloons.each_value do |v|
v.active = false
v.change_flag = false
end
@balloons[@index].active = true
return ""
end
#--------------------------------------------------------------------------
# ● 全ウィンドウを閉じる
#--------------------------------------------------------------------------
def all_window_close
@balloons.each_value do |window|
window.close
window.change_flag = false
end
end
#--------------------------------------------------------------------------
# ● 全ウィンドウを解放
#--------------------------------------------------------------------------
def dispose
@balloons.each_value do |v|
v.dispose_all_windows
v.dispose
end
end
#--------------------------------------------------------------------------
# ● フラグによる制御
#--------------------------------------------------------------------------
def flag_control
if active_window.change_flag == :close
all_window_close
end
if active_window.change_flag != false
change_balloon(active_window.change_flag)
@balloons.each_value do |v|
v.change_flag = false
end
end
end
#--------------------------------------------------------------------------
# ● ウィンドウ枠が空の状態で切り替えがあるか監視
#--------------------------------------------------------------------------
def active_check
text = $game_message.all_text.dup
return false if text == ""
unless text.include?("\w")
return change_balloon(-2)
end
text.gsub!(/\\/) { "\e" }
text.gsub!(/\e\e/) { "\\" }
text.gsub!(/\eW\[(-\d)\]/i) { change_balloon($1.to_i) }
text.gsub!(/\eW\[(\d+)\]/i) { change_balloon($1.to_i) }
end
#--------------------------------------------------------------------------
# ● 更新
#--------------------------------------------------------------------------
def update
if active_window != nil
active_window.update
flag_control
else
active_check
end
@balloons.each_value do |window|
window.update_all_windows_close
if window.id != @index and window.closing
window.update_close
end
if window.finish_close?
@balloons.delete(window.id)
end
end
end
end
#==============================================================================
# ■ Window_Balloon
#------------------------------------------------------------------------------
# 文章表示に使うメッセージウィンドウです。
#==============================================================================
class Window_Balloon < Window_Message
attr_reader :closing # ウィンドウが閉じ中
attr_reader :id # ウィンドウのID
attr_accessor :change_flag # 変更先のウィンドウID
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize(id)
super()
@id = id
@change_flag = false
@position = $game_message.position
set_position
end
#--------------------------------------------------------------------------
# ● 制御文字の事前変換
# 実際の描画を始める前に、原則として文字列に変わるものだけを置き換える。
# 文字「\」はエスケープ文字(\e)に変換。
#--------------------------------------------------------------------------
def convert_escape_characters(text)
result = super(text)
result.gsub!(/\eW\[(\d+)\]/i) { change_window($1.to_i) }
result.gsub!(/\eW\[(-\d+)\]/i) { change_window($1.to_i) }
result
end
#--------------------------------------------------------------------------
# ● 全テキストの処理
#--------------------------------------------------------------------------
def process_all_text
text = convert_escape_characters($game_message.all_text)
if @change_flag != false
return
end
fit_window_size(text.dup)
open_and_wait
pos = {}
new_page(text, pos)
process_character(text.slice!(0, 1), text, pos) until text.empty?
end
#--------------------------------------------------------------------------
# ● 改ページ処理
#--------------------------------------------------------------------------
def new_page(text, pos)
contents.clear
draw_face($game_message.face_name, $game_message.face_index, 0, 0)
reset_font_settings
pos[:x] = new_line_x
pos[:y] = 0
pos[:new_x] = new_line_x
pos[:height] = calc_line_height(text)
clear_flags
end
#--------------------------------------------------------------------------
# ● ファイバーのメイン処理
#--------------------------------------------------------------------------
def fiber_main
$game_message.visible = true
update_background
update_placement
loop do
process_all_text if $game_message.has_text?
process_input
$game_message.clear
@gold_window.close
Fiber.yield
break unless text_continue?
end
close
@change_flag = :close
$game_message.visible = false
@fiber = nil
end
#--------------------------------------------------------------------------
# ● アクティブなメッセージウィンドウの切り替え処理
# id : ふきだしの対象となるキャラクターのID
# 空の文字列を返す
#--------------------------------------------------------------------------
def change_window(id)
if @id != id and !(id == -2 and @id == $game_map.interpreter.event_id)
@change_flag = id
end
return ""
end
#--------------------------------------------------------------------------
# ● ウィンドウが完全に閉じた瞬間
#--------------------------------------------------------------------------
def finish_close?
if @finish_close
@finish_close = false
return true
end
return false
end
#--------------------------------------------------------------------------
# ● ウィンドウを閉じる
#--------------------------------------------------------------------------
def close
@closing = true unless close?
@opening = false
self
end
#--------------------------------------------------------------------------
# ● 閉じる処理の更新
#--------------------------------------------------------------------------
def update_close
self.openness -= 48
if all_close?
@closing = false
@finish_close = true
end
end
#--------------------------------------------------------------------------
# ● 全ウィンドウの閉じる処理の更新
#--------------------------------------------------------------------------
def update_all_windows_close
@gold_window.update_close if @gold_window.closing
@choice_window.update_close if @choice_window.closing
@number_window.update_close if @number_window.closing
@item_window.update_close if @item_window.closing
end
#--------------------------------------------------------------------------
# ● 背景と位置の変更判定
#--------------------------------------------------------------------------
def settings_changed?
@background != $game_message.background
end
#--------------------------------------------------------------------------
# ● ウィンドウの位置を決定
#--------------------------------------------------------------------------
def set_position
return if @id == -1
if @id != 0
[url=home.php?mod=space&uid=2631396]@character[/url] = $game_map.events[@id]
else
@character = $game_player
end
self.x = @character.screen_x - self.width / 2
self.y = @character.screen_y + 8
if @position == 0
self.y -= self.height + 40
end
end
#--------------------------------------------------------------------------
# ● ウィンドウのサイズをメッセージの内容にあわせる
#--------------------------------------------------------------------------
def fit_window_size(text)
return if @id == -1
txt = [0]
i = 0
until text.empty?
temp = text.slice!(0,1)
if temp == "\n"
i += 1
txt[i] = 0
else
if temp =~ /^[0-9A-Za-z]+$/
txt[i] += 5
else
txt[i] += 10
end
end
end
space = standard_padding * 2
self.width = (txt.max / 10 + txt.max % 10) * (22 + GOSS_BALL_WIDTH) + 8
self.height = space + $game_message.texts.size * (Font.default_size + GOSS_BALL_HEIGHT)
unless $game_message.face_name.empty?
self.width += 112
self.height = 120
end
self.arrows_visible = false
set_position
end
#--------------------------------------------------------------------------
# ● 更新
#--------------------------------------------------------------------------
def update
super
update_placement
end
#--------------------------------------------------------------------------
# ● ウィンドウ位置の更新
#--------------------------------------------------------------------------
def update_placement
if @id != -1
set_position
else
super()
end
end
end
#==============================================================================
# ■ Scene_Map
#------------------------------------------------------------------------------
# マップ画面の処理を行うクラスです。
#==============================================================================
class Scene_Map < Scene_Base
#--------------------------------------------------------------------------
# ● メッセージウィンドウの作成
#--------------------------------------------------------------------------
def create_message_window
@message_window = Balloon.new
end
#--------------------------------------------------------------------------
# ● 全ウィンドウの更新
#--------------------------------------------------------------------------
def update_all_windows
instance_variables.each do |varname|
ivar = instance_variable_get(varname)
ivar.update if ivar.is_a?(Window)
end
@message_window.update
end
#--------------------------------------------------------------------------
# ● 全ウィンドウの解放
#--------------------------------------------------------------------------
def dispose_all_windows
instance_variables.each do |varname|
ivar = instance_variable_get(varname)
ivar.dispose if ivar.is_a?(Window)
end
@message_window.dispose
end
end
#==============================================================================
# ■ Window_Base
#------------------------------------------------------------------------------
# ゲーム中の全てのウィンドウのスーパークラスです。
#==============================================================================
class Window_Base < Window
#--------------------------------------------------------------------------
# ● ちょっと追加
#--------------------------------------------------------------------------
def closing
return (@closing == true and openness != 0)
end
end
#==============================================================================
# ■ Window_ChoiceList
#------------------------------------------------------------------------------
# イベントコマンド[選択肢の表示]に使用するウィンドウです。
#==============================================================================
class Window_ChoiceList < Window_Command
#--------------------------------------------------------------------------
# ● ウィンドウ位置の更新
#--------------------------------------------------------------------------
def update_placement
self.width = [max_choice_width + 12, 96].max + padding * 2
self.width = [width, Graphics.width].min
self.height = fitting_height($game_message.choices.size)
self.x = @message_window.x + @message_window.width - self.width
if @message_window.y >= Graphics.height / 2
self.y = @message_window.y - height
else
self.y = @message_window.y + @message_window.height
end
end
end