查看: 15132|回复: 31

[原创发布] 【移植】【ULDS】无限图层显示系统 for XP Ver 2.16

[复制链接]
梦石
0
星屑
9557
在线时间
5074 小时
注册时间
2013-6-21
回帖
3459

开拓者贵宾剧作品鉴家

发表于 2014-11-9 10:01:22 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 RyanBern 于 2017-10-3 10:37 编辑

ULDS (Unlimited Layers Display System) 这个名字在 P1 可谓是如雷贯耳,按照最新的改版观点,这是一个“能够改变 RMVA 游戏制作导向”的脚本。ULDS 的强大之处不必多说,懂的人自然懂。有些人问了这脚本能不能有 XP 版,有 VX 版,我们的高冷 taroxd 已经明确表示了:不会。此外,就我个人看来,RMXP 强大的图层编辑系统已经能够满足绝大多数人们的编辑需求,因此 ULDS 似乎不是很必要。

不过啊,既然发在这里了,我觉得肯定有人问我:那你做出来的这玩意,有啥用?这个问题……似乎很难回答。但是我可以告诉你另外一个故事:原版 ULDS 刚发布的时候,其作者 taroxd 也并不知道它有啥用。所以,谁知道呢?

脚本和范例都放在下面了,我不生产 ULDS,我只是一个 VA -> XP 的搬运工。范例的话比较丑,用的是原版范例素材和一个很愚蠢的截图。如果各位美工醋们能做出来更好的范例请一定要告诉我。用法和 VA 的 ULDS 有一些不同,因此使用之前请仔细阅读说明再做改动。

[fold=第一版序]
头一回做VA->XP的移植,没有什么经验,做得不好还请见谅吧。

这次我拿@taroxd 的ULDS试试。感觉上我在移植上花的时间要比这个脚本第一次编写的时候花的时间长,主要的原因还是不熟悉Ruby的元编程吧,盯着XD的代码看了老半天……还有就是XP的Ruby版本太低了,很多能在VA里面识别的代码在XP里被无情地报错了。因此也是花了很长时间在ruby doc上。有些实在通不过的,我就只好改成了XP的写法,不过为了尊重原脚本,绝大多数我都没有做出更改。还有就是移植的过程中看到了XP和VA脚本编写风格的不同,XP倾向于把所有的代码写到一个方法中,导致每个方法都特别长,而VA倾向于把语句离散化,这样每个方法都很短。从维护和扩展角度上来说,显然VA的做法更高明一些。

使用方法不多说了,里面的说明书相应做了更改,范例的话也是有的,不过时间太仓促没来及做得更细致一些。
[/fold]
1.png
2.png
[pre lang="ruby"]#----------------------------------------------------------------------------
# ● 无限图层显示系统 Unlimited Layers Display System By Taroxd
#   XP 移植 By RyanBern
#----------------------------------------------------------------------------
#
#  使用方法:导入此脚本后,在游戏主目录新建一个名为 ULDS_Data 的文件夹,然后
#            新建 txt 文本文件 ULDS000.txt,其中 000 请替换成真正的地图 ID。
#            此后在此 txt 文件里面加入如下内容。
#
#  注意:保存 txt 文件请务必使用 UTF-8 编码,否则其中的中文不会被正常识别。
#        如果文件名里面没有中文则无影响。
#
#  另:本脚本会尝试和原版 ULDS 保持一致,固不再单独写出版本号。
#
#  <ulds=filename>
#    x: X坐标
#      公式,默认为 0
#    y: Y坐标
#      公式,默认为 0
#    z: Z坐标
#      公式,只计算一次,默认为 10,可以设置为 -100 来当作远景图使用
#    zoom: 缩放倍率
#      公式,默认为 1。缩放的原点为画面左上角。
#    zoom_x: 横向缩放倍率
#      公式,默认为 zoom
#    zoom_y: 纵向缩放倍率
#      公式,默认为 zoom
#    opacity: 不透明度
#      公式,默认为 255
#    blend_type: 合成方式
#      公式,只计算一次。默认为 0 (0:正常、1:加法、2:减法)
#    scroll: 图像跟随地图卷动的速度
#      实数,默认为 32
#    scroll_x: 图像跟随地图横向卷动的速度
#      实数,默认为 scroll
#    scroll_y:图像跟随地图纵向卷动的速度
#      实数,默认为 scroll
#    loop: 循环
#      冒号后面不需要填写任何东西。
#    visible: 图像是否显示
#      公式,默认为 true
#    path: 图像的路径名
#      默认为 Parallaxes
#    color: 合成的颜色
#      公式,只计算一次。默认为 Color.new(0, 0, 0, 0)
#    tone: 色调
#      公式,只计算一次。默认为 Tone.new(0, 0, 0, 0)
#    eval: 初始化后,以 sprite 或 plane 为 self 执行的代码。
#      公式,默认为空
#    update: 图片显示时,每帧执行的更新代码
#      公式,默认为 t += 1
#    dispose: 图片释放前执行的代码
#      公式,默认为空
#  </ulds>
#
#  其中 filename 是图片文件名(无需扩展名),放入 Pictures 文件夹内
#  这个文件夹可以通过 path 设置更改
#
#  在 <ulds=filename> 和 </ulds> 中间的部分均为选填。不填则自动设为默认值。
#  每一个设置项只能写一行。
#  每一行只能写一个设置项。
#  一般来说,正常使用时大部分都是不需要设置的。
#
#  设置项目中的“公式”表示,这一个设置项可以像技能的伤害公式一样填写。
#  “只计算一次”表示,该公式只会在刚刚进入地图时计算一次,之后不会更新。
#  可用 t 表示当前已经显示的帧数,s[n], v[n] 分别表示 n 号开关和 n 号变量。
#  width 表示图片宽度,height 表示图片高度。
#
#  例:
#   <ulds=BlueSky>
#     x: t
#     scroll_x: 16
#     scroll_y: 64
#     loop:
#   </ulds>
#
#  需要多行公式时,可以重复备注。
#  例:
#   <ulds=Slime>
#     path: Battlers
#     x: width / 2
#     y: height / 2
#     eval: self.ox = width / 2
#     eval: self.oy = height / 2
#     eval: self.angle = 180
#   </ulds>
#
#----------------------------------------------------------------------------
#  z 坐标详解:
#    ulds 图层的坐标和地图画面的三个视口(Viewport)是独立的,具体设定如下
#      【0】最低图块层、在普通角色下方
#      【1~200】在地图所有内容的上方(包括远景图,任意优先度的图块,角色图,雾图形)
#      【201~3000】在【显示图片】所产生的图片上方
#      【>3000】在【画面闪烁】效果的上方
#    目前暂不支持在地图内容上的分割(例如不能设置为在角色上方而在雾图形下方),
#    如果有需求可考虑添加。
#----------------------------------------------------------------------------
#  更新记录:
#   2014.07.10 Ver1.01: 修正了 zoom、zoom_y 会报错的问题
#   2014.07.11 Ver1.02: 修正了切换图块组之后失效的问题
#   2014.08.14 Ver1.1:  增加了 speed_x, speed_y 的设置
#   2014.08.16 Ver1.2:  fix 设定更改为 scroll
#   2014.08.29 Ver1.21: 修正了坐标误差
#   2014.09.19 Ver1.22: 修正了远景图与图层使用相同文件时报错的问题
#   2014.09.25 Ver2.0:  属性可以用公式进行设置了;其他细节改进
#   2014.09.26 Ver2.01: 增加了 path、update 的设置
#   2015.01.02 Ver2.1:  增加了 init、color、tone 的设置;其他细节改进
#   2015.01.03 Ver2.11: 修复了 zoom 属性会导致坐标误差的问题
#   2015.02.02 Ver2.12: 支持多行备注和公式中的 width 和 height;其他细节改进
#   2015.07.04 Ver2.13: 修复了循环时可能不会更新的问题
#   2017.03.22 Ver2.15: 允许文件名为空,即备注 <ulds></ulds>
#   2017.05.10 Ver2.16: 增加了 dispose 设置
#----------------------------------------------------------------------------

module Taroxd; end

module Taroxd::ULDS

  DEFAULT_PATH = 'Pictures'                    # 图片文件的默认路径
  DEFAULT_Z = 10                                 # 默认的 z 值
  RE_OUTER = /<ulds[= ]?(.*?)>(.*?)<\/ulds>/mi  # 读取备注用的正则表达式
  RE_INNER = /(\w+) *: *(.*)/                    # 读取设置用的正则表达式
  MAPDATA_PREFIX = 'ULDS_Data'

  module Base
    include Math

    attr_accessor :scroll_x, :scroll_y

    def dispose
      bitmap.dispose
      super
    end

    def adjust_x
      1.0 * @scroll_x * $game_map.display_x / 128
      #return x if @scroll_x.abs < Float::EPSILON
      #$game_map.display_x / (128.0 / @scroll_x)
      #$game_map.adjust_x(1.0 * x / @scroll_x) * @scroll_x
    end

    def adjust_y
      1.0 * @scroll_y * $game_map.display_y / 128
      #return y if @scroll_y.abs < Float::EPSILON
      #$game_map.display_y / (128.0 / @scroll_y)
      #$game_map.adjust_y(1.0 * y / @scroll_y) * @scroll_y
    end
  end

  class Sprite < ::Sprite
    include Base

    def x=(x)
      self.ox = adjust_x
      super
      #super(-adjust_x(x))
    end

    def y=(y)
      self.oy = adjust_y
      super
      #super(-adjust_y(y))
    end
  end

  class Plane < ::Plane
    include Base

    attr_reader :visible

    def initialize(_)
      super
      @visible = true
    end

    def x=(x)
      self.ox = adjust_x + x
    end

    def y=(y)
      self.oy = adjust_y + y
    end

    def visible=(visible)
      super
      @visible = visible
    end

    def width
      bitmap.width
    end

    def height
      bitmap.height
    end
  end

  class << self

    # 从备注中读取设置,并生成数组
    def from_note(note, viewport)
      note.scan(RE_OUTER).map do |name, contents|
        settings = {nil => name}
        contents.scan(RE_INNER) do |key, value|
          (settings[key] ||= '') << value << "\n"
        end
        new(settings, viewport)
      end
    end

    # 返回一个 ULDS::Sprite 或 ULDS::Plane 的实例
    def new(settings, viewport)
      @settings = settings
      container(viewport)
    end

    private

    def container(viewport)
      container = (extract('loop') ? Plane : Sprite).new(viewport)
      container.bitmap = make_bitmap
      container.instance_eval(init_container_code, __FILE__, __LINE__)
      container
    end

    # 在一个 sprite 或 plane 的上下文中执行的代码。
    # 如果难以理解,请尝试输出这段代码来查看。
    def init_container_code
      "#{binding_code}
      #{init_attr_code}
      #{define_update_code}
      #{define_dispose_code}
      #{extract 'eval'}"
    end

    # 定义变量的代码
    def binding_code
      's = $game_switches
      v = $game_variables
      t = 0'
    end

    # 只计算一次的初始化代码
    def init_attr_code
      "#{set_attr_code 'z', DEFAULT_Z}
      #{set_attr_code 'scroll_x', 32}
      #{set_attr_code 'scroll_y', 32}
      #{set_attr_code 'blend_type'}
      #{set_attr_code 'color'}
      #{set_attr_code 'tone'}"
    end

    # 更新的代码
    def define_update_code
      %{
        define_singleton_method :update do
          #{set_attr_code 'visible'}
          return unless visible
          #{set_attr_code 'zoom_x'}
          #{set_attr_code 'zoom_y'}
          #{set_attr_code 'opacity'}
          #{set_attr_code 'x', 0}
          #{set_attr_code 'y', 0}
          #{set_t_code}
        end
      }
    end

    def define_dispose_code
      code = extract('dispose')
      !code ? "" : %{
        define_singleton_method :dispose do
          #{code}
          super()
        end
      }
    end

    # 设置属性的代码
    def set_attr_code(key, default = nil)
      formula = extract(key, default)
      formula && "self.#{key} = (#{formula})"
    end

    # 设置时间的代码
    def set_t_code
      extract('update', 't += 1')
    end

    # 获得位图
    def make_bitmap
      basename = extract(nil)
      if !basename.empty?
        folder_name = "Graphics/#{extract('path', DEFAULT_PATH).chomp}"
        Bitmap.new("#{folder_name}/#{basename}")
      else
        nil
      end
    end

    # 获取备注中的设定值
    def extract(key, default = nil)
      @settings[key] || /(.+)_[xy]\Z/ =~ key && @settings[$1] || default
    end
  end
end

class Game_Map

  def note
    filename = sprintf("%s/ULDS%03d.txt", Taroxd::ULDS::MAPDATA_PREFIX, @map_id)
    if File.exist?(filename)
      File.open(filename) do |f|
        return f.read
      end
    else
      return ""
    end
  end
end

class Spriteset_Map

  def create_ulds
    @ulds = Taroxd::ULDS.from_note($game_map.note, nil)
    @ulds_map_id = $game_map.map_id
  end

  def refresh_ulds
    dispose_ulds
    create_ulds
  end

  def update_ulds
    refresh_ulds if @ulds_map_id != $game_map.map_id
    @ulds.each {|u| u.update}
  end

  def dispose_ulds
    @ulds.each {|u| u.dispose}
  end

  # 导入 -- 没有 taroxd 那么醋的我只好瑟瑟发抖地 alias
  alias rb_initialize_ulds initialize
  def initialize
    create_ulds
    rb_initialize_ulds
  end
  
  alias rb_update_ulds update
  def update
    update_ulds
    rb_update_ulds
  end
  
  alias rb_dispose_ulds dispose
  def dispose
    dispose_ulds
    rb_dispose_ulds
  end
  
end

# XP does not have define_singleton_method, then define it manually
class Object
  def define_singleton_method(sym, &block)
    class << self; self; end.send(:define_method, sym, &block)
  end
end[/pre]
ULDS-XP-2.16.7z (4.71 MB, 下载次数: 813)    

评分

参与人数 8星屑 +665 收起 理由
斜眼君 + 120 我很赞同
断电 + 100 塞糖
你最珍贵 + 60 塞糖
zmz6668 + 15 精品文章
VIPArcher + 40 塞糖
taroxd + 260 塞糖
进击の虎叔 + 45
chd114 + 25 移植Banzai

查看全部评分

…あたしは天

梦石
0
星屑
2308
在线时间
4033 小时
注册时间
2010-10-4
回帖
10548

开拓者贵宾

发表于 2014-11-9 10:07:48 | 显示全部楼层
移植累的话就重写好了……

那段生成的代码确实难以理解,不过其实把代码p出来就可以了

要写公式就躲不开 eval 的说……

点评

每张地图的设置都不一样啊,用常量岂不是很啰嗦?  发表于 2014-11-28 21:00
说起来为什么不直接用常量呢,还省得读取了= =  发表于 2014-11-28 20:58
XP地图没备注所以我就转战txt了,然后顺便把XP区那个问题也搞清了……向下移植还是很有意思的  发表于 2014-11-9 10:10
回复

使用道具 举报

梦石
0
星屑
9292
在线时间
2504 小时
注册时间
2011-5-20
回帖
14521

开拓者

发表于 2014-11-9 10:37:32 | 显示全部楼层
这两张效果图哪一张是无限图层的哪一张是默认的···

点评

呃··编辑器地图从123变成了456?  发表于 2014-11-9 12:44
不是,要是采用远景图作为地图的话,编辑器地图就不用了。如果不是,而是需要第4层图层,第5层,第6层,那么编辑器的地图仍然有用。  发表于 2014-11-9 12:32
···意思是编辑器的地图几乎废掉了吗···  发表于 2014-11-9 12:20
这个地图是原版VA的ULDS范例地图,自然翻不到。这里值得说的是,地图的显示完全没有依赖原有数据库图层  发表于 2014-11-9 12:03
你还是放一个原版的效果做个对比吧···这个地图的素材我没翻到···  发表于 2014-11-9 11:50
[img]http://service.t.sina.com.cn/widget/qmd/5339802982/c02e16bd/7.png
回复

使用道具 举报

路路 该用户已被删除
发表于 2014-11-9 11:13:35 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复

使用道具 举报

故九江太守

梦石
0
星屑
314
在线时间
2158 小时
注册时间
2012-12-5
回帖
4323
发表于 2014-11-9 11:18:16 | 显示全部楼层
{:2_271:}就是不能再编辑器里看

点评

范例中的是模仿双远景地图的效果,如果单单是想给地图加上一个光照效果一个阴影效果什么的,ULDS就能很好发挥作用  发表于 2014-11-9 19:20
回复

使用道具 举报

…あたしは天

梦石
0
星屑
2308
在线时间
4033 小时
注册时间
2010-10-4
回帖
10548

开拓者贵宾

发表于 2014-11-9 11:29:29 | 显示全部楼层
要保持一致的话或许可以这样(XP应该还是有 define_method 的吧……)
[pre lang="ruby" line="1"]def define_singleton_method(sym, &block)
  class << self; self; end.send(:define_method, sym, &block)
end[/pre]

点评

define_method不知道,define_singleton_method铁定没有,XP神烦  发表于 2014-11-9 11:39
回复

使用道具 举报

梦石
0
星屑
12161
在线时间
4435 小时
注册时间
2014-4-11
回帖
5616

开拓者

发表于 2014-11-9 19:59:39 | 显示全部楼层
这是显示太阳光的功能?

点评

不单单是这样,实际上就是在地图上面添加更多的图层,比如你同时要阴影 光照 雾效果,用XD的一句话,ULDS的功能还可以更强大。  发表于 2014-11-9 20:09
回复

使用道具 举报

梦石
0
星屑
12161
在线时间
4435 小时
注册时间
2014-4-11
回帖
5616

开拓者

发表于 2016-11-2 20:57:08 | 显示全部楼层
@RyanBern
我有问题。
我用这个脚本设置图片为背景。
当工程执行默认的加密后,就不能使用了,不能显示出图片。

点评

更新了一下版本,加密数据似乎可以读  发表于 2017-10-3 11:24
回复

使用道具 举报

梦石
0
星屑
9557
在线时间
5074 小时
注册时间
2013-6-21
回帖
3459

开拓者贵宾剧作品鉴家

 楼主| 发表于 2017-10-3 10:42:28 | 显示全部楼层
本帖最后由 RyanBern 于 2017-10-3 11:26 编辑

假装更新一下 ULDS。此后尽量和 VA 的 ULDS 保持一致。当然落后一两个 commit 也是正常的。基本上功能都弄过来了,用法上会有些改动。

以下是目前尚未解决或不清楚是否影响使用的问题:
1. 不能调出“位于角色上方但是在雾图形下方”的 z 值;也不能调出“位于地图画面上方但是位于【总在顶部显示】的事件下方”的 z
2. 如果经过 RMXP 加密,读取文件可能没问题。
3. 远景地图模式下,依然不能很愉快地设置通行度。
回复

使用道具 举报

梦石
0
星屑
1495
在线时间
1101 小时
注册时间
2015-7-4
回帖
1547

开拓者

发表于 2017-10-3 10:45:03 | 显示全部楼层
本帖最后由 斜眼君 于 2018-8-8 18:06 编辑

[DATA EXPUNGED]
根本不需要什么最后的落脚处,只需要不断前行就够了。只要脚步不停下来,道路就会在脚下不断延伸!
回复

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部