整理了 RGSS 转移到 RGD 时可能产生的(正常操作、没有 bug 条件下)不兼容问题的解决方案。
如果因为 bug 而不兼容请直接联系作者修复,感谢你的反馈!
截图存档
截图存档有时会使用获取地址的方式实现 Bitmap#_dump 和 Bitmap#_load。以柳之一的 Bitmap Marshal 为例,实现方式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class Bitmap RtlMoveMemory_pi = Win32API.new('kernel32', 'RtlMoveMemory', 'pii', 'i') RtlMoveMemory_ip = Win32API.new('kernel32', 'RtlMoveMemory', 'ipi', 'i') def _dump(limit) data = "rgba" * width * height RtlMoveMemory_pi.call(data, address, data.length) [width, height, Zlib::Deflate.deflate(data)].pack("LLa*") end def self._load(str) w, h, zdata = str.unpack("LLa*") b = self.new(w, h) RtlMoveMemory_ip.call(b.address, Zlib::Inflate.inflate(zdata), w * h * 4) return b end def address buffer, ad = "rgba", object_id * 2 + 16 RtlMoveMemory_pi.call(buffer, ad, 4) ad = buffer.unpack("L")[0] + 8 RtlMoveMemory_pi.call(buffer, ad, 4) ad = buffer.unpack("L")[0] + 16 RtlMoveMemory_pi.call(buffer, ad, 4) return buffer.unpack("L")[0] end end |
其中,有根据内存地址获取 Bitmap 内部数据的操作。但是由于 RGD 重写了 Bitmap,导致内存数据和默认 RGSS 有差异,并且 DirectX 为了把数据更新到纹理上需要使用 LockRect 的方式,直接修改数据不是正确做法。在这里可以使用 RGD 的 Bitmap#process_color 方法保存颜色,方式如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class Bitmap def _dump(limit) data = "rgba" * width * height process_color { |color_arr| color_arr.save_data(data, width * height) } [width, height, Zlib::Deflate.deflate(data)].pack("LLa*") end def self._load(str) w, h, zdata = str.unpack("LLa*") data = Zlib::Inflate.inflate(zdata) bmp = self.new(w, h) bmp.process_color { |color_arr| color_arr.load_data(data, w * h) } return bmp end end |
使用上面的做法,就可以实现 Bitmap 的 Marshal 相关操作了。
注意,RGD 实现的 Marshal 和 RGSS 相比还有一个不同。RGSS 的位图存储是从最后一行开始反向到第一行,所以保存的数据是从下往上的,而 RGD 是比较普通的从上往下顺序保存的方式。如果使用 RGD 的方式读取以往 RGSS 保存的数据,会发现上下反转了。这是正常现象,只要从头到尾使用同一套保存和读取方式就不会出现上述问题,不会影响玩家体验。
位图扩展、像素字体
有些位图扩展使用外接的 DLL 实现 Bitmap 的快速读写。和上面的类似,因为 Bitmap 的结构改变,所以外接 DLL 不能达到之前的效果,甚至可能引起错误。以 tktk_bitmap 为例,一个简单的兼容方式是直接删去 tktk_bitmap 的基础脚本(Bitmapクラスの拡張),然后根据运行过程中的错误提示自行实现相关功能。有些功能可以使用 Bitmap#process_color 实现,而另一些功能推荐使用精灵的功能实现。因为 RGD 中精灵的表现更好,所以建议优先考虑精灵。举例如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | png_save # 保存图片为 png 的功能,RGD 中提供了 save_png,功能类似。 blend_blt # 带混合效果的 blt,建议使用两个精灵,可以新建一个 Spriteset 用于管理。 clip_mask # 用一张 mask 图片来裁剪指定图片,有两种重新实现的思路。 # 可以使用 process_color 直接根据 mask 图片来修改像素颜色; # 也可以使用 Viewport 装载两个精灵,并把 mask 精灵使用特定的合成方式 # (根据不透明度返回下层精灵的值)。 change_tone # 更改位图色调,建议使用 Sprite#tone。 invert # 色调反转,可以使用 process_color 处理,也可以新建 shader 让精灵使用。 mosaic mosaic_rect # 马赛克效果,可以在 process_color 中每次取一块像素计算平均值再写入。 |
如果要开启默认像素字体,只需要使用 Font.default_pixel = true 即可,如同设置 Font.default_name 的方式一样。
混用RGSS/RGD存档引起的色调问题
使用下面的脚本,覆盖Color和Tone的marshal操作,即可解决。但使用了下述脚本后生成的存档,和使用之前的存档,不能混用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | class Color def marshal_dump [self.red, self.green, self.blue, self.alpha] end def marshal_load(data) self.red = data[0] self.green = data[1] self.blue = data[2] self.alpha = data[3] end end class Tone def marshal_dump [self.red, self.green, self.blue, self.gray] end def marshal_load(data) self.red = data[0] self.green = data[1] self.blue = data[2] self.gray = data[3] end end |
(待补充)
,
发现一个问题:覆盖1.5.4版本安装1.6之后,进行数次光标移动或直接进入游戏移动光标后,游戏会在移动时卡顿并且显示”停止运行”(APPCRASH)
希望可以解决,非常感谢!
好的,之后有空去看看怎么修