查看: 3725|回复: 14

[原创发布] 【Help窗口滚动】超限部分的说明文字滚动显示

[复制链接]
梦石
24
星屑
8942
在线时间
248 小时
注册时间
2020-12-4
回帖
259

极短24获奖极短23获奖极短22获奖

发表于 2022-6-23 13:44:09 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
本帖最后由 纯属小虫 于 2022-6-24 10:41 编辑

一直觉得help窗口文字超限之后,把文字压缩了不大美观
于是将说明文字做成了滚动显示的模式

效果:
序列 01.gif

附件下载:请塞个糖呗
说明窗口文字滚动.zip (202.71 KB, 下载次数: 34)


代码:塞个糖糖吧~
[fold=滚动窗口代码——可能会与跟help有关的窗口冲突]
[pre lang="ruby"]
=begin
作者:纯属小虫
想尝试一下滚动显示信息
以解决窗口大小不足而导致信息显示不全的问题
=end

# 参数设置
module Xiao虫
  # 等待开始滚动的帧数
  Help_window_flow_wait = 40
  # 滚动的速度(每帧滚动的像素值)
  Help_window_flow_speed = 2
end

#=============================================================================
# 帮助窗口重定义
#=============================================================================
class Window_Help
  # 导入初始参数,让 Bitmap 破限
  alias initialize_help_window_flow initialize
  def initialize
    initialize_help_window_flow
    @text_width_pro = 0
    @wait = Xiao虫::Help_window_flow_wait
    @speed = Xiao虫::Help_window_flow_speed
    @item_change = false
    @flow = false
  end

  # 重设文本框大小
  def set_text(text, align = 0)
    # 如果文本和对齐方式的至少一方与上次的不同
    if text != @text or align != @align
      @item_change = true
      @flow = true
      # 计算多于部分宽度
      bitmap = Bitmap.new(4,4)
      @text_width_pro = bitmap.text_size(text).width - 640 + 40
      bitmap.dispose
      @text_width_pro = 0 if @text_width_pro < 0
      self.contents.dispose unless self.contents.disposed?
      self.contents = Bitmap.new(width - 32 + @text_width_pro, height - 32)
      # 再描绘文本
      a = 640
      a = 0 if align == 1 #a是矩形拓展,如果是描绘敌人的居中显示时,则变成0
      self.contents.clear
      self.contents.font.color = normal_color
      self.contents.draw_text(4, 0, self.width - 40 + a, 32, text, align)
      @text = text
      @align = align
      @actor = nil
    end
    self.visible = true
  end

  # 屏蔽显示角色状态时的滚动
  alias set_actor_help_window_flow set_actor
  def set_actor(actor)
    set_actor_help_window_flow(actor)
    @flow = false
    @item_change == true
  end

  # 屏蔽显示敌人状态时的滚动
  alias set_enemy_help_window_flow set_enemy
  def set_enemy(enemy)
    set_enemy_help_window_flow(enemy)
    @flow = false
    @item_change == true
  end

  # 滚动帮助窗口
  def update
    # 引用父级的update
    super
    # 更换item之后,初始化滚动参数
    if @item_change == true
      self.ox = 0
      @wait = Xiao虫::Help_window_flow_wait
      @speed = Xiao虫::Help_window_flow_speed
      @item_change = false
    end
    # 如果没有扩展或者不滚动则直接跳过
    if @text_width_pro == 0 or @flow == false
      return
    end
    if self.contents != nil
      if @wait > 0
        @wait -= 1
        return
      end
      self.ox += @speed
      if self.ox + self.width - 32 >= self.contents.width
        @speed = -Xiao虫::Help_window_flow_speed
        @wait = Xiao虫::Help_window_flow_wait
      end
      if self.ox <= 0
        @speed = Xiao虫::Help_window_flow_speed
        @wait = Xiao虫::Help_window_flow_wait
      end

    end
  end
end


[/pre][/fold]

不过,由于RMXP的编码是UTF-8 汉字是三~四个字节
而汉字实际占用显示的像素空间是数字和字幕和空格的两倍,这种差异使得不大好计算描绘文字的实际像素长度
这里暂时没有解决精确计算字符串长度的问题,所以当说明文字里有比较多的空格和字母的时候,文字滚动会滚过头......



上述问题已经解决...代码附件已更新
直接用Bitmap 的text_size就可以计算文字实际像素长度了,我傻了...



2022/06/24  试图修正了未dispose的问题


评分

参与人数 2赞 +2 收起 理由
guoxiaomi + 1 塞糖
alexncf125 + 1 塞糖

查看全部评分

梦石
0
星屑
6483
在线时间
119 小时
注册时间
2020-1-8
回帖
205
发表于 2022-6-23 20:34:18 | 显示全部楼层
本帖最后由 RPGzh500223 于 2022-6-23 20:38 编辑

@text_width_pro = Bitmap.new(4,4)
self.contents = Bitmap.new(width - 32 + @text_width_pro, height - 32)
没考虑释放,这算是不小的问题了……

self.contents本身就是个Bitmap实例,可以self.contents.text_size计算描绘文字区域

点评

我忘了还有GC回收的机制了……/(ㄒoㄒ)/~~,其实RPG::Cache.clear就是个很明显的例子  发表于 2022-7-3 22:03
测试了一下,GC时这部分内容会被正常回收,那么其实也不算内存泄漏……  发表于 2022-6-24 12:18
第一点你可以打开任务管理器,不断切换选项,内存一直增加,很明显的内存泄漏了 第二点我只能说见仁见智了  发表于 2022-6-23 23:20
另外,没有直接用self.contents 是因为生成self.contents前需要计算宽度,如果用同一个,看起来有点别扭,所以就介入了另一个量@text_width_pro  发表于 2022-6-23 22:32
啊哈哈,@text_width_pro = Bitmap.new 其实就是个计算多于宽度的临时变量,最后被覆盖成数字了,我理解的应该是不用释放  发表于 2022-6-23 22:31

评分

参与人数 1赞 +1 收起 理由
纯属小虫 + 1 我很赞同

查看全部评分

回复 1 0

使用道具 举报

梦石
1
星屑
24088
在线时间
3339 小时
注册时间
2011-7-8
回帖
3862

开拓者

发表于 2022-6-24 02:07:33 | 显示全部楼层
本帖最后由 guoxiaomi 于 2022-6-24 12:19 编辑

2楼说的很对,你这样的写法会造成内存泄漏。(见下面楼层解释)RGSS的正常写法里,Window的contents属性都是在initialize方法里定义的,当然,这个时候必须知道窗口的宽和高。而绘制相关的方法里,只能使用self.contents.clear,然后开始绘制。

你仍然可以在 initialize 方法里先创建一个默认的 contents,然后在需要改变 contents 前(调用 self.contents = Bitmap.new 之前)释放之 self.contents.dispose 。
至于你的 @text_width_pro,这是一个实例变量,最好不要同时有 2 种类型,当你不想使用某个 Bitmap 时,必须主动调用 dispose 释放它。

=== 分割线 ===
说起来我写的新引擎里,Bitmap 除了 dispose 方法外,也会在 GC 时主动释放资源,从而避免内存泄漏,省心省力。
  1. class Bitmap
  2.   def self.create_finalizer
  3.     proc { |object_id| RGM::Base.bitmap_dispose(object_id) }
  4.   end

  5.   def initialize(*args)
  6.     # ...
  7.     ObjectSpace.define_finalizer(self, self.class.create_finalizer)
  8.   end
  9. end
复制代码

评分

参与人数 1赞 +1 收起 理由
纯属小虫 + 1 我很赞同

查看全部评分

熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复

使用道具 举报

梦石
24
星屑
8942
在线时间
248 小时
注册时间
2020-12-4
回帖
259

极短24获奖极短23获奖极短22获奖

 楼主| 发表于 2022-6-24 10:38:30 | 显示全部楼层
本帖最后由 纯属小虫 于 2022-6-24 10:48 编辑
guoxiaomi 发表于 2022-6-24 02:07
2楼说的很对,你这样的写法会造成内存泄漏。RGSS的正常写法里,Window的contents属性都是在initialize方法 ...


嗯~虽然不大清楚内存泄露会造成什么翻车现象,以及内存泄露的原理
不过我好像懂了释放的重要性

我写了一个试错脚本,还请大佬帮我看看,如果这样写,是不是就会内存泄露

[fold=极端的试错脚本][pre lang="ruby"]loop do
  bitmap = Bitmap.new(32,32)
  bitmap = 1
  bitmap = Bitmap.new(32,32)
  bitmap = 1
  bitmap = Bitmap.new(32,32)
  bitmap = 1
end[/pre][/fold]

另外,再请教一下,dispose这个操作,具体是做了什么——来自半吊子的疑惑



原脚本已更新修正
回复

使用道具 举报

梦石
1
星屑
24088
在线时间
3339 小时
注册时间
2011-7-8
回帖
3862

开拓者

发表于 2022-6-24 12:09:43 | 显示全部楼层
本帖最后由 guoxiaomi 于 2022-6-24 12:22 编辑
纯属小虫 发表于 2022-6-24 10:38
嗯~虽然不大清楚内存泄露会造成什么翻车现象,以及内存泄露的原理
不过我好像懂了释放的重要性


测试了一下,确实不会内存泄漏。
  1. 1000.times do
  2.   Bitmap.new(256, 256)
  3. end

  4. sleep 3

  5. GC.start

  6. loop do
  7.   Graphics.update
  8.   Input.update
  9.   exit if Input.trigger?(Input::C)
  10. end
复制代码

这段代码在我的电脑上操作时,内存占用会先上升到 264M(这部分 Bitmap 会占 256M,ruby 的栈占 8M),然后下降到 12M。说明GC开始后,临时的Bitmap申请的的内存都释放掉了。

RGSS内部类是如何实现的,我们也只能靠猜。可能是这样的:在创建Bitmap时,RGSS会向操作系统申请一块内存以放置图块文件,每个像素点4个字节存储RGBA。而在dispose时,RGSS会归还这部分内存,当然,Bitmap在释放后就不能执行任何操作了。如果RGSS里没有设置GC时也会归还内存,就会造成内存泄漏。不过RGSS也考虑到了这一点,那其实你怎么写问题也不大,只能说随用随还养成好习惯吧。

点评

我去测试了一下,内存占用确实也是先升高到一个限度,然后猛降低;释放了就不会升高~~~感谢提醒,以前写的脚本都忽略了释放,该改改习惯了~~~  发表于 2022-6-24 14:21

评分

参与人数 1赞 +1 收起 理由
纯属小虫 + 1 塞糖

查看全部评分

熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复

使用道具 举报

梦石
0
星屑
2179
在线时间
379 小时
注册时间
2023-6-6
回帖
16
发表于 2023-9-30 14:37:33 | 显示全部楼层
使用時 在戰鬥時 選擇技能
當技能的說明有改變文字顏色的話 並且說明文字需要滾動  遊戲FPS 會降到超低 整個很卡  不知道是甚麼問題QQ

另外說明文字明明很短  但卻因為 說明有打上 \C[N]改變文字 或者\i[n]顯示圖標  而導致腳本好像覺得該段文字超過了 於是也會滾動
求解

点评

可以打开任务管理器,看看滚动字条的时候,电脑内存占有是否上升。如果有,应该还是上述内存未释放的问题造成的。  发表于 2023-10-7 11:21
對 我有自己加入改變顏色跟顯示圖標 不過主要問題還是fps的降低QQ  发表于 2023-10-5 21:39
应该是使用了不兼容脚本导致的,说明文字中原版脚本不支持使用改字色和图标显示  发表于 2023-10-5 17:52
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部