Project1
标题:
合并两款對話腳本
[打印本页]
作者:
PCNinja
时间:
2011-8-10 22:19
标题:
合并两款對話腳本
本帖最后由 「旅」 于 2011-8-10 22:29 编辑
有沒有人能幫我把櫻雅在士的對話腳本和齒車之城的對話腳本合並了?
# ▼▲▼ XRXS 9. メッセージ表示フルグレードアップ ver..11 ▼▲▼
# by 桜雅 在土, 和希, RaTTiE
#==============================================================================
# ■ Window_Message
#==============================================================================
class Window_Message < Window_Selectable
# 一文字ずつ描写
DEFAULT_TYPING_ENABLE = true # falseにすると瞬間表示
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
alias xrxs9_initialize initialize
def initialize
xrxs9_initialize
# 再生サウンド名がない場合は""とする
if $soundname_on_speak == nil then
$soundname_on_speak = ""
end
# 外字ファイルパス設定
$gaiji_file = "./Graphics/Gaiji/sample.png"
# 外字データ読み込み
if FileTest.exist?($gaiji_file)
@gaiji_cache = Bitmap.new($gaiji_file)
else
@gaigi_cache = nil
end
# 文字透過転送用バッファ
@opacity_text_buf = Bitmap.new(32, 32)
end
#--------------------------------------------------------------------------
# ● メッセージ終了処理
#--------------------------------------------------------------------------
alias xrxs9_terminate_message terminate_message
def terminate_message
if @name_window_frame != nil
@name_window_frame.dispose
@name_window_frame = nil
end
if @name_window_text != nil
@name_window_text.dispose
@name_window_text = nil
end
xrxs9_terminate_message
end
#--------------------------------------------------------------------------
# ● リフレッシュ
#--------------------------------------------------------------------------
def refresh
# 初期化
self.contents.clear
self.contents.font.color = normal_color
self.contents.font.size = Font.default_size
@x = @y = @max_x = @max_y = @indent = @lines = 0
@face_indent = 0
@opacity = 255
@cursor_width = 0
@write_speed = 0
@write_wait = 0
@mid_stop = false
@face_file = nil
# @popchar が -2 の場合、標準位置。-1の場合、文字センター。
# 0以上の場合 キャラポップ。0は主人公、1以降はイベント。
@popchar = -2
# 選択肢なら字下げを行う
if $game_temp.choice_start == 0
@x = 8
end
# 表示待ちのメッセージがある場合
if $game_temp.message_text != nil
@now_text = $game_temp.message_text
# 顔表示指定\Fがあるか?
if (/\A\\[Ff]\[(.+?)\]/.match(@now_text))!=nil then
# ファイルチェック
if FileTest.exist?("Graphics/Pictures/" + $1 + ".png")
# 顔グラを描画
@face_file = $1 + ".png"
self.contents.blt(16, 16, RPG::Cache.picture(@face_file), Rect.new(0, 0, 96, 96))
# 全行 128ピクセルのインデントを入れる。
@x = @face_indent = 128
end
@now_text.gsub!(/\\[Ff]\[(.*?)\]/) { "" }
end
# \nameがあるか?
name_window_set = false
if (/\\[Nn]ame\[(.+?)\]/.match(@now_text)) != nil
# 値を設定
name_window_set = true
name_text = $1
# \name[]部分を削除
@now_text.sub!(/\\[Nn]ame\[(.*?)\]/) { "" }
end
# ウィンドウ位置判定
if (/\\[Pp]\[([-1,0-9]+)\]/.match(@now_text))!=nil then
@popchar = $1.to_i
if @popchar == -1
@x = @indent = 48
@y = 4
end
@now_text.gsub!(/\\[Pp]\[([-1,0-9]+)\]/) { "" }
end
# 制御文字処理
begin
last_text = @now_text.clone
# \Vを独自ルーチンに変更(追加部分)
@now_text.gsub!(/\\[Vv]\[([IiWwAaSs]?)([0-9]+)\]/) { convart_value($1, $2.to_i) }
end until @now_text == last_text
@now_text.gsub!(/\\[Nn]\[([0-9]+)\]/) do
$game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : ""
end
# 便宜上、"\\\" を "\000" に変換
@now_text.gsub!(/\\\\/) { "\000" }
# "\\C" を "\001" に、"\\G" を "\002" に、
# "\\S" を "\003" に、"\\A" を "\004" に変換
@now_text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" }
@now_text.gsub!(/\\[Gg]/) { "\002" }
@now_text.gsub!(/\\[Ss]\[([0-9]+)\]/) { "\003[#{$1}]" }
@now_text.gsub!(/\\[Aa]\[(.*?)\]/) { "\004[#{$1}]" }
@now_text.gsub!(/\\[.]/) { "\005" }
@now_text.gsub!(/\\[|]/) { "\006" }
# 競合すると何かと気まずいので、\016以降を使用する
@now_text.gsub!(/\\[>]/) { "\016" }
@now_text.gsub!(/\\[<]/) { "\017" }
@now_text.gsub!(/\\[!]/) { "\020" }
@now_text.gsub!(/\\[~]/) { "\021" }
@now_text.gsub!(/\\[Ee]\[([0-9]+)\]/) { "\022[#{$1}]" }
# インデント設定(追加部分)
@now_text.gsub!(/\\[Ii]/) { "\023" }
# テキスト透過率指定(追加部分)
@now_text.gsub!(/\\[Oo]\[([0-9]+)\]/) { "\024[#{$1}]" }
# テキストサイズ指定(追加部分)
@now_text.gsub!(/\\[Hh]\[([0-9]+)\]/) { "\025[#{$1}]" }
# 空白挿入(追加部分)
@now_text.gsub!(/\\[Bb]\[([0-9]+)\]/) { "\026[#{$1}]" }
# ルビ表示(追加部分)
@now_text.gsub!(/\\[Rr]\[(.*?)\]/) { "\027[#{$1}]" }
if @popchar >= 0
@text_save = @now_text.clone
@max_x = 0
@max_y = 4
for i in 0..3
line = @now_text.split(/\n/)[3-i]
@max_y -= 1 if line == nil and @max_y <= 4-i
next if line == nil
cx = contents.text_size(line).width
@max_x = cx if cx > @max_x
end
self.width = @max_x + 48 + @face_indent
self.height = (@max_y - 1) * 32 + 64
else
@max_x = self.width - 32 - @face_indent
end
# ここで一旦ウィンドウ位置更新
reset_window
# \nameがあるか?
if name_window_set
# オフセット位置
off_x = 0
off_y = 0
# 枠だけウィンドウの作成(余白を 2 に設定)
space = 2
x = self.x + off_x - space / 2
y = self.y + off_y - space / 2
w = self.contents.text_size(name_text).width + 8 + space
h = 26 + space
@name_window_frame = Window_Frame.new(x, y, w, h)
@name_window_frame.z = self.z + 1
# 擬似的な空中文字描写ウィンドウを作成
x = self.x + off_x + 4
y = self.y + off_y
@name_window_text = Air_Text.new(x, y, name_text)
@name_window_text.z = self.z + 2
end
end
# ウィンドウを更新
reset_window
# 選択肢の場合
if $game_temp.choice_max > 0
@item_max = $game_temp.choice_max
self.active = true
self.index = 0
end
# 数値入力の場合
if $game_temp.num_input_variable_id > 0
digits_max = $game_temp.num_input_digits_max
number = $game_variables[$game_temp.num_input_variable_id]
@input_number_window = Window_InputNumber.new(digits_max)
@input_number_window.number = number
@input_number_window.x = self.x + 8
@input_number_window.y = self.y + $game_temp.num_input_start * 32
end
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
super
# フェードインの場合
if @fade_in
self.contents_opacity += 24
if @input_number_window != nil
@input_number_window.contents_opacity += 24
end
if self.contents_opacity == 255
@fade_in = false
end
return
end
@now_text = nil if @now_text == "" # 変換
# 表示待ちのメッセージがある場合
if @now_text != nil and @mid_stop == false
if @write_wait > 0
@write_wait -= 1
return
end
text_not_skip = DEFAULT_TYPING_ENABLE
while true
# 最大 x y の保存。
@max_x = @x if @max_x < @x
@max_y = @y if @max_y < @y
# c に 1 文字を取得 (文字が取得できなくなるまでループ)
if (c = @now_text.slice!(/./m)) != nil
# \\ の場合
if c == "\000"
# 本来の文字に戻す
c = "\"
end
# \C[n] の場合
if c == "\001"
# 文字色を変更
@now_text.sub!(/\[([0-9]+)\]/, "")
color = $1.to_i
if color >= 0 and color <= 7
self.contents.font.color = text_color(color)
end
# 次の文字へ
c = ""
end
# \G の場合
if c == "\002"
# ゴールドウィンドウを作成
if @gold_window == nil and @popchar <= 0
@gold_window = Window_Gold.new
@gold_window.x = 560 - @gold_window.width
if $game_temp.in_battle
@gold_window.y = 192
else
@gold_window.y = self.y >= 128 ? 32 : 384
end
@gold_window.opacity = self.opacity
@gold_window.back_opacity = self.back_opacity
end
# 次の文字へ
c = ""
end
# \S[n] の場合
if c == "\003"
# 文字色を変更
@now_text.sub!(/\[([0-9]+)\]/, "")
speed = $1.to_i
if speed >= 0 and speed <= 19
@write_speed = speed
end
# 次の文字へ
c = ""
end
# \A[soundname] の場合
if c == "\004"
# 再生ファイルを変更するための準備
@now_text.sub!(/\[(.*?)\]/, "")
buftxt = $1.dup.to_s
# 再生ファイル名に"/"があるか?
if buftxt.match(/\//) == nil and buftxt != "" then
# なければ"Audio/SE/"を結合する
$soundname_on_speak = "Audio/SE/" + buftxt
else
# あればそのままコピー
$soundname_on_speak = buftxt.dup
end
# 次の文字へ
c = ""
elsif c == "\004"
# 次の文字へ
c = ""
end
# \. の場合
if c == "\005"
@write_wait += 5
c = ""
end
# \| の場合
if c == "\006"
@write_wait += 20
c = ""
end
# \> の場合
if c == "\016"
text_not_skip = false
c = ""
end
# \<の場合
if c == "\017"
text_not_skip = true
c = ""
end
# \!の場合
if c == "\020"
@mid_stop = true
c = ""
end
# \~の場合
if c == "\021"
terminate_message
return
end
# \Iの場合(追加部分)
if c == "\023"
# 今の@xをインデント位置に設定
@indent = @x
c = ""
end
# \Oの場合(追加部分)
if c == "\024"
@now_text.sub!(/\[([0-9]+)\]/, "")
@opacity = $1.to_i
c = ""
end
# \Hの場合(追加部分)
if c == "\025"
@now_text.sub!(/\[([0-9]+)\]/, "")
self.contents.font.size = [[$1.to_i, 6].max, 32].min
c = ""
end
# \Bの場合(追加部分)
if c == "\026"
@now_text.sub!(/\[([0-9]+)\]/, "")
@x += $1.to_i
c = ""
end
# \Rの場合(追加部分)
if c == "\027"
@now_text.sub!(/\[(.*?)\]/, "")
# 文字を描画
@x += ruby_draw_text(self.contents, @x, @y * line_height + (line_height - self.contents.font.size), $1, @opacity)
# 文字描写のSEを演奏
if $soundname_on_speak != ""
Audio.se_play($soundname_on_speak)
end
c = ""
end
# アイコン描画用シーケンスの場合(追加部分)
if c == "\030"
# アイコンファイル名を取得
@now_text.sub!(/\[(.*?)\]/, "")
# アイコンを描画
self.contents.blt(@x , @y * line_height + 8, RPG::Cache.icon($1), Rect.new(0, 0, 24, 24))
# 文字描写のSEを演奏
if $soundname_on_speak != ""
Audio.se_play($soundname_on_speak)
end
@x += 24
# 次の文字へ
c = ""
end
# 改行文字の場合
if c == "\n"
# 選択肢ならカーソルの幅を更新
if @lines >= $game_temp.choice_start
@cursor_width = [@cursor_width, @max_x - @face_indent].max
end
# y に 1 を加算
@lines += 1
@y += 1
@x = 0 + @indent + @face_indent
# 選択肢なら字下げを行う
if @lines >= $game_temp.choice_start
@x = 8 + @indent + @face_indent
end
# 次の文字へ
c = ""
end
# 外字表示の場合
if c == "\022"
# []部分の除去
@now_text.sub!(/\[([0-9]+)\]/, "")
# 外字を表示
@x += gaiji_draw(4 + @x, @y * line_height + (line_height - self.contents.font.size), $1.to_i)
# 次の文字へ
c = ""
end
if c != ""
# 文字を描画
@x += opacity_draw_text(self.contents, @x, @y * line_height + (line_height - self.contents.font.size), c, @opacity)
# 文字描写のSEを演奏
if $soundname_on_speak != "" then
Audio.se_play($soundname_on_speak)
end
end
# Bボタンが押された場合
if Input.press?(Input::B)
text_not_skip = false
end
else
text_not_skip = true
break
end
# 終了判定
if text_not_skip
break
end
end
@write_wait += @write_speed
return
end
# 数値入力中の場合
if @input_number_window != nil
@input_number_window.update
# 決定
if Input.trigger?(Input::C)
$game_system.se_play($data_system.decision_se)
$game_variables[$game_temp.num_input_variable_id] =
@input_number_window.number
$game_map.need_refresh = true
# 数値入力ウィンドウを解放
@input_number_window.dispose
@input_number_window = nil
terminate_message
end
return
end
# メッセージ表示中の場合
if @contents_showing
# 選択肢の表示中でなければポーズサインを表示
if $game_temp.choice_max == 0
self.pause = true
end
# キャンセル
if Input.trigger?(Input::B)
if $game_temp.choice_max > 0 and $game_temp.choice_cancel_type > 0
$game_system.se_play($data_system.cancel_se)
$game_temp.choice_proc.call($game_temp.choice_cancel_type - 1)
terminate_message
end
end
# 決定
if Input.trigger?(Input::C)
if $game_temp.choice_max > 0
$game_system.se_play($data_system.decision_se)
$game_temp.choice_proc.call(self.index)
end
if @mid_stop
@mid_stop = false
return
else
terminate_message
end
end
return
end
# フェードアウト中以外で表示待ちのメッセージか選択肢がある場合
if @fade_out == false and $game_temp.message_text != nil
@contents_showing = true
$game_temp.message_window_showing = true
refresh
Graphics.frame_reset
self.visible = true
self.contents_opacity = 0
if @input_number_window != nil
@input_number_window.contents_opacity = 0
end
@fade_in = true
return
end
# 表示すべきメッセージがないが、ウィンドウが可視状態の場合
if self.visible
@fade_out = true
self.opacity -= 48
if self.opacity == 0
self.visible = false
@fade_out = false
$game_temp.message_window_showing = false
end
return
end
end
#--------------------------------------------------------------------------
# ● キャラクターの取得
# parameter : パラメータ
#--------------------------------------------------------------------------
def get_character(parameter)
# パラメータで分岐
case parameter
when 0 # プレイヤー
return $game_player
else # 特定のイベント
events = $game_map.events
return events == nil ? nil : events[parameter]
end
end
#--------------------------------------------------------------------------
# ● ウィンドウの位置と不透明度の設定
#--------------------------------------------------------------------------
def reset_window
# 判定
if @popchar >= 0
events = $game_map.events
if events != nil
character = get_character(@popchar)
x = [[character.screen_x - 0 - self.width / 2, 4].max, 636 - self.width].min
y = [[character.screen_y - 48 - self.height, 4].max, 476 - self.height].min
self.x = x
self.y = y
end
elsif @popchar == -1
self.x = -4
self.y = -4
self.width = 648
self.height = 488
else
if $game_temp.in_battle
self.y = 16
else
case $game_system.message_position
when 0 # 上
self.y = 16
when 1 # 中
self.y = 160
when 2 # 下
self.y = 304
end
self.x = 80
if @face_file == nil
self.width = 480
else
self.width = 600
self.x -= 60
end
self.height = 160
end
end
self.contents = Bitmap.new(self.width - 32, self.height - 32)
if @face_file != nil
self.contents.blt(16, 16, RPG::Cache.picture(@face_file), Rect.new(0, 0, 96, 96))
end
if @popchar == -1
self.opacity = 255
self.back_opacity = 0
elsif $game_system.message_frame == 0
self.opacity = 255
self.back_opacity = 160
else
self.opacity = 0
self.back_opacity = 160
end
end
#--------------------------------------------------------------------------
# ● 外字描画
#--------------------------------------------------------------------------
# x :x座標
# y :y座標
# num :外字番号
# 返り値:外字幅(@x増加値)
#--------------------------------------------------------------------------
def gaiji_draw(x, y, num)
# 外字データが存在しない場合は何もしない
if @gaiji_cache == nil
return 0
else
# 指定した外字がキャッシュ範囲を超えている場合は何もしない
if @gaiji_cache.width < num * 24
return 0
end
# 文字サイズを計算
if self.contents.font.size >= 20 and self.contents.font.size <= 24
size = 24
else
size = self.contents.font.size * 100 * 24 / 2200
end
# 外字データをstretch_bltで転送
self.contents.stretch_blt(Rect.new(x, y, size, size), @gaiji_cache, Rect.new(num * 24, 0, 24, 24))
# 文字描写のSEを演奏
if $soundname_on_speak != "" then
Audio.se_play($soundname_on_speak)
end
# 文字サイズを返す
return size
end
end
#--------------------------------------------------------------------------
# ● line_height
#--------------------------------------------------------------------------
# 返り値:行の高さ(@y増加値)を返します。
#--------------------------------------------------------------------------
def line_height
# 現状、選択肢等に対応ができない為、自動的に32を返します。
return 32
# 文字サイズを計算
if self.contents.font.size >= 20 and self.contents.font.size <= 24
return 32
else
return self.contents.font.size * 15 / 10
end
end
#--------------------------------------------------------------------------
# ● 透過文字描画
#--------------------------------------------------------------------------
# target :描画対象。Bitmapクラスを指定。
# x :x座標
# y :y座標
# str :描画文字列
# opacity:透過率(0~255)
# 返り値 :文字幅(@x増加値)。
#--------------------------------------------------------------------------
def opacity_draw_text(target, x, y, str,opacity)
# heightとwidthを計算
height = target.font.size
width = target.text_size(str).width
# opacityに規定値以上の値が入っている場合は修正。
opacity = [[opacity, 0].max, 255].min
# opacityが255(透過なし)の場合は通常描画
if opacity == 255
target.draw_text(x, y, width, height, str)
return width
else
# 表示テキストのheight、widthがバッファサイズを上回る場合は
# バッファを再生成する。
if @opacity_text_buf.width < width or @opacity_text_buf.height < height
@opacity_text_buf.dispose
@opacity_text_buf = Bitmap.new(width, height)
# そうでない場合はバッファクリア。
else
@opacity_text_buf.clear
end
# バッファに現在の文字サイズを反映
@opacity_text_buf.font.size = target.font.size
# バッファにテキスト描画
@opacity_text_buf.draw_text(0, 0, width, height, str)
# バッファデータをtargetに転送
target.blt(x, y, @opacity_text_buf, Rect.new(0, 0, width, height), opacity)
# 文字サイズを返す
return width
end
end
#--------------------------------------------------------------------------
# ● ルビ文字描画
#--------------------------------------------------------------------------
# target :描画対象。Bitmapクラスを指定。
# x :x座標
# y :y座標
# str :描画文字列。本文,ルビの形式で入力。
# ,区切りが2つ以上あった場合は自動的に無視される。
# opacity:透過率(0~255)
# 返り値 :文字幅(@x増加値)。
#--------------------------------------------------------------------------
def ruby_draw_text(target, x, y, str,opacity)
# フォントサイズをバックアップしておく
sizeback = target.font.size
# ルビサイズの計算
target.font.size * 3 / 2 > 32 ? rubysize = 32 - target.font.size : rubysize = target.font.size / 2
rubysize = [rubysize, 6].max
# opacityに規定値以上の値が入っている場合は修正。
opacity = [[opacity, 0].max, 255].min
# strをsplitで分割し、split_sに格納
split_s = str.split(/,/)
# split_sがnilの場合は""にしておく(誤動作防止)
split_s[0] == nil ? split_s[0] = "" : nil
split_s[1] == nil ? split_s[1] = "" : nil
# heightとwidthを計算
height = sizeback + rubysize
width = target.text_size(split_s[0]).width
# バッファ用の幅計算(ルビの幅が本文の幅を越える可能性がある為)
target.font.size = rubysize
ruby_width = target.text_size(split_s[1]).width
target.font.size = sizeback
buf_width = [target.text_size(split_s[0]).width, ruby_width].max
# 本文の描画幅とルビの描画幅の差を1/2にして変数に格納(後で使用)
width - ruby_width != 0 ? sub_x = (width - ruby_width) / 2 : sub_x = 0
# opacityが255(透過なし)の場合は通常描画
if opacity == 255
# ルビの描画
target.font.size = rubysize
target.draw_text(x + sub_x, y - target.font.size, target.text_size(split_s[1]).width, target.font.size, split_s[1])
target.font.size = sizeback
# 本文の描画
target.draw_text(x, y, width, target.font.size, split_s[0])
return width
else
# 表示テキストのheight、widthがバッファサイズを上回る場合は
# バッファを再生成する。
if @opacity_text_buf.width < buf_width or @opacity_text_buf.height < height
@opacity_text_buf.dispose
@opacity_text_buf = Bitmap.new(buf_width, height)
# そうでない場合はバッファクリア。
else
@opacity_text_buf.clear
end
# バッファにテキスト描画
# ルビの描画
@opacity_text_buf.font.size = rubysize
@opacity_text_buf.draw_text(0 , 0, buf_width, rubysize, split_s[1], 1)
@opacity_text_buf.font.size = sizeback
# 本文の描画
@opacity_text_buf.draw_text(0 , rubysize, buf_width, sizeback, split_s[0], 1)
# ルビの幅が本文の幅を下回る場合
if sub_x >= 0
target.blt(x, y - rubysize, @opacity_text_buf, Rect.new(0, 0, buf_width, height), opacity)
# ルビの幅が本文の幅を上回る場合
else
target.blt(x + sub_x, y - rubysize, @opacity_text_buf, Rect.new(0, 0, buf_width, height), opacity)
end
# 文字サイズを返す
return width
end
end
#--------------------------------------------------------------------------
# ● \V変換
#--------------------------------------------------------------------------
# option :オプション。無指定又は規定外の場合はindexのユーザ変数値を返す。
# index :インデックス
# 返り値 :変換結果(アイコン表示用シーケンス込み)
#--------------------------------------------------------------------------
def convart_value(option, index)
# optionがnilの場合は""に直す(誤動作防止)
option == nil ? option = "" : nil
# optionはdowncaseしておく。
option.downcase!
# \030はアイコン表示用のシーケンス。\030[アイコンファイル名]で定義。
case option
when "i"
unless $data_items[index].name == nil
r = sprintf("\030[%s]%s", $data_items[index].icon_name, $data_items[index].name)
end
when "w"
unless $data_weapons[index].name == nil
r = sprintf("\030[%s]%s", $data_weapons[index].icon_name, $data_weapons[index].name)
end
when "a"
unless $data_armors[index].name == nil
r = sprintf("\030[%s]%s", $data_armors[index].icon_name, $data_armors[index].name)
end
when "s"
unless $data_skills[index].name == nil
r = sprintf("\030[%s]%s", $data_skills[index].icon_name, $data_skills[index].name)
end
else
r = $game_variables[index]
end
r == nil ? r = "" : nil
return r
end
#--------------------------------------------------------------------------
# ● 解放
#--------------------------------------------------------------------------
def dispose
terminate_message
# 外字キャッシュ開放
if @gaiji_cache != nil
unless @gaiji_cache.disposed?
@gaiji_cache.dispose
end
end
# 文字透過転送用バッファ開放
unless @opacity_text_buf.disposed?
@opacity_text_buf.dispose
end
$game_temp.message_window_showing = false
if @input_number_window != nil
@input_number_window.dispose
end
super
end
#--------------------------------------------------------------------------
# ● カーソルの矩形更新
#--------------------------------------------------------------------------
def update_cursor_rect
if @index >= 0
n = $game_temp.choice_start + @index
self.cursor_rect.set(4 + @indent + @face_indent, n * 32 + 4, @cursor_width, 32)
else
self.cursor_rect.empty
end
end
end
#==============================================================================
# ■ Window_Frame (枠だけで中身の無いウィンドウ)
#==============================================================================
class Window_Frame < Window_Base
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize(x, y, width, height)
super(x, y, width, height)
self.contents = nil
self.back_opacity = 160
end
#--------------------------------------------------------------------------
# ● 解放
#--------------------------------------------------------------------------
def dispose
super
end
end
#==============================================================================
# ■ Air_Text (何も無いところに文字描写 = 枠の無い瞬間表示メッセージウィンドウ)
#==============================================================================
class Air_Text < Window_Base
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize(x, y, designate_text)
super(x-16, y-16, 32 + designate_text.size * 12, 56)
self.opacity = 0
self.back_opacity = 0
self.contents = Bitmap.new(self.width - 32, self.height - 32)
w = self.contents.width
h = self.contents.height
self.contents.draw_text(0, 0, w, h, designate_text)
end
#--------------------------------------------------------------------------
# ● 解放
#--------------------------------------------------------------------------
def dispose
self.contents.clear
super
end
end
复制代码
齒車之城版:
# メッセージ制御文字追加~流々牙さん顔グラフィックバージョン~ Ver 1.04
# 配布元・サポートURL
# http://members.jcom.home.ne.jp/cogwheel/
#==============================================================================
# ■ Game_Player
#------------------------------------------------------------------------------
# プレイヤーを扱うクラスです。イベントの起動判定や、マップのスクロールなどの
# 機能を持っています。このクラスのインスタンスは $game_player で参照されます。
#==============================================================================
class Game_Player < Game_Character
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_accessor :message_speed # メッセージ速度
attr_accessor :message_history # メッセージ履歴
attr_accessor :history_size # メッセージ履歴サイズ
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
super
@message_speed = 1
@message_history = []
@history_size = 100
end
end
#==============================================================================
# ■ Window_Message
#------------------------------------------------------------------------------
# 文章表示に使うメッセージウィンドウです。
#==============================================================================
class Window_Message < Window_Selectable
#--------------------------------------------------------------------------
# ● 定数
#--------------------------------------------------------------------------
FADE = true # 顔グラのフェードイン表示
ENTER = true # エンターキー押下時のメッセージ一括表示可否
SHIFT = 1 # シフトスキップの可否
# (0:不可, 1:デバッグ中のみ可, 2:常に可)
#--------------------------------------------------------------------------
# ● 顔グラフィック表示
#--------------------------------------------------------------------------
def actor(name1, name2, write = true)
if name1 > 0
name = RPG::Face.seek($game_actors[name1].character_name)
else
case name1.abs
when 1
name = "n1"
when 2
name = "n2"
end
end
if name2 > 1
name += "_" + name2.to_s
end
if write
@face.bitmap = RPG::Cache.face(name)
@face.x = self.x + 16
@face.y = self.y + self.height / 2
@face.z = self.z + 1
@face.oy = 50
end
@fi = 100
# 最初の行を字下げ
@x = @fi + @i if @x <= @fi
end
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
super(80, 304, 480, 160)
self.contents = Bitmap.new(width - 32, height - 32)
self.visible = false
self.z = 9998
# 顔グラフィックの作成
@face = Sprite.new(self.viewport)
@face.bitmap = Bitmap.new(10, 10)
@face.visible = false
@text = ""
@fade_in = false
@fade_out = false
@contents_showing = false
@contents_showed = false
@cursor_width = 0
self.active = false
self.index = -1
# 履歴ウィンドウの作成
@h_window = Window.new(self.viewport)
@h_window.x = 77
@h_window.y = 64
@h_window.z = 10001
@h_window.width = 486
@h_window.height = 352
@h_window.opacity = 0
@h_window.back_opacity = 160
@h_window.windowskin = RPG::Cache.windowskin($game_system.windowskin_name)
@h_window.active = false
@h_window.visible = false
@c_h = 0
# メッセージスピードの初期化
unless $game_player.message_speed.is_a?(Numeric)
$game_player.message_speed = 1
end
end
#--------------------------------------------------------------------------
# ● 解放
#--------------------------------------------------------------------------
def dispose
terminate_message
$game_temp.message_window_showing = false
@face.dispose
if @input_number_window != nil
@input_number_window.dispose
end
@h_window.dispose
super
end
#--------------------------------------------------------------------------
# ● メッセージ終了処理
#--------------------------------------------------------------------------
def terminate_message
self.active = false
self.pause = false
self.index = -1
self.contents.clear
# 表示中フラグをクリア
@contents_showing = false
@contents_showed = false
# メッセージ コールバックを呼ぶ
if $game_temp.message_proc != nil
$game_temp.message_proc.call
end
# 文章、選択肢、数値入力に関する変数をクリア
$game_temp.message_text = nil
$game_temp.message_proc = nil
$game_temp.choice_start = 99
$game_temp.choice_max = 0
$game_temp.choice_cancel_type = 0
$game_temp.choice_proc = nil
$game_temp.num_input_start = 99
$game_temp.num_input_variable_id = 0
$game_temp.num_input_digits_max = 0
# ゴールドウィンドウを開放
if @gold_window != nil
@gold_window.dispose
@gold_window = nil
end
end
#--------------------------------------------------------------------------
# ● テキスト初期化設定
#--------------------------------------------------------------------------
def text_initialize
# メッセージウィンドウ初期化設定
@text = $game_temp.message_text
@back_up = @text.clone
@rubi = ""
@speed = $game_player.message_speed
font_size = 22
@wait = 0
@push_enter = false
@contents_close = false
@cursor_width = 0
# 制御文字処理
begin
last_text = @text.clone
@text.gsub!(/\\[Vv]\[(\d+)\]/) { $game_variables[$1.to_i] }
end until @text == last_text
@text.gsub!(/\\[Nn]\[(\d+)\]/) do
$game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : ""
end
# 便宜上、"\\\" を "\000" に変換
@text.gsub!(/\\\\/) { "\000" }
# "\\C" を "\001" に、"\\G" を "\002" に変換
@text.gsub!(/\\[Cc]\[(\d+)\]/) { "\001[#{$1}]" }
@text.gsub!(/\\[Gg]/) { "\002" }
# 制御文字をそれぞれバックスラッシュ記法に変換
@text.gsub!(/\\[Ss]\[(\d+)\]/) { "\003[#{$1}]" }
@text.gsub!(/\\\./) { "\004" }
@text.gsub!(/\\\;/) { "\005" }
@text.gsub!(/\\\|/) { "\006" }
@text.gsub!(/\\\!/) { "\010" }
@text.gsub!(/\\\>/) { "\016" }
@text.gsub!(/\\\</) { "\017" }
@text.gsub!(/\\\^/) { "\020" }
@text.gsub!(/\\[Ii]/) { "\021" }
@text.gsub!(/\\[Ll][Tt]/) { "\022" }
@text.gsub!(/\\[Cc][Tt]/) { "\023" }
@text.gsub!(/\\[Rr][Tt]/) { "\024" }
@text.gsub!(/\\[Ff]\[(\d+)\]/) { "\025[#{$1}]" }
@text.gsub!(/\\[Aa]\[(\-*\d+),?(\d*?)\]/) { "\026[#{$1},0#{$2}]" }
@text.gsub!(/\\[Rr]\[(.+?),(.+?)\]/) { "\027[#{$1},#{$2}]" }
@text.gsub!(/\\[Oo]\[(.+?)\]/) { "\030[#{$1}]" }
@text.gsub!(/\<[Bb]\>/) { "\031" }
@text.gsub!(/\<\/[Bb]\>/) { "\033" }
@text.gsub!(/\<[Ii]\>/) { "\034" }
@text.gsub!(/\<\/[Ii]\>/) { "\035" }
@text.gsub!(/\\[Ss][Tt]/) { "" }
@text.gsub!(/\\[Nn]/) { "\n" }
@text.gsub!(/\\[Pp](.*?)\n/) { $1 }
@x = @i = 4
@fi = @y = @py = 0
# 最初の行がルビ付きの場合、字下げを行う
@text = "\n" if @text == ""
text = @text[/^.*?\n/]
r_height = 0
while ((c = text.slice!(/./m)) != nil)
# \F[n] の場合、フォントサイズの変更
if c == "\025"
text.sub!(/\[([0-9]+)\]/, "")
font_size = $1.to_i
next
end
# ルビが存在した場合
if c == "\027"
text.sub!(/\[(.+?),(.+?)\]/, "")
# ルビのテキストサイズを格納
r_height = [r_height, font_size].max
next
end
end
# 字下げの設定
@py = [(r_height + [(r_height + 66) / 8, r_height * 2 / 3].min - 5) -
max_height(@text), 0].max
# 選択肢なら字下げを行う
if $game_temp.choice_start == 0
@x = 12
end
# "\\E[n]" がある場合、イベントnに吹き出し表示
unless self.contents.disposed?
self.contents.dispose
end
# 吹き出し表示の場合
if @text.gsub!(/\\[Ee]\[(\-*?\d+),?(\d*?)\]/) { "" }
# メッセージの幅、高さの読み込み
@event = $game_system.map_interpreter.get_character($1.to_i)
self.contents = Bitmap.new(10, 10)
self.contents.font.size = font_size
self.width = text_width(@text) + 32
self.height = [text_height(@text) + 32 + @py, 32].max
# 数値入力の場合、高さと幅の調整
if $game_temp.num_input_variable_id > 0
dummy_bitmap = Bitmap.new(32, 32)
i_width = dummy_bitmap.text_size("0").width + 8
dummy_bitmap.dispose
self.width=[self.width,i_width*$game_temp.num_input_digits_max+48].max
self.height += 32
# 高さが数値分しかない場合、数値入力を繰り上げる
$game_temp.num_input_start -= 1 if self.height == 64
end
@w_pos = $2.to_i
window_position
self.contents.dispose
else
@event = nil
self.x = 80
if $game_temp.in_battle
self.y = 16
else
case $game_system.message_position
when 0 # 上
self.y = 16
when 1 # 中
self.y = 160
when 2 # 下
self.y = 304
end
end
self.width = 480
self.height = 160
end
# ウィンドウ内容の初期化
self.contents = Bitmap.new(width - 32, height - 32)
self.contents.font.size = font_size
self.contents.font.color = normal_color
self.contents.font.bold = false
self.contents.font.italic = false
# メッセージ履歴に文章を挿入
history_write(@text.clone)
# 第一行目のフォントサイズが基準フォントサイズと異なる場合の体裁を整える
@h = @c_h = max_height(@text) - self.contents.font.size
@c_w = 0
end
#--------------------------------------------------------------------------
# ● 吹き出し表示:ウィンドウ位置設定
#--------------------------------------------------------------------------
def window_position
m_x = (@event.real_x - $game_map.display_x) / 4 - self.width / 2 + 16
m_y = (@event.real_y - $game_map.display_y) / 4
if @w_pos == 0
m_y -= self.height + 32
else
m_y += 48
end
self.x =[[m_x, 0].max, 640 - self.width].min
self.y = [[m_y, 0].max, 480 - self.height].min
if @input_number_window != nil
@input_number_window.x = self.x + 8
@input_number_window.y = self.y + 32 + @h + @py
end
end
#--------------------------------------------------------------------------
# ● リフレッシュ
#--------------------------------------------------------------------------
def refresh
# 表示待ちのメッセージがある場合
if @text != nil
# c に 1 文字を取得 (文字が取得できなくなるまでループ)
while ((c = @text.slice!(/./m)) != nil)
next unless control(c)
if @push_enter
@contents_showed = true
break
end
# 文字を描画
size = self.contents.font.size
self.contents.draw_text(@x, @h + @py, 10 + size, 10 + size, c)
# x に描画した文字の幅を加算
@x += self.contents.text_size(c).width
rubi_draw if @rubi != ""
if @speed > 0 and @contents_showed == false and
not (ENTER and Input.trigger?(Input::C)) and
not (SHIFT >= ($DEBUG ? 0 : 1) and Input.press?(Input::SHIFT))
@wait += @speed if @wait <= 0
break if @wait > 0
end
end
if @text == ""
text_end
end
end
end
#--------------------------------------------------------------------------
# ● テキスト描画終了時
#--------------------------------------------------------------------------
def text_end
@contents_showed = true
# 選択肢の場合
if $game_temp.choice_max > 0
@item_max = $game_temp.choice_max
self.active = true
self.index = 0
@c_h = @h
end
# 数値入力の場合
if $game_temp.num_input_variable_id > 0
digits_max = $game_temp.num_input_digits_max
number = $game_variables[$game_temp.num_input_variable_id]
@input_number_window = Window_InputNumber.new(digits_max)
@input_number_window.number = number
@input_number_window.x = self.x + 8
@input_number_window.y = self.y + 32 + @h + @py
end
end
#--------------------------------------------------------------------------
# ● 制御文字処理
#--------------------------------------------------------------------------
def control(c)
# \\ の場合
if c == "\000"
# 本来の文字に戻す
c = "\"
return true
end
# \C[n] の場合
if c == "\001"
c_change
return false
end
# \G の場合
if c == "\002"
gold
return false
end
# \S[n] の場合
if c == "\003"
@text.sub!(/\[(\d+)\]/, "")
@speed = $game_player.message_speed * $1.to_i
return false
end
# \. の場合
if c == "\004"
@wait = 10
c.sub!("\004", "")
return true
end
# \: の場合
if c == "\005"
@wait = 20
c.sub!("\005", "")
return true
end
# \| の場合
if c == "\006"
@wait = 40
c.sub!("\006", "")
return true
end
# \! の場合
if c == "\010"
self.pause = true
@push_enter = true
@contents_showed = true
c.sub!("\010", "")
return true
end
# \> の場合
if c == "\016"
@temp_speed = @speed
@speed = 0
return false
end
# \< の場合
if c == "\017"
@speed = @temp_speed
c.sub!("\017", "")
return true
end
# \^ の場合
if c == "\020"
@contents_close = true
return false
end
# \I の場合
if c == "\021"
@i = @x - @fi
if @y >= $game_temp.choice_start
@i = @x - @fi - 8
end
return false
end
# \LT の場合
if c == "\022"
@i = @x = @fi + 4
return false
end
# \CT の場合
if c == "\023"
@text[(/(.+?)\n/)]
width = max_width($1)[0]
@x = (@fi + self.contents.width - width) / 2
return false
end
# \RT の場合
if c == "\024"
@text[(/(.+?)\n/)]
width = max_width($1)[0]
@x = self.contents.width - width - 4
return false
end
# \F[n] の場合
if c == "\025"
s_change
return false
end
# \A[n,m] の場合
if c == "\026"
@text.sub!(/\[(\-*\d+),(\d+)\]/, "")
actor($1.to_i, $2.to_i)
return false
end
# \R[n,m] の場合
if c == "\027"
@text.sub!(/\[(.+?),(.+?)\]/) { rubi_set($1, $2) }
return false
end
# \O[i] の場合
if c == "\030"
@text.sub!(/\[(.+?)\]/, "")
letter($1.to_i)
return false
end
# <B> の場合
if c == "\031"
self.contents.font.bold = true
return false
end
# </B> の場合
if c == "\033"
self.contents.font.bold = false
return false
end
# <I> の場合
if c == "\034"
self.contents.font.italic = true
return false
end
# </I> の場合
if c == "\035"
self.contents.font.italic = false
return false
end
# 改行文字の場合
if c == "\n"
new_line
return false
end
return true
end
#--------------------------------------------------------------------------
# ● ルビ描画
#--------------------------------------------------------------------------
def rubi_draw
# フォントサイズのバックアップ
f_size = self.contents.font.size
# ルビサイズの設定
size = [(f_size + 66) / 8, f_size * 2 / 3].min
if @h_window.active
@h_window.contents.font.size = size
else
self.contents.font.size = size
end
# ルビのテキスト長 / メインテキストのテキスト長の算出
num = @rubi_s / @main_s.to_f
# 一回の描画でどれだけルビを振るか計算
cnt = num.ceil - (num.ceil - num).round
# 描画回数分だけルビの描画
for i in 1..cnt
c = @rubi.slice!(/./m)
# 履歴表示中の場合、履歴ウィンドウにルビを描画
if @h_window.active
@h_window.contents.draw_text(@rubi_x - 5 - size / 2,
@h + @py - size + 3, 10 + size, 6 + size, c, 1)
# メッセージウィンドウにルビを描画
else
self.contents.draw_text(@rubi_x - 5 - size / 2,
@h + @py - size + 3, 10 + size, 6 + size, c, 1)
end
@rubi_x += @rubi_w
@rubi_s -= 1
end
@main_s -= 1
self.contents.font.size = f_size
end
#--------------------------------------------------------------------------
# ● ルビ設定
#--------------------------------------------------------------------------
def rubi_set(main, rubi)
text = main.clone
@rubi = rubi.clone
@main_s = 0
@rubi_s = 0
while(main.slice!(/./m) != nil)
@main_s += 1
end
while(rubi.slice!(/./m) != nil)
@rubi_s += 1
end
f_size = self.contents.font.size
main_w = self.contents.text_size(text).width
self.contents.font.size = [(f_size + 66) / 8, f_size * 2 / 3].min
rubi_w = self.contents.text_size(@rubi).width
if main_w >= rubi_w or @rubi_s == 1
@rubi_x = @x + main_w.to_f / (@rubi_s * 2)
@rubi_w = main_w.to_f / @rubi_s
else
@rubi_x = @x - (rubi_w - main_w - self.contents.font.size) / 2
@rubi_w = rubi_w.to_f / @rubi_s
end
self.contents.font.size = f_size
return text
end
#--------------------------------------------------------------------------
# ● 外字の表示
#--------------------------------------------------------------------------
def letter(i)
pict = RPG::Cache.windowskin("Letter_" + (i / 16).to_s)
p_width = pict.width / 4
p_height = pict.height / 4
p_x = i % 4
p_y = (i % 16) / 4
rect = Rect.new(p_x * p_width, p_y * p_height, p_width, p_height)
if @h_window.active
@h_window.contents.blt(@x,
@h + @py + self.contents.font.size - p_height + 5, pict, rect)
else
self.contents.blt(@x,
@h + @py + self.contents.font.size - p_height + 5, pict, rect)
end
@x += p_width
end
#--------------------------------------------------------------------------
# ● 文字色変更
#--------------------------------------------------------------------------
def c_change
# 文字色を変更
@text.sub!(/\[(\d+)\]/, "")
color = $1.to_i
if color >= 0 and color <= 7
if @h_window.active
@h_window.contents.font.color = text_color(color)
else
self.contents.font.color = text_color(color)
end
end
end
#--------------------------------------------------------------------------
# ● 所持金表示
#--------------------------------------------------------------------------
def gold
# ゴールドウィンドウを作成
if @gold_window == nil
@gold_window = Window_Gold.new
@gold_window.x = 560 - @gold_window.width
if $game_temp.in_battle
@gold_window.y = 192
else
@gold_window.y = self.y >= 128 ? 32 : 384
end
@gold_window.opacity = self.opacity
@gold_window.back_opacity = self.back_opacity
end
end
#--------------------------------------------------------------------------
# ● 文字サイズ変更
#--------------------------------------------------------------------------
def s_change
# 文字色を変更
@text.sub!(/\[([0-9]+)\]/, "")
@h += self.contents.font.size - $1.to_i
self.contents.font.size = $1.to_i
end
#--------------------------------------------------------------------------
# ● 行のテキスト幅の取得
#--------------------------------------------------------------------------
def max_width(text)
# 不要な制御文字の削除
text.gsub!(/\001\[\d+\]/) { "" }
text.gsub!(/\002/) { "" }
text.gsub!(/\003\[\d+\]/) { "" }
text.gsub!(/\004/) { "" }
text.gsub!(/\005/) { "" }
text.gsub!(/\006/) { "" }
text.gsub!(/\010/) { "" }
text.gsub!(/\016/) { "" }
text.gsub!(/\017/) { "" }
text.gsub!(/\020/) { "" }
text.gsub!(/\022/) { "" }
text.gsub!(/\023/) { "" }
text.gsub!(/\024/) { "" }
text.gsub!(/\026\[\-*\d+,\d+\]/) { "" }
text.gsub!(/\027\[(.+?),(.+?)\]/) { $1 }
# 現在のウィンドウ情報を取得
size = self.contents.font.size
bold = self.contents.font.bold
italic = self.contents.font.italic
width = 0
i = @i
while ((c = text.slice!(/./m)) != nil)
# テキストが \I の場合インデントの設定
if c == "\021"
i = width
if @y >= $game_temp.choice_start
i = width - 8
end
next
end
# \F[n] の場合、フォントサイズの変更
if c == "\025"
text.sub!(/\[([0-9]+)\]/, "")
self.contents.font.size = $1.to_i
next
end
# テキストが\O[i] の場合、外字分だけ幅を増やす
if c == "\030"
text.sub!(/\[(.+?)\]/, "")
width += RPG::Cache.windowskin("Letter_"+($1.to_i/16).to_s).width / 4
next
end
# <B> の場合
if c == "\031"
self.contents.font.bold = true
next
end
# </B> の場合
if c == "\033"
self.contents.font.bold = false
next
end
# <I> の場合
if c == "\034"
self.contents.font.italic = true
next
end
# </I> の場合
if c == "\035"
self.contents.font.italic = false
next
end
width += self.contents.text_size(c).width
end
# 行終了時のウィンドウ情報の格納
e_size = self.contents.font.size
e_bold = self.contents.font.bold
e_italic = self.contents.font.italic
# ウィンドウ情報を元に戻す
self.contents.font.size = size
self.contents.font.bold = bold
self.contents.font.italic = italic
return [width, i, e_size, e_bold, e_italic]
end
#--------------------------------------------------------------------------
# ● 文章全体の幅の取得
#--------------------------------------------------------------------------
def text_width(sentence)
# 現在のウィンドウ情報を取得
size = self.contents.font.size
bold = self.contents.font.bold
italic = self.contents.font.italic
i = @i
x = @x
# 文章幅の取得開始
text = sentence.clone
width = 0
# \A[n,m] の場合
if text[/\026/]
text.sub!(/\026\[(\-*\d+),(\d+)\]/, "")
actor($1.to_i, $2.to_i, false)
width = @x
end
cnt = 0
while text != ""
t_width = max_width(text[/^.*?\n/])
# 選択肢だった場合は幅に32加算する
t_width[0] += 20 if cnt >= $game_temp.choice_start
width = [width, @i + t_width[0]].max
# ウィンドウ情報を更新して次の行へ
@i = t_width[1]
self.contents.font.size = t_width[2]
self.contents.font.bold = t_width[3]
self.contents.font.italic = t_width[4]
text.sub!(/^.*?\n/) {""}
cnt += 1
end
# ウィンドウ情報を元に戻す
self.contents.font.size = size
self.contents.font.bold = bold
self.contents.font.italic = italic
@i = i
@x = x
return width + @fi + 4
end
#--------------------------------------------------------------------------
# ● 行の最大テキスト高さを求める
#--------------------------------------------------------------------------
def max_height(sentence)
text = sentence[/(.+?)\n/]
t_size = 0
# テキストが空になるまで繰り返し
while text != "" and text != nil
c = text.slice!(/./m)
# テキストが \C[n] か \S[n] の場合次のテキストへ
if c == "\001" or c == "\003"
text.sub!(/\[([0-9]+)\]/, "")
next
end
# アクターグラフィックの場合次のテキストへ
if c == "\026"
text.sub!(/\[(\-*\d+),(\d+)\]/, "")
next
end
# テキストが\O[i] の場合
if c == "\030"
text.sub!(/\[(.+?)\]/, "")
p_height = RPG::Cache.windowskin("Letter_"+($1.to_i/16).to_s).height/4
l_height = [((p_height + 1) * 8 - 66) / 9, (p_height + 1) * 3 / 5].max
t_size = [t_size, l_height].max
next
end
# テキストが \F[n] の場合、最大テキスト高さに n を代入
if c == "\025"
text.sub!(/\[([0-9]+)\]/, "")
t_size = [t_size, $1.to_i].max
end
# 最大テキスト高さが0の場合、現在のフォントサイズを代入
t_size = self.contents.font.size if t_size == 0
end
return t_size
end
#--------------------------------------------------------------------------
# ● 文章全体の高さを求める
#--------------------------------------------------------------------------
def text_height(sentence)
# 高さ・ルビ分の高さを初期化
h = 0
size = self.contents.font.size
text = sentence.clone
if text[/^.*?\n/][/\027/]
py = [(max_height(text) + 66) / 8, max_height(text) * 2 / 3].min - 5
else
py = 0
end
# 文章の総合高さを計算
while text != ""
# 現在の行の高さを計算
height = max_height(text)
# 総高さに現在の行の高さを加算
h += height + [(height + 66) / 8, height * 2 / 3].min - 1
# \F[n] の場合、フォントサイズの変更
if text[/^.*?\n/][/.*\025\[(\d+)\]/]
self.contents.font.size = $1.to_i
end
# 次の行へ
text.sub!(/^.*?\n/) {""}
end
# 顔グラフィックがある場合
if sentence[/\026/]
h = [h, 100].max
end
self.contents.font.size = size
# 文章全体の高さを返す
return h
end
#--------------------------------------------------------------------------
# ● 改行
#--------------------------------------------------------------------------
def new_line
# 選択肢ならカーソルの幅を更新
if @h_window.active == false and @y >= $game_temp.choice_start
@cursor_width = [@cursor_width, @x].max
end
# y に 1 を加算
@y += 1
# 次の行の最大テキスト高さ + ルビ分の字下げ
height = max_height(@text)
@h += height + [(height + 66) / 8, height * 2 / 3].min - 1
@x = @fi + @i
# 選択肢なら字下げを行う
if @h_window.active == false and @y >= $game_temp.choice_start
@x = 8 + @fi + @i
# ルビ付きの場合、字下げを行う
text = @text[/^.*?\n/]
font_size = self.contents.font.size
r_height = 0
while text != "" and text != nil
c = text.slice!(/./m)
# \F[n] の場合、フォントサイズの変更
if c == "\025"
text.sub!(/\[([0-9]+)\]/, "")
font_size = $1.to_i
next
end
# ルビが存在した場合
if c == "\027"
text.sub!(/\[(.+?),(.+?)\]/, "")
# ルビのテキストサイズを格納
r_height = [r_height, font_size].max
next
end
end
# 字下げの設定
@py = [(r_height + [(r_height + 66) / 8, r_height * 2 / 3].min - 5) -
max_height(@text), 0].max
end
# 次の文字へ
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
# メッセージ履歴の呼び出し
if @h_window.active == false and (@contents_showed or
$game_system.map_interpreter.running? == false) and
(Input.trigger?(Input::L) or Input.trigger?(Input::R)) and
not $game_player.message_history.empty?
history_start
end
if @h_window.active
if @h_window.opacity < 255
@h_window.opacity += 24
@h_window.contents_opacity += 24
@bar.opacity += 24
return
end
history_update
return
end
# メッセージ履歴消去中の場合
if @h_window.opacity > 0
# 透過度を増やす
@h_window.opacity -= 48
@h_window.contents_opacity -= 48
@bar.opacity -= 48
# メッセージ履歴が完全透過状態になった場合
if @h_window.opacity == 0
@h_window.visible = false
@h_window.contents.dispose
@bar.bitmap.dispose
@bar.dispose
if @contents_showed == false
$game_temp.message_window_showing = false
end
end
return
end
super
# 吹き出し表示の場合、ウィンドウ位置設定
window_position if @event != nil
# フェードインの場合
if @fade_in
self.contents_opacity += 24
@face.opacity += 24 if FADE
if @input_number_window != nil
@input_number_window.contents_opacity += 24
end
if self.contents_opacity == 255
@fade_in = false
end
end
# 数値入力中の場合
if @input_number_window != nil
@input_number_window.update
# 決定
if Input.trigger?(Input::C)
if @push_enter
self.pause = false
@push_enter = false
@contents_showed = false
return
end
$game_system.se_play($data_system.decision_se)
$game_variables[$game_temp.num_input_variable_id] =
@input_number_window.number
$game_map.need_refresh = true
# 数値入力ウィンドウを解放
@input_number_window.dispose
@input_number_window = nil
terminate_message
end
return
end
# メッセージ表示中の場合
if @contents_showing and @contents_showed == false
if (ENTER and Input.trigger?(Input::C)) or
(SHIFT >= ($DEBUG ? 0 : 1) and Input.press?(Input::SHIFT))
@wait = 0
end
if @wait > 0
@wait -= 1
return if @wait > 0
end
refresh
return
end
# メッセージ表示終了の場合
if @contents_showed
# 選択肢の表示中でなければポーズサインを表示
if $game_temp.choice_max == 0
self.pause = true
end
# キャンセル
if Input.trigger?(Input::B)
if $game_temp.choice_max > 0 and $game_temp.choice_cancel_type > 0
$game_system.se_play($data_system.cancel_se)
$game_temp.choice_proc.call($game_temp.choice_cancel_type - 1)
terminate_message
end
end
# 決定
if Input.trigger?(Input::C)
if @push_enter
self.pause = false
@push_enter = false
@contents_showed = false
return
end
if $game_temp.choice_max > 0
$game_system.se_play($data_system.decision_se)
$game_temp.choice_proc.call(self.index)
end
terminate_message
end
if SHIFT == 2 and Input.press?(Input::SHIFT) and
$game_temp.choice_max == 0
if @push_enter
self.pause = false
@push_enter = false
@contents_showed = false
return
end
terminate_message
end
if @contents_close and $game_temp.choice_max == 0
if $game_temp.choice_max > 0
$game_system.se_play($data_system.decision_se)
$game_temp.choice_proc.call(self.index)
end
terminate_message
end
return
end
# フェードアウト中以外で表示待ちのメッセージか選択肢がある場合
if @fade_out == false and $game_temp.message_text != nil
@contents_showing = true
$game_temp.message_window_showing = true
reset_window
text_initialize
self.visible = true
self.contents_opacity = 0
@face.bitmap = nil
@face.visible = true
if FADE
@face.opacity = 0
else
@face.opacity = 255
end
if @input_number_window != nil
@input_number_window.contents_opacity = 0
end
@fade_in = true
refresh
Graphics.frame_reset
return
end
# 表示すべきメッセージがないが、ウィンドウが可視状態の場合
if self.visible
@fade_out = true
self.opacity -= 48
@face.opacity -= 48
if self.opacity == 0
self.visible = false
@face.visible = false
@fade_out = false
$game_temp.message_window_showing = false
end
return
end
end
#--------------------------------------------------------------------------
# ● メッセージ履歴テキスト格納
#--------------------------------------------------------------------------
def history_write(text)
# メッセージ履歴に不要な制御文字の削除
text.gsub!(/\002/) { "" }
text.gsub!(/\003\[\d+\]/) { "" }
text.gsub!(/\004/) { "" }
text.gsub!(/\005/) { "" }
text.gsub!(/\006/) { "" }
text.gsub!(/\010/) { "" }
text.gsub!(/\016/) { "" }
text.gsub!(/\017/) { "" }
text.gsub!(/\020/) { "" }
text.gsub!(/\026\[\-*\d+,\d+\]/) { "" }
# メッセージ履歴の初期化
unless $game_player.message_history.is_a?(Array)
$game_player.history_size = 100
$game_player.message_history = []
end
# 現在のテキストをメッセージ履歴に格納
$game_player.message_history.push([text, text_height(text)])
# メッセージ履歴のサイズが大きい場合、最初の方より履歴を削除
if $game_player.message_history.size > $game_player.history_size
$game_player.message_history.shift
end
end
#--------------------------------------------------------------------------
# ● メッセージ履歴テキスト描画
#--------------------------------------------------------------------------
def history_refresh
# 描画範囲に何もかかれていない場合、メッセージ履歴の描画を行う
while (@h >= @h_window.oy and @h != 0)
# 初期設定
@text = $game_player.message_history[@index][0].clone
h = @h
self.contents.font.size = 22
self.contents.font.color = normal_color
self.contents.font.bold = false
self.contents.font.italic = false
@rubi = ""
@x = @i = 4
@fi = @y = 0
@h += max_height(@text) - self.contents.font.size - text_height(@text)
# ルビ付きの場合、字下げを行う
text = @text[/^.*?\n/]
font_size = self.contents.font.size
r_height = 0
while ((c = text.slice!(/./m)) != nil)
# \F[n] の場合、フォントサイズの変更
if c == "\025"
text.sub!(/\[([0-9]+)\]/, "")
font_size = $1.to_i
next
end
# ルビが存在した場合
if c == "\027"
text.sub!(/\[(.+?),(.+?)\]/, "")
# ルビのテキストサイズを格納
r_height = [r_height, font_size].max
next
end
end
# 字下げの設定
@py = [(r_height + [(r_height + 66) / 8, r_height * 2 / 3].min - 5) -
max_height(@text), 0].max
# c に 1 文字を取得 (文字が取得できなくなるまでループ)
while ((c = @text.slice!(/./m)) != nil)
next unless control(c)
# 文字を描画
size = self.contents.font.size
@h_window.contents.font.size = size
@h_window.contents.font.bold = self.contents.font.bold
@h_window.contents.font.italic = self.contents.font.italic
@h_window.contents.draw_text(@x, @h + @py, 10 + size, 10 + size, c)
# x に描画した文字の幅を加算
@x += @h_window.contents.text_size(c).width
rubi_draw if @rubi != ""
end
@h = h - text_height($game_player.message_history[@index][0])
@index -= 1
end
end
#--------------------------------------------------------------------------
# ● メッセージ履歴呼び出し
#--------------------------------------------------------------------------
def history_start
# メッセージ履歴初期化設定
$game_temp.message_window_showing = true
@h_window.active = true
@h_window.visible = true
# メッセージ履歴の最終行より、どれだけ描画できるか計算を行う
@h = 0
for history in $game_player.message_history
@h += history[1]
end
# メッセージ履歴描画矩形の作成
@h_window.contents = Bitmap.new(@h_window.width - 32, @h)
@h_window.opacity = 0
@h_window.contents_opacity = 0
@h_window.contents.fill_rect(
@h_window.width - 38, 0, 6, @h, Color.new(0, 0, 0, 128))
@h_window.oy = [@h - (@h_window.height - 32), 0].max
# メッセージ履歴サイドバーの作成
@bar = Sprite.new(self.viewport)
height = [(@h_window.height - 32) ** 2 / @h, @h_window.height - 32].min
@bar.x = @h_window.x + @h_window.width - 22
@bar.y = @h_window.y + @h_window.height - 16 - height
@bar.z = 10003
@bar.opacity = 0
@bar.bitmap = Bitmap.new(6, height)
@bar.bitmap.fill_rect(0, 0, 6, height, Color.new(16, 32, 64, 224))
@bar.bitmap.fill_rect(0, 0, 5, height - 1, Color.new(32, 64, 128, 224))
@bar.bitmap.fill_rect(1, 1, 4, height - 2, Color.new(128, 224, 255, 255))
@bar.bitmap.fill_rect(1, 1, 3, height - 3, Color.new(192, 255, 255, 255))
@bar.bitmap.fill_rect(2, 2, 2, height - 4, Color.new(32, 64, 128, 192))
@bar.bitmap.fill_rect(3, 3, 1, height - 5, Color.new(48, 96, 192, 192))
@scroll_height = @h
# メッセージ履歴描画情報の初期設定
@index = $game_player.message_history.size - 1
# メッセージ履歴描画
history_refresh
end
#--------------------------------------------------------------------------
# ● メッセージ履歴フレーム更新
#--------------------------------------------------------------------------
def history_update
@h_window.update
# 十字キーの上が押下された場合
if Input.press?(Input::UP)
# ウィンドウ上方向にスクロール
@h_window.oy = [@h_window.oy - 8, 0].max
end
# 十字キーの下が押下された場合
if Input.press?(Input::DOWN)
# ウィンドウ下方向にスクロール
@h_window.oy = [[@h_window.oy + 8,
@h_window.contents.height - (@h_window.height - 32)].min, 0].max
end
# 十字キーの左が押下された場合
if Input.press?(Input::LEFT)
# ウィンドウ上方向に大きくスクロール
@h_window.oy = [@h_window.oy - 32, 0].max
end
# 十字キーの右が押下された場合
if Input.press?(Input::RIGHT)
# ウィンドウ下方向に大きくスクロール
@h_window.oy = [[@h_window.oy + 32,
@h_window.contents.height - (@h_window.height - 32)].min, 0].max
end
# L ボタンが押下された場合
if Input.press?(Input::L)
# ウィンドウ上方向に大きくスクロール
@h_window.oy = [@h_window.oy - 96, 0].max
end
# R ボタンの右が押下された場合
if Input.press?(Input::R)
# ウィンドウ下方向に大きくスクロール
@h_window.oy = [[@h_window.oy + 96,
@h_window.contents.height - (@h_window.height - 32)].min, 0].max
end
# スクロールバーの移動
@bar.y = 16 + @h_window.y +
((@h_window.height - 32) * @h_window.oy / @scroll_height.to_f).ceil
# メッセージ履歴の更新
history_refresh
if Input.trigger?(Input::B)
@h_window.active = false
end
end
#--------------------------------------------------------------------------
# ● カーソルの矩形更新
#--------------------------------------------------------------------------
def update_cursor_rect
if @index >= 0
n = @c_h + @py - ($game_temp.choice_max - 1) * 32
self.cursor_rect.set(8, n + @index * 32, @cursor_width, 32)
else
self.cursor_rect.empty
end
end
end
#==============================================================================
# ■ RPG
#------------------------------------------------------------------------------
# 基本モジュールです
#==============================================================================
module RPG
#============================================================================
# ■ Cache
#----------------------------------------------------------------------------
# 画像処理を行うモジュールです。
#============================================================================
module Cache
def self.face(filename)
self.load_bitmap("Graphics/Faces/", filename)
end
end
end
复制代码
要求只有一個: 把齒車之城版中能先後顯示臉圖的功能合併到櫻雅在土版中。
拜托各位。
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X5.0