Project1
标题:
求助bug,yanfly的物品提示窗口
[打印本页]
作者:
129s
时间:
2022-12-27 21:40
标题:
求助bug,yanfly的物品提示窗口
在draw_item那里我重新写了下,想让文本居中,但是现在情况是每次清空后,文本就对不齐了,会往左偏一点,有没有大佬知道这是为啥
就是这两句:363行
temp=(YEA::EVENT_WINDOW::WINDOW_WIDTH-text_size(item).width)/2+24
draw_text_ex(temp, rect.y, item)
其实我就是想让文本居中下
#==============================================================================
#
# ▼ Yanfly Engine Ace - 得失提示 v1.01
# -- 最后更新: 2011.12.27
# -- 使用难度: 简单, 普通
# -- 需要脚本: 无
#
#==============================================================================
$imported = {} if $imported.nil?
$imported["YEA-EventWindow"] = true
#==============================================================================
# ▼ Updates
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 2011.12.27 - Bug Fixed: Used the wrong script to hide event window.
# 2011.12.26 - Started Script and Finished.
#
#==============================================================================
# ▼ 介绍
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 可以在得到或失去物品武器金钱等时,在画面左下角显示一个得失提示窗口。
#
#==============================================================================
# ▼ 安装方式
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 打开脚本编辑器,将本脚本拷贝/复制到一个在▼ 插件脚本之下▼ Main之上的新
# 脚本页/槽中.记得保存你的工程以使脚本生效.
#
# -----------------------------------------------------------------------------
# 脚本 - 可使用的脚本.
# -----------------------------------------------------------------------------
# event_window_add_text(文本)
# 以得失提示窗口的方式显示"文本"的脚本. 使用 \n 来分行.如果你想用文本代码,记得
# 将单斜杠改为双斜杠,类似: \\n[2] 或 \\c[3] .
#
# event_window_clear_text
# 消除全部得失提示窗口的脚本,可以在切换地图时使用.
#
#==============================================================================
# ▼ 兼容性
# =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
# 本脚本仅为RPG Maker VX Ace编写.极不可能在无任何修改的情况下运行于RPG Maker VX.
#
#==============================================================================
module YEA
module EVENT_WINDOW
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# - 得失提示窗口的开关 -
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
HIDE_SWITCH = 24 # 开关开启时,关闭得失提示窗口的功能.
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# - 通用得失提示窗口设置 -
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
NEW_MAP_CLEAR = true # 是否在进入一个新地图前清空所有得失提示窗口?
WINDOW_WIDTH = 640 # 得失提示窗口的宽度.
VISIBLE_TIME = 180 # 在消失前等待的时间,即显示时间(帧).
MAX_LINES = 1 # 显示的最大行数.
WINDOW_FADE = 6 # 淡出速率.
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
# - 得失提示窗口文本设置 -
#=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
HEADER_TEXT = "\e}- " # 文字开头文本.
FOUND_TEXT = "\ec[6]获得\ec[0] " # 获得的文本.
LOST_TEXT = "\ec[4]失去\ec[0] " # 失去的文本.
AMOUNT_TEXT = "×%s" # 数量的前缀.
CLOSER_TEXT = " -" # 文字结尾文本.
end # EVENT_WINDOW
end # YEA
#==============================================================================
# ▼ 编辑以下内容可能会出现电脑损坏、死机,电脑主人脑袋爆炸、昏迷、死亡或口臭
# 所以编辑了后果自负。
#==============================================================================
#==============================================================================
# ■ Switch
#==============================================================================
module Switch
#--------------------------------------------------------------------------
# self.hide_event_window
#--------------------------------------------------------------------------
def self.hide_event_window
return false if YEA::EVENT_WINDOW::HIDE_SWITCH <= 0
return $game_switches[YEA::EVENT_WINDOW::HIDE_SWITCH]
end
end # Switch
#==============================================================================
# ■ Numeric
#==============================================================================
class Numeric
#--------------------------------------------------------------------------
# new method: group_digits
#--------------------------------------------------------------------------
unless $imported["YEA-CoreEngine"]
def group; return self.to_s; end
end # $imported["YEA-CoreEngine"]
end # Numeric
#==============================================================================
# ■ Game_Temp
#==============================================================================
class Game_Temp
#--------------------------------------------------------------------------
# public instance variables
#--------------------------------------------------------------------------
attr_accessor :event_window_data
#--------------------------------------------------------------------------
# new method: add_event_window_data
#--------------------------------------------------------------------------
def add_event_window_data(text)
@event_window_data = [] if @event_window_data.nil?
return if text == ""
@event_window_data.push(text)
end
#--------------------------------------------------------------------------
# new method: clear_event_window_data
#--------------------------------------------------------------------------
def clear_event_window_data
@event_window_data = []
end
end # Game_Temp
#==============================================================================
# ■ Game_Interpreter
#==============================================================================
class Game_Interpreter
#--------------------------------------------------------------------------
# alias method: command_126
#--------------------------------------------------------------------------
alias game_interpreter_command_125_ew command_125
def command_125
game_interpreter_command_125_ew
value = operate_value(@params[0], @params[1], @params[2])
event_window_make_gold_text(value)
end
#--------------------------------------------------------------------------
# alias method: command_126
#--------------------------------------------------------------------------
alias game_interpreter_command_126_ew command_126
def command_126
game_interpreter_command_126_ew
value = operate_value(@params[1], @params[2], @params[3])
event_window_make_item_text($data_items[@params[0]], value)
end
#--------------------------------------------------------------------------
# alias method: command_127
#--------------------------------------------------------------------------
alias game_interpreter_command_127_ew command_127
def command_127
game_interpreter_command_127_ew
value = operate_value(@params[1], @params[2], @params[3])
event_window_make_item_text($data_weapons[@params[0]], value)
end
#--------------------------------------------------------------------------
# alias method: command_128
#--------------------------------------------------------------------------
alias game_interpreter_command_128_ew command_128
def command_128
game_interpreter_command_128_ew
value = operate_value(@params[1], @params[2], @params[3])
event_window_make_item_text($data_armors[@params[0]], value)
end
#--------------------------------------------------------------------------
# new method: event_window_make_gold_text
#--------------------------------------------------------------------------
def event_window_make_gold_text(value)
return unless SceneManager.scene_is?(Scene_Map)
return if Switch.hide_event_window
if value > 0
text = YEA::EVENT_WINDOW::FOUND_TEXT
elsif value < 0
text = YEA::EVENT_WINDOW::LOST_TEXT
else; return
end
text += sprintf("%s%s", value.abs.group, Vocab::currency_unit)
event_window_add_text(text)
end
#--------------------------------------------------------------------------
# new method: event_window_make_item_text
#--------------------------------------------------------------------------
def event_window_make_item_text(item, value)
return unless SceneManager.scene_is?(Scene_Map)
return if Switch.hide_event_window
if value > 0
text = YEA::EVENT_WINDOW::FOUND_TEXT
elsif value < 0
text = YEA::EVENT_WINDOW::LOST_TEXT
else; return
end
text += sprintf("\ei[%d]%s", item.icon_index, item.name)
if value.abs > 1
fmt = YEA::EVENT_WINDOW::AMOUNT_TEXT
text += sprintf(fmt, value.abs.group)
end
event_window_add_text(text)
end
#--------------------------------------------------------------------------
# new method: event_window_add_text
#--------------------------------------------------------------------------
def event_window_add_text(text)
return unless SceneManager.scene_is?(Scene_Map)
return if Switch.hide_event_window
text = YEA::EVENT_WINDOW::HEADER_TEXT + text
text += YEA::EVENT_WINDOW::CLOSER_TEXT
SceneManager.scene.event_window_add_text(text)
end
#--------------------------------------------------------------------------
# new method: event_window_clear_text
#--------------------------------------------------------------------------
def event_window_clear_text
$game_temp.clear_event_window_data
end
end # Game_Interpreter
#==============================================================================
# ■ Window_EventWindow
#==============================================================================
class Window_EventWindow < Window_Selectable
#--------------------------------------------------------------------------
# initialize
#--------------------------------------------------------------------------
def initialize
dw = YEA::EVENT_WINDOW::WINDOW_WIDTH
super((Graphics.width-dw)/2,0, dw, fitting_height(YEA::EVENT_WINDOW::MAX_LINES))
#~ self.x -= 12
self.opacity = 0
self.contents_opacity = 0
@visible_counter = 0
modify_skin
deactivate
end
#--------------------------------------------------------------------------
# modify_skin
#--------------------------------------------------------------------------
def modify_skin
dup_skin = self.windowskin.dup
dup_skin.clear_rect(64, 0, 64, 64)
dup_skin.clear_rect(64, 64, 32, 32)
self.windowskin = dup_skin
end
#--------------------------------------------------------------------------
# item_max
#--------------------------------------------------------------------------
def item_max
return $game_temp.event_window_data ? $game_temp.event_window_data.size : 1
end
#--------------------------------------------------------------------------
# update
#--------------------------------------------------------------------------
def update
super
self.visible = show_window?
update_visible_counter
update_contents_opacity
end
#--------------------------------------------------------------------------
# show_window?
#--------------------------------------------------------------------------
def show_window?
return false if $game_message.visible
return true
end
#--------------------------------------------------------------------------
# update_visible_counter
#--------------------------------------------------------------------------
def update_visible_counter
return if @visible_counter <= 0
@visible_counter -= 1
end
#--------------------------------------------------------------------------
# update_contents_opacity
#--------------------------------------------------------------------------
def update_contents_opacity
return if @visible_counter > 0
return if self.contents_opacity <= 0
self.contents_opacity -= YEA::EVENT_WINDOW::WINDOW_FADE
end
#--------------------------------------------------------------------------
# instant_hide
#--------------------------------------------------------------------------
def instant_hide
@visible_counter = 0
self.contents_opacity = 0
end
#--------------------------------------------------------------------------
# add_text
#--------------------------------------------------------------------------
def add_text(text)
$game_temp.add_event_window_data(text)
refresh
self.contents_opacity = 255
@visible_counter = YEA::EVENT_WINDOW::VISIBLE_TIME
#~ change_y_position
select(item_max - 1)
end
#--------------------------------------------------------------------------
# change_y_position
#--------------------------------------------------------------------------
def change_y_position
maximum = [item_max, YEA::EVENT_WINDOW::MAX_LINES].min
self.y = Graphics.height - fitting_height(maximum) - 12
end
#--------------------------------------------------------------------------
# refresh
#--------------------------------------------------------------------------
def refresh
create_contents
draw_all_items
end
#--------------------------------------------------------------------------
# draw_item
#--------------------------------------------------------------------------
def draw_item(index)
$game_temp.clear_event_window_data if $game_temp.event_window_data.nil?
item = $game_temp.event_window_data[index]
return if item.nil?
rect = item_rect(index)
draw_background(rect)
temp=(YEA::EVENT_WINDOW::WINDOW_WIDTH-text_size(item).width)/2+24
draw_text_ex(temp, rect.y, item)
end
#--------------------------------------------------------------------------
# draw_background
#--------------------------------------------------------------------------
def draw_background(rect)
back_colour1 = Color.new(0, 0, 0, 192)
back_colour2 = Color.new(0, 0, 0, 0)
temp_rect=rect.clone
temp_rect.width /= 2
contents.gradient_fill_rect(temp_rect, back_colour2, back_colour1)
temp_rect.x+=temp_rect.width
contents.gradient_fill_rect(temp_rect, back_colour1, back_colour2)
end
end # Window_EventWindow
#==============================================================================
# ■ Scene_Map
#==============================================================================
class Scene_Map < Scene_Base
#--------------------------------------------------------------------------
# alias method: create_all_windows
#--------------------------------------------------------------------------
alias scene_map_create_all_windows_event_window create_all_windows
def create_all_windows
scene_map_create_all_windows_event_window
create_event_window
end
#--------------------------------------------------------------------------
# new method: create_event_window
#--------------------------------------------------------------------------
def create_event_window
@event_window = Window_EventWindow.new
end
#--------------------------------------------------------------------------
# new method: event_window_add_text
#--------------------------------------------------------------------------
def event_window_add_text(text)
@event_window.add_text(text)
end
#--------------------------------------------------------------------------
# alias method: post_transfer
#--------------------------------------------------------------------------
alias scene_map_post_transfer_ew post_transfer
def post_transfer
$game_temp.clear_event_window_data if YEA::EVENT_WINDOW::NEW_MAP_CLEAR
@event_window.instant_hide
scene_map_post_transfer_ew
end
end # Scene_Map
#==============================================================================
#
# ▼ End of File
#
#==============================================================================
复制代码
作者:
喵呜喵5
时间:
2022-12-27 23:21
本帖最后由 喵呜喵5 于 2022-12-27 23:28 编辑
text_size 不会处理转义符
text_size 计算文字尺寸时是不会处理这些转义符的,它会简单粗暴的直接根据文字的原始内容计算尺寸
因此第一个bug 是你用 text_size 计算出来的文字实际宽度是不准确的
bug 的影响就是你以为计算的结果可以让文字能保证居中,实际转义符多了位置偏左偏右都有可能
draw_text_ex 会修改窗口后续所有文本的字体大小
在 draw_text_ex 的文本中,遇到 \{ 时会让对应字体大小缩小,你配置的提示文本用到了这个特性。文字大小变化靠的是修改当前窗口的 contents.font.size 属性来实现的
因为 draw_text_ex 最开始都会调用 reset_font_settings 将字体的尺寸恢复为初始值保证每次绘制相同内容的结果都是一样的所以普通代码这样做没问题
但是在还没恢复初始值时你调用了 text_size ,而 text_size 是根据 contents.font.size 来计算文字宽度的结果的
所以,在 draw_text_ex 前加入一段代码:p contents.font.size 就会注意到:窗口在输出第一段提示的时候和输出后续几段提示的时候当前字体大小实际上不一样的,
因此就是你游戏里的表现在相同的提示文本下,第一段的位移和其他几段不一样
为什么是每次清空后文本就对不齐了
因为每次清空后会调用 refresh 方法,会删掉当前窗口的 content 新创建一个,相当于将字体大小恢复为初始值
解决方向
提供以下四种思路你自己挑个简单的:
1. 在 draw_text_ex 后面手动加上 reset_font_settings 重置一下字体大小,这样每次调用 text_size 时当前窗口的字体大小都是一致的了,然后大家就都是歪的了(喂)
2. 不使用 \{ ,而是直接在 create_contents 后面加上 contents.font.size = XXX 来手动设置字体大小,保证每次调用 text_size 时当前窗口的字体大小都是一致的
3. CLOSER_TEXT 里加上 \} 把文字尺寸复原回来
4. 自己写一个能正确处理转义符的 text_size 方法,参考我这脚本的 207 行
https://script.miaowm5.com/post/1
(我看了眼,代码实现太复杂了还是别参考了)(喂)
实现思路实际上就是在一个透明窗口上调用 draw_text_ex 绘制完文字后,看绘制完文字时的光标位置,从而得出实际的文字长度
作者:
喵呜喵5
时间:
2022-12-27 23:33
题外话:
这脚本的功能我没看懂,为啥就显示获得1个物品却需要把所有获得的物品都记录下来,并且每次获得物品还用全部都描绘一遍
这要是一直不触发切换地图自动清空的行为而疯狂获得物品,游戏不就炸了
作者:
129s
时间:
2022-12-28 10:33
喵呜喵5 发表于 2022-12-27 23:21
text_size 不会处理转义符
text_size 计算文字尺寸时是不会处理这些转义符的,它会简单粗暴的直接根据文字 ...
感谢喵佬
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X3.1