兄弟实在不行可以试试这个
另外还要
A1的要放在上面,ネームウィンドウ on的是要放在事情的注释里 然后每一次对话的话加个NW名前指定 Name 如果想不麻烦点可以再名前指定下面的NAME_LLIST加上文件名和文件名所对应的名字,实在不知道查翻译去 |
百里_飞柳 发表于 2024-7-15 20:02 只是改了名字加框的位置,还有对话框文本的高度,还有色号 |
百里_飞柳 发表于 2024-7-15 20:02 #============================================================================= # ■ 对话框扩展 by 老鹰(https://github.com/OneEyedEagle/EAGLE-RGSS3) #============================================================================= $imported ||= {} $imported["EAGLE-MessageEX"] = "1.11.8" #============================================================================= # - 2024.6.23.11 修复暗色背景在淡出后,背景消失的bug #============================================================================= # 【兼容模式】 # - 本模式用于与其他对话框兼容,确保其他对话框正常使用,同时可以用本对话框及扩展 # # 若此常量被设为 true,则本对话框不再覆盖其他对话框: # 而在事件脚本中调用 $game_message.eagle_message = true 后, # 本对话框将被激活,变更为正在使用的对话框; # 调用 $game_message.eagle_message = false 则可切回之前的原有对话框。 # # 若此常量被设为 false,则本对话框将完全替代默认对话框。 # # - 由于对话框存在动态的开启关闭特效,若对话框切换后,旧对话框仍然显示在地图上, # 则请在切换对话框的事件脚本前后添加【等待10帧】,来保证旧对话框有时间顺利完成关闭。 # EAGLE_MSG_EX_COMPAT_MODE = false module MESSAGE_EX #============================================================================= # ● 什么是转义符? #============================================================================= # - 鼠标放置于编辑器对话框中停留一段时间,即可看到默认支持的转义符及其作用 # 如 \| 代表文本显示到该位置时,将等待 1s # 如 \c[5] 代表之后的文本将使用 5 号颜色进行绘制 # # - 转义符即为特别约定的、能够起到特殊功能的文本, # 在对话框中,我们约定转义符均以 \ 符号为开头,之后接其他符号、字母、数字, # 并且一般情况下转义符自身不会被绘制、显示 #============================================================================= # ● 什么是扩展转义符? #============================================================================= # - 本插件对默认的转义符进行了扩展, # 我们约定在对话框中编写 \code[param] 类型的文本,即可执行 code 对应的功能, # 而 param 为特殊格式的字符串,本插件中命名其为“变量参数字符串”, # 它将被作为调用 code 功能所需的自定义设置传入 # # - code “指令名”解析: # 下述列举出的各类转义符(英文、数字的组合) # # - param “变量参数字符串”解析: # · 由 变量名(字母组合)+ 参数值(整数或nil(用$符号代表传入的为nil))重复构成 # - 字符串中可以增加无意义的空格,用于在视觉上区分不同变量 # - 字符串中 变量名 和 参数值 之间可以添加 = 符号,增强阅读性 # · 当传入 无变量名 的 参数值 时,将存入其【默认】变量 # · 对于没有传入值的 变量 ,将读取上一次设置所存储的值 # · 带有【重置】的变量,将在每一次设置转义符时,重置为脚本中的预设值 # # - 示例: # 某个转义符的帮助: # \foo[param] → 执行某个功能 # 变量名称 a → 【默认】设置某个功能 # 变量名称 b → 设置某个功能 # 变量名称 c → 设置某个功能 # # 在对话中编写: # 对话文本\foo[1 b=-1 tc=0 d$],其他对话文本 # # 实际产生的效果: # → 调用 foo 的功能,同时给它的所有变量传入预设值 # 再给 a 变量传入值 1,b 变量传入值 -1,tc 变量传入值 0,d 变量传入值 nil # (转义符的帮助中并没有写 tc 和 d 两个变量, # 但是这样传入并不会出错,也不会产生任何其他影响) # # - 注意: # · 若没有明确说明,则转义符\code[param]不会被绘制、显示 # · “指令名”和“变量参数字符串”的大小写差异不会造成影响 # · 转义符会在对话文本逐字显示到它时生效 # 但若有【预先】,则会在绘制开始前生效(绘制中途不会再次生效) # 但若有【结尾】,则会在全部文字绘制完成后生效 #============================================================================= # ● 扩展转义符列表 #============================================================================= # 【索引】 # 此处放置转义符及其一句话简介,可通过搜索转义符进行快速定位 # # (文本替换类) # \conv 自定义的文本替换 # \rb 利用Ruby脚本获取替换文本 # \info 显示数据库指定对象的图标和名称 # \nl 换行符 # # (绘制类) # \pic 绘制图片 # # (控制类) # \font 文字绘制的基本设置,包括文字大小、加粗、阴影、边框、发光、底纹等 # \win 对话框的基本设置,包括对话框皮肤背景、位置、大小、文字显示等 # \move 对话框的动态移动 # \auto 自动对话的设置 # \pop 气泡对话框的基本设置,包括显示位置、大小、指示箭头等 # \face 脸图的动态设置,包括脸图当前显示索引、循环等 # \facep 脸图的预先设置,包括脸图位置、移入移出方式等 # \facem 脸图的实时动作,包括跳跃、移动等 # \name 姓名框的预先设置,包括姓名文本、姓名框位置、大小等 # \pause 等待按键时的帧动画设置,包括帧动画类型、显示位置等 # \shake 控制对话框的震动 # \wait 直接等待 # \ins 对话框立即完全显示 # \hold 保留当前对话框,直到下一个不包含该转义符的对话框关闭 # \close 当前对话框必定处理关闭 # \next 当前对话框不关闭,下一次的显示文本在该对话框内继续显示 # \clc 向上移出隐藏全部文字,在新一行里继续绘制之后的文字 # # (文字特效类) # \cin 文字移入 # \cout 文字移出 # \uout 文字消散移出 # \csin 文字正弦扭曲 # \cwave 文字上下浮动 # \cswing 文字左右摇摆 # \czoom 文字缩放 # \cshake 文字抖动 # \cshake2 文字抖动(高频率版本) # \cflash 文字闪烁 # \cmirror 文字镜像 # \cu 文字间歇消散 # \ctog 文字间歇切换 # \cneon 文字霓虹灯变色 # \cmc 文字叠加 # \cjump 文字跳跃 # \cfk 文字明灭闪烁 # # (变量环境) # \env 保存、读取应用指定的变量环境,方便进行不同对话框设置之间的切换 # \temp 对话框关闭时,将对话框重置为开启前的环境 # # (高级) # \func 设置一些进阶功能 # \eval 在对话中途,执行Ruby脚本 # \set 设置文字分组 # \setm 对指定文字分组进行处理 # # (扩展) # \cg 渐变色绘制 #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # ○ 文本替换类 # 此类别的转义符将在绘制开始前,进行一次对应文本的替换 # 将按照下面的排列顺序(从上往下)进行替换,因此请注意相互之间的嵌套层级 #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #---------------------------------------------------------------------------- # \conv[string] 或 \M[string] #---------------------------------------------------------------------------- # 【功能】 # 整个转义符将被替换成 CONVERT_ESCAPE 中所设置的 string 所对应的文本 # # 【参数】 # string → 在CONVERT_ESCAPE哈希表中的键值(若不存在,则返回空字符串) # # 【常量设置:文本替换】 # (由于解析问题,字符串中请将 "\" 替换成 "\\") # (如果目标转义符是用 <> 代替 [],如姓名框中的名称, # 则需将姓名框中名称中的 "\" 替换成 "\e") CONVERT_ESCAPE = { # String => String, "底部" => "\\win[ali0dw1dh1o2do-2dx0dy-60]\\pause[do0o4]\\temp", "顶部" => "\\win[ali0dw1dh1o8do-8dx0dy60]\\pause[do0o4]\\temp", } # (之后的常量也推荐用这种方式进行新增/覆盖) # (也可以在新脚本页中新增 module MESSAGE_EX 和 end ,并在其中添加常量设置) CONVERT_ESCAPE["系统"] = "\\win[ali1dw1dh1o5do-5dx0dy0]\\pause[do2o5]\\temp" # # 【示例】 # - 脚本常量 CONVERT_ESCAPE["测试用"] = "这是一句测试语句。" # - 对话编写 # 测试对话为 \conv[测试用]。 # 或 测试对话为 \M[测试用]。 # - 实际对话 # 测试对话为 这是一句测试语句。 # #---------------------------------------------------------------------------- # \rb{string} #---------------------------------------------------------------------------- # 【功能】 # 整个转义符将被替换成 eval(string) 的执行结果(强制转化为文本) # # 【参数】 # string → Ruby脚本语句,可以用 ; 分隔多句,不可含有花括号 # # 【注意】 # 该转义符使用花括号,同时 string 中不可以出现花括号 # 可用 s 代替 $game_switches ,用 v 代替 $game_variables # 可用 event 代表执行当前对话框的事件(Game_Event对象) # # 【示例】 # - 对话编写(1号变量值为1,2号变量值为2) # 这是一句测试用对话,都已经说了\rb{v[1]+v[2]}次了! # - 实际对话 # 这是一句测试用对话,都已经说了3次了! # #---------------------------------------------------------------------------- # \info[type+id,n] #---------------------------------------------------------------------------- # 【功能】 # 整个转义符将被替换成指定数据库对象的 图标+名称 的文本 # # 【参数】 # type → 数据库对象的类型(s代表技能,i代表物品,w代表武器,a代表防具) # id → 数据库对象的序号 # n → 绘制类型(可省略,0默认绘制图标+名称,1仅绘制图标,2仅绘制名称) # # 【注意】 # 加号只是表示由两个必须的参数构成,实际编写时不要写 + 符号! # # 【示例】 # - 对话编写 # 1号物品是\info[i1],2号武器的名称是\info[w2,2] # - 实际对话 # 1号物品是【图标】恢复剂,2号武器的名称是战斧 # #---------------------------------------------------------------------------- # \nl #---------------------------------------------------------------------------- # 【功能】 # 将被替换成换行转义符 \n(效果等同编辑器中的手动回车) # # 【注意】 # 由于编辑器自身限制,部分文本框无法识别输入的\n,因此添加了该转义符, # 实际上并没有什么用处 # #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # ○ 绘制类 # 此类别的转义符将被视为绘制内容,与通常文字一样占用绘制空间 #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #---------------------------------------------------------------------------- # \pic[filename|param] #---------------------------------------------------------------------------- # 【功能】 # 在当前位置绘制指定名称的图片 # # 【参数】 # filename → 图片的名称,可省略后缀名 # (图片存放于 Grphics/Pictures 目录下) # param → 变量参数字符串,可省略不写 # (变量一览) # w → 指定绘制图片的宽度(默认与原图一致,若不同则利用stretch_blt进行缩放) # h → 指定绘制图片的高度 # opa → 【默认】指定绘制图片的不透明度(默认255) # # 【示例】 # - 对话编写 # 这是测试对话\pic[猫猫快乐] # - 实际对话 # (在转义符所在位置绘制目录下文件名为 猫猫快乐 的图片,显示宽高不变) # 【示例】 # - 对话编写 # 这是测试对话\pic[猫猫疑惑|w=50 h=50] # - 实际对话 # (在转义符所在位置绘制目录下文件名为 猫猫疑惑 的图片,且宽度高度固定为50) # #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # ○ 控制类 # 此类别的转义符将对各类功能进行设置、调用 # 对于带有“是否”描述的变量,数字0代表 false,正数(推荐数字1)代表 true # 对于未说明 nil 效果的变量,请尽量不要传入 nil(传入符号$代表传入nil) #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #---------------------------------------------------------------------------- # \c[id] #---------------------------------------------------------------------------- # 【功能】 # 变更之后的文字绘制颜色(扩展了默认的\c[id]转义符) # # 【参数】 # id → 可传入 TEXT_COLORS 常量中所设置的字符串,将匹配其对应的颜色 # 如 \c[pink] 将使用 "pink" 所对应的 Color 作为文字颜色 # 若匹配失败,将执行 id.to_i 转为数字,使用默认的索引颜色 # (若传入 -1,则重置为 DEFAULT_COLOR_INDEX ,同时不透明度重置为 255) # # 【常量设置:每次开启对话框时,文字颜色重置为该索引颜色】 DEFAULT_COLOR_INDEX = 0 # # 【常量设置:标识符映射到Color】 TEXT_COLORS = { "pink" => Color.new(255, 187, 217), } # # 【示例】 # - 脚本常量 TEXT_COLORS["gold"] = Color.new(255,215,0) # - 对话编写 # 这是\c[gold]测试\c[0]对话。 # - 实际对话 # (“测试”文字将变成设置的gold对应颜色) # #---------------------------------------------------------------------------- # \font[param] #---------------------------------------------------------------------------- # 【功能】 # 设置文字的绘制参数 # # 【参数】 # param → 变量参数字符串 # (变量一览) # name → 字体名称的索引(在INDEX_TO_FONT中设置)(若为nil,则与默认一致) # size → 【默认】字体大小 # c → 文字颜色的索引号(与 \c 一致) # (若传入 -1,则重置为 DEFAULT_COLOR_INDEX ,同时不透明度重置为 255) # ca → 文字的不透明度(0~255) # i → 是否斜体(font.italic) # b → 是否加粗(font.bold) # s → 是否添加阴影(font.shadow) # o → 是否添加边框(font.outline) # or/og/ob/oa → 设置边框颜色RGBA(0~255) # p → 底部花纹的类型(0不绘制,1边框,2实心方框) # pc → 底部花纹的颜色索引号(具体查看 Windowskin 右下角,同默认\c[id]颜色) # l → 是否绘制外发光(若开启,则强制关闭阴影和边框) # lc → 外发光的颜色索引号 # lp → 外发光的强度 # d → 是否绘制删除线 # dc → 删除线的颜色索引号 # u → 是否绘制下划线 # uc → 下划线的颜色索引号 # k → 是否生成文字破碎效果(参考:http://www.whiteflute.org/wfrgss/) # kv → 单个像素的破碎概率(百分数,数字越大,文字破碎效果越明显) # # 【常量设置:参数预设值】 FONT_PARAMS_INIT = { # \font[] :name => nil, :size => nil, # 字体大小 :ca => 255, # 不透明度 :i => nil, # 斜体绘制 :b => nil, # 加粗绘制 :s => nil, # 阴影 :o => nil, # 描边 :or => nil, :og => nil, :ob => nil, :oa => nil, :p => 0, # 底纹 :pc => 0, # 底纹颜色index :l => 0, # 外发光 :lc => 0, # 外发光颜色index :lp => 2, # 外发光强度 :d => 0, # 删除线 :dc => 0, # 删除线颜色index :u => 0, # 下划线 :uc => 0, # 下划线颜色index :k => 0, # 文字破碎 :kv => 50, # 像素破碎概率 } # # 【常量设置:序号映射到字体名称】 INDEX_TO_FONT = { # 数字 => 字体名称字符串 1 => "黑体", } # # 【示例】 # - 对话编写 # 这是\font[d=1]测试\font[d=0]对话。 # - 实际对话 # (“测试”文字将绘制删除线) # #---------------------------------------------------------------------------- # \win[param] #---------------------------------------------------------------------------- # 【功能】 # 对话框窗口的各类设置 # # 【参数】 # param → 变量参数字符串 # (变量一览) # (窗口属性相关) # z → 对话框的z值(仅正整数有效)(默认取va里的200) # skin → 对话框所用windowskin的index(按常量设置进行 index → skin名称 映射) # bg → 对话框背景图片的index(按常量设置进行 index → 图片名称 映射) # (只有当 事件指令-显示文字-窗口背景 为 普通窗口 时,才生效) # (若图片读取成功,将不再显示窗口皮肤;若读取失败,仍绘制窗口皮肤) # bgo → 对话框背景图片与对话框的对齐原点(对应九宫格小键盘) # (默认背景图片的左上角与对话框左上角对齐,值为7) # # (窗口位置相关) # o → 【默认】对话框的显示原点的类型(对应九宫格小键盘)(默认左上角7) # x/y → 对话框显示原点在屏幕上的坐标(默认nil,取va设置,对话框位于底部) # do → 将屏幕进行九宫格划分,对话框显示原点在屏幕上的位置类型(覆盖x/y) # (参考九宫格小键盘,有效值为-1~-9,-1在屏幕左下角,-5在屏幕中心点) # dx/dy → x、y坐标的增加量(默认0) # fix → 是否修正对话框位置(保证对话框完整显示在屏幕内) # # (窗口大小相关) # w → 窗口内容的宽度(不含边框)(默认0不设置)(优先级高于dw和fw) # dw → 窗口内容宽度是否随文字绘制而动态变化(默认0,不动态变化) # fw → 窗口内容宽度是否设置为全部文字绘制完成时的宽度(优先级高于dw) # wmin/wmax → 窗口内容宽度的最小最大值(启用dw/fw时生效)(默认0不设置) # h → 窗口内容的高度(不含边框)(默认0不设置)(优先级高于dh和fh) # (若小于对话框的 line_height 方法值,则识别为行数,乘以行高,作为高度值) # dh → 窗口内容高度是否随文字绘制而动态变化(默认0,不动态变化) # fh → 窗口内容高度是否指定为全部文字绘制完成时的高度(优先级高于dh) # hmin/hmax → 窗口内容高度的最小最大值(启用dh/fh时生效)(若小于行高,则为行数) # # (文本显示相关) # se → 启用的打字音类型index(默认0,按常量设置进行 index → 声效SE设置 映射) # ali → 文本的对齐方式(0左对齐,1居中对齐,2右对齐;默认0) # ck → 增加的字符间距值(默认0) # lh → 设置基础行高 line_height 值(若为nil则取当前字号) # ld → 增加的行间距值(默认0)(每一行的行高将取该行的最大高度) # cwi → 单个文字绘制完成后的等待帧数(最小值0) # cwo → 单个文字移出开始后的等待帧数(最小值0) # cor → 全部文字移出的顺序类型(0正序,1逆序,2乱序,默认0) # cfast → 是否允许按键快进(默认1,可以按键快进) # cdx/cdy/cdw/cdh → 文本绘制区域与窗口padding左侧/上侧/右侧/下侧的间距(默认0) # # 【常量设置:参数预设值】 WIN_PARAMS_INIT = { # \win[] # (窗口属性相关) :z => 200, :skin => 0, # 对话框所用windowskin的类型 :bg => nil, # 对话框背景所用图片(覆盖窗口皮肤) :bgo => 7, # 对话框背景图片与对话框的对齐原点 # (窗口位置相关) :o => 7, # 原点位置类型 默认为7左上角 :x => nil, # 原点坐标xy :y => nil, :do => 0, # 相较于屏幕的九宫格位置(覆盖x/y的设置) :dx => 0, # 坐标偏移值xy :dy => 0, :fix => 0, # 是否进行位置修正,防止对话框跑出屏幕 # (窗口大小相关) :w => 0, :h => 4, :dw => 0, # 若为1,则代表宽度会依据文字动态调整 :fw => 0, # 若为1,则窗口打开时即为文字绘制完成时所需宽度值 :wmin => 0, # 设置宽度的上下限(当dw==1时生效) :wmax => 0, # (有脸图时宽度会自动增加脸图宽度) :dh => 0, # 若为1,则代表高度会依据文字动态调整 :fh => 0, # 若为1,则窗口打开时即为文字绘制完成时所需高度值 :hmin => 0, # 设置高度的上下限(当dh==1时生效) :hmax => 0, # (文本显示相关) :se => 0, # 打字音类型序号(默认0,无声效) :ali => 0, # 设置文本对齐方式 :ck => 0, # 增加的字符间距值 :lh => nil, # 基础行高(若为nil,则取当前文字大小) :ld => 4, # 增加的行间距值 :cwi => 2, # 单个文字绘制后的等待帧数(最小值0) :cwo => 0, # 单个文字开始移出后的等待帧数(最小值0) :cor => 0, # 全部文字移出的顺序类型 :cfast => 1, # 是否允许快进 :cdx => 0, # 文本左侧与窗口padding的间距 :cdy => 0, # 文本上边距 :cdw => 0, # 文本右边距 :cdh => 0, # 文本下边距 } # # 【常量设置:序号映射到windowskin文件名】 # (其中 index 必须为整数) # (窗口皮肤图片存储于 Graphics/System 目录下) INDEX_TO_WINDOWSKIN = { # 数字 => 皮肤文件名(可省略后缀) 0 => "Window", # 默认所用皮肤名称 } # # 【常量设置:序号映射到窗口背景图片文件名】 # (图片的左上角会与对话框的左上角对齐) # (其中 index 必须为整数) # (图片存储于 Graphics/System 目录下) INDEX_TO_WINDOW_BG = { # 数字 => "背景图片名称" } # # 【常量设置:序号映射到打字音效】 # (音效文件存储于 Audio/SE 目录下) INDEX_TO_SE = { # 数字 => SE文件名, 音量, 音调 0 => ["", 80, 100], # 默认设置,不推荐修改 1 => ["Cursor1", 40, 150], } # # 【示例】 # - 对话编写 # \win[o5 do-5 dw1dh1]这是测试对话。 # - 实际对话 # (对话框显示在屏幕中心,且随着文字显示而动态扩展) # 【示例】 # - 对话编写 # \win[o=2 do=-2 dy=-20 fw1fh1]这是测试对话,看看到底怎么样。 # - 实际对话 # (对话框显示在屏幕底部,且依据文字动态变更宽高) # #---------------------------------------------------------------------------- # \move[param] #---------------------------------------------------------------------------- # 【功能】 # 动态移动对话框位置,并等待移动结束 # # 【注意】 # 若设置了 win 转义符的 do 参数,则该移动无效 # 若设置了 pop 转义符,则该移动无效 # # 【参数】 # param → 变量参数字符串 # (变量一览) # t → 移动所需的总共帧数(默认20帧) # x → 直接指定移动的目的地x(若为0,则重置为win转义符中的x,或RGSS中初始位置0) # y → 直接指定移动的目的地y(若为0,则重置为win转义符中的y,或RGSS中初始位置底部) # dx → 在当前位置基础上,水平移动的距离(正数为向右,负数为向左) # dy → 在当前位置基础上,竖直移动的距离(正数为向下,负数为向上) # # 【示例】 # - 对话编写 # 这是测试对话,\move[dx=40 dy=30]看看到底怎么样。 # - 实际对话 # (在显示完“这是测试对话,”后,对话框将向下移动40,向下移动30的距离, # 然后继续显示剩余的文字) # #---------------------------------------------------------------------------- # \auto[t] #---------------------------------------------------------------------------- # 【功能】 # 等待按键时,设置文本自动继续 # # 【参数】 # t → 在t帧后自动结束按键等待,并继续事件处理(默认nil,不自动继续) # # 【常量设置:参数预设值】 # 当未调用 \auto[t] 进行设置,或其值为 nil 时,读取此处的值 WIN_AUTO_T = nil # # 【常量设置:提示文本】 # 自动播放的UI中显示的文本 WIN_AUTO_TEXT = "自动播放" # # 【常量设置:UI的宽高】 WIN_AUTO_W = 100 WIN_AUTO_H = 40 # # 【常量设置:UI的原点】 # 九宫格小键盘,如 5 代表中点为原点,9 代表右上角为原点 WIN_AUTO_O = 9 # # 【常量设置:UI的位置】 # 九宫格小键盘,如 3 代表绑定到对话框的右下角,5 代表绑定到对话框的中心 # -2 代表绑定到屏幕的底部中点,-9 代表绑定到屏幕的右上角 WIN_AUTO_DO = -9 # # 【常量设置:UI的坐标偏移值】 WIN_AUTO_DX = 0 WIN_AUTO_DY = 0 # # 【示例】 # - 对话编写 # 这是测试对话,看看到底怎么样。\auto[60] # - 实际对话 # (在显示完成后,等待1s后自动关闭当前对话框,继续之后的事件指令) # #---------------------------------------------------------------------------- # \pop[param] 【预先】 #---------------------------------------------------------------------------- # 【功能】 # 气泡类型对话框的各类设置 # # 【参数】 # param → 变量参数字符串 # (变量一览) # (窗口属性相关) # skin → pop状态下对话框所用皮肤的index(按常量设置进行 index → skin名称 映射) # (默认nil,取win转义符中的skin变量的值) # # (窗口位置相关) # id → 【重置】【默认】所绑定对象的id # 【地图】设置 0 取执行当前对话框的事件的id # 正数id 取当前地图id号的事件,目标事件不存在则取当前事件 # 负数id 取队列中数据库id号的角色,目标角色不在队伍中则取队首角色 # 【战斗】设置 正数id 取敌群中index序号为id的敌人,目标敌人不存在则pop无效 # 负数id 取我方参战角色中数据库id号的角色,目标角色不存在则pop无效 # mx/my → 【重置】绑定到地图的 (mx, my) 处(同编辑器坐标)(格子中心为显示原点) # (当未设置id时,该变量设置才生效) # do → 对话框相对于绑定对象的位置类型(默认8,即对话框原点位于目标的顶部中间) # (参考九宫格小键盘,1代表目标左下角,5代表目标中心,9代表目标右上角) # o → 对话框原点的类型 # (若为nil,则为 10-do,即当do为8时,对话框原点为底部中点2) # d → 对话框原点远离绑定对象中心点的像素值(默认0) # (用于设置对话框与绑定对象的距离,将按do自动决定xy如何增减) # dx/dy → x、y方向上的像素增量(默认0) # fix → 是否进行位置修正(保证pop对话框完整显示在屏幕内) # # (窗口大小相关)(与win中相同,均覆盖win中的对应设置) # w → pop对话框的内容固定宽度(默认0不设置)(优先级高于dw/fw) # h → pop对话框的内容固定高度 # (若小于对话框的 line_height 方法值,则识别为行数,乘以行高,作为高度值) # dw → 是否随文字绘制而动态变更pop对话框的内容宽度 # fw → 是否指定为全部文字绘制完成时的所需宽度(覆盖dw) # dh → 是否随文字绘制而动态变更pop对话框的内容高度 # fh → 是否指定为全部文字绘制完成时的所需高度(覆盖dh) # # (Tag精灵相关) # tag → 所用的tag箭头图片的index(按常量设置进行 index → tag名称 映射) # td → 设置tag与所绑定对象的中心的远离偏移值(按pop的do自动设置xy)(默认0) # # 【常量设置:参数预设值】 POP_PARAMS_INIT = { # \pop[] :skin => nil, # pop模式下所用skin类型 :do => 8, # 对话框相对于绑定对象的位置(九宫格小键盘) :o => nil, # 对话框显示原点,若为nil,则取 10 - :do :d => 0, # 指定原点远离事件格子中心的偏移量 :dx => 0, # 指定x、y方向上的偏移量 :dy => 0, :fix => 0, # 是否进行位置修正 :w => 0, # 指定固定的宽度和高度(优先级高于win_params) :h => 0, :dw => 0, # 若为1,则代表宽度会依据文字动态调整 :fw => 1, # 若为1,则窗口打开时将预绘制成文字区域最终大小 :dh => 0, # 若为1,则代表高度会依据文字动态调整 :fh => 1, # 若为1,则窗口打开时将预绘制成文字区域最终大小 :tag => 1, # tag所用文件名index(0时表示不启用) :td => 3, # tag与绑定事件格子中心位置的远离值 } # # 【常量设置:序号映射到Tag】 # (其中 index 为正整数;为 0 时代表不启用tag) # (图片存储于 Graphics/System 目录下) # 【Tag图片解析】任意大小,3帧×3帧规格 # 7 8 9 # 4 5 6 ← pop对话框的原点位置类型 与 对应所用的tag位图区域 # 1 2 3 # (比如 pop对话框的原点类型为 2 时,tag显示在对话框底部中央,图像使用2号区域) # 【注意】tag的存在不会使pop对话框产生额外偏移,请利用pop参数d/dx/dy自行移动 INDEX_TO_WINDOWTAG = { 1 => "Window_Tag", # 默认所用tag名称 } # # 【常量设置:窗口皮肤绑定Tag】 # (当使用的窗口皮肤在此处有设置时,将必定使用此处对应设置的Tag) WINDOWSKIN_TO_WINDOWTAG = { -1 => 1, } # # 【示例】 # - 对话编写 # \pop[-1]这是测试对话。 # - 实际对话 # (在玩家头顶显示气泡对话框) # #---------------------------------------------------------------------------- # \face[param] #---------------------------------------------------------------------------- # 【功能】 # 脸图的动态设置 # # 【注意】 # 本对话框对显示脸图进行了规格扩展: # 当脸图文件名包含 _数字1x数字2 时(其中为字母x), # 将定义该脸图文件的规格为 行数(数字1)x列数(数字2)(默认2行x4列) # 如:ace_actor.png → 该脸图规格为 2行4列,含有8张脸图,与默认一致 # 如:ace_actor_1x1.png → 该脸图规格为 1行1列,含有1张脸图,只有index为0时生效 # 如:ace_actor_1x4.png → 该脸图规格为 1行4列,含有4张脸图 # # 【参数】 # param → 变量参数字符串 # (变量一览) # i → 【重置】【默认】脸图文件不改变,切换所显示脸图的序号index # ls/le → 【重置】定义脸图自动循环播放的开始index/结束index(-1时不启用自动播放) # lt → 自动循环播放时,每两帧之间的等待间隔帧数 # lw → 自动循环播放时,每一次loop结束时的等待帧数(nil代表不再循环) # # # 【高级】 # - 本对话框的宽高可以动态变化,脸图不影响对话框高度, # 也因此本对话框允许脸图超出范围,这样方便显示更大规格的脸图(立绘)。 # 但一般大家都使用默认 96x96 规格的脸图,且默认的脸图恰好显示在默认对话框内, # 此时如果不把脸图包裹住的话比较难看,因此增加该项设置: # 开启时,当使用默认规格脸图,将强制对话框内容高度大于等于脸图高度 FORCE_WIN_H_BIGGER_THAN_DEFAULT_FACE = true # # 【常量设置:参数预设值】 FACE_PARAMS_INIT = { # \face[] :lt => 30, # 循环时,每两帧之间的间隔 :lw => 60, # 循环后,等待帧数 # \facep[] :dir => 0, # 脸图显示方向 1为右侧 :m => 0, # 脸图镜像显示 :it => 15, # 脸图移入所需帧数 :ot => 10, # 脸图移出所需帧数 :dx => 0, # 脸图x方向的偏移增量 :dy => 0, # 脸图y方向的偏移增量 :dw => 8, # 脸图显示宽度的补足量 :z => 1, # 脸图z值增量 } # # 【示例】 # - 对话编写 # 这是测试对话。\facep[dir1]\face[2]\facem[jump] # - 实际对话 # (脸图显示到右侧,在对话最后切换成第1行第3列的脸图,且跳跃一次) # #---------------------------------------------------------------------------- # \facep[param] 【预先】 #---------------------------------------------------------------------------- # 【功能】 # 脸图的预先设置 # # 【参数】 # param → 变量参数字符串 # (变量一览) # dir → 【默认】脸图的显示位置(0左侧,1右侧;默认0) # m → 是否镜像显示脸图(默认0,不开启镜像) # it → 脸图淡入时所用帧数 # ot → 脸图淡出时所用帧数 # dx → 脸图在x方向上的偏移增量(默认0) # dy → 脸图在y方向上的偏移增量(默认0) # dw → 当嵌入对话框内时,脸图宽度的补足增量(默认0) # z → 脸图的z值增量(默认1,在对话框上面) # (当传入 -1 时将显示在对话框下面,此时脸图不占用对话框宽度) # #---------------------------------------------------------------------------- # \facem[str|param] #---------------------------------------------------------------------------- # 【功能】 # 脸图的实时动作设置 # # 【参数】 # str → 脸图动作的字符串 # param → 脸图动作的变量参数字符串,可省略 # # (脸图动作一览) # in → 脸图移入(无参数) # out → 脸图移出(无参数) # jump → 脸图进行一次短暂跳跃(无参数) # 使用示例: \facem[jump] 脸图小幅度跳跃一次 # move → 脸图移动到指定位置 # (变量一览) # x/y → 直接指定移动的目的地(以脸图移入后的位置为原点) # dx/dy → 指定在当前位置基础上的移动增量 # t → 移动所需的时间(三次立方平滑) # 使用示例: \facem[move|dx=50] 脸图朝右侧移动50像素 # # 【注意】 # - 脸图动作期间,对话框不会暂停绘制,请自行调用 wait 转义符进行等待。 # - 若在执行动作时,又呼叫了新的动作, # 则在当前动作执行完成后,只会继续执行最后传入的一个动作。 # #---------------------------------------------------------------------------- # \name[param] 【预先】 #---------------------------------------------------------------------------- # 【功能】 # 姓名框的设置 # # 【注意】 # - param 中用 | 分隔 姓名字符串(其中转义符用<>代替[])与 变量参数字符串 # (若无变量参数的设置,可省略 | 符号) # - 若存在多个 \name ,只会取最后一个成功设置的姓名,但变量参数会依次生效覆盖 # # 【姓名字符串】 # - 特别的,如果只写了数字,且在数据库中有该ID号角色,则将替换为该角色的名称 # 如: \name[1] → 将在姓名框中显示 艾里克 # 如: \name[999] → 因为数据库中没有该ID号角色,姓名框中依然显示 999 # # 【参数】 # param → 变量参数字符串 # (变量一览) # o → 姓名框的显示原点(对应九宫格小键盘)(默认7,姓名框左上角为显示原点) # do → 基于对话框的九宫格位置,姓名框的显示原点的实际位置 # (默认7,位于对话框左上角7)(0时为嵌入对话框中,且o自动设为7) # dx/dy → 姓名框x、y坐标的额外偏移量 # opa → 姓名框背景的不透明度(默认255)(文字的不透明度锁定为255) # skin → 姓名框所用皮肤的index(默认nil,同win中设置) # size → 姓名框文字大小(默认nil,取Font默认值) # bg → 姓名框背景图片的index(按常量设置进行 index → 图片名称 映射) # (若读取成功,将不显示窗口皮肤;若读取失败,仍绘制窗口皮肤) # bgo → 姓名框背景图片与姓名框的对齐原点(对应九宫格小键盘) # (默认7,背景图片的左上角与姓名框左上角对齐) # cx/cy → 姓名框的文字起始绘制位置(默认为0,0) # # 【高级】 # - 由于姓名框可能遮挡脸图,因此本对话框新增了自动调整,确保姓名框不遮挡脸图 # 可利用 $game_message.no_name_overlap_face = true/false # 来设置是否开启该功能(默认 true 代表开启) DEFAULT_NO_OVERLAP_FACE = true # # 【常量设置:参数预设值】 NAME_PARAMS_INIT = { # \name[] :o => 1, # 自身的显示原点位置 :do => 7, # 相较于对话框的显示原点位置 :dx => 0, # 姓名框整体的偏移增量(如果为嵌入,则会自动增加占位的宽高) :dy => 0, :opa => 255, # 背景不透明度 :skin => nil, # 姓名框所用windowskin的类型(nil为与对话框一致) :size => nil, # 姓名框文字大小 :bg => nil, # 姓名框背景所用图片index(覆盖窗口皮肤) :bgo => 1, # 姓名框背景图片与姓名框的对齐原点 :cx => 0, # 姓名框内部,绘制姓名时的初始位置 :cy => 0, } # # 【常量设置:全部姓名前统一增加的字符串】 # (支持draw_text_ex中的转义符)(\c[]转义符支持 TEXT_COLORS 扩展) # (由于解析问题,字符串中请将 "\" 替换成 "\e" ,并用 <> 代替 []) ESCAPE_STRING_NAME_PREFIX = "\ec<6>" # # 【常量设置:序号映射到姓名框背景图片文件名】 # (如果 bgo 为 7,则图片左上角会与姓名框左上角对齐) # (其中 序号 必须为整数) # (图片存储于 Graphics/System 目录下) INDEX_TO_NAME_BG = { # 姓名框背景 # 序号数字 => " 背景图片名称" } # # 【示例】 # - 对话编写 # \name[主角]这是测试对话。\name[|o1do9] # - 实际对话 # (显示姓名框,其中名称为“主角”,且姓名框左下角位于对话框右上角) # #---------------------------------------------------------------------------- # \pause[param] #---------------------------------------------------------------------------- # 【功能】 # 等待按键时的帧动画的设置 # # 【参数】 # param → 变量参数字符串 # (变量一览) # id → 【默认】所用的等待按键帧动画在INDEX_TO_PAUSE中的序号 # o → 帧动画的显示原点位置类型(九宫格小键盘)(默认左上角7) # do → 基于对话框的九宫格位置,自身显示位置的类型(0时显示在文末)(默认2) # dx/dy → xy方向上的补足偏移值(默认0) # t → 每两帧之间的等待帧数(默认10) # v → 是否显示等待按键的帧动画(默认1,显示等待按键动画) # # 【常量设置:参数预设值】 PAUSE_PARAMS_INIT = { # \pause[] :id => 0, :o => 4, # 自身的显示原点类型 :do => 0, # 相对于对话框的显示位置(九宫格小键盘)(0时为在文末) :dx => 0, # xy偏移值 :dy => 0, :t => 7, # 每两帧之间的等待帧数 :v => 1, # 是否显示 } # # 【常量设置:序号映射到等待按键的帧动画】 # (其中 index 必须为整数) # (图片存储于 Graphics/System 目录下) # (帧动画统一从左上开始设为0号位置,并按行优先从左往右遍历) INDEX_TO_PAUSE = { # 文件名 范围(nil则为整张图) 一行中的帧数 一列中的帧数 #index=>[String, Rect, Integer, Integer] -1 => ["", nil, 1, 1], # 不显示 0 => ["Window", Rect.new(96,64,32,32), 2, 2], # 默认 使用皮肤窗口里的箭头 } # # 【常量设置:是否屏蔽默认的输入等待动画】 # (指默认位于对话框底部中央的4帧动画,推荐屏蔽,只用pause的帧动画) NO_DEFAULT_PAUSE = true # # 【示例】 # - 对话编写 # 这是测试对话。\pause[0o5do3dx-12dy-12] # - 实际对话 # (等待按键的精灵位于对话框右下角) # #---------------------------------------------------------------------------- # \shake[param] #---------------------------------------------------------------------------- # 【功能】 # 进行对话框震动(与事件指令中的屏幕震动一致)并等待至结束 # # 【参数】 # param → 变量参数字符串 # (变量一览) # p → 震动的强度(默认5) # s → 震动的速度(默认5) # t → 【默认】震动的持续帧数(将补足平滑结束的帧数)(默认40) # y → 是否由 x 方向的震动修改为 y 方向的震动(默认0,即false,依然为x方向) # # 【示例】 # - 对话编写 # 这是测试对话,\shake[p7]吓死我了,还以为地震了。 # - 实际对话 # (在显示完逗号后,开始对话框震动,并等待结束) # #---------------------------------------------------------------------------- # \wait[t] #---------------------------------------------------------------------------- # 【功能】 # 直接等待指定帧数 # # 【参数】 # t → 等待的帧数 # # 【注意】 # - 和默认的等待转义符保持一致,不会被快进、期间不处理按键 # #---------------------------------------------------------------------------- # \ins 【预先】 #---------------------------------------------------------------------------- # 【功能】 # 当前对话框不再处理绘制间隔的等待(先完成打开,再一次性绘制全部内容) # #---------------------------------------------------------------------------- # \hold 或 \hold[str] 【结尾】 #---------------------------------------------------------------------------- # 【功能】 # 保留当前对话框,直至没有该指令的对话框关闭,关闭所有保留的对话框 # # 【参数】 # str →【可选】任意字符串,代表该保留对话框的唯一ID # 如果设置,则对话框打开时,会关闭已保留对话框中全部是该ID的对话框 # 如果不设置,则会始终保留,直到没有\hold指令的对话框关闭 # # 【示例】 # 显示文本:这是测试对话。\hold[1] # 显示文本:这是第二句测试对话。\hold[2] # 显示文本:这是第三句测试对话。\hold[1] # # → 第一句对话保留,第二句对话和第一句对话会一起保留, # 第三句对话前首先关闭第一句对话,再和第二句对话一起保留 # #---------------------------------------------------------------------------- # \close 【结尾】 #---------------------------------------------------------------------------- # 【功能】 # 当前对话框不再受 settings_changed? 影响,必定进行关闭处理 # #---------------------------------------------------------------------------- # \next 【结尾】 #---------------------------------------------------------------------------- # 【功能】 # 当前对话框在按键继续后不关闭,而是保留显示, # 在处理下一条事件指令-显示文本时,文本将继续显示在对话框的新行。 # (中途可以调用其它事件指令,对话框将一直保持开启状态。) # #---------------------------------------------------------------------------- # \clc #---------------------------------------------------------------------------- # 【功能】 # 将当前全部已经绘制的文字上移,直至移出对话框的显示范围, # 然后在新的一行中继续绘制剩余文字。 # (在输入等待时,依然可以通过方向键进行滚动,以浏览之前移出显示范围的文字) # (最好先固定对话框的显示高度,再使用本功能,否则下侧可能出现较多的空白区域, # 因为在动态高度情况下,对话框高度由全部文字的高度和决定,与这些移动无关) # # 【常量设置:文字移出的所用帧数】 CLC_CHARAS_OUT_FRAME = 20 #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # ○ 文字特效类 # 以下 param 传入 任意非0非空字符(如 1)代表以预设值开启特效 # 只传入 0 代表关闭该特效 # 除非标注【叠加】,否则多特效同时执行可能会造成奇怪效果 #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # 【常量设置:初始激活的文字特效转义符及其变量参数】 CHARA_PARAMS_INIT = { # 文字特效类转义符sym => 变量参数字符串"code_string" #:cin => "1", } #---------------------------------------------------------------------------- # \cin[param] 【独占】(移入完成后才进行其余特效的更新) #---------------------------------------------------------------------------- # 【功能】 # 开启文字移入的特效 # # 【注意】 # 移入使用缓动函数,具体可以见 MESSAGE_EX.ease_value 方法 # # 【参数】 # param → 变量参数字符串 # (变量一览) # r → 是否将以下全部变量的值变更为正负范围内的随机数? # 比如传入的 vx5,则实际的 vx 为 -5 ~ 5 中随机一个值 # t → 移入所用帧数(即移动到最终位置所用帧数)(不透明度从0平滑增加到255) # vzt/vz → 每zvt(最小值1)帧zoom放缩值增加vz的值(整数) # va → 每帧内angle的增值 # dx/dy → 移入前所在位置的偏移量 # (以下参数不受 r 的影响) # do → 移入前所在位置 # (大于0时为对话框的九宫格位置,小于0时为屏幕九宫格位置,0时最终显示位置) # 如:do5dx0dy0 就是文字从对话框中心位置移入到最终显示位置 # vo → 每帧不透明度的增量(默认0,将设置为 255/t) # rxt/rx → 每rxt(最小值1)帧src_rect的x增加rx像素的值(默认0) # ryt/ry → 每ryt(最小值1)帧src_rect的y增加ry像素的值(默认0) # # 【常量设置:参数预设值】 CIN_PARAMS_INIT = { # \cin[] :r => 0, # 随机取值? :t => 15, # 移入所用帧数 :do => 0, # 移入前所在位置 :dx => 0, # 移入前所在位置的偏移量 :dy => 0, :vz => 0, # 每vzt帧zoom的增量 :vzt => 1, :va => 0, # 每帧角度增量 :vo => 0, # 每帧不透明度增量 :rxt => 1, :rx => 0, # 每rxt帧src_rect.x的增量 :ryt => 1, :ry => 0, # 每ryt帧src_rect.y的增值 } # # 【示例】 # - 对话编写 # \cin[dy20]这是测试对话,看看移入效果如何。 # - 实际对话 # (文字移入效果修改为由下方20像素处往目的地移入) # #---------------------------------------------------------------------------- # \cout[param] 【独占】(移出时关闭其余特效更新) #---------------------------------------------------------------------------- # 【功能】 # 开启文字移出的特效 # # 【注意】 # 移出使用缓动函数,具体可以见 MESSAGE_EX.ease_value 方法 # # 【参数】 # param → 变量参数字符串 # (变量一览) # r → 是否将以下全部变量的值变更为正负范围内的随机数? # 比如传入的 vx5,则实际的 vx 为 -5 ~ 5 中随机一个值 # t → 移出所用帧数(即移动到最终位置所用帧数)(不透明度从255平滑减小到0) # vzt/vz → 每zvt(最小值1)帧zoom放缩值增加vz的值(整数) # va → 每帧内angle的增值 # dx/dy → 移出后所在位置的偏移量 # (以下参数不受 r 的影响) # do → 移出后所在位置 # (大于0时为对话框的九宫格位置,小于0时为屏幕九宫格位置,0时当前位置) # 如:do5dx0dy0 就是文字移出到对话框中心位置 # vo → 每帧不透明度的减量(默认为 255/t) # rxt/rx → 每rxt(最小值1)帧src_rect的x增加rx像素的值(默认0) # ryt/ry → 每ryt(最小值1)帧src_rect的y增加ry像素的值(默认0) # # 【常量设置:参数预设值】 COUT_PARAMS_INIT = { # \cout[] :r => 0, # 随机取值? :t => 15, # 移出所用帧数 :do => 0, # 移出后所在位置 :dx => 0, # 移出后所在位置的偏移量 :dy => 0, :vz => 0, # 每vzt帧zoom的增量 :vzt => 1, :va => 0, # 每帧角度增量 :vo => 0, # 每帧不透明度减量 :rxt => 1, # 每rxt帧src_rect.x的增量 :rx => 0, :ryt => 1, # 每ryt帧src_rect.y的增值 :ry => 0, } # # 【示例】 # - 对话编写 # \cout[do5]这是测试对话,看看移出效果如何。 # - 实际对话 # (文字移出效果修改为移到对话框中心处渐隐) # #---------------------------------------------------------------------------- # \uout[param] 【独占】 #---------------------------------------------------------------------------- # 【功能】 # 【需要前置Unravel_Bitmap插件】利用消散移出文字 # # 【参数】 # param → 变量参数字符串 # (变量一览) # n → 消散的粒子总数(大约) # d → 单个粒子的大小(直径/边长) # o → 单个粒子消失时的透明度变更最小值 # dir → 整体消散方向类型(同九宫格小键盘)(1379-四角;5-四方向;46-左右向上) # s → 粒子形状类型(0-正方向;1-圆形;2-三角形) # # 【常量设置:参数预设值】 UOUT_PARAMS_INIT = { # \uout[] :n => 200, # 消散的粒子总数 :d => 2, # 消散的粒子的大小(直径/边长) :o => 1, # 透明度变更量的最小值 :dir => 4, # 消散方向类型 :s => 0, # 粒子的形状类型 } # # 【常量设置:类型序号映射到消散方向类型】 CU_PARAM_DIR = { # 定义消散方向类型的id 1 => :LD, 3 => :RD, 4 => :LR, 5 => :LRUD, 6 => :LR, 7 => :LU, 9 => :RU } # # 【常量设置:类型序号映射到粒子形状类型】 CU_PARAM_S = { # 定义粒子形状类型的id 0 => :S, # 正方形 1 => :C, # 圆形(耗时) 2 => :T # 三角形 } # # 【示例】 # - 对话编写 # \uout[1]这是测试对话,看看移出效果如何。 # - 实际对话 # (文字移出效果修改为消散) # #---------------------------------------------------------------------------- # \csin[param] #---------------------------------------------------------------------------- # 【功能】 # 开启正弦波浪扭曲特效 # # 【参数】 # param → 变量参数字符串 # (变量一览) # a → 正弦波浪的幅度(像素数) # l → 正弦波浪的频度(像素数) # s → 正弦波浪的动画速度(默认360) # p → 正弦波浪的相位角度(最大360°)(一般不需要设置) # # 【常量设置:参数预设值】 CSIN_PARAMS_INIT = { :a => 6, # 幅度 :l => 10, # 频度 :s => 30, # 速度 :p => 0, # 相位 } # #---------------------------------------------------------------------------- # \cwave[param] #---------------------------------------------------------------------------- # 【功能】 # 开启文字上下浮动特效 # # 【参数】 # param → 变量参数字符串 # (变量一览) # h → 上下浮动的最大偏移像素值 # t → 每隔t帧进行一次1像素的偏移 # vy → 起始时的y方向移动速度(正数为向下) # # 【常量设置:参数预设值】 CWAVE_PARAMS_INIT = { # \cwave[] :h => 2, # Y方向上的最大偏移值 :t => 4, # 移动一像素所耗帧数 :vy => -1, # Y方向速度(正数向下) } # #---------------------------------------------------------------------------- # \cswing[param] #---------------------------------------------------------------------------- # 【功能】 # 开启左右摇摆特效(本质为精灵旋转) # # 【参数】 # param → 变量参数字符串 # (变量一览) # d → 每次更新增加的角度值 # (d为0时,角度值不缓慢增加,而是直接到最大值,但初始方向随机) # t → 每次角度更新后等待t帧 # t2 → 每次角度到达最大值后等待t2帧 # a → 角度可到达的最大值(左右对称) # o → 摇摆不动点所在位置类型(键盘九宫格) # # 【常量设置:参数预设值】 CSWING_PARAMS_INIT = { # \cswing[] :d => 0, # 每次更新增加的角度值 :t => 1, # 每次角度更新后等待t帧 :t2 => 15, # 每次角度到达最大值后等待t2帧 :a => 5, # 角度可到达的最大值(左右对称) :o => 8, # 摇摆不动点所在位置类型(键盘九宫格)(2为底部中心) } # #---------------------------------------------------------------------------- # \czoom[param] #---------------------------------------------------------------------------- # 【功能】 # 开启文字缩放特效(本质为精灵缩放) # # 【参数】 # param → 变量参数字符串 # (变量一览) # t → 在进行一次缩放变更后的等待帧数 # dx → x方向的每次缩放增量(单位%,即 1 代表每t帧放大1%,zoom_x增加0.01) # dy → y方向的每次缩放增量(单位%,即 1 代表每t帧放大1%,zoom_y增加0.01) # o → 缩放不动点所在位置类型(键盘九宫格) # min → x和y方向上缩放总量的最小值 # (在RGSS3中,负数的缩放量不会显示,推荐设置为自然数) # (在RGD中,负数的缩放量将反向显示,推荐设置为最大值的相反数) # max → x和y方向上缩放总量的最大值 # # 【常量设置:参数预设值】 CZOOM_PARAMS_INIT = { # \czoom[] :t => 0, # 在进行一次缩放变更后的等待帧数 :dx => 2, # x方向的每次缩放增量(缩放总量在-100~100之间,整数) :dy => 0, # y方向的每次缩放增量 :o => 5, # 缩放不动点所在位置类型(键盘九宫格)(5为中心) :min => 0, # xy缩放总量的最小值 :max => 100, # xy缩放总量的最大值 } # #---------------------------------------------------------------------------- # \cshake[param] #---------------------------------------------------------------------------- # 【功能】 # 开启抖动特效 # # 【参数】 # param → 变量参数字符串 # (变量一览) # l/r/u/d → 设置 左右上下 四个方向的最大移动偏移值 # vx/vy → 设置x、y方向上的初始移动速度(正数为向右、向下)(0为随机方向) # vxt/vyt → 设置x、y方向上移动一次后的等待帧数 # # 【常量设置:参数预设值】 CSHAKE_PARAMS_INIT = { # \cshake[] :l => 0, # 距离所在原点的最大偏移量(左右上下) :r => 1, :u => 1, :d => 1, :vx => 0, # x的初始移动方向(0为随机方向) :vxt => 2, # x方向移动一像素所耗帧数 :vy => 0, # y的初始移动方向(0为随机方向) :vyt => 1, # y方向移动一像素所耗帧数 } # #---------------------------------------------------------------------------- # \cshake2[param] #---------------------------------------------------------------------------- # 【功能】 # 开启抖动特效(频率更大的震动) # # 【参数】 # param → 变量参数字符串 # (变量一览) # dx → 往左或往右的最大震动距离 # dy → 往上或往下的最大震动距离 # l → 震动幅度 # # 【常量设置:参数预设值】 CSHAKE2_PARAMS_INIT = { # \cshake[] :dx => 4, :dy => 4, :l => 3, } # #---------------------------------------------------------------------------- # \cflash[param] 【叠加】 #---------------------------------------------------------------------------- # 【功能】 # 开启文字闪烁特效(本质为精灵flash) # # 【参数】 # param → 变量参数字符串 # (变量一览) # r/g/b/a → 闪烁的颜色(红、绿、蓝、不透明度)(默认均255) # (如:r50g50b100a200) # d → 闪烁从开始到完成需要的帧数 # t → 闪烁完成后的等待帧数 # # 【常量设置:参数预设值】 CFLASH_PARAMS_INIT = { # \cflash[] :r => 255, # 闪烁颜色RGBA :g => 255, :b => 255, :a => 255, :d => 60, # 闪烁帧数 :t => 60, # 闪烁后的等待时间 } # #---------------------------------------------------------------------------- # \cmirror[param] 【叠加】 #---------------------------------------------------------------------------- # 【功能】 # 开启横轴镜像绘制(本质为精灵mirror) # # 【参数】 # param → 变量参数字符串(无任何设置参数) # # 【常量设置:参数预设值】 CMIRROR_PARAMS_INIT = {} # # 【示例】 # - 对话编写 # 这是\cmirror[1]测试对话\cmirror[0],看看效果如何。 # - 实际对话 # (“测试对话”四个字将开启左右翻转) # #---------------------------------------------------------------------------- # \cu[param] 【叠加】 #---------------------------------------------------------------------------- # 【功能】 # 【需要前置Unravel_Bitmap插件】开启字符消散特效 # # 【参数】 # param → 变量参数字符串 # (变量一览) # t → 每两次执行消散之间的间隔帧数(正整数) # (其余同 \uout 转义符) # # 【常量设置:参数预设值】 CU_PARAMS_INIT = { # \cu[] :t => 10, # 每两次消散之间的时间间隔 :n => 20, # 消散的粒子总数 :d => 2, # 消散的粒子的大小(直径/边长) :o => 1, # 透明度变更量的最小值 :dir => 4, # 消散方向类型 :s => 0, # 粒子的形状类型 } # #---------------------------------------------------------------------------- # \ctog[param] 【叠加】 #---------------------------------------------------------------------------- # 【功能】 # 开启文字切换特效(本质为切换精灵的bitmap) # # 【参数】 # param → 变量参数字符串 # (变量一览) # i → 使用 i 号对应的文字组(具体见 CTOG_CHARAS 常量,设置 i → 文字组) # n → 从文字组中挑选出 n 个字符作为切换文字(若为0,则取全部) # t → 文字切换一次后的等待帧数 # r → 是否启用随机切换 # # 【常量设置:参数预设值】 CTOG_PARAMS_INIT = { # \ctog[] :i => 0, # 选取i号文字组 :n => 0, # 从文字组中选取n个字符 :t => 10, # 文字切换的等待帧数 :r => 1, # 是否随机选择下一个文字? } # # 【常量设置:序号映射到文字切换组】 CTOG_CHARAS = { # 定义文字切换特效的文字组(若为数字,则取 IconSet 中的图标) 0 => ['▀', '▄', '█', '▌', '✖'], 1 => ['0','1','2','3','4','5','6','7','8','9'], 2 => [376,377,378,379,380,381,382,383], } # #---------------------------------------------------------------------------- # \cneon[param] 【叠加】 #---------------------------------------------------------------------------- # 【功能】 # 开启文字渐变更新特效(本质为精灵color变换) # # 【参数】 # param → 变量参数字符串 # (变量一览) # t → 颜色之间的渐变帧数 # c → 【可重复填写】指定渐变颜色的索引号 # 从 当前颜色开始(默认0号颜色),按照传入顺序依次变化 # # 【常量设置:参数预设值】 CNEON_PARAMS_INIT = { # \cneon[] :t => 60, # 颜色之间的切换帧数 } # # 【示例】 # - 对话编写 # 这是\cneon[t60c1c10c17]测试对话\cneon[0]。 # - 实际对话 # (“测试对话”四个字将按照 0→1→10→17→1→10→17... 的颜色索引进行循环变色) # #---------------------------------------------------------------------------- # \cmc[param] 【叠加】 #---------------------------------------------------------------------------- # 【功能】 # 叠加绘制文字 # # 【参数】 # param → 变量参数字符串 # (变量一览) # i → 使用 i 号对应的文字组(具体见 CMC_CHARAS 常量) # n → 从文字组中挑选出 n 个字符作为切换文字(若为0,则取全部) # c → 指定叠加绘制的文字的颜色索引号(-1时与原始文字颜色一致) # # 【常量设置:参数预设值】 CMC_PARAMS_INIT = { # \cmc[] :i => 0, # 选取i号文字组 :n => 0, # 从文字组中选取n个字符(若为0,则取全部) :c => 10, # 叠加绘制的文字的颜色索引号 } # # 【常量设置:序号映射到叠加绘制文字组】 CMC_CHARAS = { # 定义文字叠加绘制的文字组(若为数字,则取 IconSet 中的图标) 0 => ['✖'], 1 => [4], } # #---------------------------------------------------------------------------- # \cjump[param] #---------------------------------------------------------------------------- # 【功能】 # 开启文字跳跃特效 # # 【参数】 # param → 变量参数字符串 # (变量一览) # tc → 跳跃前的等待帧数 # t → 跳跃的持续帧数 # h → 跳跃的最大高度 # w → 下一次跳跃前的等待帧数(nil时不再跳跃) # # 【常量设置:参数预设值】 CJUMP_PARAMS_INIT = { # \cjump[] :tc => 0, # 跳跃前的等待帧数 :t => 20, # 跳跃的持续帧数 :h => 4, # 跳跃的最大高度 :w => 60, # 下一次跳跃前的等待帧数(nil时不再跳跃) } # #---------------------------------------------------------------------------- # \cfk[param] #---------------------------------------------------------------------------- # 【功能】 # 开启文字明灭闪烁特效 # # 【参数】 # param → 变量参数字符串 # (变量一览) # t → 明灭的持续帧数(不透明度从255到0的所用时间) # (0时直接显隐,负数时代表 0~数字 之间的随机数) # w → 下一次明灭前的等待帧数(nil时不再明灭) # # 【常量设置:参数预设值】 CFK_PARAMS_INIT = { # \cfk[] :t => 30, :w => 60, } # # 【常量设置:当t为0时,完全隐藏后、显示前的等待帧数】 CFK_T0_WAIT = 20 #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # ○ 变量环境 # 此处放置环境处理,效仿python的conda,将对话框的设置状态进行打包存储与读取 #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # 【关于环境】 # 由于对话框可设置的变量众多, # 当需要不同情况使用不同样式的对话框时,不得不编写一大串的转义符进行设置; # 而转义符的设置在默认情况下是跨对话框的,想要改回之前的又要写一大串,非常不便。 # 因此引入了该类别的转义符,以简化不同设置间切换所需的操作。 # # 环境本质上是 Game_Message 类实例的拷贝。 # #---------------------------------------------------------------------------- # \env[sym] 【预先】 #---------------------------------------------------------------------------- # 【功能】 # 读取名称为 sym 的环境,并立即应用于当前与之后的对话框 # 当前环境被设置为 sym # # 【注意】 # - 默认激活的环境为 0,因此可以用 \env[0] 切回最原始的环境 # - 环境的命名没有限制,但最好为字母和数字的组合 # - 当不存在 sym 环境时,将会把当前对话框执行前的环境存储为 sym # # 【示例】 # - 对话编写 # \env[测试]这是测试用对话。 # - 实际对话 # (进入 "测试" 对应的环境,之后的转义符修改都将只修改 "测试" 环境中的设置) # (若不存在 "测试" 环境,则将当前的环境存储为 "测试") # # 【常量设置:环境预设】 # (此处环境的初始状态为脚本中预设的全部值,之后再依据此处设置进行覆盖) # (出于便捷考虑,读档后此处设置的环境均会被重置,即不保存游戏中途对这些环境的修改) # (因此,此处设置的环境请不要与游戏中途的可保存的环境发生名称冲突) # (和文本预设一致,此处转义符需要将 \ 替换成 \\ ) DEFAULT_ENVS = { # 环境名称 => "字符串" "0" => "", # 默认初始环境,全部为预设值,推荐不要修改 "底部" => "\\win[o2do-2dy-30w200h3]", # 对话框居下显示 } # # 【常量设置:设置当对话框关闭时,是否把环境重置为默认的0】 # (若设置为 true,则每次对话框关闭时,环境重置为 0) # (若设置为 false ,则不会自动重置环境,请手动写 \env[0]) # (若设置为 数字,则该序号的开关 $game_switches[id] 开启时,才自动重置环境 ) S_ID_RESET_ENV = true # # (对话框关闭的情形: # 1.下一个事件指令不为显示文本 # 2.下一个事件指令为显示文本,但对话框的背景与当前的不同 # 3.当前对话中有\close转义符) #---------------------------------------------------------------------------- # \env[sym|save] 【结尾】 #---------------------------------------------------------------------------- # 【功能】 # 将当前对话框绘制完成时的环境,保存为 sym # 同时当前环境设置为 sym # # 【注意】 # - 在每一次对话框开启前,以及env生效并切换环境后,都会更新一次当前环境 # # 【示例】 # - 对话编写 # \env[底部对话|save]\win[o2do-2dy-30]这是测试用对话。 # - 实际对话 # (将当前对话框的环境存为 "底部对话" ,若环境已经存在则覆盖, # 之后进入 "底部对话" 的环境) # #---------------------------------------------------------------------------- # \temp 【结尾】 #---------------------------------------------------------------------------- # 【功能】 # 当前对话框结束时,将环境重置回对话框开启前的环境 # # 【注意】 # - 在当前对话框结束前,转义符参数的修改仍然生效 # 因此可能导致中途生成的 并行对话 等,继承了当前修改后的参数 # # - 当同时存在 \temp、\env[sym2]、\env[sym3|save] 时,执行顺序如下(当前环境为 sym1): # 1、在绘制开始前,存储了一次 sym1 环境 # 2、执行预先转义符:temp记录下最初环境为 sym1;env将当前激活环境修改为sym2并应用 # 3、对话框关闭后:当前对话框修改后的环境存入 sym3; # temp生效,将环境重置为 sym1,继续下一个对话 # #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # ○ 高级 # 此处放置高级处理,需要结合一定的脚本知识才能灵活运用 #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= #---------------------------------------------------------------------------- # \func[param] 【预先】 #---------------------------------------------------------------------------- # 【功能】 # 设置一些进阶的功能,将在对话框打开前生效 # # 【参数】 # param → 变量参数字符串 # (变量一览) # open → 使用 i 号对应的对话框打开方式 # close → 使用 i 号对应的对话框关闭方式 # 0 为默认的上下打开关闭,1 为淡入淡出,2 为动态缩放展开,3 为动态滑入滑出 # # aw → 是否开启对话框的自动换行(auto wrap) # 若开启,当文字绘制到对话框边界padding处时,将进行自动换行 # 只是非常基础的按单个文字切割的自动换行方式,会切割单词,不考虑标点符号 # # para → 是否并行处理子窗口 # 若开启,则对话框的下一条指令为 选择支/数字输入/物品选择 时, # 会在对话框打开、开始绘制文字时,同步打开并激活选择框/数字输入框/物品选择 # # 当子窗口的按键处理结束并关闭时,对话框将同步强制关闭 # (警告:对话框中未被绘制的转义符可能不会生效!) # (注意:子窗口的嵌入对话框会失效!) # # 【常量设置:参数预设值】 FUNC_PARAMS_INIT = { # \func[] :open => 2, # 打开方式 :close => 2, # 关闭方式 :aw => 1, # 自动换行 :para => 0, # 并行处理子窗口 } # # 【示例】 # - 对话编写 # 这是测试用对话。\func[para=1] # - 实际对话 # (若下条指令为选择框,将并行打开) # #---------------------------------------------------------------------------- # \eval{string} 或 {{string}} #---------------------------------------------------------------------------- # 【功能】 # 当绘制到该转义符时,执行 eval(string),并丢弃返回值 # # 【参数】 # string → Ruby语句的字符串,可以用 ; 进行分割多句 # # 【注意】 # - 该转义符使用花括号,同时 string 中不可以出现花括号 # # - 可用 s 代替 $game_switches ,用 v 代替 $game_variables # 可用 msg 代表当前对话(Window_Message类的实例) # 如 \eval{s[1]=true} 或 {{s[1]=true}} # 就是当文字绘制到该转义符时,打开1号开关,并继续绘制 # # - 由于文本替换类的转义符优先级最高,实际绘制的内容为对话框打开时的状态 # 即如果存在 \eval{v[1]=5}\v[1],其中1号变量初值为0, # 尽管绘制时其值变为了5,但实际绘制的\v[1]仍然为对话框打开时的值0 # #---------------------------------------------------------------------------- # \set[sym] #---------------------------------------------------------------------------- # 【功能】 # 打开标识符为 sym 字符串的分组(初始时为空分组), # 之后绘制的文字均会被存入该分组中 # # 【注意】 # - 单个文字可以被存入多个分组中 # - 约定 0 分组为全部文字所在分组,因此可以传入 0 来回到无分组状态 # # 【参数】 # sym → 分组的唯一标识符(字符串) # # 【高级】 # Window_EagleMessage 类新增方法 chara_set(sym) { |s| do_something } # 该方法能够用于对 sym 分组中的文字精灵s进行逐个操作, # 若 不传入sym 或 传入 0 或 传入 '0' 或传入 "",则转为对全部文字精灵进行操作 # # 【示例】 # - 对话编写 # \set[1]这是测试用\set[0]对话。 # - 实际对话 # (“这是测试用”被存入标识符为 "1" 的分组,全部文字被存入标识符为 "0" 的分组) # #---------------------------------------------------------------------------- # \setm[sym|effect|param] #---------------------------------------------------------------------------- # 【功能】 # 对sym分组中的文字精灵,执行effect特效,并传入param变量参数字符串作为特效的参数 # # 【参数】 # sym → 分组的唯一标识符,同 \set 中的注释 # effect → 文字特效类转义符中的转义符,比如 ctog # param → 对应文字特效的变量参数字符串,与转义符自己的帮助保持一致 # 若只传入 0,则为关闭该特效 # # 【示例】 # - 对话编写 # \ctog[1]这是测试用\ctog[0]对话。\wait[60]\setm[0|ctog|0] # - 实际对话 # (文本显示完的1s后,关闭全部文字精灵的ctog特效) # (“这是测试用” 的 ctog 特效在对话结尾处被关闭) # # 【示例】 # - 对话编写 # \set[1]\ctog[1]测试用文字\set[0],\!第二句话。\setm[1|ctog|0] # - 实际对话 # (在对话结尾时,仅关闭 1 分组中 “测试用文字” 的 ctog 特效) # #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # ○ 扩展类 # 此处放置整合其他插件效果的转义符,统一放置于 $game_message.ex_params 中 #=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= # 【常量设置:定义初始激活的扩展类转义符的预设变量参数字符串】 EX_PARAMS_INIT = { # 渐变绘制转义符 \cg => "颜色索引字符串", :cg => "", } #---------------------------------------------------------------------------- # \cg[c1..] #---------------------------------------------------------------------------- # 【功能】 # 【需要前置Sion_GradientText插件】之后的文本开启纵轴渐变描绘 # # 【参数】 # 按序排列的 c + Windowskin颜色索引号,可以重复填写 # 不传入任何参数时,代表关闭渐变绘制 # # 【示例】 # - 对话编写 # \cg[c1c2c1]测试用\cg[]文字。 # - 实际对话 # (用 1号 2号 1号颜色由上至下渐变绘制“测试用”三个字) # #============================================================================= # ● 其它设置 #============================================================================= #---------------------------------------------------------------------------- # ○ 新游戏开始时,对话框预定将要显示的文本 # (由于解析问题,请将 "\" 替换成 "\\") ESCAPE_STRING_INIT = "" #-------------------------------------------------------------------------- # ○ 切换显示/隐藏 # (每帧判定,返回 true 时,会切换对话框的显示/隐藏) # (文字将执行其移入移出效果) def self.toggle_visible? false #Input.trigger?(:A) end #---------------------------------------------------------------------------- # ○ 内容滚动 # # - 当对话框的宽度或高度被固定时, # 若所绘制的文字超出对话框范围,将自动开启内容滚动效果 # # - 当进入 等待按键 状态时,按住 方向键 即可朝对应方向滚动浏览对话框全部内容 #---------------------------------------------------------------------------- # ○ 当文字绘制超出对话框区域,导致内容需要滚动时,新增了一个缓动动画来获得空行 # 该项设置缓动动画的持续帧数 CHARAS_SCROLL_OUT_FRAME = 12 #---------------------------------------------------------------------------- # ○ 当对话框内容无需滚动浏览时,若该常量设置为 true,则使用方向键也可以继续对话 # 如果设置为 false,则无改变(仍然需要按确定键或取消键继续对话) INPUT_NEXT_WITH_DIR4 = false #---------------------------------------------------------------------------- # ○ 预定绘制文本 # # - 利用该脚本存储文本,在下次打开对话框时,全部存储文本将按序插入到对话开头 # # $game_message.add_escape(param_string) # # param_string 解析: 【String】型常量 # # - 示例: # $game_message.add_escape("\\win[ali1]") # → 之后的对话框中 文本居中 绘制 # $game_message.add_escape("\\pop[0]") # → 下一次的对话框为pop类型,绑定在当前执行对话框的事件上 # # - 注意: # · 由于解析问题,在 param_string 中请将 "\" 替换成 "\\" # · 当存在多条预定文本,将按照预定时间的先后顺序,依次放入下一次对话框的开头 # · 预定的字符串只会被放入对话框一次 # · 不会去除 param_string 中的非转义符文本 # · 为了确保win、pop等转义符能够顺利更改对话框位置等属性, # 位于开头的转义符将会在对话框打开前执行完毕 # #============================================================================= # ● 特别感谢 #============================================================================= # - 葱兔(http://onira.lofter.com/) #============================================================================= # - 请不要轻易修改以下内容! #============================================================================= end module MESSAGE_EX #-------------------------------------------------------------------------- # ● 【计算】获取缓动函数的返回值 # type 为该函数被调用的场景 # x 为缓动函数的 当前时间/总时间 的比值(0~1之间小数) # 若使用了【组件-缓动函数 by老鹰】,则可以调用其中的缓动函数 #-------------------------------------------------------------------------- def self.ease_value(type, x) if $imported["EAGLE-EasingFunction"] case type when :msg_open # 对话框打开 - 动态缩放展开 return EasingFuction.call("easeOutBack", x) when :msg_close # 对话框关闭 - 动态缩放闭合 return EasingFuction.call("easeInBack", x) when :msg_xywh # 对话框通常情况下变更位置和大小 return EasingFuction.call("easeOutQuart", x) when :msg_vp # 视图ox和oy变动时(文字绘制在可视范围外,或clc清屏) return EasingFuction.call("easeOutQuart", x) when :face_xy # 脸图移动处理 return EasingFuction.call("easeOutElastic", x) when :chara_xy # 文字移动处理 return EasingFuction.call("easeOutExpo", x) when :msg_open_slide # 对话框打开 - 滑入 return EasingFuction.call("easeOutBack", x) when :msg_close_slide # 对话框关闭 - 滑出 return EasingFuction.call("easeInBack", x) end end return 1 - 2**(-10 * x) end #-------------------------------------------------------------------------- # ● 获取指定转义符的基础设置 #-------------------------------------------------------------------------- def self.get_default_params(param_sym) MESSAGE_EX.const_get("#{param_sym.to_s.upcase}_PARAMS_INIT".to_sym) rescue {} end #-------------------------------------------------------------------------- # ● 读取指定文字组 #-------------------------------------------------------------------------- def self.get_charas_array(sym, index, num) h = MESSAGE_EX.const_get("#{sym.to_s.upcase}_CHARAS".to_sym) rescue {} array = h[index] return [] if array.nil? return array if num == 0 return array.sample(num) end #-------------------------------------------------------------------------- # ● 获取\conv[string]的替换字符串 #-------------------------------------------------------------------------- def self.get_conv(s) CONVERT_ESCAPE end #-------------------------------------------------------------------------- # ● 获取姓名框绘制内容的前缀 #-------------------------------------------------------------------------- def self.get_name_prefix ESCAPE_STRING_NAME_PREFIX end #-------------------------------------------------------------------------- # ● 读取对应的 windowskin 位图 #-------------------------------------------------------------------------- def self.windowskin(index) begin return Cache.system(INDEX_TO_WINDOWSKIN[index]) rescue return Cache.system(INDEX_TO_WINDOWSKIN[0]) end end #-------------------------------------------------------------------------- # ● 读取对应的 bg 位图 #-------------------------------------------------------------------------- def self.windowbg(index, w = nil, h = nil) Cache.system(INDEX_TO_WINDOW_BG[index]) rescue nil end def self.namebg(index, w = nil, h = nil) Cache.system(INDEX_TO_NAME_BG[index]) rescue nil end #-------------------------------------------------------------------------- # ● 播放对应的SE #-------------------------------------------------------------------------- def self.se(index) params = INDEX_TO_SE[index] || INDEX_TO_SE[0] return if params[0] == "" volume = params[1] || INDEX_TO_SE[0][1] pitch = params[2] || INDEX_TO_SE[0][2] Audio.se_play("Audio/SE/" + params[0], volume, pitch) end #-------------------------------------------------------------------------- # ● 读取对应的 tag 位图 #-------------------------------------------------------------------------- def self.windowtag(index) begin return Cache.system(INDEX_TO_WINDOWTAG[index]) rescue return Cache.empty_bitmap end end #-------------------------------------------------------------------------- # ● 重设tag # i => 具体在tag位图上的帧序号,九宫格顺序排列 # o => tag位图的显示原点,理论上为pop对话框的do # _do => tag位图的显示位置原点,理论上为pop对话框的o #-------------------------------------------------------------------------- def self.set_windowtag(window, sprite, i, o, _do) w = sprite.src_rect.width; h = sprite.src_rect.height # 单个tag的宽度和高度 sprite.src_rect.x = w * (2 - (9 - i) % 3) sprite.src_rect.y = h * ((9 - i) / 3) self.reset_xy_dorigin(sprite, window, _do) self.reset_xy_origin(sprite, o) end #-------------------------------------------------------------------------- # ● 读取 pause 按键等待精灵的信息组 #-------------------------------------------------------------------------- def self.pause_params(index) INDEX_TO_PAUSE[index] || INDEX_TO_PAUSE[0] end #-------------------------------------------------------------------------- # ● 读取绘制图片时的图片名称 #-------------------------------------------------------------------------- def self.get_pic_file(filename) filename end #============================================================================== # ○ 共享方法 #============================================================================== #-------------------------------------------------------------------------- # ● 判定当前场景 #-------------------------------------------------------------------------- def self.in_scene?(s) return SceneManager.scene_is?(Scene_Map) if s == :map # 地图场景中? return SceneManager.scene_is?(Scene_Battle) if s == :battle # 战斗场景中? return false end #-------------------------------------------------------------------------- # ● 获取指定对象的信息文本 #-------------------------------------------------------------------------- def self.get_data_info(type, id, n ='0') case type when 's'; obj = $data_skills[id] when 'i'; obj = $data_items[id] when 'w'; obj = $data_weapons[id] when 'a'; obj = $data_armors[id] end if obj case n when 0, '0'; return "\ei[#{obj.icon_index}]#{obj.name}" when 1, '1'; return "\ei[#{obj.icon_index}]" when 2, '2'; return "#{obj.name}" end end return "" end #-------------------------------------------------------------------------- # ● 解析字符串参数 #-------------------------------------------------------------------------- def self.parse_param(param_hash, param_text, default_type = "default") param_text = param_text.downcase rescue "" # 只有首位是省略名字的参数设置 param_text.slice!(/ */) t = param_text.slice!(/^\-?\d+/) param_hash[default_type.to_sym] = t.to_i if t && t != "" while(param_text != "") param_text.slice!(/ */) t = param_text.slice!(/^[a-z]+/) param_text.slice!(/ */) if param_text[0] == '=' param_text[0] = '' param_text.slice!(/ */) end if param_text[0] == "$" param_text[0] = '' next param_hash[t.to_sym] = nil end param_hash[t.to_sym] = (param_text.slice!(/^\-?\d+/)).to_i end end #-------------------------------------------------------------------------- # ● 获取文本颜色 #-------------------------------------------------------------------------- def self.text_color(n, windowskin = Cache.system("Window")) return TEXT_COLORS[n] if TEXT_COLORS[n] n_ = n.to_i n_ = DEFAULT_COLOR_INDEX if n_ < 0 windowskin.get_pixel(64 + (n_ % 8) * 8, 96 + (n_ / 8) * 8) end #-------------------------------------------------------------------------- # ● 将指定值变更为布尔量 #-------------------------------------------------------------------------- def self.check_bool(v) return true if v == true return false if v.nil? || v == false || v == 0 return true end #-------------------------------------------------------------------------- # ● 应用font参数到font对象上 #-------------------------------------------------------------------------- def self.apply_font_params(font, ps) font.name = INDEX_TO_FONT[ps[:name]] if ps[:name] font.size = ps[:size] || Font.default_size font.color.alpha = ps[:ca] font.italic = ps[:i] ? MESSAGE_EX.check_bool(ps[:i]) : Font.default_italic font.bold = ps[:b] ? MESSAGE_EX.check_bool(ps[:b]) : Font.default_bold font.shadow = ps[:s] ? MESSAGE_EX.check_bool(ps[:s]) : Font.default_shadow font.outline = ps[:o] ? MESSAGE_EX.check_bool(ps[:o]) : Font.default_outline if ps[:or] font.out_color.set(ps[:or],ps[:og],ps[:ob],ps[:oa]) else font.out_color = Font.default_out_color end ps[:l] = MESSAGE_EX.check_bool(ps[:l]) ps[:lc] ||= 0 ps[:lp] ||= 2 ps[:d] = MESSAGE_EX.check_bool(ps[:d]) ps[:dc] ||= 0 ps[:u] = MESSAGE_EX.check_bool(ps[:u]) ps[:uc] ||= 0 ps[:k] = MESSAGE_EX.check_bool(ps[:k]) ps[:kv] ||= 50 end #-------------------------------------------------------------------------- # ● 重置指定精灵的显示原点 #-------------------------------------------------------------------------- def self.reset_sprite_oxy(obj, o) case o # 固定不动点的位置类型 以九宫格小键盘察看 when 1 obj.ox = 0 obj.oy = obj.height when 2 obj.ox = obj.width / 2 obj.oy = obj.height when 3 obj.ox = obj.width obj.oy = obj.height when 4 obj.ox = 0 obj.oy = obj.height / 2 when 5 obj.ox = obj.width / 2 obj.oy = obj.height / 2 when 6 obj.ox = obj.width obj.oy = obj.height / 2 when 7 # 【默认】显示原点为左上角 obj.ox = 0 obj.oy = 0 when 8 obj.ox = obj.width / 2 obj.oy = 0 when 9 obj.ox = obj.width obj.oy = 0 end end #-------------------------------------------------------------------------- # ● 重置指定对象的显示原点位置 #-------------------------------------------------------------------------- def self.reset_xy_origin(obj, o) case o # 固定不动点的位置类型 以九宫格小键盘察看 when 1 obj.y = obj.y - obj.height when 2 obj.x = obj.x - obj.width / 2 obj.y = obj.y - obj.height when 3 obj.x = obj.x - obj.width obj.y = obj.y - obj.height when 4 obj.y = obj.y - obj.height / 2 when 5 obj.x = obj.x - obj.width / 2 obj.y = obj.y - obj.height / 2 when 6 obj.x = obj.x - obj.width obj.y = obj.y - obj.height / 2 when 7; return # 【默认】显示原点为左上角 when 8 obj.x = obj.x - obj.width / 2 when 9 obj.x = obj.x - obj.width end end #-------------------------------------------------------------------------- # ● 重置指定对象依据另一对象小键盘位置的新位置 #-------------------------------------------------------------------------- def self.reset_xy_dorigin(obj, obj2, o) # 左上角和左上角对齐 if o < 0 # o小于0时,将obj2重置为全屏 obj2 = Rect.new(0,0,Graphics.width,Graphics.height) o = o.abs end case o when 1,4,7; obj.x = obj2.x when 2,5,8; obj.x = obj2.x + obj2.width / 2 when 3,6,9; obj.x = obj2.x + obj2.width end case o when 1,2,3; obj.y = obj2.y + obj2.height when 4,5,6; obj.y = obj2.y + obj2.height / 2 when 7,8,9; obj.y = obj2.y end end #-------------------------------------------------------------------------- # ● 基于指定位图,计算文本块所占宽高 # (只进行 \\ 到 \e 的文本替换、忽略除\i以外的全部转义符、未考虑字号变化) # k → 字符间距 ld → 行间距 #-------------------------------------------------------------------------- def self.calculate_text_wh(bitmap, text, k = 0, ld = 0) text_clone = text.dup; array_width = []; array_height = [] # 转义符替换 text_clone.gsub!(/\\/) { "\e" } text_clone.gsub!(/\e\e/) { "\\" } text_clone.gsub!(/\e[\.\|\^\!\$<>\{|\}]/i) { "" } # 每一行计算宽度高度 text_clone.each_line do |line| icon_count = 0 # 获取 \i[] 数目 line.gsub!(/\ei\[\d+\]/i){ icon_count += 1; "" } # 清除掉全部的\w[wd]格式转义符 line.gsub!(/\e\w+\[(\d|\w)+\]/i) { "" } r = bitmap.text_size(line) w = r.width + icon_count * 24 + (line.length - 1 + icon_count) * k array_width.push(w) h = icon_count > 0 ? [r.height, 24].max : r.height array_height.push(h) end return [array_width.max, array_height.inject{|sum, v| sum = sum + v + ld}] end #-------------------------------------------------------------------------- # ● 基于指定文本设置game_message的参数 #-------------------------------------------------------------------------- def self.set_game_message(game_message, text) @window_clone_env ||= Window_EagleMessage_CloneEnv.new(game_message) @window_clone_env.set_game_message(game_message, text) end #-------------------------------------------------------------------------- # ● 计算最小包围盒 #-------------------------------------------------------------------------- def self.get_smallest_box(rects) return Rect.new if rects.empty? r = rects.pop rects.each do |r2| r.width = [r.x + r.width, r2.x + r2.width].max - [r.x, r2.x].min r.height = [r.y + r.height, r2.y + r2.height].max - [r.y, r2.y].min r.x = r2.x if r2.x < r.x # 新矩形在现有矩形的左外侧,更新x位置 r.y = r2.y if r2.y < r.y # 新矩形在现有矩形的上外侧,更新y位置 end return r end #-------------------------------------------------------------------------- # ● 矩形之间碰撞? #-------------------------------------------------------------------------- def self.rect_collide_rect?(rect1, rect2) if((rect1.x > rect2.x && rect1.x > rect2.x + rect2.width-1) || (rect1.x < rect2.x && rect1.x + rect1.width-1 < rect2.x) || (rect1.y > rect2.y && rect1.y > rect2.y + rect2.height-1) || (rect1.y < rect2.y && rect1.y + rect1.height-1 < rect2.y)) return false end return true end end # end of MESSAGE_EX #============================================================================== # ○ 定义能够响应的文字特效 #============================================================================== module MESSAGE_EX::CHARA_EFFECTS def eagle_chara_effect_cin(param = ''); end def eagle_chara_effect_cout(param = ''); end if defined?(Unravel_Bitmap) def eagle_chara_effect_uout(param = ''); end def eagle_chara_effect_cu(param = ''); end end def eagle_chara_effect_csin(param = ''); end def eagle_chara_effect_cwave(param = ''); end def eagle_chara_effect_cswing(param = ''); end def eagle_chara_effect_czoom(param = ''); end def eagle_chara_effect_cshake(param = ''); end def eagle_chara_effect_cshake2(param = ''); end def eagle_chara_effect_cflash(param = ''); end def eagle_chara_effect_cmirror(param = ''); end def eagle_chara_effect_ctog(param = ''); end def eagle_chara_effect_cneon(param = ''); end def eagle_chara_effect_cmc(param = ''); end def eagle_chara_effect_cjump(param = ''); end def eagle_chara_effect_cfk(param = ''); end end #============================================================================= # ○ DataManager #============================================================================= class << DataManager #-------------------------------------------------------------------------- # ● 设置新游戏 #-------------------------------------------------------------------------- alias eagle_message_ex_setup_new_game setup_new_game def setup_new_game eagle_message_ex_setup_new_game $game_message.add_escape(MESSAGE_EX::ESCAPE_STRING_INIT) $game_system.reset_game_message_envs end end #============================================================================= # ○ Game_Message #============================================================================= class Game_Message attr_reader :params_need_apply # 存储需要被预定应用的符号(调用对应处理方法) attr_accessor :escape_strings # 存储预定要添加的字符串 attr_accessor :chara_params # 存储文字特效预设 code_symbol => param_string attr_accessor :font_params, :win_params, :pop_params attr_accessor :face_params, :name_params, :pause_params attr_accessor :func_params, :ex_params, :env, :default_env attr_accessor :event_id, :child_window_w_des, :child_window_h_des attr_accessor :no_name_overlap_face, :no_input_pause, :active # 对话框在显示中 attr_accessor :eagle_text # 存储实际绘制的文本(去除了预处理的转义符) attr_accessor :eagle_message # 兼容模式 #-------------------------------------------------------------------------- # ● 初始化对象 #-------------------------------------------------------------------------- alias eagle_message_ex_init initialize def initialize eagle_message_ex_init check_flags set_default_params reset_child_window_wh_add end #-------------------------------------------------------------------------- # ● 检查flags #-------------------------------------------------------------------------- def check_flags # 当前环境(默认 '0') @env = '0' if @env.nil? # 姓名框不遮挡脸图? if @no_name_overlap_face == nil @no_name_overlap_face = MESSAGE_EX::DEFAULT_NO_OVERLAP_FACE end # 不进入按键等待?(扩展用) @no_input_pause = false if @no_input_pause.nil? # 如果处于兼容模式,且变量值为nil,确保变量值为false if EAGLE_MSG_EX_COMPAT_MODE == true @eagle_message = false if @eagle_message.nil? end end #-------------------------------------------------------------------------- # ● 获取全部可保存params的符号的数组 #-------------------------------------------------------------------------- def eagle_params [:chara, :font, :win, :pop, :face, :name, :pause, :func, :ex] end #-------------------------------------------------------------------------- # ● 获取params的初始值 #-------------------------------------------------------------------------- def set_default_params eagle_params.each do |sym| send("#{sym}_params=".to_sym, MESSAGE_EX.get_default_params(sym).dup) end @params_need_apply = eagle_params.dup # 添加修改预定,用于应用初始值 @escape_strings = [] # 存储等待执行的转义符字符串 end #-------------------------------------------------------------------------- # ● 检查params是否都存在(读档后调用,确保新增变量写入旧存档中) #-------------------------------------------------------------------------- def check_params check_flags eagle_params.each do |sym| params = self.send("#{sym}_params".to_sym) def_params = MESSAGE_EX.get_default_params(sym).dup if params == nil self.send("#{sym}_params=".to_sym, def_params) add_apply(sym) else params = def_params.merge(params) self.send("#{sym}_params=".to_sym, params) end end end #-------------------------------------------------------------------------- # ● 清除(每次对话框关闭前被调用) #-------------------------------------------------------------------------- alias eagle_message_ex_clear clear def clear eagle_message_ex_clear @eagle_text = "" @event_id = 0 # 存储当前执行的Game_Interpreter的事件ID if EAGLE_MSG_EX_COMPAT_MODE == false # 如果不处于兼容模式,确保变量恒为true @eagle_message = true end end #-------------------------------------------------------------------------- # ● 重置额外增加的宽高(new_page时调用) #-------------------------------------------------------------------------- def reset_child_window_wh_add @child_window_w_des = 0 # 因子窗口嵌入而额外增加的宽高 @child_window_h_des = 0 end #-------------------------------------------------------------------------- # ● 下一次对话时要解析的转义符 # 【由于解析问题,字符串中请将 "\" 替换成 "\e" 】 #-------------------------------------------------------------------------- def add_escape(string) @escape_strings.push(string) end #-------------------------------------------------------------------------- # ● 判定是否需要进入等待按键状态 #-------------------------------------------------------------------------- def input_pause? return false if @no_input_pause !(choice? || num_input? || item_choice?) end #-------------------------------------------------------------------------- # ● 使用了各个对话框组件? #-------------------------------------------------------------------------- def pop?; @pop_params[:type] != nil; end def pop_tag?; @pop_params[:tag] > 0; end def face?; @face_params[:name] != ""; end def name?; @name_params[:name] != ""; end #-------------------------------------------------------------------------- # ● 添加修改预定 #-------------------------------------------------------------------------- def add_apply(param_sym) return if @params_need_apply.include?(param_sym) @params_need_apply.push(param_sym) end #-------------------------------------------------------------------------- # ● 清空预定修改 #-------------------------------------------------------------------------- def clear_applys @params_need_apply.clear end #-------------------------------------------------------------------------- # ● 重置指定参数 #-------------------------------------------------------------------------- def reset_params(param_sym, code_string = nil) return eagle_params.each{|sym| reset_params(sym)} if param_sym.nil? return reset_params_c(code_string) if param_sym == :chara return reset_params_ex(code_string) if param_sym == :ex default_params = MESSAGE_EX.get_default_params(param_sym) if code_string.nil? # 直接清除全部参数 new_params = default_params.dup else new_params = method( param_sym.to_s + "_params" ).call.dup # 获取旧的hash code_string.split("|").each { |c| new_params[c.to_sym] = default_params[c.to_sym] } end self.send((param_sym.to_s+"_params=").to_sym, new_params) add_apply(param_sym) # 添加修改预定,用于应用结果 end #-------------------------------------------------------------------------- # ● 重置指定文字特效 #-------------------------------------------------------------------------- def reset_params_c(code_string = nil) default_params = MESSAGE_EX.get_default_params(:chara) return @chara_params = default_params if code_string.nil? code_string.split("|").each { |c| if default_params[c.to_sym] @chara_params[c.to_sym] = default_params[c.to_sym] else @chara_params.delete(c.to_sym) end } end #-------------------------------------------------------------------------- # ● 重置扩展转义符 #-------------------------------------------------------------------------- def reset_params_ex(code_string = nil) default_params = MESSAGE_EX.get_default_params(:ex) return @ex_params = default_params if code_string.nil? code_string.split("|").each { |c| if default_params[c.to_sym] @ex_params[c.to_sym] = default_params[c.to_sym] else @ex_params.delete(c.to_sym) end } end #-------------------------------------------------------------------------- # ● 参数拷贝 #-------------------------------------------------------------------------- def clone2 t = Game_Message.new clone_rgss(t) t.visible = true eagle_params.each do |sym| m = "#{sym}_params" t.send("#{m}=".to_sym, method(m.to_sym).call.clone) end clone_ex(t) t end #-------------------------------------------------------------------------- # ● 参数拷贝(RGSS中的变量) #-------------------------------------------------------------------------- def clone_rgss(t) t.background = @background t.position = @position end #-------------------------------------------------------------------------- # ● 参数拷贝(扩展) #-------------------------------------------------------------------------- def clone_ex(t) t.no_name_overlap_face = @no_name_overlap_face end #-------------------------------------------------------------------------- # ● 保存当前环境 #-------------------------------------------------------------------------- def save_env(sym = '0') if sym == '0' # 如果是默认环境,则保存到自己,防止与子窗口的默认环境相互干扰 @default_env = self.clone2 return end $game_system.message_envs[sym] = self.clone2 end #-------------------------------------------------------------------------- # ● 读取指定环境 #-------------------------------------------------------------------------- def load_env(sym = '0') t = $game_system.message_envs[sym] t = @default_env if sym == '0' return false if t.nil? # 应用params eagle_params.each do |s| m = "#{s}_params" self.send("#{m}=".to_sym, t.method(m.to_sym).call.clone) end # 新增转义符的应用预定 @params_need_apply = eagle_params # 应用扩展数据 t.clone_ex(self) return true end #-------------------------------------------------------------------------- # ● 将临时环境存入指定环境,并返回临时环境 #-------------------------------------------------------------------------- def load_temp_env(sym = '0', temp = :eagle_temp) if sym == '0' @default_env = $game_system.message_envs[temp] else $game_system.message_envs[sym] = $game_system.message_envs[temp] end return $game_system.message_envs[temp] end end #============================================================================= # ○ Game_System #============================================================================= class Game_System attr_reader :message_envs # 对话框环境 #-------------------------------------------------------------------------- # ● 初始化对象 #-------------------------------------------------------------------------- alias eagle_message_ex_initialize initialize def initialize eagle_message_ex_initialize @message_envs = {} # sym => game_message end #-------------------------------------------------------------------------- # ● 读档后的处理 #-------------------------------------------------------------------------- alias eagle_message_ex_on_after_load on_after_load def on_after_load eagle_message_ex_on_after_load reset_game_message_envs $game_message.check_params # 确保新增AddOn时,参数hash存在 @message_envs.each { |sym, g| g.check_params } end #-------------------------------------------------------------------------- # ● 重置初始环境 #-------------------------------------------------------------------------- def reset_game_message_envs MESSAGE_EX::DEFAULT_ENVS.each do |sym, text| g = Game_Message.new MESSAGE_EX.set_game_message(g, text) @message_envs[sym] = g end $game_message.save_env if $game_message.default_env == nil end end #============================================================================= # ○ Game_Interpreter #============================================================================= class Game_Interpreter #-------------------------------------------------------------------------- # ● 显示文字 #-------------------------------------------------------------------------- alias eagle_message_ex_command_101 command_101 def command_101 $game_message.event_id = @event_id eagle_message_ex_command_101 end end #============================================================================= # ○ Window_EagleMessage #============================================================================= class Window_EagleMessage < Window_Base include MESSAGE_EX::CHARA_EFFECTS attr_reader :eagle_charas_w, :eagle_charas_h, :eagle_chara_viewport #-------------------------------------------------------------------------- # ● 获取主参数组(方便子窗口修改为自己的game_message) #-------------------------------------------------------------------------- def game_message; $game_message; end def game_message=(g); $game_message = g; end #-------------------------------------------------------------------------- # ● 【通用方法】 #-------------------------------------------------------------------------- def parse_param(param_hash, param_text, default_type = "default") MESSAGE_EX.parse_param(param_hash, param_text, default_type) end def text_color(n) MESSAGE_EX.text_color(n, self.windowskin) end #-------------------------------------------------------------------------- # ● 初始化对象 #-------------------------------------------------------------------------- def initialize super(0, 0, window_width, window_height) create_all_windows eagle_message_init_assets eagle_message_init_params eagle_message_reset self.openness = 0 end #-------------------------------------------------------------------------- # ● 生成所有子窗口 #-------------------------------------------------------------------------- def create_all_windows @gold_window = Window_EagleMsgGold.new(self) @choice_window = Window_EagleChoiceList.new(self) rescue Window_ChoiceList.new(self) @number_window = Window_EagleNumberInput.new(self) rescue Window_NumberInput.new(self) @item_window = Window_EagleKeyItem.new(self) rescue Window_KeyItem.new(self) end #-------------------------------------------------------------------------- # ● 初始化组件 # (在进行 clone 时,需要将该方法中的组件直接赋值给拷贝窗口) #-------------------------------------------------------------------------- def eagle_message_init_assets @back_sprite = Sprite.new # 显示背景图片的精灵 @eagle_chara_viewport = Viewport.new # 文字精灵的显示区域 @eagle_chara_sprites = [] # 存储全部的文字精灵 @eagle_sprite_pop_tag = Sprite.new # pop状态下的tag精灵 @eagle_sprite_face = nil # 脸图精灵 @eagle_window_name = Window_EagleMsgName.new(self) # 姓名框 @eagle_sprite_pause = Sprite_EaglePauseTag.new(self) # 等待按键的精灵 end #-------------------------------------------------------------------------- # ● 初始化参数(只会在 initialize 时执行一次) # (推荐将一些不需要传递给拷贝窗口的数据置于此处) #-------------------------------------------------------------------------- def eagle_message_init_params self.back_opacity = 255 # 背景不透明度 self.arrows_visible = false # 内容位图未完全显示时出现的箭头 @fiber = nil # 纤程 @background = 0 # 背景类型 @position = 2 # 显示位置 @flag_draw = true # true 代表进行实际的绘制 @flag_open_close = false # 当正在进行打开/关闭时,置为 true @flag_input_pause = false # 当正在进行按键等待时,置为 true @flag_need_open = true # true 代表需要执行open_and_wait @flag_need_change_wh = false # true 代表需要进行宽高的动态变化 @flag_need_close = false # true 代表当前对话框必需处理关闭 @flag_hold = false # true 代表当前对话框会被拷贝保留,并同步更新 @flag_instant = false # true 代表当前对话框不再处理文字显示时的等待 @flag_next = false # true 代表当前对话框不关闭,下一显示文字将继续使用 @flag_temp = false # true 代表当前对话框的任何修改将不被保存 @flag_temp_env = nil # 存储当前对话框开启前的环境 @flag_save_env = nil # 当不为 nil 时,当前对话框状态保存到对应环境中 @flag_no_fix = false # 关闭位置修正功能 @eagle_dup_windows ||= [] # 存储生成的全部拷贝对话框 @eagle_evals = [] # 当前对话中的待执行脚本 [eval_str, eval_str...] @eagle_chara_sets = {} # 存储文字的全部分组 {分组名 => [文字精灵]} @eagle_current_set = nil # 当前分组的名称 # 对话框动态移动偏移量(此处新增定义,防止子类覆盖了 eagle_message_reset) @eagle_move_x = @eagle_move_y = 0 # 存储对话框在上一帧的位置(此处新增定义,防止子类覆盖了 eagle_message_reset) @eagle_last_x = @eagle_last_y = nil # 对话框位置的强制增量 @eagle_offset_x = @eagle_offset_y = 0 eagle_check_func("") # 预先执行一遍func,确保它们都是布尔量 end #-------------------------------------------------------------------------- # ● 拷贝自身 #-------------------------------------------------------------------------- def clone(window = Window_EagleMessage_Clone) t = window.new(game_message.clone2) t.game_message.win_params[:z] = 0 t.move(self.x, self.y, self.width, self.height) t.z = self.z - 5 t.windowskin = self.windowskin # 拷贝背景精灵 t.back_bitmap = @back_bitmap t.back_sprite = @back_sprite @back_bitmap = nil # 拷贝视图 t.eagle_chara_viewport = @eagle_chara_viewport # 拷贝文字组 t.eagle_chara_sprites = @eagle_chara_sprites t.eagle_chara_sprites.each { |s| s.bind_window(t) } # 复制文本宽高 t.eagle_set_chara_wh(@eagle_charas_w, @eagle_charas_h, @eagle_charas_w_final, @eagle_charas_h_final) # 拷贝pop对象 t.eagle_pop_obj = @eagle_pop_obj # 拷贝pop的tag t.eagle_sprite_pop_tag = @eagle_sprite_pop_tag # 拷贝脸图 if @eagle_sprite_face t.eagle_sprite_face = @eagle_sprite_face t.eagle_sprite_face.bind_window(t) end # 拷贝姓名框 t.eagle_window_name = @eagle_window_name t.eagle_window_name.bind_window(t) # 拷贝pause精灵 t.eagle_sprite_pause = @eagle_sprite_pause t.eagle_sprite_pause.bind_window(t) # 扩展 t = clone_ex(t) # 集体更新z值 t.eagle_reset_z # 自身初始化组件与重置 eagle_message_init_assets # 更新自身的z值 eagle_reset_z t end #-------------------------------------------------------------------------- # ● 拷贝自身(扩展用处理) #-------------------------------------------------------------------------- def clone_ex(t) t end #-------------------------------------------------------------------------- # ● 释放 #-------------------------------------------------------------------------- def dispose dispose_all_windows dispose_back_bitmap @back_sprite.dispose @eagle_chara_sprites.each { |s| s.dispose } @eagle_window_name.dispose @eagle_sprite_face.dispose if @eagle_sprite_face @eagle_sprite_pop_tag.dispose @eagle_sprite_pause.dispose @eagle_dup_windows.each { |w| w.dispose if !w.disposed? } @eagle_chara_viewport.dispose super end #-------------------------------------------------------------------------- # ● 释放所有窗口 #-------------------------------------------------------------------------- def dispose_all_windows @gold_window.dispose @choice_window.dispose @number_window.dispose @item_window.dispose end #-------------------------------------------------------------------------- # ● 释放背景位图 #-------------------------------------------------------------------------- def dispose_back_bitmap @back_bitmap.dispose if @back_bitmap @back_bitmap = nil end #-------------------------------------------------------------------------- # ● 重置对话框 #-------------------------------------------------------------------------- def eagle_message_reset eagle_message_reset_continue eagle_move_out_assets # 移出全部组件 @eagle_last_x = @eagle_last_y = nil # 重置存储的对话框的上一个位置 @eagle_move_x = @eagle_move_y = 0 # 重置对话框动态移动位置 @eagle_win_des_w = @eagle_win_des_h = 0 # 重置对话框最终显示宽高 @eagle_charas_w = @eagle_charas_h = 0 # 重置文字区域的宽高 @eagle_charas_w_final = @eagle_charas_h_final = 0 face_params[:width] = 0 # 重置脸图的宽度(用于文字偏移) @eagle_pop_obj = nil # 重置pop对象,防止报错 eagle_reset_z # 重置z值 clear_flags # 清除显示标志 end #-------------------------------------------------------------------------- # ● 重置对话框(对话框不关闭,清空全部设置,并继续显示) #-------------------------------------------------------------------------- def eagle_message_reset_continue show if !self.visible # 确保对话框显示 if @flag_next # 如果继续显示在当前对话框里,则不移出文字 else eagle_message_sprites_move_out # 移出全部文字精灵 eagle_reset_charas_oxy # 重置文字显示区域 @eagle_chara_sets.clear # 清空文字分组 end eagle_process_env # 处理环境的存储或读取 eagle_process_temp # 处理临时环境 @eagle_sprite_pop_tag.visible = false # 隐藏pop的tag @eagle_sprite_pause.visible = false # 隐藏等待按键pause精灵 @eagle_sprite_pause.bind_last_chara(nil) # 重置pause精灵的文末位置 @eagle_sprite_pause_width_add = 0 # 因pause精灵而扩展的窗口宽度 @eagle_next_chara_x = 0 # 重置下一个文字的绘制坐标x(左对齐、不考虑换行) @eagle_force_close = false # 重置强制关闭 end #-------------------------------------------------------------------------- # ● 移出全部组件 #-------------------------------------------------------------------------- def eagle_move_out_assets pop_params[:with_tag] = false @eagle_sprite_pop_tag.visible = false # 隐藏pop的tag @eagle_sprite_pause.visible = false # 隐藏pause精灵 face_params[:name] = "" # 移出显示的脸图 eagle_move_out_face # 关闭姓名框(因为对话框关闭后,姓名框不再更新,调小openness确保先关闭) @eagle_window_name.close @eagle_window_name.openness -= 15 end #-------------------------------------------------------------------------- # ● 更新全部组件的不透明度 #-------------------------------------------------------------------------- def update_assets_opacity(opa) @eagle_chara_sprites.each { |c| c.opacity = opa } if game_message.pop? && pop_params[:with_tag] @eagle_sprite_pop_tag.opacity = opa end @eagle_sprite_face.opa = opa if @eagle_sprite_face if game_message.name? @eagle_window_name.opacity = opa if @eagle_window_name.back_opacity > 0 @eagle_window_name.contents_opacity = opa end update_back_sprite_opa(opa) end #-------------------------------------------------------------------------- # ● 重设z值 #-------------------------------------------------------------------------- def eagle_reset_z self.z = win_params[:z] if win_params[:z] > 0 @back_sprite.z = self.z @eagle_chara_viewport.z = self.z + 1 @eagle_sprite_pop_tag.z = self.z + 1 @eagle_sprite_pause.z = self.z + 2 @eagle_window_name.z = self.z + 3 end #-------------------------------------------------------------------------- # ● 显示窗口 #-------------------------------------------------------------------------- def show self.visible = true @back_sprite.visible = true if self.opacity == 0 @eagle_chara_sprites.each { |s| s.move_in } if game_message.pop? && pop_params[:with_tag] @eagle_sprite_pop_tag.visible = true end @eagle_sprite_face.visible = true if @eagle_sprite_face @eagle_window_name.show if game_message.name? @eagle_sprite_pause.visible = true if @flag_input_pause show_ex self end #-------------------------------------------------------------------------- # ● 显示(扩展用) #-------------------------------------------------------------------------- def show_ex @eagle_dup_windows.each { |w| w.show } end #-------------------------------------------------------------------------- # ● 隐藏窗口 #-------------------------------------------------------------------------- def hide self.visible = false @back_sprite.visible = false @eagle_chara_sprites.each { |s| s.move_out_temp } @eagle_sprite_pop_tag.visible = false @eagle_sprite_face.visible = false if @eagle_sprite_face @eagle_window_name.hide @eagle_sprite_pause.visible = false hide_ex self end #-------------------------------------------------------------------------- # ● 隐藏(扩展用) #-------------------------------------------------------------------------- def hide_ex @eagle_dup_windows.each { |w| w.hide } end #-------------------------------------------------------------------------- # ● 更新画面 #-------------------------------------------------------------------------- def update super eagle_update_before_fiber update_fiber eagle_update_after_fiber end #-------------------------------------------------------------------------- # ● 更新fiber #-------------------------------------------------------------------------- def update_fiber if @fiber @fiber.resume elsif game_message.busy? && !game_message.scroll_mode @fiber = Fiber.new { fiber_main } @fiber.resume else game_message.visible = false end end #-------------------------------------------------------------------------- # ● 更新(在 @fiber 更新之前) #-------------------------------------------------------------------------- def eagle_update_before_fiber update_all_windows update_back_sprite if self.openness > 0 eagle_update_assets_after_open eagle_update_func_after_open end end #-------------------------------------------------------------------------- # ● 更新所有窗口 #-------------------------------------------------------------------------- def update_all_windows @gold_window.update @choice_window.update @number_window.update @item_window.update end #-------------------------------------------------------------------------- # ● 对话框打开后进行组件更新 #-------------------------------------------------------------------------- def eagle_update_assets_after_open eagle_pop_update if game_message.pop? @eagle_window_name.update @eagle_sprite_face.update if @eagle_sprite_face @eagle_sprite_pause.update if @eagle_sprite_pause.visible end #-------------------------------------------------------------------------- # ● 对话框打开后进行扩展功能更新 #-------------------------------------------------------------------------- def eagle_update_func_after_open (self.visible ? hide : show) if MESSAGE_EX.toggle_visible? end #-------------------------------------------------------------------------- # ● 更新(在 @fiber 更新之后) #-------------------------------------------------------------------------- def eagle_update_after_fiber @eagle_chara_sprites.each { |s| s.update } eagle_update_dup_windows end #-------------------------------------------------------------------------- # ● 更新拷贝窗口 #-------------------------------------------------------------------------- def eagle_update_dup_windows if @eagle_dup_windows.size > 0 @eagle_dup_windows.each { |w| w.update } if @eagle_dup_windows[-1].openness <= 0 t = @eagle_dup_windows.pop t.dispose end end end #-------------------------------------------------------------------------- # ● 打开直至完成(当有文字绘制完成时执行) #-------------------------------------------------------------------------- def open_and_wait @flag_open_close = true eagle_process_open_and_wait @eagle_window_name.start if game_message.name? # 对话框打开后再打开姓名框 @flag_open_close = false @flag_need_open = false end #-------------------------------------------------------------------------- # ● 处理打开方式(打开直至完成) #-------------------------------------------------------------------------- def eagle_process_open_and_wait case func_params[:open] when 3 eagle_open_type_slide when 2 eagle_open_type_ease when 1 eagle_open_type_fade else # :default eagle_open_type_default end end #-------------------------------------------------------------------------- # ● 打开-滑动移入 #-------------------------------------------------------------------------- def eagle_open_type_slide self.openness = 0 @eagle_chara_sprites.each { |c| c.visible = false } # 临时屏蔽位置修改功能,让对话框能显示到屏幕外 @flag_no_fix = true h = {:ins => true, :open => true} eagle_set_wh(h) self.openness = 255 # 直接指定初始位置在屏幕外 @eagle_last_x = self.x @eagle_last_y = self.y > Graphics.height/2 ? (Graphics.height+20) : (0-self.height-20) # 移动回真实显示位置 eagle_set_wh({:ease_type => :msg_open_slide}) # 解除屏蔽 @flag_no_fix = false @eagle_chara_sprites.each { |c| c.move_in; c.visible = true } end #-------------------------------------------------------------------------- # ● 打开-动态展开 #-------------------------------------------------------------------------- def eagle_open_type_ease @eagle_chara_sprites.each { |c| c.visible = false } eagle_set_wh({:w => 1, :h => 1, :ins => true, :open => true}) if self.openness == 0 self.openness = 255 eagle_set_wh({:open => true}) @eagle_chara_sprites.each { |c| c.move_in; c.visible = true } end #-------------------------------------------------------------------------- # ● 打开-淡入 #-------------------------------------------------------------------------- def eagle_open_type_fade eagle_set_wh({:ins => true, :open => true}) update_back_sprite_zoom(nil, nil) # 将背景精灵的缩放重置为 1.0 @eagle_chara_sprites.each { |c| c.move_in } self.openness = 255 @eagle_window_name.openness = 255 if game_message.name? _opa = 0 while ( _opa < 255 ) _opa += 26 self.opacity = _opa if @background == 0 && !@back_sprite.visible update_assets_opacity(_opa) Fiber.yield eagle_win_update # 因为update中不更新基础对话框的位置,故加入一次更新 end end #-------------------------------------------------------------------------- # ● 打开-默认openness #-------------------------------------------------------------------------- def eagle_open_type_default eagle_set_wh({:ins => true, :open => true}) update_back_sprite_zoom(nil, nil) # 将背景精灵的缩放重置为 1 @eagle_chara_sprites.each { |c| c.visible = false } open until open? update_back_sprite_opa(self.openness) Fiber.yield end @eagle_chara_sprites.each { |c| c.move_in; c.visible = true } end #-------------------------------------------------------------------------- # ● 关闭直至完成 #-------------------------------------------------------------------------- def close_and_wait @flag_open_close = true show if !self.visible Fiber.yield # 关闭前等待1帧,用于截图等 eagle_message_sprites_move_out eagle_process_close_and_wait @flag_open_close = false @flag_need_open = true @back_sprite.visible = false end #-------------------------------------------------------------------------- # ● 处理关闭方式(关闭直至完成) #-------------------------------------------------------------------------- def eagle_process_close_and_wait case func_params[:close] when 3 eagle_close_type_slide when 2 eagle_close_type_ease when 1 eagle_close_type_fade else # :default eagle_close_type_default end end #-------------------------------------------------------------------------- # ● 关闭-滑出 #-------------------------------------------------------------------------- def eagle_close_type_slide eagle_move_out_assets @flag_no_fix = true # 直接指定目的位置在屏幕外 h = {:ease_type => :msg_close_slide, :close => true, :w => self.width, :h => self.height} h[:x_init] = self.x h[:y_init] = self.y h[:x] = self.x h[:y] = self.y > Graphics.height/2 ? (Graphics.height+20) : (0-self.height-20) # 由于 eagle_set_wh 原理是把基于目前xywh的增量逐渐减小至0,然后完成更新, # 需要先强制把当前y改成目的地处,才能正常依靠增量减小而逼近目的地 @eagle_offset_y = h[:y] - h[:y_init] eagle_set_wh(h) @flag_no_fix = false self.openness = 0 close @eagle_offset_y = 0 end #-------------------------------------------------------------------------- # ● 关闭-动态缩小 #-------------------------------------------------------------------------- def eagle_close_type_ease eagle_move_out_assets eagle_set_wh({:w => 1, :h => 1, :close => true}) if self.openness > 0 self.openness = 0 close if @eagle_window_name # 如果是透明对话框,没有缩小过程,姓名框来不及关闭 @eagle_window_name.contents_opacity = 0 @eagle_window_name.update end end #-------------------------------------------------------------------------- # ● 关闭-淡出 #-------------------------------------------------------------------------- def eagle_close_type_fade _opa = [self.opacity, @back_sprite.opacity].max while ( _opa > 0 ) @eagle_offset_y -= 2 _opa -= 30 self.opacity = _opa if @background == 0 && !@back_sprite.visible update_assets_opacity(_opa) Fiber.yield eagle_win_update # 因为update中不更新基础对话框的位置,故加入一次更新 end self.openness = 0 close @eagle_offset_y = 0 end #-------------------------------------------------------------------------- # ● 关闭-默认openness #-------------------------------------------------------------------------- def eagle_close_type_default close until all_close? update_back_sprite_opa(self.openness) Fiber.yield end end #-------------------------------------------------------------------------- # ● 关闭 #-------------------------------------------------------------------------- def close super eagle_message_reset eagle_reset_env # 特殊:重置环境 end #-------------------------------------------------------------------------- # ● 判定是否所有窗口已全部关闭 #-------------------------------------------------------------------------- def all_close? close? && @choice_window.close? && @number_window.close? && @item_window.close? end #-------------------------------------------------------------------------- # ● 移出全部文字精灵 #-------------------------------------------------------------------------- def eagle_message_sprites_move_out while(!@eagle_chara_sprites.empty?) c = eagle_take_out_a_chara ensure_character_visible(c, true) # 不要聚焦当前文字的缓动动画,太慢 c.move_out # 已经交由文字池进行后续更新释放 if @eagle_force_close # 如果强制关闭,则不等待移出了 else win_params[:cwo].times { Fiber.yield } if @flag_need_change_wh || # 如果预定了宽高变化,则这里不需要再逐个变化了 win_params[:cwo] == 0 # 如果根本没有逐个移出,也不需要动态变化宽高 else eagle_recalc_charas_wh_when_out end end end @eagle_chara_sets.clear end #-------------------------------------------------------------------------- # ● 取出一个文字精灵 #-------------------------------------------------------------------------- def eagle_take_out_a_chara case win_params[:cor] when 0, false; return @eagle_chara_sprites.shift when 1, true; return @eagle_chara_sprites.pop when 2; i = rand(@eagle_chara_sprites.size) return @eagle_chara_sprites.delete_at(i) end end #-------------------------------------------------------------------------- # ● 取出一个文字精灵后,重新计算宽高 #-------------------------------------------------------------------------- def eagle_recalc_charas_wh_when_out rects = @eagle_chara_sprites.collect { |s| s.screen_rect } r = MESSAGE_EX.get_smallest_box(rects) @eagle_charas_w = r.width @eagle_charas_h = r.height eagle_set_wh({:ins => true}) end #-------------------------------------------------------------------------- # ● 设置对话框大小位置,并等待更新结束 #-------------------------------------------------------------------------- def eagle_set_wh(_p = {}) eagle_before_set_xywh(_p) eagle_set_params_xywh(_p) eagle_apply_params_xywh(_p) wait_until_des_wh(_p) eagle_after_set_xywh(_p) end #-------------------------------------------------------------------------- # ● 对话框位置大小更新前的处理 #-------------------------------------------------------------------------- def eagle_before_set_xywh(_p) end #-------------------------------------------------------------------------- # ● 设置对话框xywh的参数Hash #-------------------------------------------------------------------------- def eagle_set_params_xywh(_p = {}) _p[:update] = [] # 将会进行更新的属性 _p[:ins] = false if _p[:ins].nil? # 如果需要立刻更新完成,置为 true _p[:ins] = true if @background == 2 # 透明背景时直接更新完成 _p[:open] = false if _p[:open].nil? # 如果目标是打开窗口,置为 true _p[:t] ||= 20 # 更新所需时间(帧) # _p[:ease_type] # 指定预设所用的缓动函数类别,见 MESSAGE_EX.ease_value() # 先计算目标宽高(该变量与其它参数均无关,只需要预绘制后的文字区域宽高) #_p[:w] 与 _p[:h] 为更新结束时的宽高,如果为 nil,将自动计算 _p[:w_init] = self.width if _p[:w].nil? _p[:w] = eagle_window_width _p[:w] += eagle_window_width_add(_p[:w]) end _p[:w_d] = _p[:w] - _p[:w_init] _p[:update].push(:w) if _p[:w_d] != 0 _p[:h_init] = self.height if _p[:h].nil? _p[:h] = eagle_window_height _p[:h] += eagle_window_height_add(_p[:h]) end _p[:h_d] = _p[:h] - _p[:h_init] _p[:update].push(:h) if _p[:h_d] != 0 # 如果为打开/预定变更宽高,记录最终的宽高 if _p[:open] || @flag_need_change_wh @eagle_win_des_w = _p[:w] @eagle_win_des_h = _p[:h] end # 需要先计算出目标宽高,再更新该设置,才能保证更新后的xy为真正的移动目标位置 eagle_win_update #_p[:x] 与 _p[:y] 为更新结束时的位置,如果为 nil,且对话框未关闭,将自动计算 if _p[:open] || @eagle_last_x.nil? || @eagle_last_y.nil? # 如果为打开,则已经直接移到了目的地,此处不再变更xy _p[:x] = nil _p[:y] = nil elsif self.openness == 255 _p[:x_init] = @eagle_last_x if _p[:x_init].nil? _p[:y_init] = @eagle_last_y if _p[:y_init].nil? _p[:x] = self.x if _p[:x].nil? _p[:y] = self.y if _p[:y].nil? end if _p[:x] _p[:x_d] = _p[:x] - _p[:x_init] _p[:update].push(:x) if _p[:x_d] != 0 end if _p[:y] _p[:y_d] = _p[:y] - _p[:y_init] _p[:update].push(:y) if _p[:y_d] != 0 end end #-------------------------------------------------------------------------- # ● 应用对话框xywh的参数Hash的预修改 #-------------------------------------------------------------------------- def eagle_apply_params_xywh(_p = {}) if _p[:x_d] # 如果设置了移动,则覆盖移动增量来进行对话框的移动 @eagle_move_x = - _p[:x_d] end if _p[:y_d] @eagle_move_y = - _p[:y_d] end if _p[:ins] # 处理立即完成宽高的更新 @eagle_move_x = 0 @eagle_move_y = 0 self.width = _p[:w] self.height = _p[:h] _p[:update].clear end end #-------------------------------------------------------------------------- # ● 更新对话框宽高直至完成 #-------------------------------------------------------------------------- def wait_until_des_wh(_p = {}) return eagle_after_wh_change if _p[:update].empty? max_w = [_p[:w], _p[:w_init]].max max_h = [_p[:h], _p[:h_init]].max _i = 0; _t = _p[:t] _t = 0 if _t < 0 while(true) break if self.openness == 0 break if _i > _t per = _i * 1.0 / _t if _i == _t per = 1 else f = :msg_xywh f = :msg_open if _p[:open] f = :msg_close if _p[:close] f = _p[:ease_type] if _p[:ease_type] per = MESSAGE_EX.ease_value(f, per) end _p[:update].each do |sym| case sym when :x _x = _p[:x_init] + _p[:x_d] * per @eagle_move_x = (_x - _p[:x]).round when :y _y = _p[:y_init] + _p[:y_d] * per @eagle_move_y = (_y - _p[:y]).round when :w self.width = (_p[:w_init] + _p[:w_d] * per).round when :h self.height = (_p[:h_init] + _p[:h_d] * per).round end end eagle_after_wh_change update_back_sprite_zoom(max_w, max_h) Fiber.yield _i += 1 end end #-------------------------------------------------------------------------- # ● 在宽度高度变化后的处理 # 此时 self.width 与 self.height 为实时的宽高,非最终完成时的宽高 #-------------------------------------------------------------------------- def eagle_after_wh_change eagle_win_update # 先更新对话框位置 eagle_recreate_back_bitmap(self.width, self.height) # 再生成新背景位图 end #-------------------------------------------------------------------------- # ● 对话框进行位置大小更新后的处理 #-------------------------------------------------------------------------- def eagle_after_set_xywh(_p) @eagle_last_x = self.x # 存储对话框的新位置,之后将作为移动前的初始值 @eagle_last_y = self.y end #-------------------------------------------------------------------------- # ● 获取窗口的初始宽度高度 #-------------------------------------------------------------------------- def window_width; Graphics.width; end def window_height; fitting_height(4); end #-------------------------------------------------------------------------- # ● 获取窗口的实际宽度高度 #-------------------------------------------------------------------------- def eagle_window_width w = eagle_window_charas_width if w w = [w, eagle_name_width].max # 确保姓名框的嵌入 w += eagle_face_width # 确保脸图有地方显示 w += standard_padding * 2 # 增加边框 return w end return window_width end def eagle_window_height h = eagle_window_charas_height if h h += eagle_name_height # 确保姓名框的嵌入 h = [h, eagle_face_height].max if eagle_face_in_window? # 确保脸图完整显示 h += standard_padding * 2 # 增加边框 return h end return window_height end #-------------------------------------------------------------------------- # ● 获取窗口的文字的宽度高度 #-------------------------------------------------------------------------- def eagle_window_charas_width return pop_params[:w] if game_message.pop? && pop_params[:w] > 0 return win_params[:w] if win_params[:w] > 0 w = nil w = @eagle_charas_w if eagle_dynamic_w? w = @eagle_charas_w_final if eagle_dyn_fit_w? if w w = win_params[:wmin] if win_params[:wmin] > 0 && w < win_params[:wmin] w = win_params[:wmax] if win_params[:wmax] > 0 && w > win_params[:wmax] end return w end def eagle_window_charas_height if game_message.pop? && pop_params[:h] > 0 return eagle_check_param_h(pop_params[:h]) end return eagle_check_param_h(win_params[:h]) if win_params[:h] > 0 h = nil h = [@eagle_charas_h, line_height].max if eagle_dynamic_h? h = @eagle_charas_h_final if eagle_dyn_fit_h? if h h = win_params[:hmin] if win_params[:hmin] > 0 && h < win_params[:hmin] h = win_params[:hmax] if win_params[:hmax] > 0 && h > win_params[:hmax] end return h end #-------------------------------------------------------------------------- # ● 检查内容高度参数 # 如果h小于行高,则判定其为行数 #-------------------------------------------------------------------------- def eagle_check_param_h(h) return 0 if h <= 0 h = line_height * h + win_params[:ld] * (h - 1) if h < line_height return h end #-------------------------------------------------------------------------- # ● 直接指定宽度高度? #-------------------------------------------------------------------------- def eagle_fix_w? return pop_params[:w] > 0 if game_message.pop? return win_params[:w] > 0 end def eagle_fix_h? return pop_params[:h] > 0 if game_message.pop? return win_params[:h] > 0 end #-------------------------------------------------------------------------- # ● 动态调整宽度高度? #-------------------------------------------------------------------------- def eagle_dynamic_w? game_message.pop? ? pop_params[:dw] : win_params[:dw] end def eagle_dynamic_h? game_message.pop? ? pop_params[:dh] : win_params[:dh] end #-------------------------------------------------------------------------- # ● 预计算完整文字区域的宽度高度? #-------------------------------------------------------------------------- def eagle_dyn_fit_w? game_message.pop? ? pop_params[:fw] : win_params[:fw] end def eagle_dyn_fit_h? game_message.pop? ? pop_params[:fh] : win_params[:fh] end #-------------------------------------------------------------------------- # ● 可由子窗口增加对话框的宽度高度? #-------------------------------------------------------------------------- def eagle_add_w_by_child_window? return false if eagle_fix_w? return true if eagle_dynamic_w? || eagle_dyn_fit_w? return false end def eagle_add_h_by_child_window? return false if eagle_fix_h? return true if eagle_dynamic_h? || eagle_dyn_fit_h? return false end #-------------------------------------------------------------------------- # ● 额外增加的窗口宽度高度 #-------------------------------------------------------------------------- def eagle_window_width_add(cur_width) eagle_window_w_empty + game_message.child_window_w_des end def eagle_window_height_add(cur_height) eagle_window_h_empty + game_message.child_window_h_des end #-------------------------------------------------------------------------- # ● 窗口内容中,无法被用于文本绘制的宽高 #-------------------------------------------------------------------------- def eagle_window_w_empty win_params[:cdx] + @eagle_sprite_pause_width_add + win_params[:cdw] end def eagle_window_h_empty win_params[:cdy] + win_params[:cdh] end #-------------------------------------------------------------------------- # ● 更新win参数组(初始化/一页绘制完成时调用) #-------------------------------------------------------------------------- def eagle_win_update return eagle_pop_update if game_message.pop? && @eagle_pop_obj eagle_change_windowskin self.x = win_params[:x] || default_init_x self.y = win_params[:y] || default_init_y MESSAGE_EX.reset_xy_dorigin(self, nil, win_params[:do]) if win_params[:do] < 0 MESSAGE_EX.reset_xy_origin(self, win_params[:o]) eagle_set_xy_ex self.x = self.x + win_params[:dx] + @eagle_move_x + @eagle_offset_x self.y = self.y + win_params[:dy] + @eagle_move_y + @eagle_offset_y eagle_fix_position if win_params[:fix] eagle_after_update_xy end #-------------------------------------------------------------------------- # ● 获取对话框的初始位置 #-------------------------------------------------------------------------- def default_init_x; 0; end def default_init_y; (@position*(Graphics.height-@eagle_win_des_h)/2); end #-------------------------------------------------------------------------- # ● 重定义对话框的位置(此时已经处理完了xy或do的初始指定位置)(扩展用) #-------------------------------------------------------------------------- def eagle_set_xy_ex end #-------------------------------------------------------------------------- # ● 修正位置(确保对话框完整显示) #-------------------------------------------------------------------------- def eagle_fix_position return if @flag_no_fix self.x = [[self.x, 0].max, Graphics.width - self.width].min self.y = [[self.y, 0].max, Graphics.height - self.height].min end #-------------------------------------------------------------------------- # ● 更新xy后的操作 #-------------------------------------------------------------------------- def eagle_after_update_xy eagle_set_charas_viewport eagle_name_update if game_message.name? if game_message.pop? && pop_params[:with_tag] eagle_pop_tag_fix_position # 可能修改了对话框位置,检查下tag要不要显示 end end #-------------------------------------------------------------------------- # ● 设置文字显示区域的矩形(屏幕坐标) #-------------------------------------------------------------------------- def eagle_set_charas_viewport @eagle_chara_viewport.rect.set(eagle_charas_x0, eagle_charas_y0, eagle_charas_max_w + eagle_window_w_empty, eagle_charas_max_h + eagle_window_h_empty) end #-------------------------------------------------------------------------- # ● 更新pop参数组 #-------------------------------------------------------------------------- def eagle_pop_update eagle_change_windowskin(pop_params[:skin]) eagle_pop_init_xy o = pop_params[:o] # 设置对话框的显示原点 o ||= 10 - pop_params[:do] # 显示原点恰好与绑定对象的位置相反 MESSAGE_EX.reset_xy_origin(self, o) # 将对话框移动到绑定对象的对应方向上,并加上偏移量 case pop_params[:do] when 1,4,7; self.x -= (pop_params[:chara_w] / 2 + pop_params[:d]) when 3,6,9; self.x += (pop_params[:chara_w] / 2 + pop_params[:d]) end case pop_params[:do] when 1,2,3; self.y += (pop_params[:d]) when 4,5,6; self.y -= (pop_params[:chara_h] / 2) when 7,8,9; self.y -= (pop_params[:chara_h] + pop_params[:d]) end self.x += @eagle_move_x + @eagle_offset_x self.y += @eagle_move_y + @eagle_offset_y eagle_pop_tag_update # 更新pop的tag的位置 self.x += pop_params[:dx] # 坐标的补足偏移量 self.y += pop_params[:dy] eagle_fix_position if pop_params[:fix] eagle_after_update_xy end #-------------------------------------------------------------------------- # ● 更新pop的初始位置 #-------------------------------------------------------------------------- def eagle_pop_init_xy # 对话框左上角定位到绑定对象位图的对应o位置 case pop_params[:type] when :map_chara # 如果对象使用的是行走图,则为Game_Chacter(行走图底部中心为显示原点) self.x = @eagle_pop_obj.screen_x self.y = @eagle_pop_obj.screen_y when :battle_sprite # 如果对象为战斗者精灵,则为Sprite_Battler(底部中心为显示原点) self.x = @eagle_pop_obj.x self.y = @eagle_pop_obj.y when :map_grid # 如果为地图格子,则格子底部中心为显示原点 self.x = $game_map.adjust_x(@eagle_pop_obj[0]) * 32 + 16 self.y = $game_map.adjust_y(@eagle_pop_obj[1]) * 32 + 32 end end #-------------------------------------------------------------------------- # ● 更新pop的tag #-------------------------------------------------------------------------- def eagle_pop_tag_update return if !pop_params[:with_tag] i = 10 - pop_params[:do] # tag的显示帧恰好与pop对话框的do值相对 # tag的显示原点,是pop对话框的do,即目标物体的九宫格位置 o = pop_params[:do] # 但注意,需要调整到 2468 的位置 o = 2 if o == 1 || o == 3 o = 8 if o == 7 || o == 9 _do = pop_params[:o] # 对话框的显示原点是tag的显示位置 _do ||= 10 - pop_params[:do] MESSAGE_EX.set_windowtag(self, @eagle_sprite_pop_tag, i, o, _do) case i # 坐标距离事件格子中心的偏移量 when 1,4,7; @eagle_sprite_pop_tag.x -= pop_params[:td] when 3,6,9; @eagle_sprite_pop_tag.x += pop_params[:td] end case i when 1,2,3; @eagle_sprite_pop_tag.y -= pop_params[:td] when 7,8,9; @eagle_sprite_pop_tag.y += pop_params[:td] end end #-------------------------------------------------------------------------- # ● 修正pop的tag的位置 #-------------------------------------------------------------------------- def eagle_pop_tag_fix_position # 若tag因为对话框的fix position而位于对话框内,则隐藏 s = @eagle_sprite_pop_tag return if !pop_params[:with_tag] s.visible = true d = pop_params[:td] rect1 = Rect.new(s.x+d, s.y+d, s.width-2*d, s.height-2*d) rect2 = Rect.new(self.x, self.y, self.width, self.height) if MESSAGE_EX.rect_collide_rect?(rect1, rect2) s.visible = false end end #-------------------------------------------------------------------------- # ● 更新name参数组(随win/pop参数组更新) #-------------------------------------------------------------------------- def eagle_name_update if name_params[:do] == 0 # 嵌入 # 考虑到姓名框自己也有边框,此处 standard_padding 一加一减抵消了 @eagle_window_name.x = self.x + \ @eagle_window_name.rect_real.x + eagle_face_left_width @eagle_window_name.y = self.y + \ @eagle_window_name.rect_real.y else MESSAGE_EX.reset_xy_dorigin(@eagle_window_name, self, name_params[:do]) MESSAGE_EX.reset_xy_origin(@eagle_window_name, name_params[:o]) # 若姓名框遮挡了脸图,则移动到不遮挡的地方 if game_message.no_name_overlap_face && eagle_face_width > 0 lx = self.x + eagle_face_left_width rx = self.x + self.width - eagle_face_right_width w = @eagle_window_name.width @eagle_window_name.x = lx if @eagle_window_name.x < lx @eagle_window_name.x = rx-w if @eagle_window_name.x+w > rx end end @eagle_window_name.x += name_params[:dx] # 坐标的补足偏移量 @eagle_window_name.y += name_params[:dy] @eagle_window_name.update_with_msg end #-------------------------------------------------------------------------- # ● 变更窗口皮肤 #-------------------------------------------------------------------------- def eagle_change_windowskin(index = nil) index = win_params[:skin] if index.nil? eagle_set_pop_tag_by_windowskin(index) return if @win_skin_draw == index @win_skin_draw = index self.windowskin = MESSAGE_EX.windowskin(index) change_color(text_color(font_params[:c])) end #-------------------------------------------------------------------------- # ● 获取当前窗口皮肤的序号 #-------------------------------------------------------------------------- def get_cur_windowskin_index(index = nil) return index if index return pop_params[:skin] if game_message.pop? && !pop_params[:skin].nil? return win_params[:skin] end #-------------------------------------------------------------------------- # ● 依据窗口皮肤设置tag序号 #-------------------------------------------------------------------------- def eagle_set_pop_tag_by_windowskin(index = nil) tag_id = MESSAGE_EX::WINDOWSKIN_TO_WINDOWTAG[index] return if tag_id.nil? eagle_reset_pop_tag_bitmap(tag_id) end #-------------------------------------------------------------------------- # ● 重新生成背景位图 #-------------------------------------------------------------------------- def eagle_recreate_back_bitmap(w = self.width, h = self.height) case @background when 1 # 暗色背景 if @back_bitmap && @back_bitmap.width == w && @back_bitmap.height == h else # 重绘 @back_bitmap.dispose if @back_bitmap @back_bitmap = Bitmap.new(w, h) rect1 = Rect.new(0, 0, w, 12) rect2 = Rect.new(0, 12, w, h - 24) rect3 = Rect.new(0, h - 12, w, 12) @back_bitmap.gradient_fill_rect(rect1, back_color2, back_color1, true) @back_bitmap.fill_rect(rect2, back_color1) @back_bitmap.gradient_fill_rect(rect3, back_color1, back_color2, true) end @back_sprite.bitmap = @back_bitmap update_back_sprite @back_sprite.visible = true @back_sprite.opacity = 255 self.opacity = 0 when 2 # 透明背景 @back_sprite.visible = false @back_sprite.opacity = 255 # 依靠该值来进行关闭-淡出 self.opacity = 0 else # 普通 return if win_params[:bg] && eagle_draw_bg_pic(w, h) @back_sprite.visible = false self.opacity = 255 end end #-------------------------------------------------------------------------- # ● 获取暗色背景的背景色 #-------------------------------------------------------------------------- def back_color1; Color.new(0, 0, 0, 160); end def back_color2; Color.new(0, 0, 0, 0); end #-------------------------------------------------------------------------- # ● 绘制背景图片 #-------------------------------------------------------------------------- def eagle_draw_bg_pic(w, h) @back_sprite.visible = true self.opacity = 0 _bitmap = MESSAGE_EX.windowbg(win_params[:bg], w, h) if _bitmap != nil @back_sprite.bitmap = _bitmap return true end return false end #-------------------------------------------------------------------------- # ● 更新背景精灵 #-------------------------------------------------------------------------- def update_back_sprite _o = win_params[:bgo] _o = win_params[:o] if @background == 1 # 暗色背景下,与对话框的原点一致 MESSAGE_EX.reset_xy_dorigin(@back_sprite, self, _o) MESSAGE_EX.reset_sprite_oxy(@back_sprite, _o) @back_sprite.update end #-------------------------------------------------------------------------- # ● 更新背景精灵的缩放 #-------------------------------------------------------------------------- def update_back_sprite_zoom(max_w = nil, max_h = nil) if @background != 0 # 正常背景下,使用了图片背景,才进行缩放 @back_sprite.zoom_x = @back_sprite.zoom_y = 1 return end if max_w == nil @back_sprite.zoom_x = 1 else @back_sprite.zoom_x = self.width * 1.0 / max_w end if max_h == nil @back_sprite.zoom_y = 1 else @back_sprite.zoom_y = self.height * 1.0 / max_h end end #-------------------------------------------------------------------------- # ● 更新背景精灵的不透明度 #-------------------------------------------------------------------------- def update_back_sprite_opa(opa); @back_sprite.opacity = opa; end #-------------------------------------------------------------------------- # ● 处理纤程的主逻辑 #-------------------------------------------------------------------------- def fiber_main game_message.visible = true eagle_process_before_start loop do eagle_process_before_draw process_all_text process_input eagle_process_before_close Fiber.yield break unless text_continue? eagle_process_after_check_continue end close_and_wait if !@flag_next game_message.visible = false @fiber = nil end #-------------------------------------------------------------------------- # ● 首次开启对话框时的处理 #-------------------------------------------------------------------------- def eagle_process_before_start @background = game_message.background @position = game_message.position end #-------------------------------------------------------------------------- # ● 绘制全部文本前 #-------------------------------------------------------------------------- def eagle_process_before_draw @flag_temp_env = game_message.env # 保存处理文本前的环境名(用于temp) game_message.save_env(:eagle_temp) # 保存处理文本前的环境(用于temp) game_message.active = true # 对话框开始处理文字,该flag置为true用于判定 end #-------------------------------------------------------------------------- # ● 关闭前 #-------------------------------------------------------------------------- def eagle_process_before_close game_message.clear @gold_window.close if @gold_window game_message.active = false # 对话框不再显示了,将该flag置为false end #-------------------------------------------------------------------------- # ● 判定文字是否继续显示(覆盖) #-------------------------------------------------------------------------- def text_continue? return false if @flag_need_close return game_message.has_text? && !settings_changed? end #-------------------------------------------------------------------------- # ● 判定对话框设置是否被更改(覆盖) # 此时 $game_message 中存储了下一条指令的对话信息 # 若返回 false,则会保留当前对话框不关闭,继续显示下一个指令的文本 #-------------------------------------------------------------------------- def settings_changed? # 因为有动态移动,不再关注位置的改变 @background != game_message.background #|| @position != game_message.position end #-------------------------------------------------------------------------- # ● 当前对话框继续显示,一些变量重置的处理 #-------------------------------------------------------------------------- def eagle_process_after_check_continue if @flag_hold # 保留当前对话框时 # 如果想要对话框从当前位置继续移动,则需要该处理,否则是在新位置打开新的 #self.openness = 255 #@flag_need_open = false end eagle_message_reset_continue @flag_need_change_wh = true # 由于没有打开关闭,需要执行一次更新宽高 end #-------------------------------------------------------------------------- # ● 获取即将绘制的所有文本内容 #-------------------------------------------------------------------------- def eagle_all_text text = game_message.all_text if !game_message.escape_strings.empty? # 如果存在待处理的转义符串,加到开头 text = game_message.escape_strings.inject("") { |sum, s| sum = sum + s } + text game_message.escape_strings.clear end text = convert_escape_characters(text) text end #-------------------------------------------------------------------------- # ● 进行控制符的事前变换 # 在实际绘制前、将控制符替换为实际的内容。 # 为了减少歧异,文字「\」会被首先替换为转义符(\e)。 #-------------------------------------------------------------------------- def convert_escape_characters(text) result = text.to_s.clone result = eagle_process_conv(result) result = eagle_process_rb(result) result = super(result) # 此处将 \\ 替换成了 \e result = eagle_process_extra(result) result end #-------------------------------------------------------------------------- # ● 替换转义符(此时依旧是 \\ 开头的转义符) #-------------------------------------------------------------------------- def eagle_process_conv(text) text.gsub!(/\\(conv|M)\[(.*?)\]/i) { MESSAGE_EX.get_conv($2) } text end #-------------------------------------------------------------------------- # ● 处理脚本转义符(此时依旧是 \\ 开头的转义符) #-------------------------------------------------------------------------- def eagle_process_rb(text) s = $game_switches; v = $game_variables event = $game_map.events[game_message.event_id] rescue nil text.gsub!(/\\RB\{(.*?)\}/i) { eval($1).to_s } text end #-------------------------------------------------------------------------- # ● 处理其它转义符(此时是 \e 开头的转义符) #-------------------------------------------------------------------------- def eagle_process_extra(text) text.gsub!(/\eINFO\[(\w)[ ,]*(\d+)[ ,]*(\d+)?\]/i) { MESSAGE_EX.get_data_info($1, $2.to_i, $3 || '0') } text.gsub!(/\eNL/i) { "\n" } # 换行转义符 text end #-------------------------------------------------------------------------- # ● (覆盖)处理所有文本内容 #-------------------------------------------------------------------------- def process_all_text return if !game_message.has_text? text = eagle_all_text; pos = {} new_page(text, pos) if func_params[:para] && !input_pause? @fiber_para = Fiber.new { process_all_text_para(text, pos); @fiber_para = nil } return end process_all_text_para(text, pos) end #-------------------------------------------------------------------------- # ● 处理所有文本内容(并行用) #-------------------------------------------------------------------------- def process_all_text_para(text, pos) if @flag_need_open # 打开窗口 open_and_wait elsif @flag_need_change_wh # 如果需要更新宽高 eagle_set_wh @flag_need_change_wh = false end loop do # 循环绘制每个文字 break if text.empty? process_character(text.slice!(0, 1), text, pos) break @pause_skip = true if @eagle_force_close end eagle_process_draw_update if !@eagle_chara_sprites.empty? end #-------------------------------------------------------------------------- # ● 强制中断绘制全部文本 #-------------------------------------------------------------------------- def force_close @eagle_force_close = true # 若还在绘制,则直接结束绘制并跳过最后的等待按键 @eagle_auto_continue_c = 0 # 若进入了按键等待,则将计数置0,并依靠auto跳过按键 end #-------------------------------------------------------------------------- # ● 翻页处理(删去了翻页功能) #-------------------------------------------------------------------------- def new_page(text, pos) game_message.reset_child_window_wh_add # 重置子窗口嵌入时占据的宽高 @eagle_force_close = false # 重置强制关闭 pos[:x] = 0; pos[:y] = 0 # 重置pos参数 pos[:new_x] = 0; pos[:height] = line_height if @flag_next # 旧页面不清空,继续绘制 pos[:y] = @eagle_charas_h_final + win_params[:ld] # 不要忘记加个行间距 @flag_need_change_wh = true # 如果是旧页面继续绘制,则需要更新宽高 eagle_after_set_xywh({}) # 重置记录的当前xy,作为窗口移动的初始位置 end reset_font_settings eagle_check_pre_settings(text) # 处理预先内容(脸图、姓名等) # 存储实际绘制的文本,预先转义符已删去(扩展用,获取显示的对话文本) game_message.eagle_text = text.clone eagle_apply_params_changes # 执行预定的转义符修改 clear_flags pre_calc_charas_wh(text, pos) # 预绘制,计算最终宽高 clear_flags # 重置绘制会用到的变量 # 打开窗口前执行位于文本开头的转义符,确保pop等修改对话框位置 loop do break if text[0] == nil or text[0] != "\e" text[0] = '' process_escape_character(obtain_escape_code(text), text, pos) end end #-------------------------------------------------------------------------- # ● 清除标志(此处放置每次绘制前需要清空的数据) #-------------------------------------------------------------------------- def clear_flags @show_fast = false # 快进的标志 @line_show_fast = false # 行单位快进的标志 @pause_skip = false # “不等待输入”的标志 pop_params[:type] = nil # pop绑定对象的类型 end #-------------------------------------------------------------------------- # ● 应用预定的转义符更新 #-------------------------------------------------------------------------- def eagle_apply_params_changes game_message.params_need_apply.each do |sym| m_c = ("eagle_text_control_#{sym}").to_sym method(m_c).call("") if respond_to?(m_c) end game_message.clear_applys end #-------------------------------------------------------------------------- # ● 预先绘制一次,获取文字区域绘制完成时的宽高 #-------------------------------------------------------------------------- def pre_calc_charas_wh(text, pos) text_ = text.clone; pos_ = pos.clone @flag_draw = false # 不进行实际绘制 game_message.save_env(:pre_draw) # 保存预绘制前的环境 last_c_w = @eagle_charas_w # 保存预绘制前的文字区域宽高 last_c_h = @eagle_charas_h @eagle_charas_w = @eagle_charas_h = 0 process_character(text_.slice!(0, 1), text_, pos_) until text_.empty? @eagle_charas_w_final = [@eagle_charas_w, last_c_w].max # 文字绘制后的宽高 @eagle_charas_h_final = @eagle_charas_h before_input_pause unless @pause_skip # 此处追加对pause精灵占用宽度的处理 @eagle_charas_w = last_c_w @eagle_charas_h = last_c_h # 复原当前文字区域宽高 self.ox = self.oy = 0 game_message.load_env(:pre_draw) # 复原转义符环境 game_message.clear_applys MESSAGE_EX.apply_font_params(self.contents.font, font_params) # 重置字体设置 @flag_draw = true end #-------------------------------------------------------------------------- # ● 文字显示区域的左上角位置(屏幕坐标系) #-------------------------------------------------------------------------- def eagle_charas_x0 self.x + standard_padding + eagle_face_left_width + win_params[:cdx] end def eagle_charas_y0 self.y + standard_padding + eagle_name_height + win_params[:cdy] end #-------------------------------------------------------------------------- # ● 计算文字显示区域的宽度和高度 #-------------------------------------------------------------------------- def eagle_charas_max_w self.width - standard_padding*2 - eagle_face_width - eagle_window_w_empty end def eagle_charas_max_h self.height - standard_padding*2 - eagle_name_height - eagle_window_h_empty end #-------------------------------------------------------------------------- # ● 文字显示区域的显示原点 #-------------------------------------------------------------------------- def eagle_charas_ox; self.ox; end def eagle_charas_oy; self.oy; end #-------------------------------------------------------------------------- # ● 更新正在移入移出文字的显示区域的显示原点 #-------------------------------------------------------------------------- def update_moving_charas_oxy @eagle_chara_sprites.each { |c| c.reset_window_oxy(self.ox, self.oy) if c.move_updating? } end #-------------------------------------------------------------------------- # ● 重置文字显示区域 #-------------------------------------------------------------------------- def eagle_reset_charas_oxy # 重置初始区域 self.ox = self.oy = 0 # 重置显示区域 @eagle_chara_viewport.rect.set(0,0,Graphics.width,Graphics.height) # 重置文字宽高 @eagle_charas_w = @eagle_charas_h = 0 @eagle_charas_w_final = @eagle_charas_h_final = 0 end #-------------------------------------------------------------------------- # ● 重新生成适合全部文字的位图 #-------------------------------------------------------------------------- def recreate_contents_for_charas w = @eagle_charas_w + eagle_window_w_empty h = @eagle_charas_h + eagle_window_h_empty w = 1 if w == 0 h = 1 if h == 0 f = self.contents.font.dup self.contents.dispose if self.contents self.contents = Bitmap.new(w, h) self.contents.font = f end #-------------------------------------------------------------------------- # ● (覆盖)普通文字的处理 #-------------------------------------------------------------------------- def process_normal_character(c, pos) c_rect = text_size(c); c_w = c_rect.width; c_h = c_rect.height eagle_auto_new_line(c_w, pos) if @flag_draw s = eagle_new_chara_sprite(pos[:x], pos[:y], c_w, c_h) s.eagle_font.draw(s.bitmap, 0, 0, c_w, c_h, c, 0) end eagle_process_draw_end(c_w, c_h, pos) end #-------------------------------------------------------------------------- # ● (覆盖)处理控制符指定的图标绘制 #-------------------------------------------------------------------------- def process_draw_icon(icon_index, pos) eagle_auto_new_line(24, pos) if @flag_draw s = eagle_new_chara_sprite(pos[:x], pos[:y], 24, 24) s.eagle_font.draw_icon(s.bitmap, 0, 0, icon_index) end eagle_process_draw_end(24, 24, pos) end #-------------------------------------------------------------------------- # ● 处理控制符指定的图片绘制 #-------------------------------------------------------------------------- def process_draw_pic(text, pos) param = text.slice!(/^\[.*?\]/)[1..-2] params = param.split('|') # [filename, param_str] begin _bitmap = Cache.picture(MESSAGE_EX.get_pic_file(params[0])) rescue p "【对话框扩展】未找到\\pic所需的Graphics/Pictures/#{params[0]}图片!" return end h = {} parse_param(h, params[1], :opa) if params[1] h[:w] ||= _bitmap.width h[:h] ||= _bitmap.height h[:opa] ||= 255 eagle_auto_new_line(h[:w], pos) if @flag_draw s = eagle_new_chara_sprite(pos[:x], pos[:y], h[:w], h[:h]) s.eagle_font.draw_pic(s.bitmap, _bitmap, h) end eagle_process_draw_end(h[:w], h[:h], pos) end #-------------------------------------------------------------------------- # ● (封装)生成一个新的文字精灵 #-------------------------------------------------------------------------- def eagle_new_chara_sprite(c_x, c_y, c_w, c_h) f = Font_EagleCharacter.new(font_params) f.set_param(:skin, win_params[:skin]) f.set_param(:ex_cg, ex_params[:cg]) s = MESSAGE_EX.charapool_new(self, f, c_x, c_y, c_w, c_h, @eagle_chara_viewport) s.start_effects(game_message.chara_params) @eagle_chara_sprites.push(s) # 存入实时更新的文字数组 @eagle_chara_sets[@eagle_current_set].push(s) if @eagle_current_set # 分组 s end #-------------------------------------------------------------------------- # ● 检查自动换行 #-------------------------------------------------------------------------- def eagle_auto_new_line(c_w, pos) return if func_params[:aw] == false return if @flag_draw == false return if !eagle_fix_w? && eagle_dynamic_w? max_w = eagle_charas_max_w return if max_w <= 0 return if pos[:x] + c_w <= max_w # 若当前文字绘制完成后会超出边界,则换行 process_new_line('', pos) end #-------------------------------------------------------------------------- # ● 绘制完成时的处理 #-------------------------------------------------------------------------- def eagle_process_draw_end(c_w, c_h, pos) # 处理下一次绘制的参数 pos[:x] += (c_w + game_message.win_params[:ck]) pos[:height] = [pos[:height], c_h].max # 记录下一个文字绘制位置x @eagle_next_chara_x = pos[:x] # 处理文字区域大小更改 @eagle_charas_w = pos[:x] if @eagle_charas_w < pos[:x] @eagle_charas_h = pos[:y] + pos[:height] if @eagle_charas_h < pos[:y] + pos[:height] return if !@flag_draw return if show_fast? # 如果是立即显示,则不更新 eagle_process_draw_update wait_for_one_character end #-------------------------------------------------------------------------- # ● 绘制完成时的更新 #-------------------------------------------------------------------------- def eagle_process_draw_update # 重设对话框宽高,并更新对话框位置 eagle_set_wh({:ins => true}) # 对齐需要用到对话框的宽高,因此在更新xywh后执行 eagle_charas_reset_alignment(win_params[:ali]) # 确保最后绘制的文字在视图区域内 ensure_character_visible(@eagle_chara_sprites[-1]) end #-------------------------------------------------------------------------- # ● 重排列全部文字精灵 #-------------------------------------------------------------------------- def eagle_charas_reset_alignment(align) return if @eagle_chara_sprites.empty? charas = [] # 存储当前迭代行的全部文字精灵 # 存储当前迭代行的y值(同y的为同一行)(未考虑列排文字) charas_y = @eagle_chara_sprites[0].origin_y # 初始为第一行 # 最大宽度 = [可供文字绘制区域的最大宽度, 文字占据宽度].max max_w = [eagle_charas_max_w, @eagle_charas_w].max @eagle_chara_sprites.each do |s| next charas.push(s) if s.origin_y == charas_y # 第一行的首字符会存入 # 对同一行的字符重排 eagle_charas_realign_line(charas, align, max_w) charas.clear # 将当前迭代的 下一行的首字符 存入 charas.push(s) charas_y = s.origin_y end # 对最后一行进行重排列 eagle_charas_realign_line(charas, align, max_w) if !charas.empty? end #-------------------------------------------------------------------------- # ● 重排列同一行上的文字精灵 #-------------------------------------------------------------------------- def eagle_charas_realign_line(charas, align, max_w) w_line = charas[-1].origin_x - charas[0].origin_x + charas[-1].width h_line = charas.collect{ |c| c.height }.max charas.each do |c| case align when 0 # 左对齐(默认对齐方式) _x = c.origin_x when 1 # 居中排列 _x = c.origin_x + (max_w - w_line) / 2 when 2 # 右排列 _x = c.origin_x + max_w - w_line end _y = c.origin_y + h_line - c.height # 底部对齐 c.reset_xy(_x, _y) end end #-------------------------------------------------------------------------- # ● 确保指定文字在视图内 #-------------------------------------------------------------------------- def ensure_character_visible(c, no_anim = false) return if c.nil? ox_1 = self.ox ox_d = 0 ox_d = c._x - self.ox if c._x < self.ox d = c._x + c.width - @eagle_chara_viewport.rect.width - self.ox ox_d = d if d > 0 oy_1 = self.oy oy_d = 0 oy_d = c._y - self.oy if c._y < self.oy d = c._y + c.height - @eagle_chara_viewport.rect.height - self.oy oy_d = d if d > 0 if !no_anim && @flag_draw && !@flag_open_close && (ox_d != 0 || oy_d != 0) # 因为是在新行的首字符绘制完成后调用该方法,因此先把这个字符隐藏了 c.visible = false t = MESSAGE_EX::CHARAS_SCROLL_OUT_FRAME (t+1).times do |i| per = i * 1.0 / t per = MESSAGE_EX.ease_value(:msg_vp, per) self.ox = (ox_1 + ox_d * per).round if ox_d != 0 self.oy = (oy_1 + oy_d * per).round if oy_d != 0 update_moving_charas_oxy Fiber.yield end c.visible = true end self.ox = ox_1 + ox_d self.oy = oy_1 + oy_d update_moving_charas_oxy # 保证文字跟着contents一起移动 end #-------------------------------------------------------------------------- # ● 处于快进显示? #-------------------------------------------------------------------------- def show_fast? @flag_instant || @show_fast || @line_show_fast end #-------------------------------------------------------------------------- # ● 输出一个字符后的等待 #-------------------------------------------------------------------------- def wait_for_one_character MESSAGE_EX.se(game_message.win_params[:se]) win_params[:cwi].times do return if show_fast? update_show_fast if win_params[:cfast] Fiber.yield end end #-------------------------------------------------------------------------- # ● 监听“确定”键的按下,更新快进的标志 #-------------------------------------------------------------------------- def update_show_fast @show_fast = true if Input.trigger?(:C) end #-------------------------------------------------------------------------- # ● 换行文字的处理(删去翻页) # 由于自动对齐的存在,无需预先计算当前行高,text参数无效 #-------------------------------------------------------------------------- def process_new_line(text, pos) pos[:height] += win_params[:ld] # 当前行增加一个行间距 @line_show_fast = false pos[:x] = pos[:new_x] pos[:y] += pos[:height] pos[:height] = line_height end #-------------------------------------------------------------------------- # ● 设置【预先】指令的参数 #-------------------------------------------------------------------------- def eagle_check_pre_settings(text) eagle_check_temp(text) eagle_check_env(text) eagle_check_hold(text) eagle_check_instant(text) eagle_check_close(text) eagle_check_next(text) eagle_check_eval(text) eagle_draw_face(text) eagle_draw_name(text) eagle_check_func(text) end #-------------------------------------------------------------------------- # ● 设置/执行temp指令 #-------------------------------------------------------------------------- def eagle_check_temp(text) text.gsub!(/\e(temp)/i) { "" } @flag_temp = true if $1 end def eagle_process_temp return if @flag_temp == false @flag_temp = false game_message.load_temp_env(@flag_temp_env, :eagle_temp) game_message.load_env(@flag_temp_env) game_message.env = @flag_temp_env end #-------------------------------------------------------------------------- # ● 设置env指令 #-------------------------------------------------------------------------- def eagle_check_env(text) text.gsub!(/\eenv\[(.*?)\]/m) { t = $1; sym = t t.include?('|') ? sym = t.slice!(/.*?\|/).chop : t = "load" eagle_check_env_method(sym, t) "" } end def eagle_check_env_method(sym, m = "load") case m when "save" @flag_save_env = sym when "load" game_message.env = sym game_message.save_env(sym) if !game_message.load_env(sym) else p "对话框的 env 转义符参数错误!环境 #{sym} 与未定义的 #{m} 动作。" end end def eagle_process_env return if @flag_save_env == nil game_message.save_env(@flag_save_env) game_message.env = @flag_save_env @flag_save_env = nil end def eagle_reset_env # 在 close 方法中调用 v = MESSAGE_EX::S_ID_RESET_ENV if v == true || (v.is_a?(Integer) && $game_switches[v] == true) game_message.env = '0' game_message.load_env('0') end end #-------------------------------------------------------------------------- # ● 设置/执行hold指令 #-------------------------------------------------------------------------- def eagle_check_hold(text) @flag_hold = false @flag_hold_str = "" text.gsub!(/\ehold(\[(.*?)\])/i) { @flag_hold = true @flag_hold_str = $1 ? $1.to_s : "" "" } # 移出已存在的具有该 flag_hold_id 的保留对话框 if @flag_hold_str != "" @eagle_dup_windows.each_with_index do |w, i| w.close_clone if w.flag_hold_id == @flag_hold_str end end end def eagle_process_hold if @flag_hold t = self.clone t.flag_hold_id = @flag_hold_str # 重置之前存储的窗口的z值(确保最近的显示在最上面) @eagle_dup_windows.each_with_index do |w, i| next if t.close_clone? w.z = t.z - (i+1) * 5; w.eagle_reset_z end @eagle_dup_windows.unshift(t) self.openness = 0 @flag_need_open = true else eagle_release_hold end end def eagle_release_hold # 所有暂存窗口关闭 @eagle_dup_windows.each { |w| w.close_clone } end #-------------------------------------------------------------------------- # ● 设置instant指令 #-------------------------------------------------------------------------- def eagle_check_instant(text) text.gsub!(/\e(ins)/i) { "" } @flag_instant = $1 ? true : false end #-------------------------------------------------------------------------- # ● 设置close指令 #-------------------------------------------------------------------------- def eagle_check_close(text) text.gsub!(/\e(close)/i) { "" } @flag_need_close = $1 ? true : false end #-------------------------------------------------------------------------- # ● 设置next指令 #-------------------------------------------------------------------------- def eagle_check_next(text) text.gsub!(/\e(next)/i) { "" } @flag_next = $1 ? true : false end #-------------------------------------------------------------------------- # ● 设置eval指令 #-------------------------------------------------------------------------- def eagle_check_eval(text) @eagle_evals.clear # 清除旧的 text.gsub!(/\eeval\{(.*?)\}/m) { @eagle_evals.push($1) # ID 从 1 开始,防止之后param传入nil出错 "\eeval[#{@eagle_evals.size}]" } text.gsub!(/\{\{(.*?)\}\}/m) { @eagle_evals.push($1) "\eeval[#{@eagle_evals.size}]" } end #-------------------------------------------------------------------------- # ● 分析【预先】转义符的全部参数(按出现顺序处理) #-------------------------------------------------------------------------- def parse_pre_params(text, sym, hash, default_type = :default) params = [] text.gsub!(/\e#{sym}\[(.*?)\]/i) { params.push($1); "" } params.push("") if params.empty? params.each { |param| parse_param(hash, param, default_type) } end #-------------------------------------------------------------------------- # ● 初始化脸图 #-------------------------------------------------------------------------- def eagle_draw_face(text) face_params[:ls] = -1 # 设置循环开始编号(递增至le,再从ls循环) face_params[:le] = -1 # 设置循环结束编号 parse_pre_params(text, 'facep', face_params, :dir) face_params[:dir] = MESSAGE_EX.check_bool(face_params[:dir]) face_params[:m] = MESSAGE_EX.check_bool(face_params[:m]) face_params[:name] = game_message.face_name face_params[:i] = game_message.face_index return eagle_move_out_face if face_params[:name] == "" if @eagle_sprite_face return if @eagle_sprite_face.no_change? eagle_move_out_face end @eagle_sprite_face = MESSAGE_EX.facepool_new @eagle_sprite_face.reset(self) @eagle_sprite_face.motion(:fade_in) end #-------------------------------------------------------------------------- # ● 初始化姓名框 #-------------------------------------------------------------------------- def name_params; game_message.name_params; end def eagle_draw_name(text) # 用 | 分隔需要绘制的name字符串(其中转义符用<>代替[])和参数组 str_name = "" text.gsub!(/\ename\[(.*?)\]/i) { t = $1.dup if t.include?('|') s = t.slice!(/.*?\|/).chop str_name = s if !s.empty? "\ename[#{t}]" else str_name = t "" end } parse_pre_params(text, 'name', name_params, :o) name_params[:name] = process_name_string(str_name) process_draw_name end def process_name_string(str) # 预处理姓名字符串 return "" if str == "" t = str # 特别的:如果str仅为数字,且为数据库中有效的角色ID,则将替换为其名称 v = str.to_i t = $game_actors[v].name if v > 0 and $game_actors[v] != nil # 读取统一的前置文本 t = MESSAGE_EX.get_name_prefix + t # 将转义符中的 <> 替换回 [] t.gsub!(/<(.*?)>/) { "[" + $1 + "]" } # 处理转义符 t = convert_escape_characters(t) return t end def process_draw_name @eagle_window_name.reset if @eagle_window_name end #-------------------------------------------------------------------------- # ● 姓名框占用的宽度 #-------------------------------------------------------------------------- def eagle_name_width return 0 if !game_message.name? return 0 if name_params[:do] != 0 # 不是嵌入,则不占用 return @eagle_window_name.contents.width + \ @eagle_window_name.rect_real.x + @eagle_window_name.rect_real.width + \ name_params[:dx] end #-------------------------------------------------------------------------- # ● 姓名框占用的高度 #-------------------------------------------------------------------------- def eagle_name_height return 0 if !game_message.name? return 0 if name_params[:do] != 0 # 不是嵌入,则不占用 return @eagle_window_name.contents.height + \ @eagle_window_name.rect_real.y + @eagle_window_name.rect_real.height + \ name_params[:dy] + standard_padding end #-------------------------------------------------------------------------- # ● 设置func参数 #-------------------------------------------------------------------------- def func_params; game_message.func_params; end def eagle_check_func(text) parse_pre_params(text, 'func', func_params) func_params[:aw] = MESSAGE_EX.check_bool(func_params[:aw]) func_params[:para] = MESSAGE_EX.check_bool(func_params[:para]) end #-------------------------------------------------------------------------- # ● 子窗口可以嵌入? #-------------------------------------------------------------------------- def child_window_embed_in? open? && func_params[:para] == false end #-------------------------------------------------------------------------- # ● 控制符的处理 # code : 控制符的实际形式(比如“\C[1]”是“C”) # text : 绘制处理中的字符串缓存(字符串可能会被修改) # pos : 绘制位置 {:x, :y, :new_x, :height} #-------------------------------------------------------------------------- def process_escape_character(code, text, pos) return if eagle_call_process_escape(code, text, pos) temp_code = code.downcase m_c = ("eagle_text_control_" + temp_code).to_sym m_e = ("eagle_chara_effect_" + temp_code).to_sym if respond_to?(m_c) param = obtain_escape_param_string(text) method(m_c).call(param) elsif respond_to?(m_e) param = obtain_escape_param_string(text) # 当只传入 0 时,代表关闭该特效 return eagle_chara_effect_clear(temp_code.to_sym) if param == '0' game_message.chara_params[temp_code.to_sym] = param method(m_e).call(param) else super(code, text, pos) end end #-------------------------------------------------------------------------- # ● 控制符的处理(方便扩展的编写方式) # code : 控制符的实际形式(比如“\C[1]”是“C”) # text : 绘制处理中的字符串缓存(字符串可能会被修改) # pos : 绘制位置 {:x, :y, :new_x, :height} # 返回 true 则代表转义符执行成功,否则继续匹配组件和默认转义符 #-------------------------------------------------------------------------- def eagle_call_process_escape(code, text, pos) c = code.upcase if c == '$' && @gold_window @gold_window.open? ? @gold_window.close : @gold_window.open return true end if c == '.' wait(15); return true end if c == '|' wait(60); return true end if c == '!' input_pause; return true end if c == '>' @line_show_fast = true; return true end if c == '<' @line_show_fast = false; return true end if c == '^' @pause_skip = true; return true end if c == 'C' font_params[:c] = obtain_escape_param_string(text) change_color(text_color(font_params[:c])) return true end if c == "PIC" process_draw_pic(text, pos) return true end if c == "CLC" process_pos_clc(text, pos) return true end return false end #-------------------------------------------------------------------------- # ● (覆盖)获取控制符的实际形式(这个方法会破坏原始数据) #-------------------------------------------------------------------------- def obtain_escape_code(text) text.slice!(/^[\$\.\|\^!><\{\}\\]|^[\d\w]+/i) end #-------------------------------------------------------------------------- # ● 获取控制符的参数(变量参数字符串形式)(这个方法会破坏原始数据) #-------------------------------------------------------------------------- def obtain_escape_param_string(text) text.slice!(/^\[[ =\|\$\-\d\w]+\]/)[1..-2] rescue "" end #-------------------------------------------------------------------------- # ● 清除暂存的指定文字特效 #-------------------------------------------------------------------------- def eagle_chara_effect_clear(code_sym) game_message.chara_params.delete(code_sym) end #-------------------------------------------------------------------------- # ● 设置\clc清屏效果 #-------------------------------------------------------------------------- def process_pos_clc(text, pos) text[0] = '' if text[0] == "\n" process_new_line(text, pos) oy_1 = self.oy oy_d = pos[:y] if @flag_draw t = MESSAGE_EX::CLC_CHARAS_OUT_FRAME (t+1).times do |i| per = i * 1.0 / t per = MESSAGE_EX.ease_value(:msg_vp, per) self.oy = (oy_1 + oy_d * per).round update_moving_charas_oxy Fiber.yield end end self.oy = oy_1 + oy_d update_moving_charas_oxy end #-------------------------------------------------------------------------- # ● 设置font参数 #-------------------------------------------------------------------------- def font_params; game_message.font_params; end def eagle_text_control_font(param = "") parse_param(font_params, param, :size) change_color(text_color(font_params[:c])) MESSAGE_EX.apply_font_params(self.contents.font, font_params) end #-------------------------------------------------------------------------- # ● (覆盖)重置字体设置 #-------------------------------------------------------------------------- def reset_font_settings font_params[:c] = MESSAGE_EX::DEFAULT_COLOR_INDEX font_params[:ca] = 255 change_color(text_color(font_params[:c])) end #-------------------------------------------------------------------------- # ● (覆盖)放大字体尺寸 #-------------------------------------------------------------------------- def make_font_bigger self.contents.font.size += 4 if self.contents.font.size <= 64 font_params[:size] = self.contents.font.size end #-------------------------------------------------------------------------- # ● (覆盖)缩小字体尺寸 #-------------------------------------------------------------------------- def make_font_smaller self.contents.font.size -= 4 if self.contents.font.size >= 16 font_params[:size] = self.contents.font.size end #-------------------------------------------------------------------------- # ● 设置win参数 #-------------------------------------------------------------------------- def win_params; game_message.win_params; end def eagle_text_control_win(param = "") parse_param(win_params, param, :o) win_params[:hmin] = eagle_check_param_h(win_params[:hmin]) win_params[:hmax] = eagle_check_param_h(win_params[:hmax]) win_params[:dw] = MESSAGE_EX.check_bool(win_params[:dw]) win_params[:fw] = MESSAGE_EX.check_bool(win_params[:fw]) win_params[:dh] = MESSAGE_EX.check_bool(win_params[:dh]) win_params[:fh] = MESSAGE_EX.check_bool(win_params[:fh]) win_params[:cwi] = 0 if win_params[:cwi] < 0 win_params[:cwo] = 0 if win_params[:cwo] < 0 win_params[:cfast] = MESSAGE_EX.check_bool(win_params[:cfast]) win_params[:fix] = MESSAGE_EX.check_bool(win_params[:fix]) eagle_reset_z end #-------------------------------------------------------------------------- # ● (覆盖)获取基础行高 #-------------------------------------------------------------------------- def line_height h = win_params[:lh] || Font.default_size return h if h > 0 return super end #-------------------------------------------------------------------------- # ● 设置pop参数 #-------------------------------------------------------------------------- def pop_params; game_message.pop_params; end def eagle_text_control_pop(param = "") pop_params[:id] = nil # 重置绑定对象 pop_params[:mx] = nil pop_params[:my] = nil parse_param(pop_params, param, :id) pop_params[:type] = nil # 清除可能的误设置 @eagle_pop_obj = eagle_get_pop_obj # 获取所绑定的对象 return pop_params[:type] = nil if @eagle_pop_obj.nil? s = eagle_get_pop_sprite # 获取所绑定对象的精灵 return pop_params[:type] = nil if s.nil? eagle_set_pop_sprite_info(s) pop_params[:dw] = MESSAGE_EX.check_bool(pop_params[:dw]) pop_params[:fw] = MESSAGE_EX.check_bool(pop_params[:fw]) pop_params[:dh] = MESSAGE_EX.check_bool(pop_params[:dh]) pop_params[:fh] = MESSAGE_EX.check_bool(pop_params[:fh]) pop_params[:fix] = MESSAGE_EX.check_bool(pop_params[:fix]) pop_params[:with_tag] = show_pop_tag? # 设置pop的tag eagle_reset_pop_tag_bitmap if pop_params[:with_tag] eagle_pop_update @eagle_sprite_pop_tag.opacity = 255 @eagle_sprite_pop_tag.visible = pop_params[:with_tag] end #-------------------------------------------------------------------------- # ● 获取pop的弹出对象(需要有x、y、width、height方法) #-------------------------------------------------------------------------- def eagle_get_pop_obj if pop_params[:id] return eagle_get_pop_obj_m if MESSAGE_EX.in_scene?(:map) return eagle_get_pop_obj_b if MESSAGE_EX.in_scene?(:battle) end return eagle_get_pop_obj_ex end #-------------------------------------------------------------------------- # ● 获取pop的对象(地图场景中)(Game_Character的实例) #-------------------------------------------------------------------------- def eagle_get_pop_obj_m pop_params[:type] = :map_chara id = pop_params[:id] if id == 0 # 当前事件 return $game_map.events[game_message.event_id] elsif id > 0 # 第id号事件 chara = $game_map.events[id] chara ||= $game_map.events[game_message.event_id] return chara elsif id < 0 # 队伍中数据库id号角色(不存在则取队长) id = id.abs $game_player.followers.each { |f| return f if f.actor && f.actor.actor.id == id } return $game_player end end #-------------------------------------------------------------------------- # ● 获取pop的对象(战斗场景中)(Sprite_Battler的实例) #-------------------------------------------------------------------------- def eagle_get_pop_obj_b pop_params[:type] = :battle_sprite id = pop_params[:id] return nil if id.nil? if id > 0 # 敌人index SceneManager.scene.spriteset.battler_sprites.each do |s| return s if s.battler && s.battler.enemy? && s.battler.index == id-1 end elsif id < 0 # 我方数据库id id = id.abs SceneManager.scene.spriteset.battler_sprites.each do |s| return s if s.battler && s.battler.actor? && s.battler.id == id end end return nil end #-------------------------------------------------------------------------- # ● 获取pop的对象(无 id 设置时) #-------------------------------------------------------------------------- def eagle_get_pop_obj_ex if MESSAGE_EX.in_scene?(:map) && pop_params[:mx] && pop_params[:my] pop_params[:type] = :map_grid return [pop_params[:mx], pop_params[:my]] end return nil end #-------------------------------------------------------------------------- # ● 获取pop对象的精灵(用于计算偏移值) #-------------------------------------------------------------------------- def eagle_get_pop_sprite # 地图场景中,所存储的并非精灵,需要再次检索 if pop_params[:type] == :map_chara begin SceneManager.scene.spriteset.character_sprites.each do |s| return s if s.character == @eagle_pop_obj end rescue p "【对话框扩展 by老鹰】未找到pop转义符绑定事件的精灵!可能存在兼容问题!" end return nil end return @eagle_pop_obj end #-------------------------------------------------------------------------- # ● 存储用于pop更新的精灵对象的信息 #-------------------------------------------------------------------------- def eagle_set_pop_sprite_info(s) if s.is_a?(Sprite) pop_params[:chara_w] = s.width pop_params[:chara_h] = s.height end if pop_params[:type] == :map_grid pop_params[:chara_w] = 32 pop_params[:chara_h] = 32 end end #-------------------------------------------------------------------------- # ● 可以显示pop的tag? #-------------------------------------------------------------------------- def show_pop_tag? game_message.pop_tag? && @background == 0 && pop_params[:do] > 0 && pop_params[:do] < 10 end #-------------------------------------------------------------------------- # ● 重置tag的位图 #-------------------------------------------------------------------------- def eagle_reset_pop_tag_bitmap(tag_id = pop_params[:tag]) @eagle_sprite_pop_tag.bitmap = MESSAGE_EX.windowtag(tag_id) w = @eagle_sprite_pop_tag.bitmap.width h = @eagle_sprite_pop_tag.bitmap.height @eagle_sprite_pop_tag.src_rect.width = w / 3 @eagle_sprite_pop_tag.src_rect.height = h / 3 end #-------------------------------------------------------------------------- # ● 设置face参数 #-------------------------------------------------------------------------- def face_params; game_message.face_params; end def eagle_text_control_face(param = "") return if !@flag_draw face_params[:ls] = -1 # 设置循环开始编号(+1直至le,再从ls循环) face_params[:le] = -1 # 设置循环结束编号 parse_param(face_params, param, :i) @eagle_sprite_face.apply_face_params if @eagle_sprite_face end #-------------------------------------------------------------------------- # ● 执行facem #-------------------------------------------------------------------------- def eagle_text_control_facem(param = "") return if !@flag_draw return if @eagle_sprite_face == nil params = param.split('|') @eagle_sprite_face.motion(params[0], params[1] || "") end #-------------------------------------------------------------------------- # ● 移出脸图 #-------------------------------------------------------------------------- def eagle_move_out_face return if @eagle_sprite_face.nil? @eagle_sprite_face.motion(:fade_out) MESSAGE_EX.facepool_push(@eagle_sprite_face) # 由精灵池接管 @eagle_sprite_face = nil end #-------------------------------------------------------------------------- # ● 脸图占用的宽度 #-------------------------------------------------------------------------- def eagle_face_width return 0 if !game_message.face? return 0 if face_params[:z] < 0 face_params[:width] + face_params[:dw] end #-------------------------------------------------------------------------- # ● 脸图在左侧占用的宽度(用于调整文字区域的左侧起始位置) #-------------------------------------------------------------------------- def eagle_face_left_width return 0 if face_params[:dir] # 显示在右侧时 v = eagle_face_width + face_params[:dx] [v, 0].max end #-------------------------------------------------------------------------- # ● 脸图在右侧占用的宽度 #-------------------------------------------------------------------------- def eagle_face_right_width return 0 if !face_params[:dir] # 显示在左侧时 v = eagle_face_width - face_params[:dx] [v, 0].max end #-------------------------------------------------------------------------- # ● 脸图占用的高度 #-------------------------------------------------------------------------- def eagle_face_height face_params[:height] || 0 end #-------------------------------------------------------------------------- # ● 保证脸图完全显示在对话框内? #-------------------------------------------------------------------------- def eagle_face_in_window? return false if @eagle_sprite_face == nil return MESSAGE_EX::FORCE_WIN_H_BIGGER_THAN_DEFAULT_FACE && @eagle_sprite_face.face_default_size? end #-------------------------------------------------------------------------- # ● 设置pause参数 #-------------------------------------------------------------------------- def pause_params; game_message.pause_params; end def eagle_text_control_pause(param = "") parse_param(pause_params, param, :id) @eagle_sprite_pause.reset if @eagle_sprite_pause end #-------------------------------------------------------------------------- # ● 设置wait参数 #-------------------------------------------------------------------------- def eagle_text_control_wait(param = '0') wait(param.to_i) end #-------------------------------------------------------------------------- # ● (覆盖)等待 #-------------------------------------------------------------------------- def wait(duration) return if !@flag_draw # 如果在对话快速显示的中途进行等待,则执行一次绘制后处理,以进行排版等 eagle_process_draw_update if show_fast? duration.times { break if @eagle_force_close; Fiber.yield } end #-------------------------------------------------------------------------- # ● 设置auto参数 #-------------------------------------------------------------------------- def eagle_text_control_auto(param = '0') win_params[:auto_t] = param.to_i end #-------------------------------------------------------------------------- # ● 执行shake #-------------------------------------------------------------------------- def eagle_text_control_shake(param = '0') return if !@flag_draw h = {} h[:p] = 5 # shake power h[:s] = 5 # shake speed h[:t] = 40 # shake duration h[:y] = 0 # 震动方向 parse_param(h, param, :t) # 等待震动至结束 shake = 0 # 对话框的偏移值 shake_direction = 1 # 下一次位移量 while h[:t] > 0 delta = (h[:p] * h[:s] * shake_direction) / 10.0 shake += delta shake_direction = -1 if shake > h[:p] * 2 shake_direction = 1 if shake < - h[:p] * 2 h[:t] -= 1 if h[:y] == 0 self.x += shake else self.y += shake end eagle_after_update_xy Fiber.yield end shake = shake.to_i # 平滑移动回初始位置 d = shake > 0 ? -1 : 1 while shake != 0 shake += d if h[:y] == 0 self.x += shake else self.y += shake end eagle_after_update_xy Fiber.yield end end #-------------------------------------------------------------------------- # ● 执行move指令 #-------------------------------------------------------------------------- def eagle_text_control_move(param = '0') return if !@flag_draw return if win_params[:do] < 0 || game_message.pop? win_params[:move_init_x] ||= (win_params[:x] || default_init_x) win_params[:move_init_y] ||= (win_params[:y] || default_init_y) h = { :x => nil, :y => nil, :dx => nil, :dy => nil, :t => 20 } parse_param(h, param, :t) _x = nil; _y = nil if h[:x] _x = (h[:x] == 0 ? win_params[:move_init_x] : h[:x]) else _x = self.x + h[:dx] if h[:dx] end if h[:y] _y = (h[:y] == 0 ? win_params[:move_init_y] : h[:y]) else _y = self.y + h[:dy] if h[:dy] end # 直接重设目的地xy win_params[:x] = _x if _x win_params[:y] = _y if _y # 执行移动 h2 = {} h2[:x] = _x if _x h2[:y] = _y if _y h2[:t] = h[:t] eagle_set_wh(h2) end #-------------------------------------------------------------------------- # ● 执行eval指令 #-------------------------------------------------------------------------- def eagle_text_control_eval(param = '0') return if !@flag_draw id_ = param.to_i if id_ > 0 && @eagle_evals[id_ - 1] s = $game_switches; v = $game_variables; msg = self eval( @eagle_evals[id_ - 1] ) end end #-------------------------------------------------------------------------- # ● 设置set参数 #-------------------------------------------------------------------------- def eagle_text_control_set(param = '0') return if !@flag_draw return @eagle_current_set = nil if param == '0' @eagle_current_set = param @eagle_chara_sets[@eagle_current_set] ||= [] end def eagle_text_control_setm(param = '0') return if !@flag_draw params = param.split('|') # [set_sym, effect_sym, param] if params[2] == "0" chara_set(params[0]) { |s| s.finish_effect(params[1].to_sym) } else chara_set(params[0]) { |s| s.start_effect(params[1].to_sym, params[2]) } end end #-------------------------------------------------------------------------- # ● 对指定分组内的文字执行block # 传入空字符串或 0 时为全部文字 #-------------------------------------------------------------------------- def chara_set(set_sym = nil) # block if set_sym.nil? || set_sym.empty? || set_sym == 0 || set_sym == '0' @eagle_chara_sprites.each { |s| yield(s) } return end return if @eagle_chara_sets[set_sym].nil? @eagle_chara_sets[set_sym].each { |s| yield(s) } end #-------------------------------------------------------------------------- # ● 设置扩展参数 #-------------------------------------------------------------------------- def ex_params; game_message.ex_params; end #-------------------------------------------------------------------------- # ● 设置cg参数 / 渐变绘制预定 #-------------------------------------------------------------------------- if defined?(Sion_GradientText) def eagle_text_control_cg(param = '0') ex_params[:cg].clear ex_params[:cg] = param if param != '' && param != '0' end end #-------------------------------------------------------------------------- # ● 输入处理(此处为全部绘制完成后,判定接下来的输入类型) #-------------------------------------------------------------------------- def process_input if game_message.choice? input_choice elsif game_message.num_input? input_number elsif game_message.item_choice? input_item elsif input_pause? input_pause end eagle_process_hold end #-------------------------------------------------------------------------- # ● 需要输入等待? #-------------------------------------------------------------------------- def input_pause? game_message.input_pause? && !@pause_skip end #-------------------------------------------------------------------------- # ● 处理输入等待 #-------------------------------------------------------------------------- def input_pause return if !@flag_draw before_input_pause eagle_process_draw_update # 统一更新一次 @eagle_sprite_pause.bind_last_chara(@eagle_chara_sprites[-1]) @eagle_sprite_pause.show @flag_input_pause = true self.pause = true unless MESSAGE_EX::NO_DEFAULT_PAUSE process_input_pause self.pause = false @flag_input_pause = false @eagle_sprite_pause.hide end #-------------------------------------------------------------------------- # ● 输入等待前的操作 #-------------------------------------------------------------------------- def before_input_pause # 当pause精灵位于句末且紧靠边界时 # 增加对话框宽度保证它在对话框内部(不可占用padding) if pause_params[:v] != 0 && pause_params[:do] <= 0 && input_pause? && eagle_add_w_by_child_window? # 最大可用于文字绘制的宽度 eagle_charas_max_w # 全部文字实际绘制的宽度 @eagle_charas_w_final + win_params[:cdw] # 最后一行所需的绘制宽度 @eagle_next_chara_x if @eagle_next_chara_x >= @eagle_charas_w_final @eagle_sprite_pause_width_add = @eagle_sprite_pause.width else d = @eagle_charas_w_final + win_params[:cdw] - @eagle_next_chara_x d -= @eagle_sprite_pause.width @eagle_sprite_pause_width_add = -d if d <= 0 end else @eagle_sprite_pause_width_add = 0 end end #-------------------------------------------------------------------------- # ● 执行输入等待 #-------------------------------------------------------------------------- def process_input_pause @eagle_auto_continue_c = win_params[:auto_t] || MESSAGE_EX::WIN_AUTO_T recreate_contents_for_charas ox_max = [self.ox, @eagle_charas_w - @eagle_chara_viewport.rect.width].max oy_max = self.oy flag_move = ox_max != 0 || oy_max != 0 self.arrows_visible = true d_oxy = 1; last_input = nil; last_input_c = 0 @flag_input_loop = true while @flag_input_loop Fiber.yield process_input_pause_auto # 处理自动继续 process_input_pause_key # 处理按键继续 if flag_move # 处理内容滚动 if last_input == Input.dir4 # 先处理变速,防止同时按多个方向,导致速度不对 last_input_c += 1 d_oxy += 1 if last_input_c % 10 == 0 else d_oxy = 1 last_input_c = 0 end last_input = Input.dir4 _ox = self.ox; _oy = self.oy if Input.press?(:UP) self.oy -= d_oxy self.oy = 0 if self.oy < 0 elsif Input.press?(:DOWN) self.oy += d_oxy self.oy = oy_max if self.oy > oy_max elsif Input.press?(:LEFT) self.ox -= d_oxy self.ox = 0 if self.ox < 0 elsif Input.press?(:RIGHT) self.ox += d_oxy self.ox = ox_max if self.ox > ox_max end update_moving_charas_oxy if _ox != self.ox || _oy != self.oy elsif MESSAGE_EX::INPUT_NEXT_WITH_DIR4 @flag_input_loop = false if Input.dir4 > 0 end end self.arrows_visible = false Fiber.yield end #-------------------------------------------------------------------------- # ● 等待按键时,自动继续的处理 #-------------------------------------------------------------------------- def process_input_pause_auto if @eagle_auto_continue_c return @flag_input_loop = false if @eagle_auto_continue_c <= 0 process_while_auto_wait_input_pause(@eagle_auto_continue_c) @eagle_auto_continue_c -= 1 end end #-------------------------------------------------------------------------- # ● 等待按键时,启用auto时的额外处理 # c 为自动继续的剩余帧数,从 win_params[:auto_t] 获取总等待帧数 #-------------------------------------------------------------------------- def process_while_auto_wait_input_pause(c) @eagle_sprite_pause.redraw_auto_countdown(c) end #-------------------------------------------------------------------------- # ● 等待按键时,按键继续的处理 #-------------------------------------------------------------------------- def process_input_pause_key return @flag_input_loop = false if check_input? end #-------------------------------------------------------------------------- # ● 检查输入等待的按键 #-------------------------------------------------------------------------- def check_input? Input.trigger?(:B) || Input.trigger?(:C) end #-------------------------------------------------------------------------- # ● 处理选项的输入(覆盖) #-------------------------------------------------------------------------- def input_choice input_wait_until_msg_wh(@choice_window) input_wait_while_active(@choice_window) end #-------------------------------------------------------------------------- # ● 处理数值的输入(覆盖) #-------------------------------------------------------------------------- def input_number input_wait_until_msg_wh(@number_window) input_wait_while_active(@number_window) end #-------------------------------------------------------------------------- # ● 处理物品的选择(覆盖) #-------------------------------------------------------------------------- def input_item input_wait_until_msg_wh(@item_window) input_wait_while_active(@item_window) end #-------------------------------------------------------------------------- # ● 等待对话框宽高处理结束 #-------------------------------------------------------------------------- def input_wait_until_msg_wh(child_window) child_window.hide.start eagle_set_wh if child_window_embed_in? # 执行因子窗口嵌入而变更的窗口大小 child_window.show.open.activate end #-------------------------------------------------------------------------- # ● 并行等待子窗口处理结束 #-------------------------------------------------------------------------- def input_wait_while_active(child_window) add_w = game_message.child_window_w_des add_h = game_message.child_window_h_des while child_window.active break child_window.deactivate.close if @eagle_force_close @fiber_para.resume if @fiber_para if add_w != game_message.child_window_w_des || add_h != game_message.child_window_h_des eagle_set_wh # 执行因子窗口嵌入而变更的窗口大小 add_w = game_message.child_window_w_des add_h = game_message.child_window_h_des end Fiber.yield end @fiber_para = nil end end # end of class Window_EagleMessage #============================================================================= # ○ 对话框拷贝 #============================================================================= class Window_EagleMessage_Clone < Window_EagleMessage attr_accessor :back_bitmap, :back_sprite attr_accessor :eagle_chara_viewport attr_accessor :eagle_chara_sprites, :eagle_sprite_pop_tag attr_accessor :eagle_sprite_face, :eagle_window_name, :eagle_sprite_pause attr_accessor :eagle_pop_obj attr_accessor :flag_hold_id #-------------------------------------------------------------------------- # ● 初始化对象 #-------------------------------------------------------------------------- def initialize(game_message) @game_message = game_message super() self.openness = 255 @fin = false # 结束显示? @flag_hold_id = nil end #-------------------------------------------------------------------------- # ● 获取主参数 #-------------------------------------------------------------------------- def game_message; @game_message; end #-------------------------------------------------------------------------- # ● 初始化组件(覆盖,不再初始化,防止在赋值前还要dispose) #-------------------------------------------------------------------------- def eagle_message_init_assets; end #-------------------------------------------------------------------------- # ● (覆盖)去除全部子窗口 #-------------------------------------------------------------------------- def create_all_windows; end def dispose_all_windows; end def update_all_windows; end #-------------------------------------------------------------------------- # ● (覆盖)判定是否所有窗口已全部关闭 #-------------------------------------------------------------------------- def all_close?; close?; end #-------------------------------------------------------------------------- # ● 设置xywh #-------------------------------------------------------------------------- def move(x, y, w, h) super @eagle_win_des_w = w # 同时记录该变量,防止nil时 default_init_y 报错 @eagle_win_des_h = h @eagle_last_x = x # 同时设置上次更新的位置,确保 eagle_set_wh 能用 @eagle_last_y = y end #-------------------------------------------------------------------------- # ○ 记录文本的宽高(用于更新大小) #-------------------------------------------------------------------------- def eagle_set_chara_wh(w, h, w_final, h_final) @eagle_charas_w = w @eagle_charas_h = h @eagle_charas_w_final = w_final @eagle_charas_h_final = h_final end #-------------------------------------------------------------------------- # ○ 关闭对话框 #-------------------------------------------------------------------------- def close_clone @fin = true end #-------------------------------------------------------------------------- # ○ 已经计划关闭? #-------------------------------------------------------------------------- def close_clone? @fin == true end #-------------------------------------------------------------------------- # ● 重置单页对话框(覆盖,防止过早移出组件) #-------------------------------------------------------------------------- def eagle_message_reset @eagle_sprite_pause_width_add = 0 # 拷贝窗口中不存在pause精灵 end #-------------------------------------------------------------------------- # ● 更新纤程 #-------------------------------------------------------------------------- def update_fiber if @fiber @fiber.resume elsif self.openness >= 255 && !@fin @fiber = Fiber.new { fiber_main } @fiber.resume end end #-------------------------------------------------------------------------- # ● 处理纤程的主逻辑 #-------------------------------------------------------------------------- def fiber_main eagle_set_wh( {:open => true} ) # 由于pause精灵需要去除,增加更新宽高 loop do Fiber.yield break if @fin end eagle_process_before_close close_and_wait @fiber = nil end end #============================================================================= # ○ 对话框拷贝 - 用于环境初始化 #============================================================================= class Window_EagleMessage_CloneEnv < Window_EagleMessage #-------------------------------------------------------------------------- # ● 初始化对象 #-------------------------------------------------------------------------- def initialize(game_message) @game_message = game_message super() self.openness = 0 end #-------------------------------------------------------------------------- # ● 获取主参数 #-------------------------------------------------------------------------- def game_message; @game_message; end def game_message=(g); @game_message = g; end #-------------------------------------------------------------------------- # ● 初始化组件(覆盖,不再初始化,防止在赋值前还要dispose) #-------------------------------------------------------------------------- def eagle_message_init_assets; end #-------------------------------------------------------------------------- # ● (覆盖)去除全部子窗口 #-------------------------------------------------------------------------- def create_all_windows; end def dispose_all_windows; end def update_all_windows; end #-------------------------------------------------------------------------- # ● (覆盖)重置对话框 #-------------------------------------------------------------------------- def eagle_message_reset; end #-------------------------------------------------------------------------- # ● 重设z值 #-------------------------------------------------------------------------- def eagle_reset_z; end #-------------------------------------------------------------------------- # ● (覆盖)更新 #-------------------------------------------------------------------------- def update; end #-------------------------------------------------------------------------- # ● 设置game_message # 本质上为全部绘制一次(但不真实绘制) # 空方法为去除对组件的设置 #-------------------------------------------------------------------------- def set_game_message(game_message, text) @game_message = game_message text_ = text.clone text_ = convert_escape_characters(text_) pos_ = { :x => 0, :y => 0, :new_x => 0, :height => 0} @flag_draw = false process_character(text_.slice!(0, 1), text_, pos_) until text_.empty? end #-------------------------------------------------------------------------- # ● 绘制完成时的处理 #-------------------------------------------------------------------------- def eagle_process_draw_end(c_w, c_h, pos); end #-------------------------------------------------------------------------- # ● 可以显示pop的tag? #-------------------------------------------------------------------------- def show_pop_tag?; false; end end #============================================================================= # ○ 金钱框窗口 #============================================================================= class Window_EagleMsgGold < Window_Gold #-------------------------------------------------------------------------- # ● 初始化对象 #-------------------------------------------------------------------------- def initialize(window_msg) bind_window(window_msg) super() self.x = Graphics.width - self.width self.y = 0 self.openness = 0 end def bind_window(window); @window_msg = window; end end #============================================================================= # ○ 姓名框窗口 #============================================================================= class Window_EagleMsgName < Window_Base attr_reader :rect_real #-------------------------------------------------------------------------- # ● 获取文字颜色 # n : 文字颜色编号(0..31) #-------------------------------------------------------------------------- def text_color(n) MESSAGE_EX.text_color(n, self.windowskin) end #-------------------------------------------------------------------------- # ● 初始化对象 #-------------------------------------------------------------------------- def initialize(window_msg) bind_window(window_msg) super(0, 0, 32, 32) self.visible = false # 从 opacity=0 修改为 visible,确保不会一瞬间出现背景框 @back_sprite = Sprite.new @flag_use_back_sprite = false @params = {} # 在背景图片的影响下,姓名框四个方向的增加量 @rect_real = Rect.new(0, 0, 0, 0) end def bind_window(window); @window_msg = window; end def name_params; @window_msg.name_params; end #-------------------------------------------------------------------------- # ● 获取行高 #-------------------------------------------------------------------------- def line_height; name_params[:size] || Font.default_size; end #-------------------------------------------------------------------------- # ● 姓名没有变化? #-------------------------------------------------------------------------- def no_change? @params[:name] == name_params[:name] end #-------------------------------------------------------------------------- # ● 开始 #-------------------------------------------------------------------------- def start if @flag_use_back_sprite # 显示背景图片时,隐藏默认窗口皮肤 @back_sprite.visible = true self.opacity = 0 self.back_opacity = 0 else @back_sprite.visible = false self.opacity = name_params[:opa] self.back_opacity = name_params[:opa] if name_params[:do] == 0 # 嵌入时,隐藏背景框 self.opacity = 0 self.back_opacity = 0 end end self.contents_opacity = 255 self.openness = 255 if self.back_opacity == 0 # 没有背景框,则省略open过程 self.show.open end #-------------------------------------------------------------------------- # ● 重置 #-------------------------------------------------------------------------- def reset return close if name_params[:name] == "" skin = @window_msg.get_cur_windowskin_index(name_params[:skin]) self.windowskin = MESSAGE_EX.windowskin(skin) return if open? && no_change? @params[:name] = name_params[:name] reset_size(name_params[:name]) redraw(name_params[:name]) if name_params[:bg] && eagle_draw_bg_pic(self.width, self.height) @flag_use_back_sprite = true @back_sprite.z = self.z - 1 @back_sprite.opacity = 0 # 在更新前,先确保背景图片不显示 @back_sprite.visible = false else @flag_use_back_sprite = false end reset_rect_real #open # 等待对话框中调用 start 方法来显示姓名框 end #-------------------------------------------------------------------------- # ● 重设窗口大小 #-------------------------------------------------------------------------- def reset_size(t) reset_font_settings w, h = MESSAGE_EX.calculate_text_wh(contents, t) h = [h, contents.font.size].max w = w + name_params[:cx] h = h + name_params[:cy] move(0, 0, w + standard_padding * 2, h + standard_padding * 2) create_contents end #-------------------------------------------------------------------------- # ● 重绘 #-------------------------------------------------------------------------- def redraw(t) change_color(text_color(@window_msg.font_params[:c])) MESSAGE_EX.apply_font_params(contents.font, @window_msg.font_params) draw_text_ex(name_params[:cx], name_params[:cy], t) end #-------------------------------------------------------------------------- # ● 重置字体设置 #-------------------------------------------------------------------------- def reset_font_settings change_color(normal_color) contents.font.size = name_params[:size] || Font.default_size end #-------------------------------------------------------------------------- # ● 获取控制符的参数(这个方法会破坏原始数据) #-------------------------------------------------------------------------- def obtain_escape_param_string(text) text.slice!(/^\[[\|\$\-\d\w]+\]/)[1..-2] rescue "" end #-------------------------------------------------------------------------- # ● 控制符的处理 # code : 控制符的实际形式(比如“\C[1]”是“C”) # text : 绘制处理中的字符串缓存(字符串可能会被修改) # pos : 绘制位置 {:x, :y, :new_x, :height} #-------------------------------------------------------------------------- def process_escape_character(code, text, pos) if code.upcase == 'C' change_color(text_color(obtain_escape_param_string(text))) return end super(code, text, pos) end #-------------------------------------------------------------------------- # ● 绘制背景图片 #-------------------------------------------------------------------------- def eagle_draw_bg_pic(w, h) _bitmap = MESSAGE_EX.namebg(name_params[:bg], w, h) if _bitmap != nil @back_sprite.bitmap = _bitmap return true end return false end #-------------------------------------------------------------------------- # ● 更新背景精灵 #-------------------------------------------------------------------------- def update_back_sprite MESSAGE_EX.reset_xy_dorigin(@back_sprite, self, name_params[:bgo]) MESSAGE_EX.reset_sprite_oxy(@back_sprite, name_params[:bgo]) @back_sprite.z = self.z - 1 end #-------------------------------------------------------------------------- # ● 计算四方向上的增量(因为背景图片可能大于文字区域) #-------------------------------------------------------------------------- def reset_rect_real if @flag_use_back_sprite update_back_sprite xw = self.x + standard_padding; ww = self.width - standard_padding * 2 yw = self.y + standard_padding; hw = self.height - standard_padding * 2 xp = @back_sprite.x - @back_sprite.ox yp = @back_sprite.y - @back_sprite.oy @rect_real.x = 0 @rect_real.x = xw - xp if xp < xw @rect_real.y = 0 @rect_real.y = yw - yp if yp < yw t = xp + @back_sprite.width - xw - ww @rect_real.width = 0 @rect_real.width = t if t > 0 t = yp + @back_sprite.height - yw - hw @rect_real.height = 0 @rect_real.height = t if t > 0 end end #-------------------------------------------------------------------------- # ● 更新(在 eagle_win_update 中调用) #-------------------------------------------------------------------------- def update_with_msg update_position update_back_sprite if @flag_use_back_sprite end #-------------------------------------------------------------------------- # ● 更新位置 # 尽管已经更新了姓名框位置,但保留此处用于扩展 #-------------------------------------------------------------------------- def update_position end #-------------------------------------------------------------------------- # ● 显示 #-------------------------------------------------------------------------- def show @back_sprite.visible = true if @flag_use_back_sprite super end #-------------------------------------------------------------------------- # ● 隐藏 #-------------------------------------------------------------------------- def hide @back_sprite.visible = false if @flag_use_back_sprite super end #-------------------------------------------------------------------------- # ● 更新(每帧调用) #-------------------------------------------------------------------------- def update super @back_sprite.opacity = get_back_sprite_opacity if @flag_use_back_sprite end #-------------------------------------------------------------------------- # ● 更新背景图片的透明度 #-------------------------------------------------------------------------- def get_back_sprite_opacity return 0 if self.visible == false if self.back_opacity == 0 return self.contents_opacity if self.contents_opacity < 255 end return self.openness end end #============================================================================= # ○ 等待按键的精灵 #============================================================================= class Sprite_EaglePauseTag < Sprite #-------------------------------------------------------------------------- # ● 初始化对象 #-------------------------------------------------------------------------- def initialize(window_bind) super(nil) bind_window(window_bind) @type_source = 0 # 记录当前源位图的类型(见module中对应【设置】) @type_pos = 0 # 记录当前相对于对话框的位置类型 @last_chara = nil @last_pause_index = "" init_auto_countdown reset hide end def bind_window(window_bind); @window_bind = window_bind; end def params; @window_bind.pause_params; end #-------------------------------------------------------------------------- # ● 释放 #-------------------------------------------------------------------------- def dispose @sprite_auto.bitmap.dispose if @sprite_auto.bitmap @sprite_auto.dispose @s_bitmap.dispose self.bitmap.dispose super end #-------------------------------------------------------------------------- # ● 绑定文末精灵 #-------------------------------------------------------------------------- def bind_last_chara(sprite_chara) @last_chara = sprite_chara reset_position end #-------------------------------------------------------------------------- # ● 重置 #-------------------------------------------------------------------------- def reset reset_source if @last_pause_index != params[:id] reset_bitmap end #-------------------------------------------------------------------------- # ● 重置源位图 #-------------------------------------------------------------------------- def reset_source @s_bitmap.dispose if @s_bitmap @last_pause_index = params[:id] _params = MESSAGE_EX.pause_params(@last_pause_index) _bitmap = Cache.system(_params[0]) _rect = _params[1].nil? ? _bitmap.rect : _params[1] @s_bitmap_row = _params[2] # 源位图中一行中帧数目 @s_bitmap_col = _params[3] # 源位图中一列中帧数目 @s_bitmap_n = @s_bitmap_row * @s_bitmap_col # 总帧数 @s_bitmap = Bitmap.new(_rect.width, _rect.height) @s_bitmap.blt(0, 0, _bitmap, _rect) @s_rect = Rect.new(0, 0, @s_bitmap.width / @s_bitmap_row, @s_bitmap.height / @s_bitmap_col) self.bitmap.dispose if self.bitmap self.bitmap = Bitmap.new(@s_rect.width, @s_rect.height) @index = 0 # 当前index end #-------------------------------------------------------------------------- # ● 重绘位图 #-------------------------------------------------------------------------- def reset_bitmap self.bitmap.clear @s_rect.x = (@index % @s_bitmap_row) * @s_rect.width @s_rect.y = (@index / @s_bitmap_row) * @s_rect.height self.bitmap.blt(0, 0, @s_bitmap, @s_rect) @count = 0 end #-------------------------------------------------------------------------- # ● 更新位置 #-------------------------------------------------------------------------- def reset_position self.viewport = nil if params[:do] > 0 MESSAGE_EX.reset_xy_dorigin(self, @window_bind, params[:do]) elsif @last_chara self.viewport = @window_bind.eagle_chara_viewport self.x = @last_chara._x + @last_chara.width - @window_bind.eagle_charas_ox self.y = @last_chara._y + @last_chara.height/2 - @window_bind.eagle_charas_oy else self.x = @window_bind.eagle_charas_x0 self.y = @window_bind.eagle_charas_y0 end self.x += params[:dx] self.y += params[:dy] MESSAGE_EX.reset_xy_origin(self, params[:o]) reset_auto_countdown_position end #-------------------------------------------------------------------------- # ● 更新 #-------------------------------------------------------------------------- def update super update_index reset_position if self.viewport && @last_chara end #-------------------------------------------------------------------------- # ● 更新帧动画 #-------------------------------------------------------------------------- def update_index return if (@count += 1) < params[:t] @index = (@index + 1) % @s_bitmap_n reset_bitmap end #-------------------------------------------------------------------------- # ● 显示 #-------------------------------------------------------------------------- def show return if params[:v] == 0 reset_position self.visible = true self end #-------------------------------------------------------------------------- # ● 隐藏 #-------------------------------------------------------------------------- def hide @sprite_auto.visible = false self.visible = false self end #-------------------------------------------------------------------------- # ● 初始化自动倒计时 #-------------------------------------------------------------------------- def init_auto_countdown @sprite_auto = Sprite.new @sprite_auto.bitmap = Bitmap.new(MESSAGE_EX::WIN_AUTO_W, MESSAGE_EX::WIN_AUTO_H) @sprite_auto.bitmap.font.color = Color.new(0,0,0,255) @sprite_auto.bitmap.font.shadow = false @sprite_auto.bitmap.font.outline = false # 用于复制的白色文字 @auto_temp_bitmap = Bitmap.new(@sprite_auto.width, @sprite_auto.height) @auto_temp_bitmap.font.color = Color.new(255,255,255,150) @auto_temp_bitmap.font.shadow = false @auto_temp_bitmap.font.outline = false t = MESSAGE_EX::WIN_AUTO_TEXT @auto_temp_bitmap.draw_text(0, 0, @sprite_auto.width, @sprite_auto.height, t, 1) end #-------------------------------------------------------------------------- # ● 重置自动倒计时的位置 #-------------------------------------------------------------------------- def reset_auto_countdown_position MESSAGE_EX.reset_sprite_oxy(@sprite_auto, MESSAGE_EX::WIN_AUTO_O) MESSAGE_EX.reset_xy_dorigin(@sprite_auto, @window_bind, MESSAGE_EX::WIN_AUTO_DO) @sprite_auto.x += MESSAGE_EX::WIN_AUTO_DX @sprite_auto.y += MESSAGE_EX::WIN_AUTO_DY @sprite_auto.z = self.z + 1 @sprite_auto.bitmap.clear @sprite_auto.visible = @window_bind.openness > 0 && @window_bind.win_params[:auto_t] != nil end #-------------------------------------------------------------------------- # ● 重绘自动倒计时 #-------------------------------------------------------------------------- def redraw_auto_countdown(cd) count_rate = cd * 1.0 / @window_bind.win_params[:auto_t] b = @sprite_auto.bitmap b.clear b.fill_rect(0, 0, b.width, b.height, Color.new(255,255,255,150)) _x = (b.width-2) * (1-count_rate) r = Rect.new(1+_x, 1, b.width-2-_x, b.height-2) b.fill_rect(r, Color.new(0,0,0,150)) # 绘制黑色文字 t = MESSAGE_EX::WIN_AUTO_TEXT b.draw_text(0, 0, b.width, b.height, t, 1) # 绘制白色文字 r2 = Rect.new(_x, 0, b.width, b.height) b.blt(_x, 0, @auto_temp_bitmap, r2) end end #============================================================================== # ○ 精灵池(用于更新需要延迟消失的精灵) #============================================================================== module MESSAGE_EX #-------------------------------------------------------------------------- # ● 重置 #-------------------------------------------------------------------------- def self.pools_reset all_pools.each do |type| get_pool(type).each { |s| s.dispose } get_pool(type).clear end end #-------------------------------------------------------------------------- # ● 更新 #-------------------------------------------------------------------------- def self.pools_update all_pools.each do |type| get_pool(type).each { |s| s.update if !s.disposed? && !s.finish? } end end #-------------------------------------------------------------------------- # ● 从指定池子中取出一个可用的精灵(失败则返回nil) #-------------------------------------------------------------------------- def self.pool_new(type) while true s = get_pool(type).shift return nil if s.nil? next if s.disposed? if !s.finish? get_pool(type).unshift(s) return nil end return s end end #-------------------------------------------------------------------------- # ● 将指定精灵放入指定池子 # 【注】精灵需要存在 finish? 方法,该方法返回 true 代表可以被重置复用 # 返回 false 代表需要继续自己的 update #-------------------------------------------------------------------------- def self.pool_push(type, s) return if s.disposed? return get_pool(type).unshift(s) if s.finish? get_pool(type).push(s) end #-------------------------------------------------------------------------- # ● 定义可用的池 #-------------------------------------------------------------------------- def self.all_pools [:chara, :face] end #-------------------------------------------------------------------------- # ● 定义全局数组 #-------------------------------------------------------------------------- @pool_charas = [] # 文字精灵池 @pool_faces = [] # 脸图精灵池 def self.get_pool(type) return @pool_charas if type == :chara return @pool_faces if type == :face end #-------------------------------------------------------------------------- # ● 对文字精灵池的操作 #-------------------------------------------------------------------------- def self.charapool_push(s) pool_push(:chara, s) end def self.charapool_new(window, font, x,y,w,h, viewport) s = pool_new(:chara) return Sprite_EagleCharacter.new(window, font, x,y,w,h, viewport) if s.nil? s.bind_viewport(viewport) s.bind_window(window) s.bind_font(font) s.reset(x,y,w,h) s end #-------------------------------------------------------------------------- # ● 对脸图精灵池的操作 #-------------------------------------------------------------------------- def self.facepool_push(s) pool_push(:face, s) end def self.facepool_new s = pool_new(:face) return Sprite_EagleFace.new if s.nil? s end end #============================================================================= # ○ Scene_Base #============================================================================= class Scene_Base #-------------------------------------------------------------------------- # ● 开始处理 #-------------------------------------------------------------------------- alias eagle_message_pool_start start def start MESSAGE_EX.pools_reset eagle_message_pool_start end #-------------------------------------------------------------------------- # ● 更新画面(基础) #-------------------------------------------------------------------------- alias eagle_message_pool_update_basic update_basic def update_basic eagle_message_pool_update_basic MESSAGE_EX.pools_update end #-------------------------------------------------------------------------- # ● 结束处理 #-------------------------------------------------------------------------- alias eagle_message_pool_terminate terminate def terminate eagle_message_pool_terminate MESSAGE_EX.pools_reset end end #============================================================================= # ○ 脸图精灵 #============================================================================= class Sprite_EagleFace < Sprite attr_accessor :opa #-------------------------------------------------------------------------- # ● 绑定 #-------------------------------------------------------------------------- def bind_window(w); @window = w; end def face_params; @window.face_params; end #-------------------------------------------------------------------------- # ● 已经结束使用? #-------------------------------------------------------------------------- def finish? @flag_fin == true end #-------------------------------------------------------------------------- # ● 初始化/重置 #-------------------------------------------------------------------------- def reset(window) bind_window(window) init_params apply_face_bitmap apply_face_params end #-------------------------------------------------------------------------- # ● 初始化参数 #-------------------------------------------------------------------------- def init_params @params = {} # 自用参数组 @flag_fin = false # 可复用的标志 @fiber = nil # 移动用 fiber @fiber_tmp = nil # 若fiber未执行完,则只预存一个 fiber # 为了更好的扩展性,不直接使用默认属性,而是利用中间变量去赋值 @x0 = @y0 = 0 # 因绑定对话框而获得的基础坐标 @x1 = @y1 = 0 # 因为移动而增加的偏移 @opa = 0 # 不透明度 end #-------------------------------------------------------------------------- # ● 脸图未更改? #-------------------------------------------------------------------------- def no_change? self.bitmap && !self.bitmap.disposed? && @params[:name] == face_params[:name] && @params[:i] == face_params[:i] end #-------------------------------------------------------------------------- # ● 设置脸图文件 #-------------------------------------------------------------------------- def apply_face_bitmap @params[:name] = face_params[:name] self.bitmap = Cache.face(@params[:name]) @params[:name] =~ /_(\d+)x(\d+)_?/i # 从文件名获取行数和列数(默认为2行4列) @params[:num_line] = $1 ? $1.to_i : face_default_line @params[:num_col] = $2 ? $2.to_i : face_default_col @params[:num] = @params[:num_line] * @params[:num_col] @params[:sole_w] = self.bitmap.width / @params[:num_col] @params[:sole_h] = self.bitmap.height / @params[:num_line] # 传出脸图宽高,用于对话框中的文字位移 face_params[:width] = @params[:sole_w] face_params[:height] = @params[:sole_h] # 脸图以底部中心为显示原点 self.ox = @params[:sole_w] / 2 self.oy = @params[:sole_h] end #-------------------------------------------------------------------------- # ● 脸图默认规格(行和列) #-------------------------------------------------------------------------- def face_default_line; 2; end def face_default_col; 4; end #-------------------------------------------------------------------------- # ● 默认大小的脸图? #-------------------------------------------------------------------------- def face_default_size? @params[:sole_w] == 96 && @params[:sole_h] == 96 end #-------------------------------------------------------------------------- # ● 导入face参数 #-------------------------------------------------------------------------- def apply_face_params # 移入移出的参数 @params[:it] = face_params[:it] @params[:ot] = face_params[:ot] # 判断是否需要循环的flag @params[:flag_l] = (face_params[:ls] > -1 && face_params[:le] > face_params[:ls]) @params[:ls] = face_params[:ls] @params[:lt] = face_params[:lt] @params[:lw] = face_params[:lw] @params[:li_c] = face_params[:ls] # 循环用index计数 @params[:lt_c] = face_params[:lt] # 循环用time计数 @params[:lw_c] = face_params[:lw] # 循环后wait计数 @params[:i] = face_params[:i] apply_index end #-------------------------------------------------------------------------- # ● 应用当前帧 #-------------------------------------------------------------------------- def apply_index return if @params[:i] == nil @params[:i] = 0 if @params[:i] >= @params[:num] w = @params[:sole_w] h = @params[:sole_h] x = @params[:i] % @params[:num_col] * w y = @params[:i] / @params[:num_col] * h rect = Rect.new(x, y, w, h) self.src_rect = rect end #-------------------------------------------------------------------------- # ● 更新 #-------------------------------------------------------------------------- def update super @fiber.resume if @fiber update_position update_pattern end #-------------------------------------------------------------------------- # ● 更新位置 #-------------------------------------------------------------------------- def update_position if @window if face_params[:dir] # 脸图放置于右侧时 @x0 = @window.x + @window.width - @window.standard_padding - self.ox else # 脸图放置于左侧时 @x0 = @window.x + @window.standard_padding + self.ox end @x0 += face_params[:dx] @y0 = @window.y + @window.height - @window.standard_padding + face_params[:dy] self.mirror = face_params[:m] self.z = @window.z + face_params[:z] end self.x = @x0 + @x1 self.y = @y0 + @y1 self.opacity = @opa end #-------------------------------------------------------------------------- # ● 更新自动播放 #-------------------------------------------------------------------------- def update_pattern if @params[:flag_l] if @params[:li_c] >= @params[:le] # 每次loop之间的等待 return if @params[:lw].nil? @params[:lw_c] -= 1 return if @params[:lw_c] > 0 @params[:lw_c] = @params[:lw] @params[:li_c] = @params[:ls] else # 每帧之间的等待 @params[:lt_c] -= 1 return if @params[:lt_c] > 0 @params[:lt_c] = @params[:lt] @params[:li_c] += 1 end @params[:i] = @params[:li_c] apply_index end end #-------------------------------------------------------------------------- # ● 执行动作 #-------------------------------------------------------------------------- def motion(type, param_str = "") m_c = ("fiber_#{type}").to_sym if respond_to?(m_c) @fiber = nil if type == :fade_out if @fiber @fiber_tmp = Fiber.new { fiber_main(m_c, param_str) } else @fiber = Fiber.new { fiber_main(m_c, param_str) } end else p "对话框中 \\facem 转义符,指令 #{type} 无效!请检查指令名称及其大小写!" end end #-------------------------------------------------------------------------- # ● Fiber主逻辑 #-------------------------------------------------------------------------- def fiber_main(m_c, param_str) method(m_c).call(param_str) @fiber = nil @fiber = @fiber_tmp if @fiber_tmp @fiber_tmp = nil end #-------------------------------------------------------------------------- # ● 动作:淡入 #-------------------------------------------------------------------------- def fiber_fade_in(param_str = "") v = 255.0 / @params[:it] while(@opa < 255) @opa += v yield self if block_given? Fiber.yield end end def fiber_in(param_str = ""); fiber_fade_in(param_str); end #-------------------------------------------------------------------------- # ● 动作:淡出 #-------------------------------------------------------------------------- def fiber_fade_out(param_str = "") bind_window(nil) v = 255.0 / @params[:ot] while(@opa > 0) @opa -= v yield self if block_given? Fiber.yield end @flag_fin = true end def fiber_out(param_str = ""); fiber_fade_out(param_str); end #-------------------------------------------------------------------------- # ● 动作:跳跃 #-------------------------------------------------------------------------- def fiber_jump(param_str = "") t = 0 while t <= 10 @y1 = (t-5)**2 * 40 * 1.0/25 - 40 yield self if block_given? Fiber.yield t += 1 end end #-------------------------------------------------------------------------- # ● 动作:移动 #-------------------------------------------------------------------------- def fiber_move(param_str = "") h = { :x => nil, :y => nil, :dx => nil, :dy => nil, :t => 30 } MESSAGE_EX.parse_param(h, param_str, :t) init_x1 = @x1 des_x = init_x1 des_x = init_x1 + h[:dx] if h[:dx] des_x = h[:x] if h[:x] init_y1 = @y1 des_y = init_y1 des_y = init_y1 + h[:dy] if h[:dy] des_y = h[:y] if h[:y] return if init_x1 == des_x && init_y1 == des_y d_x = des_x - init_x1 d_y = des_y - init_y1 _i = 0; _t = h[:t] while(true) break if _i > _t per = _i * 1.0 / _t per = (_i == _t ? 1 : MESSAGE_EX.ease_value(:face_xy, per)) @x1 = (init_x1 + d_x * per).round @y1 = (init_y1 + d_y * per).round yield self if block_given? Fiber.yield _i += 1 end end end #============================================================================= # ○ 文字绘制类 #============================================================================= class Font_EagleCharacter attr_reader :text # 上一次绘制的文本 #-------------------------------------------------------------------------- # ● 初始化 #-------------------------------------------------------------------------- def initialize(font_params) @params = font_params.dup @text = "" end #-------------------------------------------------------------------------- # ● 设置参数 #-------------------------------------------------------------------------- def set_param(sym, value) @params[sym] = value end #-------------------------------------------------------------------------- # ● 获取文字颜色 # n : 文字颜色编号(0..31) #-------------------------------------------------------------------------- def text_color(n) MESSAGE_EX.text_color(n, MESSAGE_EX.windowskin(@params[:skin])) end #-------------------------------------------------------------------------- # ● 获取渐变色数组 #-------------------------------------------------------------------------- def get_gradient_color(str) result = [] param = str.downcase while(param != "") param.slice!(/\D+/) result.push((param.slice!(/\d+/)).to_i) end result end #-------------------------------------------------------------------------- # ● 执行文字绘制 #-------------------------------------------------------------------------- def draw(bitmap, x, y, w, h, c, ali = 0) @text = c bitmap.font.color = text_color(@params[:c]) MESSAGE_EX.apply_font_params(bitmap.font, @params) draw_param_p(bitmap, x, y, w, h) if @params[:p] draw_param_l(bitmap, x, y, w, h, c, ali) if @params[:l] if defined?(Sion_GradientText) && @params[:ex_cg] && @params[:ex_cg] != '' grad_cs = get_gradient_color(@params[:ex_cg]) Sion_GradientText.draw_text(bitmap,x,y,w*2,h,c,ali,grad_cs) else bitmap.draw_text(x, y, w*2, h, c, ali) end draw_param_m(bitmap, x, y, w, h) if @params[:m] draw_param_k(bitmap, x, y, w, h) if @params[:k] draw_param_d(bitmap) if @params[:d] draw_param_u(bitmap) if @params[:u] end #-------------------------------------------------------------------------- # ● 执行图标绘制 #-------------------------------------------------------------------------- def draw_icon(bitmap, x, y, icon_index) draw_param_p(bitmap, x, y, 24, 24) if @params[:p] draw_param_l_rect(bitmap, x, y, 24, 24) if @params[:l] _bitmap = Cache.system("Iconset") rect = Rect.new(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24) bitmap.blt(x, y, _bitmap, rect, 255) draw_param_m(bitmap, x, y, 24, 24) if @params[:m] draw_param_k(bitmap, x, y, 24, 24) if @params[:k] draw_param_d(bitmap) if @params[:d] draw_param_u(bitmap) if @params[:u] end #-------------------------------------------------------------------------- # ● 绘制底纹 #-------------------------------------------------------------------------- def draw_param_p(bitmap, x, y, w, h) color = text_color(@params[:pc]) case @params[:p] when 1 # 边框 bitmap.fill_rect(x, y, w, h, color) bitmap.clear_rect(x+1, y+1, w-2, h-2) when 2 # 纯色方块 bitmap.fill_rect(x, y, w, h, color) end end #-------------------------------------------------------------------------- # ● 绘制外发光 #-------------------------------------------------------------------------- def draw_param_l(bitmap, x, y, w, h, c, ali) bitmap.font.outline = false bitmap.font.shadow = false color = bitmap.font.color.dup bitmap.font.color = text_color(@params[:lc]) @params[:lp].times do bitmap.draw_text(x, y, w+4, h, c, ali) bitmap.blur end bitmap.font.color = color end def draw_param_l_rect(bitmap, x, y, w, h) c = text_color(@params[:lc]) bitmap.fill_rect(x, y, w, h, c) bitmap.blur end #-------------------------------------------------------------------------- # ● 绘制删除线 #-------------------------------------------------------------------------- def draw_param_d(bitmap) c = text_color(@params[:dc]) bitmap.fill_rect(0, bitmap.height/2 - 1, bitmap.width, 1, c) end #-------------------------------------------------------------------------- # ● 绘制下划线 #-------------------------------------------------------------------------- def draw_param_u(bitmap) c = text_color(@params[:uc]) bitmap.fill_rect(0, bitmap.height - 1, bitmap.width, 1, c) end #-------------------------------------------------------------------------- # ● 绘制叠加文字 #-------------------------------------------------------------------------- def draw_param_m(bitmap, x, y, w, h) color = bitmap.font.color.dup bitmap.font.color = text_color(@params[:mc]) if @params[:mc] >= 0 @params[:m].each do |c| if c.is_a?(Integer) _bitmap = Cache.system("Iconset") rect = Rect.new(c % 16 * 24, c / 16 * 24, 24, 24) bitmap.blt(x+w/2-12, y+h/2-12, _bitmap, rect, 255) else bitmap.draw_text(x, y, w, h, c, 1) end end bitmap.font.color = color end #-------------------------------------------------------------------------- # ● 文字破碎 #-------------------------------------------------------------------------- def draw_param_k(bitmap, x, y, w, h) v = @params[:kv] if v >= 100 bitmap.clear_rect(x, y, w, h) return end for xi in x...(x + w) for yi in y...(y + h) c = bitmap.get_pixel(xi, yi) next if c.alpha == 0 bitmap.set_pixel(xi, yi, Color.new(255,255,255, 0)) if rand(100) < v end end end #-------------------------------------------------------------------------- # ● 执行图片绘制 #-------------------------------------------------------------------------- def draw_pic(bitmap, pic_bitmap, h) bitmap.stretch_blt(bitmap.rect, pic_bitmap, pic_bitmap.rect, h[:opa]) end end #============================================================================= # ○ 单个文字的精灵 #============================================================================= class Sprite_EagleCharacter < Sprite attr_reader :origin_x, :origin_y, :_x, :_y, :eagle_font attr_accessor :flag_update_pos #-------------------------------------------------------------------------- # ● 初始化对象 # window_bind :所绑定的显示窗口,需要有以下方法 # .z 返回窗口的z值(当前文字精灵将高于该值) # .eagle_charas_x0 .eagle_charas_y0 返回文字显示区域的左上角坐标(屏幕坐标) # .eagle_charas_ox .eagle_charas_oy 返回文字显示区域的显示原点(文字区域坐标) # .eagle_charas_max_h 返回文字区域的最大高度 # font_bind :所绑定的字符绘制类 Font_EagleCharacter 的对象 #-------------------------------------------------------------------------- def initialize(window_bind, font_bind, x, y, w, h, viewport = nil) super(viewport) bind_viewport(viewport) bind_window(window_bind) bind_font(font_bind) reset(x, y, w, h) end #-------------------------------------------------------------------------- # ● 释放 #-------------------------------------------------------------------------- def dispose self.bitmap.dispose if !self.bitmap.disposed? super end #-------------------------------------------------------------------------- # ● 获取文字在屏幕上的碰撞矩形(计算了绑定的viewport的位置) #-------------------------------------------------------------------------- def screen_rect r = Rect.new(self.x - self.ox, self.y - self.oy, self.width, self.height) if self.viewport r.x += self.viewport.rect.x r.y += self.viewport.rect.y end r end #-------------------------------------------------------------------------- # ● 文字中心点是否在视图内部? #-------------------------------------------------------------------------- def in_viewport? return true if self.viewport.nil? lux = self.x; luy = self.y rdx = lux + self.width; rdy = luy + self.height return false if lux < 0 || rdx > self.viewport.rect.width return false if luy < 0 || rdy > self.viewport.rect.height return true end #-------------------------------------------------------------------------- # ● 设置绑定的视图 #-------------------------------------------------------------------------- def bind_viewport(vp) @viewport_bind = vp self.viewport = vp end # 临时解绑与重新绑定 def unbind_viewport self.viewport = nil end def rebind_viewport self.viewport = @viewport_bind end #-------------------------------------------------------------------------- # ● 设置绑定的窗口 #-------------------------------------------------------------------------- def bind_window(window_bind) @window_bind = window_bind self.z = @window_bind.z + 1 if @window_bind end #-------------------------------------------------------------------------- # ● 设置绑定的绘制参数 #-------------------------------------------------------------------------- def bind_font(font_bind) @eagle_font = font_bind end #-------------------------------------------------------------------------- # ● 在位置不变的情况下,文字精灵不再受限于对话框 #-------------------------------------------------------------------------- def free_from_msg reset_oxy(7) bind_viewport(nil) # 取消视图,确保不会出现资源崩溃,且不再限制可见范围 update_position # 更新一次位置,用于刷新保存的@x0和@_ox @window_bind = nil # 取消窗口的绑定 end #-------------------------------------------------------------------------- # ● 重置 #-------------------------------------------------------------------------- def reset(x, y, w, h) self.bitmap.dispose if self.bitmap self.bitmap = Bitmap.new(w, h) # (x0,y0) 当前的文字显示区域的左上角的屏幕坐标 @x0 = 0; @y0 = 0 # (_ox,_oy) 当前的文字显示区域的显示原点位置(对话框内部坐标系) @_ox = 0; @_oy = 0 # 左对齐时,本文字的显示位置(存储为标准位置,方便对齐) @origin_x = x; @origin_y = y # 设置本文字的显示位置 reset_xy(x, y) reset_oxy(7) # 重置参数 @dx = 0; @dy = 0 # 动态移动时的偏移值 @flag_first_move_in = true # 第一次移入? @flag_update_pos = true # 需要更新位置? @flag_move = nil # 在移动中? # 重置特效参数 @effects = {} # effect_sym => param_string @effect_params = {} # effect_sym => param_has # 重置精灵参数 self.src_rect = Rect.new(0,0,self.width,self.height) self.zoom_x = self.zoom_y = 1.0 self.angle = 0 self.wave_amp = 0 self.wave_length = 0 self.wave_speed = 0 self.wave_phase = 0 self.mirror = false self.blend_type = 0 self.color = Color.new(255,255,255,0) self.opacity = 255 self.visible = true end #-------------------------------------------------------------------------- # ● 设置相对偏移值(以对话框中的文字显示区域的屏幕左上角为原点) #-------------------------------------------------------------------------- def reset_xy(x = nil, y = nil) @_x = x if x # 存储文字相对对话框左上角的显示位置 @_y = y if y end #-------------------------------------------------------------------------- # ● 设置移动增量 #-------------------------------------------------------------------------- def reset_dxy(dx = nil, dy = nil) @dx = dx if dx @dy = dy if dy end #-------------------------------------------------------------------------- # ● 设置显示原点 #-------------------------------------------------------------------------- def reset_oxy(o) MESSAGE_EX.reset_sprite_oxy(self, o) end #-------------------------------------------------------------------------- # ● 设置显示视图的原点位置 # (当在移入移出时,若所绑定窗口的内容原点变动,靠此方法强制移动) #-------------------------------------------------------------------------- def reset_window_oxy(ox = nil, oy = nil) @_ox = ox if ox @_oy = oy if oy end #-------------------------------------------------------------------------- # ● 结束 #-------------------------------------------------------------------------- def finish @flag_move = :end self.opacity = 0 end #-------------------------------------------------------------------------- # ● 结束使命?(在文字池中使用,进行文字精灵的复用) #-------------------------------------------------------------------------- def finish? @flag_move == :end end #-------------------------------------------------------------------------- # ● 解析参数 #-------------------------------------------------------------------------- def parse_param(params, param_s, default_type = "default") MESSAGE_EX.parse_param(params, param_s, default_type) end #-------------------------------------------------------------------------- # ● 初始化特效的默认参数 #-------------------------------------------------------------------------- def init_effect_params(sym) MESSAGE_EX.get_default_params(sym) end #-------------------------------------------------------------------------- # ● 开始特效(整合) #-------------------------------------------------------------------------- def start_effects(effects) @effects = {} # code_symbol => param_string effects.each { |sym, param_s| start_effect(sym, param_s) } end #-------------------------------------------------------------------------- # ● 开始特效 #-------------------------------------------------------------------------- def start_effect(sym, param_s) @effects[sym] = param_s @effect_params[sym] = init_effect_params(sym).dup # 初始化 m = ("start_effect_" + sym.to_s).to_sym method(m).call(@effect_params[sym], param_s.dup) if respond_to?(m) end # def start_effect_code(param) code → 转义符 # end #-------------------------------------------------------------------------- # ● 更新特效(整合) #-------------------------------------------------------------------------- def update_effects @effects.each { |sym, param_s| m = ("update_effect_" + sym.to_s).to_sym method(m).call(@effect_params[sym]) if respond_to?(m) } end # def update_effect_code(param) code → 转义符 # end #-------------------------------------------------------------------------- # ● 结束特效(整合) #-------------------------------------------------------------------------- def finish_effects @effects.each { |sym, param| m = ("finish_effect_" + sym.to_s).to_sym method(m).call(@effect_params[sym]) if respond_to?(m) } @effects.clear end #-------------------------------------------------------------------------- # ● 结束特效 #-------------------------------------------------------------------------- def finish_effect(sym) return if [email protected]?(sym) m = ("finish_effect_" + sym.to_s).to_sym method(m).call(@effect_params[sym]) if respond_to?(m) @effects.delete(sym) end # def finish_effect_code(param) code → 转义符 # end #-------------------------------------------------------------------------- # ● 更新 #-------------------------------------------------------------------------- def update return if finish? update_position if @flag_update_pos return move_update(@flag_move) if @flag_move if update_effects? super update_effects end end #-------------------------------------------------------------------------- # ● 可以更新特效? #-------------------------------------------------------------------------- def update_effects? self.visible && !finish? && [email protected]? end #-------------------------------------------------------------------------- # ● 更新位置 #-------------------------------------------------------------------------- def update_position self.x = @_x + @dx + self.ox self.y = @_y + @dy + self.oy if @window_bind @x0 = @window_bind.eagle_charas_x0 @y0 = @window_bind.eagle_charas_y0 if self.viewport @_ox = @window_bind.eagle_charas_ox @_oy = @window_bind.eagle_charas_oy self.x -= self.viewport.rect.x self.y -= self.viewport.rect.y end end self.x += (@x0 - @_ox) self.y += (@y0 - @_oy) end #-------------------------------------------------------------------------- # ● 更新移动 #-------------------------------------------------------------------------- def move_update(sym = :cin) # 只有移动结束时,才进行其他更新 params = @effect_params[sym] params[:tc] += 1 per = params[:tc] * 1.0 / params[:t] per = (params[:tc] == params[:t] ? 1 : MESSAGE_EX.ease_value(:chara_xy, per)) @dx = (params[:dx_init] + params[:dx_d] * per).round @dy = (params[:dy_init] + params[:dy_d] * per).round if (params[:rxc] += 1) == params[:rxt] params[:rxc] = 0 self.src_rect.x += params[:rx] end if (params[:ryc] += 1) == params[:ryt] params[:ryc] = 0 self.src_rect.y += params[:ry] end (params[:vzc] = 0;@_zoom += params[:vz]) if (params[:vzc] += 1) == params[:vzt] self.zoom_x = self.zoom_y = 1.0 + @_zoom/100.0 self.angle += params[:va] self.opacity += params[:vo] move_end(sym) if params[:tc] == params[:t] end def move_end(sym = :cin) @flag_move = nil rebind_viewport reset_oxy(7) if sym == :cin @dx = @dy = 0 update_position self.zoom_x = self.zoom_y = 1.0 self.opacity = 255 @flag_first_move_in = false elsif sym == :cout finish @flag_move = :end end end #-------------------------------------------------------------------------- # ● 正在进行移入移出? #-------------------------------------------------------------------------- def move_updating? @flag_move != nil end #-------------------------------------------------------------------------- # ● 移入 #-------------------------------------------------------------------------- def start_effect_cin(params, param_s, flag_move_in = true) parse_param(params, param_s) params[:t] = 1 if params[:t] < 1 params[:vzc] = 0 # 计数用 params[:vzt] = 1 if params[:vzt] < 1 rand_cin(params, param_s) if params[:r] != 0 _vo = 255 / params[:t] # 移入时每帧不透明度增量 params[:vo] = [_vo, params[:vo], 1].max params[:rxc] = 0; params[:ryc] = 0 params[:rxt] = 1 if params[:rxt] < 1 params[:ryt] = 1 if params[:ryt] < 1 move_in if flag_move_in end #-------------------------------------------------------------------------- # ● 随机移入 #-------------------------------------------------------------------------- RAND_V = lambda { |v| rand(v * 2 + 1) - v } def rand_cin(params, param_s) params[:t] = rand(params[:t]) + 1 params[:vz] = RAND_V.call(params[:vz]) params[:vzt] = rand(params[:vzt]) + 1 params[:va] = RAND_V.call(params[:va]) params[:dx] = RAND_V.call(params[:dx]) params[:dy] = RAND_V.call(params[:dy]) end #-------------------------------------------------------------------------- # ● 执行移入 #-------------------------------------------------------------------------- def move_in params = @effect_params[:cin] rebind_viewport # 重新绑定视图 update_position # 记录包含视图位移的值 # 如果没有定义移入特效 或 不是首次移入且在视图外 if params.nil? || (!@flag_first_move_in && !in_viewport?) self.opacity = 255 # 直接指定不透明度 @flag_move = nil return end unbind_viewport # 为了移入,先取消视图 @dx = @dy = 0 update_position # 用于获取实际的最终显示位置(屏幕坐标) _rect = Rect.new(self.x, self.y, self.width, self.height) if params[:do] != 0 MESSAGE_EX.reset_xy_dorigin(_rect, @window_bind, params[:do]) end @dx = params[:dx_init] = _rect.x + params[:dx] - self.x @dy = params[:dy_init] = _rect.y + params[:dy] - self.y params[:dx_d] = self.x - (_rect.x + params[:dx]) params[:dy_d] = self.y - (_rect.y + params[:dy]) @_zoom = -(params[:t]/params[:vzt]) * params[:vz] self.angle = -params[:t] * params[:va] self.src_rect.x = -(params[:t]/params[:rxt]) * params[:rx] self.src_rect.y = -(params[:t]/params[:ryt]) * params[:ry] self.zoom_x = self.zoom_y = 1.0 + @_zoom/100.0 self.opacity = 0 reset_oxy(5) params[:tc] = 0 @flag_move = :cin end #-------------------------------------------------------------------------- # ● 移出 #-------------------------------------------------------------------------- def start_effect_cout(params, param_s) start_effect_cin(params, param_s, false) params[:vo] *= -1 end #-------------------------------------------------------------------------- # ● 执行移出(外部调用的方法) #-------------------------------------------------------------------------- def move_out finish_effects # 先结束全部特效 finish if !in_viewport? # 若精灵在视图外,则会直接结束 if !finish? process_move_out # 处理移出模式 end free_from_msg # 不再受限于对话框内,但位置保持不变 MESSAGE_EX.charapool_push(self) # 由文字池接管 end #-------------------------------------------------------------------------- # ● 执行移出(外部调用的方法)(临时移出,之后可以再执行move_in) #-------------------------------------------------------------------------- def move_out_temp finish if !in_viewport? # 若精灵在视图外,则会直接结束 unbind_viewport if !finish? process_move_out update_position end end #-------------------------------------------------------------------------- # ● 处理移出模式 #-------------------------------------------------------------------------- def process_move_out if @effect_params[:cout] && !@effect_params[:cout].empty? return move_out_cout(@effect_params[:cout]) end if @effect_params[:uout] && !@effect_params[:uout].empty? return move_out_uout(@effect_params[:uout]) end finish # 如果未预订任何移出模式,则直接结束 end #-------------------------------------------------------------------------- # ● 执行默认移出 #-------------------------------------------------------------------------- def move_out_cout(params) _x = self.x; _y = self.y if(self.viewport) _x += self.viewport.rect.x; _y += self.viewport.rect.y end _rect = Rect.new(_x, _y, self.width, self.height) if params[:do] != 0 MESSAGE_EX.reset_xy_dorigin(_rect, @window_bind, params[:do]) MESSAGE_EX.reset_xy_origin(_rect, 5) end params[:dx_init] = 0 params[:dy_init] = 0 params[:dx_d] = (_rect.x + params[:dx]) - _x params[:dy_d] = (_rect.y + params[:dy]) - _y @dx = @dy = @_zoom = 0 reset_oxy(5) params[:tc] = 0 @flag_move = :cout end #-------------------------------------------------------------------------- # ● 消散移出 #-------------------------------------------------------------------------- def start_effect_uout(params, param_s) parse_param(params, param_s) params[:dir] = MESSAGE_EX::CU_PARAM_DIR[ params[:dir] ] params[:s] = MESSAGE_EX::CU_PARAM_S[ params[:s] ] end def move_out_uout(params) _x = self.x; _y = self.y if(self.viewport) _x += self.viewport.rect.x; _y += self.viewport.rect.y end Unravel_Bitmap.new(_x, _y, self.bitmap.clone, 0, 0, self.width, self.height, params[:n], params[:d], params[:o], params[:dir], params[:s]) finish end #-------------------------------------------------------------------------- # ● 正弦扭曲特效 #-------------------------------------------------------------------------- def start_effect_csin(params, param_s) parse_param(params, param_s) self.wave_amp = params[:a] self.wave_length = params[:l] self.wave_speed = params[:s] self.wave_phase = params[:p] end #-------------------------------------------------------------------------- # ● 波浪特效 #-------------------------------------------------------------------------- def start_effect_cwave(params, param_s) params[:tc] = 0 # 移动计数用初值(一次性) parse_param(params, param_s) end def update_effect_cwave(params) return if (params[:tc] += 1) < params[:t] params[:tc] = 0 @dy += params[:vy] params[:vy] *= -1 if @dy < -params[:h] || @dy > params[:h] end #-------------------------------------------------------------------------- # ● 抖动特效 #-------------------------------------------------------------------------- def start_effect_cshake(params, param_s) params[:vxc] = 0 # 移动计数用初值(一次性) params[:vyc] = 0 # 移动计数用初值(一次性) parse_param(params, param_s) params[:vx] = rand(2) * 2 - 1 if params[:vx] == 0 params[:vy] = rand(2) * 2 - 1 if params[:vy] == 0 end def update_effect_cshake(params) if (params[:vxc] += 1) > params[:vxt] params[:vxc] = 0 @dx += params[:vx] params[:vx] *= -1 if @dx < -params[:l] || @dx > params[:r] end if (params[:vyc] += 1) > params[:vyt] params[:vyc] = 0 @dy += params[:vy] params[:vy] *= -1 if @dy < -params[:u] || @dy > params[:d] end end #-------------------------------------------------------------------------- # ● 抖动特效2 #-------------------------------------------------------------------------- def start_effect_cshake2(params, param_s) parse_param(params, param_s) end def update_effect_cshake2(params) @dx = (-1.0 + params[:l] * rand()) * params[:dx] @dy = (-1.0 + params[:l] * rand()) * params[:dy] end #-------------------------------------------------------------------------- # ● 摇摆特效 #-------------------------------------------------------------------------- def start_effect_cswing(params, param_s) params[:ac] = 0 # 当前偏移角度和 params[:tc] = 0 parse_param(params, param_s) reset_oxy(params[:o]) self.angle = 0 end def update_effect_cswing(params) return if (params[:tc] -= 1) > 0 if params[:d] == 0 params[:ac] = self.angle == 0 ? rand(2)*2-1 : (self.angle > 0 ? -1 : 1) params[:ac] *= params[:a] else params[:ac] += params[:d] params[:tc] = params[:t] end if params[:ac].abs >= params[:a] params[:ac] = params[:a] * (params[:ac] > 0 ? 1 : -1) params[:d] *= -1 params[:tc] = params[:t2] end self.angle = params[:ac] end #-------------------------------------------------------------------------- # ● 缩放特效 #-------------------------------------------------------------------------- def start_effect_czoom(params, param_s) params[:tc] = 0 # 计时 parse_param(params, param_s) params[:zoom_x] = 100 # 初始的总缩放量 params[:zoom_y] = 100 reset_oxy(params[:o]) end def update_effect_czoom(params) return if (params[:tc] -= 1) > 0 params[:tc] = params[:t] if params[:dx] != 0 params[:zoom_x] += params[:dx] params[:dx] *= -1 if params[:zoom_x] > params[:max] || params[:zoom_x] < params[:min] self.zoom_x = params[:zoom_x] * 1.0 / 100 end if params[:dy] != 0 params[:zoom_y] += params[:dy] params[:dy] *= -1 if params[:zoom_y] > params[:max] || params[:zoom_y] < params[:min] self.zoom_y = params[:zoom_y] * 1.0 / 100 end end #-------------------------------------------------------------------------- # ● 闪烁特效 #-------------------------------------------------------------------------- def start_effect_cflash(params, param_s) params[:tc] = 0 # 闪烁后的等待时间计数 parse_param(params, param_s) params[:color] = Color.new(params[:r], params[:g], params[:b], params[:a]) end def update_effect_cflash(params) return if (params[:tc] -= 1) > 0 params[:tc] = params[:t] + params[:d] self.flash(params[:color], params[:d]) end #-------------------------------------------------------------------------- # ● 镜像特效 #-------------------------------------------------------------------------- def start_effect_cmirror(params, param_s) params[:b] = '0' parse_param(params, param_s, :b) self.mirror = (params[:b] == '0' ? false : true) end def finish_effect_cmirror(params) self.mirror = false end #-------------------------------------------------------------------------- # ● 消散特效 #-------------------------------------------------------------------------- def start_effect_cu(params, param_s) params[:t_c] = 0 # 间隔计数 parse_param(params, param_s) params[:dir] = MESSAGE_EX::CU_PARAM_DIR[ params[:dir] ] params[:s] = MESSAGE_EX::CU_PARAM_S[ params[:s] ] end def update_effect_cu(params) return if !in_viewport? return if (params[:t_c] += 1) < params[:t] params[:t_c] = 0 _x = self.x; _y = self.y if(self.viewport) _x += self.viewport.rect.x; _y += self.viewport.rect.y end Unravel_Bitmap.new(_x, _y, self.bitmap.clone, 0, 0, self.width, self.height, params[:n], params[:d], params[:o], params[:dir], params[:s]) end #-------------------------------------------------------------------------- # ● 位图切换特效 #-------------------------------------------------------------------------- def start_effect_ctog(params, param_s) parse_param(params, param_s) params[:bitmaps] = [] params[:bitmaps].push(self.bitmap) charas = MESSAGE_EX.get_charas_array(:ctog, params[:i], params[:n]) charas.each do |c| s = Bitmap.new(self.width, self.height) if c.is_a?(Integer) @eagle_font.draw_icon(s, 0+self.width/2-12, 0+self.height/2-12, c) else r = s.text_size(c) @eagle_font.draw(s, (self.width-r.width)/2, (self.height-r.height)/2, self.width, self.height, c, 0) end params[:bitmaps].push(s) end params[:i_cur] = 0 params[:i_max] = params[:bitmaps].size params[:tc] = 0 end def update_effect_ctog(params) return if (params[:tc] += 1) < params[:t] params[:tc] = 0 if(params[:r] > 0) params[:i_cur] = rand(params[:i_max]) else params[:i_cur] += 1 params[:i_cur] %= params[:i_max] end self.bitmap = params[:bitmaps][params[:i_cur]] end def finish_effect_ctog(params) self.bitmap = params[:bitmaps].shift params[:bitmaps].each { |b| b.dispose } params[:bitmaps].clear end #-------------------------------------------------------------------------- # ● 霓虹灯特效 #-------------------------------------------------------------------------- def start_effect_cneon(params, param_s) params[:c] = [] s = param_s.downcase while(s != "") sym = s.slice!(/\D+/) v = (s.slice!(/\d+/)).to_i next params[:c].push(v) if sym == "c" params[sym.to_sym] = v end params[:tc] = 0 params[:c1] = self.color params[:c1].alpha = 255 params[:c2] = @window_bind.text_color(params[:c][0]) params[:i] = 0 end def update_effect_cneon(params) return if @window_bind.nil? params[:tc] += 1 self.color.red = params[:c1].red + (params[:c2].red - params[:c1].red)*1.0/ params[:t] * params[:tc] self.color.green = params[:c1].green + (params[:c2].green - params[:c1].green)*1.0 / params[:t] * params[:tc] self.color.blue = params[:c1].blue + (params[:c2].blue - params[:c1].blue)*1.0 / params[:t] * params[:tc] if params[:tc] >= params[:t] params[:c1] = @window_bind.text_color(params[:c][params[:i]]) params[:i] += 1 params[:i] = 0 if params[:i] >= params[:c].size params[:c2] = @window_bind.text_color(params[:c][params[:i]]) params[:tc] = 0 end end #-------------------------------------------------------------------------- # ● 文字叠加绘制 #-------------------------------------------------------------------------- def start_effect_cmc(params, param_s) parse_param(params, param_s) charas = MESSAGE_EX.get_charas_array(:cmc, params[:i], params[:n]) @eagle_font.set_param(:m, charas) @eagle_font.set_param(:mc, params[:c]) end #-------------------------------------------------------------------------- # ● 跳跃特效 #-------------------------------------------------------------------------- def start_effect_cjump(params, param_s) parse_param(params, param_s) params[:tc] *= -1 # 二次函数的x项系数 params[:A] = (4.0 * params[:h]) / (params[:t] * params[:t]) end def update_effect_cjump(params) if params[:tc] < 0 # 等待中 elsif params[:tc] <= params[:t] # 跳跃中 @dy = (params[:tc]-params[:t]/2)**2 * params[:A] - params[:h] elsif params[:w] && params[:tc] >= params[:t] + params[:w] # 跳跃后的等待结束 params[:tc] = 0 end params[:tc] += 1 end #-------------------------------------------------------------------------- # ● 明灭特效 #-------------------------------------------------------------------------- def start_effect_cfk(params, param_s) parse_param(params, param_s) params[:c] = 0 params[:wait] = 0 end def update_effect_cfk(params) return if params[:wait] == nil || (params[:wait] -= 1) > 0 if params[:c] == 0 self.opacity = 255 if params[:t] > 0 params[:t_] = params[:t] params[:dopa] = 255.0 / params[:t_] elsif params[:t] == 0 params[:t_] = MESSAGE_EX::CFK_T0_WAIT params[:dopa] = 255 else params[:t_] = rand(-params[:t]) params[:dopa] = 255.0 / params[:t_] end end params[:c] += 1 self.opacity += (params[:c]<=params[:t_] ? -params[:dopa] : params[:dopa]) if self.opacity >= 255 params[:c] = 0 params[:wait] = params[:w] end end end #============================================================================= # ○ 兼容模式 #============================================================================= module MESSAGE_EX::COMPA_MODE #-------------------------------------------------------------------------- # ● 更新画面 #-------------------------------------------------------------------------- def update_all_windows if $game_message.eagle_message == true @message_window = @msg_windows[1] else @message_window = @msg_windows[0] end eagle_message_ex_compa_mode_update_all_windows end #-------------------------------------------------------------------------- # ● 释放所有窗口 #-------------------------------------------------------------------------- def dispose_all_windows @msg_windows.each { |w| w.dispose } @message_window = nil eagle_message_ex_compa_mode_dispose_all_windows end end #============================================================================= # ○ Scene_Map #============================================================================= class Spriteset_Map; attr_reader :character_sprites; end class Scene_Map attr_reader :spriteset, :message_window if EAGLE_MSG_EX_COMPAT_MODE == true alias eagle_message_ex_compa_mode_update_all_windows update_all_windows alias eagle_message_ex_compa_mode_dispose_all_windows dispose_all_windows include MESSAGE_EX::COMPA_MODE #-------------------------------------------------------------------------- # ● 生成信息窗口 #-------------------------------------------------------------------------- alias eagle_message_ex_compa_mode_create_message_window create_message_window def create_message_window eagle_message_ex_compa_mode_create_message_window @msg_windows = [@message_window, Window_EagleMessage.new] end else #-------------------------------------------------------------------------- # ● 生成信息窗口 #-------------------------------------------------------------------------- def create_message_window @message_window = Window_EagleMessage.new end end end #============================================================================= # ○ Scene_Battle #============================================================================= class Scene_Battle attr_reader :spriteset, :message_window if EAGLE_MSG_EX_COMPAT_MODE == true alias eagle_message_ex_compa_mode_update_all_windows update_all_windows alias eagle_message_ex_compa_mode_dispose_all_windows dispose_all_windows include MESSAGE_EX::COMPA_MODE #-------------------------------------------------------------------------- # ● 生成信息窗口 #-------------------------------------------------------------------------- alias eagle_message_ex_compa_mode_create_message_window create_message_window def create_message_window eagle_message_ex_compa_mode_create_message_window @msg_windows = [@message_window, Window_EagleMessage.new] end else #-------------------------------------------------------------------------- # ● 生成信息窗口 #-------------------------------------------------------------------------- def create_message_window @message_window = Window_EagleMessage.new end end end |
百里_飞柳 发表于 2024-7-15 20:02 我在事件页设置的文本为居中,设置第二项文本时候本来设置的巨下,但是却和上一个文本一样执行起来还是居中 |
百里_飞柳 发表于 2024-7-15 20:02 方便的话价加个企鹅或者啥的呗 |
zhang493154524 发表于 2024-7-15 18:17 名字加框是指什么,具体是怎么编写的转义符呢? 最好直接把文本内容列出来 |
百里_飞柳 发表于 2024-6-21 17:26 大佬你对对话框就是设置名字加框文本之后,然后加一个不设置名字的文本,然后再加上设置名字加框的文本,名字就不显示了,怎么破 |
本帖最后由 zhang493154524 于 2024-7-13 05:16 编辑 百里_飞柳 发表于 2024-6-21 17:26 名字是蓝色的怎么改成黄色 |
站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作
GMT+8, 2024-11-21 23:06
Powered by Discuz! X3.1
© 2001-2013 Comsenz Inc.