设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 4429|回复: 7
打印 上一主题 下一主题

[原创发布] 【原创】改良存读档系统优化版 Ver 1.2

[复制链接]

Lv4.逐梦者 (版主)

梦石
0
星屑
9532
在线时间
5073 小时
注册时间
2013-6-21
帖子
3580

开拓者贵宾剧作品鉴家

跳转到指定楼层
1
发表于 2013-6-21 19:57:18 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

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

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

x
本帖最后由 RyanBern 于 2016-3-12 09:45 编辑

不知道有没有人发过类似的东西,不过好歹是原创,拿出来跟大家分享一下。
本脚本适用于RMXP。由于是借助RMXP预置脚本改的,所以应该不会有什么冲突,除非原有的系统被改得面目全非。


这是我刚入住6R时献上的第一个技术贴,不过没什么人气,现在拿出来返工一下。简单优化了一下脚本。
代码如下,有什么BUG欢迎报告:
RUBY 代码复制
  1. #=============================================================================
  2. # 改良存读档优化版 Ver 1.21
  3. #-----------------------------------------------------------------------------
  4. # By : RyanBern
  5. #-----------------------------------------------------------------------------
  6. # 功能说明:
  7. #     在原始的存读档系统上做了一些加强,提供了一些扩展内容,界面比较简单,可以
  8. #     试着在游戏中使用。
  9. #     1.屏蔽了 Window_SaveFile,而选择了可以滚动的 Window_Selectable,存档数量
  10. #       想存多少就存多少。
  11. #     2.自动存档功能,这个是为一些没有存档意识的玩家写的系统,有了它系统就可以
  12. #       按照一定规律自动保存进度,再也不用担心进度丢失了。存档的时机为主角切换
  13. #       到另一个地图之后,可以通过更改下面的常量来控制。
  14. #     3.存档覆盖提示功能,这个也是为一些粗心玩家设定的系统,当存储的位置已经有
  15. #       了文件时,再存档会跳出覆盖提示,避免误操作。
  16. #-----------------------------------------------------------------------------
  17. # 另外里面的 Window_Selectable 是我扩展的内容,可以单独拿出来使用,扩展的功能
  18. # 是可以指定每一行的行高,这样 Window_Selectable 滚动内容的行高就可以不必限制
  19. # 为 32 了。
  20. #-----------------------------------------------------------------------------
  21. # 更新记录:
  22. #     2014.12.25  精简代码,修复多了 end 的 BUG
  23. #     2016.03.12  缓解 F12 冲突的问题
  24. #=============================================================================
  25. module RB
  26.   # 存档数最大值
  27.   SAVES_MAX = 20
  28.  
  29.   # 如果打开12号开关,将不会自动存档
  30.   NO_AUTOSAVE = 12
  31.  
  32.   # 禁止自动存档的地图ID数组,如果主角移动前的地图的ID在数组中
  33.   # 那么切换地图后将不会自动存档
  34.   NO_AUTOSAVE_MAPS = []
  35. end
  36.  
  37. #=============================================================================
  38. # ■ Window_Selectable
  39. #-----------------------------------------------------------------------------
  40. #  拥有光标的移动以及滚动功能的窗口类。
  41. #   RB 加强版,可以设定一行的高度
  42. #   指定某一行的高度可以这样 Window_Selectable.new(0, 0, 120, 120, 54)
  43. #   表示该窗口一行高度为 54,如果不写,默认为 32(原始默认高度)
  44. #=============================================================================
  45.  
  46. class Window_Selectable < Window_Base
  47.   #--------------------------------------------------------------------------
  48.   # ● 定义实例变量
  49.   #--------------------------------------------------------------------------
  50.   attr_reader   :index                    # 光标位置
  51.   attr_reader   :help_window              # 帮助窗口
  52.   attr_accessor :row_height               # 行高
  53.   #--------------------------------------------------------------------------
  54.   # ● 初始画对像
  55.   #     x      : 窗口的 X 坐标
  56.   #     y      : 窗口的 Y 坐标
  57.   #     width  : 窗口的宽
  58.   #     height : 窗口的高
  59.   #--------------------------------------------------------------------------
  60.   def initialize(x, y, width, height, row_height=32)
  61.     super(x, y, width, height)
  62.     @item_max = 1
  63.     @column_max = 1
  64.     @index = -1
  65.     @row_height = row_height
  66.   end
  67.   #--------------------------------------------------------------------------
  68.   # ● 获取开头行
  69.   #--------------------------------------------------------------------------
  70.   def top_row
  71.     # 将窗口内容的传送源 Y 坐标、1 行的高 @row_height 等分
  72.     return self.oy / @row_height
  73.   end
  74.   #--------------------------------------------------------------------------
  75.   # ● 设置开头行
  76.   #     row : 显示开头的行
  77.   #--------------------------------------------------------------------------
  78.   def top_row=(row)
  79.     # row 未满 0 的场合更正为 0
  80.     if row < 0
  81.       row = 0
  82.     end
  83.     # row 超过 row_max - 1 的情况下更正为 row_max - 1
  84.     if row > row_max - 1
  85.       row = row_max - 1
  86.     end
  87.     # row 1 行高的 @row_height 倍、窗口内容的传送源 Y 坐标
  88.     self.oy = row * @row_height
  89.   end
  90.   #--------------------------------------------------------------------------
  91.   # ● 获取 1 页可以显示的行数
  92.   #--------------------------------------------------------------------------
  93.   def page_row_max
  94.     # 窗口的高度,设置画面的高度减去 32 ,除以 1 行的高度 @row_height
  95.     return (self.height - 32) / @row_height
  96.   end
  97.   #--------------------------------------------------------------------------
  98.   # ● 更新光标矩形
  99.   #--------------------------------------------------------------------------
  100.   def update_cursor_rect
  101.     # 光标位置不满 0 的情况下
  102.     if @index < 0
  103.       self.cursor_rect.empty
  104.       return
  105.     end
  106.     # 获取当前的行
  107.     row = @index / @column_max
  108.     # 当前行被显示开头行前面的情况下
  109.     if row < self.top_row
  110.       # 从当前行向开头行滚动
  111.       self.top_row = row
  112.     end
  113.     # 当前行被显示末尾行之后的情况下
  114.     if row > self.top_row + (self.page_row_max - 1)
  115.       # 从当前行向末尾滚动
  116.       self.top_row = row - (self.page_row_max - 1)
  117.     end
  118.     # 计算光标的宽
  119.     cursor_width = self.width / @column_max - 32
  120.     # 计算光标坐标
  121.     x = @index % @column_max * (cursor_width + 32)
  122.     y = @index / @column_max * @row_height - self.oy
  123.     # 更新光标矩形
  124.     self.cursor_rect.set(x, y, cursor_width, @row_height)
  125.   end
  126. end
  127. class Window_File < Window_Selectable
  128.   #--------------------------------------------------------------------------
  129.   # ● 初始化目标
  130.   #--------------------------------------------------------------------------
  131.   def initialize
  132.     super(0, 64, 640, 416 ,96)
  133.     @column_max = 1
  134.     case $scene
  135.     when Scene_Save
  136.       @item_max = RB::SAVES_MAX
  137.     when Scene_Load
  138.       @item_max = RB::SAVES_MAX + 1
  139.     end
  140.     refresh
  141.     self.index = 0
  142.   end
  143.   #--------------------------------------------------------------------------
  144.   # ● 刷新
  145.   #--------------------------------------------------------------------------
  146.   def refresh
  147.     if @item_max == 0
  148.       return
  149.     end
  150.     self.contents = Bitmap.new(width - 32, @item_max * 96)
  151.     self.contents.clear
  152.     for j in 0...@item_max
  153.       x = 64
  154.       y = j * 96
  155.       self.contents.font.color = normal_color
  156.       case $scene
  157.       when Scene_Save
  158.       name = "文件 #{j + 1}"
  159.       self.contents.draw_text(4, y, 600, 32, name)
  160.       @filename = "Save#{j + 1}.rxdata"
  161.       @name_width = contents.text_size(name).width
  162.       @time_stamp = Time.at(0)
  163.       @file_exist = FileTest.exist?(@filename)
  164.       when Scene_Load
  165.         if j == 0
  166.           name = "自动存档"
  167.         else
  168.           name = "文件 #{j}"
  169.         end
  170.         self.contents.draw_text(4, y, 600, 32, name)
  171.       @filename = "Save#{j}.rxdata"
  172.       @name_width = contents.text_size(name).width
  173.       @time_stamp = Time.at(0)
  174.       @file_exist = FileTest.exist?(@filename)
  175.       end
  176.       if @file_exist
  177.         file = File.open(@filename, "r")
  178.         @time_stamp = file.mtime
  179.         @characters = Marshal.load(file)
  180.         @frame_count = Marshal.load(file)
  181.         @game_system = Marshal.load(file)
  182.         @game_switches = Marshal.load(file)
  183.         @game_variables = Marshal.load(file)
  184.         @total_sec = @frame_count / Graphics.frame_rate
  185.         file.close
  186.       end
  187.       # 存档文件存在的情况下
  188.       if @file_exist
  189.         # 描绘角色
  190.         for i in 0...@characters.size
  191.           bitmap = RPG::Cache.character(@characters[i][0], @characters[i][1])
  192.           cw = bitmap.rect.width / 4
  193.           ch = bitmap.rect.height / 4
  194.           src_rect = Rect.new(0, 0, cw, ch)
  195.           x = 300 - @characters.size * 32 + i * 64 - cw / 2
  196.           self.contents.blt(x, 68 - ch + y, bitmap, src_rect)
  197.         end
  198.         # 描绘游戏时间
  199.         hour = @total_sec / 60 / 60
  200.         min = @total_sec / 60 % 60
  201.         sec = @total_sec % 60
  202.         time_string = sprintf("%02d:%02d:%02d", hour, min, sec)
  203.         self.contents.font.color = normal_color
  204.         self.contents.draw_text(4, 8 + y, 600, 32, time_string, 2)
  205.         # 描绘时间标记
  206.         self.contents.font.color = normal_color
  207.         time_string = @time_stamp.strftime("%Y/%m/%d %H:%M")
  208.         self.contents.draw_text(4, 40 + y, 600, 32, time_string, 2)
  209.       end
  210.     end
  211.   end
  212. end
  213. #==============================================================================
  214. # ■ Window_ReplaceConfirm
  215. #------------------------------------------------------------------------------
  216. #  确认是否覆盖原始存档的窗口
  217. #==============================================================================
  218.  
  219. class Window_ReplaceConfirm < Window_Selectable
  220.   #--------------------------------------------------------------------------
  221.   # ● 初始化对像
  222.   #--------------------------------------------------------------------------
  223.   def initialize
  224.     super(160, 176, 320, 128)
  225.     self.contents = Bitmap.new(width - 32, height - 32)
  226.     @item_max = 2
  227.     @column_max = 2
  228.     @commands = ["是的",  "不要"]
  229.     refresh
  230.     self.index = 0
  231.   end
  232.   #--------------------------------------------------------------------------
  233.   # ● 刷新
  234.   #--------------------------------------------------------------------------
  235.   def refresh
  236.     self.contents.clear
  237.     self.contents.font.color = system_color
  238.     self.contents.draw_text(4, 0, 328, 32, "当前位置已经存在存档文件")
  239.     self.contents.draw_text(4, 32, 328, 32, "确认要覆盖当前存档文件吗?")
  240.     self.contents.font.color = normal_color
  241.     for i in 0...@item_max
  242.       draw_item(i)
  243.     end
  244.   end
  245.   #--------------------------------------------------------------------------
  246.   # ● 描绘项目
  247.   #     index : 项目编号
  248.   #--------------------------------------------------------------------------
  249.   def draw_item(index)
  250.     x = 4 + index * 144
  251.     self.contents.draw_text(x, 64, 128, 32, @commands[index])
  252.   end
  253.   def update_cursor_rect
  254.     if @index < 0
  255.       self.cursor_rect.empty
  256.     else
  257.       self.cursor_rect.set(@index * 144, 64, (self.width - 32) / 2, 32)
  258.     end
  259.   end
  260. end
  261. #==============================================================================
  262. # ■ Scene_File
  263. #------------------------------------------------------------------------------
  264. #  存档画面及读档画面的超级类。
  265. #==============================================================================
  266.  
  267. class Scene_File
  268.   #--------------------------------------------------------------------------
  269.   # ● 主处理
  270.   #--------------------------------------------------------------------------
  271.   def main
  272.     # 生成帮助窗口
  273.     @help_window = Window_Help.new
  274.     @help_window.set_text(@help_text)
  275.     @file_window = Window_File.new
  276.     @file_window.index = $game_temp.last_file_index
  277.     @file_window.active = true
  278.     @confirm_window = Window_ReplaceConfirm.new
  279.     @confirm_window.active = false
  280.     @confirm_window.visible = false
  281.     @confirm_window.z = @file_window.z + 10
  282.     # 执行过渡
  283.     Graphics.transition
  284.     # 主循环
  285.     loop do
  286.       # 刷新游戏画面
  287.       Graphics.update
  288.       # 刷新输入信息
  289.       Input.update
  290.       # 刷新画面
  291.       update
  292.       # 如果画面被切换的话就中断循环
  293.       if $scene != self
  294.         break
  295.       end
  296.     end
  297.     # 准备过渡
  298.     Graphics.freeze
  299.     # 释放窗口
  300.     @help_window.dispose
  301.     @file_window.dispose
  302.     @confirm_window.dispose
  303.   end
  304.   #--------------------------------------------------------------------------
  305.   # ● 刷新画面
  306.   #--------------------------------------------------------------------------
  307.   def update
  308.     # 刷新窗口
  309.     @help_window.update
  310.     @file_window.update
  311.     @confirm_window.update
  312.     case $scene
  313.     when Scene_Save
  314.       if @file_window.active
  315.         update_file
  316.         return
  317.       end
  318.       if @confirm_window.active
  319.         update_confirm
  320.         return
  321.       end
  322.     when Scene_Load
  323.       # 按下 C 键的情况下
  324.       if Input.trigger?(Input::C)
  325.         # 调用过程 on_decision (定义继承目标)
  326.         on_decision(make_filename_load(@file_window.index))
  327.         $game_temp.last_file_index = @file_window.index
  328.         return
  329.       end
  330.       # 按下 B 键的情况下
  331.       if Input.trigger?(Input::B)
  332.         # 调用过程 on_cancel (定义继承目标)
  333.         on_cancel
  334.         return
  335.       end
  336.     end
  337.   end
  338.   #--------------------------------------------------------------------------
  339.   # ● 生成文件名
  340.   #     file_index : 文件名的索引 (0~3)
  341.   #--------------------------------------------------------------------------
  342.   def make_filename(file_index)
  343.     return "Save#{file_index + 1}.rxdata"
  344.   end
  345.   def make_filename_load(file_index)
  346.     return "Save#{file_index}.rxdata"
  347.   end
  348. end
  349.  
  350.  
  351. class Scene_Save < Scene_File
  352.   #--------------------------------------------------------------------------
  353.   # ● 初始化对像
  354.   #--------------------------------------------------------------------------
  355.   def initialize
  356.     super("要储存到哪个文件?")
  357.   end
  358.   def update_file
  359.     filename = make_filename(@file_window.index)
  360.     if Input.trigger?(Input::C)
  361.       $game_system.se_play($data_system.decision_se)
  362.       if FileTest.exist?(filename)
  363.         @file_window.active = false
  364.         @confirm_window.active = true
  365.         @confirm_window.visible = true
  366.       else
  367.         # 演奏存档 SE
  368.         $game_system.se_play($data_system.save_se)
  369.         # 写入存档数据
  370.         file = File.open(filename, "wb")
  371.         write_save_data(file)
  372.         file.close
  373.         # 如果被事件调用
  374.         if $game_temp.save_calling
  375.           # 清除存档调用标志
  376.           $game_temp.save_calling = false
  377.           # 切换到地图画面
  378.           $scene = Scene_Map.new
  379.           return
  380.         end
  381.         # 切换到菜单画面
  382.         $scene = Scene_Menu.new(4)
  383.       end
  384.     end
  385.     if Input.trigger?(Input::B)
  386.       # 演奏取消 SE
  387.       $game_system.se_play($data_system.cancel_se)
  388.       # 如果被事件调用
  389.       if $game_temp.save_calling
  390.         # 清除存档调用标志
  391.         $game_temp.save_calling = false
  392.         # 切换到地图画面
  393.         $scene = Scene_Map.new
  394.         return
  395.       end
  396.       # 切换到菜单画面
  397.       $scene = Scene_Menu.new(4)
  398.     end
  399.   end
  400.   def update_confirm
  401.     filename = make_filename(@file_window.index)
  402.     if Input.trigger?(Input::C)
  403.       case @confirm_window.index
  404.       when 0
  405.         # 演奏存档 SE
  406.         $game_system.se_play($data_system.save_se)
  407.         # 写入存档数据
  408.         file = File.open(filename, "wb")
  409.         write_save_data(file)
  410.         file.close
  411.         # 如果被事件调用
  412.         if $game_temp.save_calling
  413.           # 清除存档调用标志
  414.           $game_temp.save_calling = false
  415.           # 切换到地图画面
  416.           $scene = Scene_Map.new
  417.           return
  418.         end
  419.         # 切换到菜单画面
  420.         $scene = Scene_Menu.new(4)
  421.       when 1
  422.         $game_system.se_play($data_system.cancel_se)
  423.         @file_window.active = true
  424.         @confirm_window.active = false
  425.         @confirm_window.visible = false
  426.       end
  427.     end
  428.     if Input.trigger?(Input::B)
  429.       $game_system.se_play($data_system.cancel_se)
  430.       @file_window.active = true
  431.       @confirm_window.active = false
  432.       @confirm_window.visible = false
  433.     end
  434.   end
  435.   def autosave
  436.     filename = "Save0.rxdata"
  437.     file = File.open(filename, "wb")
  438.     write_save_data(file)
  439.     file.close
  440.   end
  441. end
  442.  
  443.  
  444. class Scene_Load < Scene_File
  445.   #--------------------------------------------------------------------------
  446.   # ● 初始化对像
  447.   #--------------------------------------------------------------------------
  448.   def initialize
  449.     # 再生成临时对像
  450.     $game_temp = Game_Temp.new
  451.     # 选择存档时间最新的文件
  452.     $game_temp.last_file_index = 0
  453.     latest_time = Time.at(0)
  454.     for i in 0..RB::SAVES_MAX
  455.       filename = make_filename_load(i)
  456.       if FileTest.exist?(filename)
  457.         file = File.open(filename, "r")
  458.         if file.mtime > latest_time
  459.           latest_time = file.mtime
  460.           $game_temp.last_file_index = i
  461.         end
  462.         file.close
  463.       end
  464.     end
  465.     super("要载入哪个文件?")
  466.   end
  467. end
  468.  
  469. class Scene_Map
  470.   unless method_defined? :rb_transfer_player_20141225
  471.     alias rb_transfer_player_20141225 transfer_player
  472.     def transfer_player
  473.       rb_transfer_player_20141225
  474.       unless RB::NO_AUTOSAVE_MAPS.include?($game_map.map_id) || $game_switches[RB::NO_AUTOSAVE]
  475.         save = Scene_Save.new
  476.         save.autosave
  477.       end
  478.     end
  479.   end
  480. end

附范例一枚:
Project5.rar (190.96 KB, 下载次数: 221)
注意有几个地方,我不知道该怎么标注,大家注意Scene_Save里面返回上一级的命令$scene = Scene_Menu.new(x),不同人的菜单不一样的,如果改过Scene_Menu的同学还请注意一下括号里面的数字。

点评

无图无真相  发表于 2013-7-28 19:59

评分

参与人数 1星屑 +6 收起 理由
龙和许也 + 6 塞糖

查看全部评分

Lv3.寻梦者

梦石
0
星屑
1556
在线时间
626 小时
注册时间
2010-8-5
帖子
451
2
发表于 2013-7-28 19:44:54 | 只看该作者
这么好的帖子为啥没人呢.~~~占个沙发{:2_287:}
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
130
在线时间
1 小时
注册时间
2013-7-30
帖子
2
3
发表于 2013-7-30 15:25:31 | 只看该作者
在下新手,受教了。

——新手玩家
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
11 小时
注册时间
2013-8-2
帖子
12
4
发表于 2013-8-2 16:33:30 | 只看该作者
好像不错个说,试试看
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
169 小时
注册时间
2010-7-7
帖子
48
5
发表于 2013-8-3 09:51:28 | 只看该作者
652行是不是多了一个end啊,有错误啊,删掉后可用
回复 支持 反对

使用道具 举报

Lv4.逐梦者 (版主)

梦石
0
星屑
9532
在线时间
5073 小时
注册时间
2013-6-21
帖子
3580

开拓者贵宾剧作品鉴家

6
 楼主| 发表于 2014-12-25 18:59:10 | 只看该作者
1.20版本更新,自顶一下。
主要更新的是修复了一些错误,另外精简了一些代码。
功能还是原来的
回复 支持 反对

使用道具 举报

Lv4.逐梦者

梦石
0
星屑
9280
在线时间
2504 小时
注册时间
2011-5-20
帖子
15389

开拓者

7
发表于 2014-12-25 19:21:18 | 只看该作者
RyanBern 发表于 2014-12-25 01:59
1.20版本更新,自顶一下。
主要更新的是修复了一些错误,另外精简了一些代码。
功能还是原来的 ...

来个通用版吧(···这是在做什么···)
[img]http://service.t.sina.com.cn/widget/qmd/5339802982/c02e16bd/7.png
回复 支持 反对

使用道具 举报

Lv2.观梦者

梦石
0
星屑
263
在线时间
1575 小时
注册时间
2010-6-17
帖子
2892

开拓者贵宾

8
发表于 2017-2-1 12:27:57 | 只看该作者
要是想显示小截图怎么做啊?
快来点我一下,你会豁然开朗的
喵Kano特制
←开发中……

←暂时弃坑 电脑上资源全没
回复 支持 反对

使用道具 举报

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

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-11-30 14:33

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表