Project1

标题: 关于截图存档脚本的改进(解决后请转移到RM讨论区) [打印本页]

作者: eve592370698    时间: 2013-1-7 23:19
标题: 关于截图存档脚本的改进(解决后请转移到RM讨论区)
本帖最后由 eve592370698 于 2013-1-16 20:57 编辑

怎么说呢,这次更新的重大改革是在张半仙的帮助下,截图存档问题基本完成。这里要讨论这么一个问题,
每个Scene这个类的main似乎都有这么些代码
RUBY 代码复制
  1. # 主循环
  2.     loop do
  3.       # 刷新游戏画面
  4.       Graphics.update
  5.       # 刷新输入信息
  6.       Input.update
  7.       # 刷新画面
  8.       update
  9.       # 如果画面被切换就中断循环
  10.       if $scene != self
  11.         break
  12.       end
  13.     end
还有两个Graphics.transition和Graphics.freeze
就以我之前的截图存档为例吧:我的脚本模仿了VA的特点,层级结构举例大概可以表示为
Scene_Loadsave < Scene_Base < Scene

看看我的这个代码
RUBY 代码复制
  1. class Scene_Base < Scene
  2.   #设定一些常数
  3.  
  4.  
  5.  
  6. =begin ————————————————————————
  7.   ★警告!方法initialize永远是最优先的main作为一些小有必要的补充而已!
  8. 为了精简合并代码,这里对main的一些共性东西做了合并处理
  9.  
  10. =end  
  11.   def main
  12.     #↓首先是加载
  13.     main_setup
  14.     #↓为了便于扩展,这里填补空白
  15.     main_add
  16.     # 执行过渡
  17.     Graphics.transition
  18.     #更新
  19.     main_update
  20.     # 更新完毕装备过渡
  21.     Graphics.freeze
  22.     #↓最后是释放
  23.     main_dispose
  24.   end
  25.  
  26. end

可以说基本上的Scene这个类的main无外乎这种基本流程罢了。再看看我的
RUBY 代码复制
  1. class Scene_Loadsave < Scene_Base
  2.  
  3.  
  4.  
  5. #--------------------------------------------------------------------------
  6. # ● 初始化对像
  7. #     $last_savefile_index : 记录光标位置
  8. #--------------------------------------------------------------------------
  9.   def initialize(allow = true)
  10.     $last_savefile_index = 0 if $last_savefile_index == nil
  11.     # 再生成临时对像
  12.     $game_temp = Game_Temp.new
  13.     # 选择存档时间最新的文件
  14.     $game_temp.last_file_index = 0
  15.     latest_time = Time.at(0)
  16.     for i in 0..51
  17.       filename = SCR_AUTO_SAVE_LOAD::DIR+"Save#{i}.rxdata"
  18.       if FileTest.exist?(filename)
  19.         file = File.open(filename, "r")
  20.         if file.mtime > latest_time
  21.           latest_time = file.mtime
  22.           $game_temp.last_file_index = i
  23.         end
  24.         file.close
  25.       end
  26.     end
  27.     @allow_save = allow
  28.     @菜单级别 = 0
  29.   end
  30. #--------------------------------------------------------------------------
  31. #  主处理
  32. #--------------------------------------------------------------------------
  33.   def main_setup
  34.     @savestate = 0
  35.     # 生成窗口
  36.  
  37.     最开始对话框
  38.     @存档列表 = Window_Command.new(160,SCR_AUTO_SAVE_LOAD::List)
  39.     @存档列表.y = 64
  40.     @存档列表.height = 416 + 120
  41.  
  42.  
  43.     ########################################################
  44.  
  45.  
  46.       #存档画面我当然也这么加上120
  47.       @存档列表.index = $game_temp.last_file_index
  48.       @content_window = Window_File.new($game_temp.last_file_index)
  49.       @content_window.z = 0
  50.       @存档列表.active = true
  51.         ###############覆盖存档
  52.  
  53. #        @help_window.set_text("确定要覆盖这个进度吗?")
  54.  
  55.  
  56.  
  57.  
  58.   end
  59. =begin --------------------------------------------
  60.   ★ 释放窗口
  61.  
  62. =end #------------------------------
  63.   def 释放部分窗口
  64.     if @option_window != nil
  65.       @option_window.dispose
  66.       @option_window = nil
  67.  
  68.     end
  69.     if @help_window != nil
  70.       @help_window.dispose
  71.       @help_window = nil
  72.     end
  73.  
  74.   end  
  75.   def main_dispose
  76.     释放部分窗口
  77.  
  78.     # 释放剩下的窗口
  79.     @存档列表.dispose
  80.  
  81.     @content_window.dispose
  82.     #删除没用的数据
  83.     删除临时数据
  84.   end
  85. end
代码把main拆分了之后不难看出,调理更加清晰。

游戏截图.PNG (111.65 KB, 下载次数: 39)

游戏截图.PNG

工程截图.PNG (64.85 KB, 下载次数: 33)

工程截图.PNG

仿真精灵幻境.rar

991.82 KB, 下载次数: 217


作者: zhangbanxian    时间: 2013-1-7 23:19
本帖最后由 zhangbanxian 于 2013-1-8 15:16 编辑
eve592370698 发表于 2013-1-8 14:35
已经转账了一些,谢了。我最头疼的是截图问题,我把每次存档返回地图代码屏蔽了,可是如不返回地图再存档 ...


汗,原脚本不是你写的?
  1. class Scene_Loadsave < Scene_Base
  2.   def main
  3.     main_add
  4.     File.delete(SCR_AUTO_SAVE_LOAD::DIR+"shot.jpg") if FileTest.exist?(SCR_AUTO_SAVE_LOAD::DIR+"shot.jpg")
  5.   end
  6. def save_file(s=false)
  7.     #半仙改
  8.     if Input.trigger?(Input::C) && !FileTest.exist?(SCR_AUTO_SAVE_LOAD::DIR+"Save#{@存档列表.index}.rxdata") or s
  9.         # 演奏冻结 SE
  10.         # 演奏存档 SE
  11.           $game_system.se_play($data_system.save_se)
  12.           # 写入存档数据
  13.           file = File.open(SCR_AUTO_SAVE_LOAD::DIR+"Save#{@存档列表.index}.rxdata", "wb")
  14.           write_save_data(file)
  15.           if FileTest.exist?(SCR_AUTO_SAVE_LOAD::DIR+"shot.jpg")
  16.             open(SCR_AUTO_SAVE_LOAD::DIR+"shot.jpg","rb") do |f1|
  17.               open(SCR_AUTO_SAVE_LOAD::DIR+"Save#{@存档列表.index}.jpg","wb"){|f2|f2.write(f1.read)}
  18.             end            
  19.             #File.rename(SCR_AUTO_SAVE_LOAD::DIR+"shot.jpg", SCR_AUTO_SAVE_LOAD::DIR+"Save#{@存档列表.index}.jpg")
  20.           end
  21.           file.close
  22.           $game_temp.last_file_index = @存档列表.index
  23. =begin  解除只能存一个档的限制        # 如果被事件调用
  24.           if $game_temp.save_calling
  25.             # 清除存档调用标志
  26.             $game_temp.save_calling = false
  27.             # 切换到地图画面
  28.             $scene = Scene_Map.new   
  29.             return
  30.           end
  31.         # 切换到菜单画面
  32. =end #         $scene = Scene_Map.new  
  33.          
  34.     end
  35.     #———————————————————————#
  36.     @content_window.refresh
  37.   end
  38. end
复制代码

作者: 羞射了    时间: 2013-1-8 01:40
简单测试后说下初步结论:
1、对话框大小的问题,是不是那个确定取消的框的问题?
        @option_window = Window_Command.new(160, ["确定", "取消"] , 2 )
            @option_window.height = 64 #可以用这个来强行指定宽度
2、关于效率,我只复制了运行这个sl菜单的必要脚本,开到80帧运行最多掉到70+,个人认为问题不大,但是不排除你其他脚本可能对速度造成的影响。

3、其他BUG,貌似储存和删除后信息栏的内容没有及时刷新。

多个存档似乎可以显示同一个截图,但是编号对不上就会出现一句提示语句和其他文字重合了。

暂时就知道这些了。
作者: zhangbanxian    时间: 2013-1-8 13:45
最大的bug就是存档覆盖不能吧,帮你改好了- -b
  1. #==============================================================================
  2. #  Scene_Loadsave
  3. #------------------------------------------------------------------------------
  4. # 处理存取档画面的类。
  5. #==============================================================================

  6. class Scene_Loadsave < Scene_Base
  7. #--------------------------------------------------------------------------
  8. # ● 初始化对像
  9. #     $last_savefile_index : 记录光标位置
  10. #--------------------------------------------------------------------------
  11.   def initialize(allow = true)
  12.     $last_savefile_index = 0 if $last_savefile_index == nil
  13.     # 再生成临时对像
  14.     $game_temp = Game_Temp.new
  15.     # 选择存档时间最新的文件
  16.     $game_temp.last_file_index = 0
  17.     latest_time = Time.at(0)
  18.     for i in 0..51
  19.       filename = SCR_AUTO_SAVE_LOAD::DIR+"Save#{i}.rxdata"
  20.       if FileTest.exist?(filename)
  21.         file = File.open(filename, "r")
  22.         if file.mtime > latest_time
  23.           latest_time = file.mtime
  24.           $game_temp.last_file_index = i
  25.         end
  26.         file.close
  27.       end
  28.     end
  29.     @allow_save = allow
  30.     @菜单级别 = 0
  31.   end
  32. #--------------------------------------------------------------------------
  33. #  主处理
  34. #--------------------------------------------------------------------------
  35.   def main_add
  36.     @savestate = 0
  37.     # 生成窗口
  38.    
  39.     最开始对话框
  40.     @存档列表 = Window_Command.new(160,SCR_AUTO_SAVE_LOAD::List)
  41.     @存档列表.y = 64
  42.     @存档列表.height = 416 + 120
  43.    
  44.    
  45.     ########################################################
  46.    
  47.       
  48.       #存档画面我当然也这么加上120
  49.       @存档列表.index = $game_temp.last_file_index
  50.       @content_window = Window_File.new($game_temp.last_file_index)
  51.       @content_window.z = 0
  52.       @存档列表.active = true
  53.         ###############覆盖存档
  54.         
  55. #        @help_window.set_text("确定要覆盖这个进度吗?")
  56.         

  57.     # 执行过渡
  58.     Graphics.transition
  59.     # 主循环
  60.     loop do
  61.       # 刷新游戏画面
  62.       Graphics.update
  63.       # 刷新输入信息
  64.       Input.update
  65.       # 刷新画面
  66.       update
  67.       # 如果画面被切换的话就中断循环
  68.       if $scene != self
  69.         break
  70.       end
  71.     end
  72.     # 准备过渡
  73.     Graphics.freeze
  74.     main_dispose

  75.   end

  76. #--------------------------------------------------------------------------
  77. #  ● 刷新画面
  78.   def update
  79.     @option_window.update
  80.     if @菜单级别 == 0
  81. =begin
  82.   □ 刷新窗口,这个很头疼,曾经因为运行效率问题我被折磨得很惨
  83.       @help_window.update这里考虑到实际作用不大,所以放弃了
  84.       因为禁止存档状态下添加了新的功能,所以相对想办法合并了一下子。
  85. =end
  86.       @存档列表.update
  87.    
  88.       
  89.       
  90.     #头疼的效率问题就在这里↓
  91. #    @content_window.update
  92.       if @存档列表.index != @content_window.index
  93.         @content_window.index = @存档列表.index
  94.         @content_window.refresh
  95.       end   
  96.       if Input.trigger?(Input::B) #取消
  97.         $game_system.se_play($data_system.cancel_se)
  98.         # 淡入淡出 BGM
  99.         
  100.           # 返回地图
  101.           if $game_message.menu_call == true
  102.               # 切换到地图画面
  103.             $scene = Scene_Menu.new(4) # 切换到菜单画面
  104.           elsif $game_map == nil #当地图不存在也就是游戏没有开始的时候
  105.             $scene = Scene_Title.new
  106.           else
  107.             $scene = Scene_Map.new
  108.           end
  109.          
  110.          
  111.       elsif Input.trigger?(Input::C) #←确定
  112.         # 文件不存在的情况下
  113.         unless FileTest.exist?(SCR_AUTO_SAVE_LOAD::DIR+"Save#{@存档列表.index}.rxdata")
  114.           if @option_window.index == 1 and @allow_save #存档时
  115.             
  116.             save_file
  117.             
  118.           else # 读取时,演奏冻结 SE
  119.             $game_system.se_play($data_system.buzzer_se)
  120.           end
  121.         else #文件存在的情况下
  122.           if @option_window.index == 0 #读取
  123.             #当然是直接读取文件了
  124.             load_file
  125.           else
  126.             #首先是切换菜单级别
  127.             @菜单级别 = 1
  128.             释放部分窗口
  129.             setup_help( 160 , 0 )
  130.             #然后根据具体情况更新内容
  131.             if @allow_save #允许存档的情况下为覆盖存档
  132.               @help_window.set_text("您确定要覆盖此存档吗?")
  133.             else #不允许的情况下自然是删除了
  134.               
  135.               @help_window.set_text("您确定要删除此存档吗?")
  136.               
  137.             end
  138.             
  139.             @option_window = Window_Command.new(160, ["确定", "取消"] , 2 )
  140.           end
  141.          
  142.          
  143.          
  144.         end
  145.         
  146.       end
  147.     else
  148.       if @option_window.index == 0 and Input.trigger?(Input::C)
  149.         if @allow_save #选择覆盖存档
  150.           save_file(true)#半仙改
  151.          
  152.         else #选择删除存档
  153.          
  154.           do_delete
  155.         end
  156.         
  157.         #把没有必要的重复操作合并把
  158.         @菜单级别 = 0
  159.         释放部分窗口
  160.         最开始对话框
  161.       elsif ( @option_window.index != 0 and Input.trigger?(Input::C)) or Input.trigger?(Input::B)
  162.         #自然是取消的场合了
  163.         $game_system.se_play($data_system.cancel_se)
  164.         
  165.         #把没有必要的重复操作合并把
  166.         @菜单级别 = 0
  167.         释放部分窗口
  168.         最开始对话框
  169.       end
  170.       
  171.     end  
  172.     @option_window.height = 64 if @option_window.height != 64 #半仙改

  173.   end
  174.   
  175.   
  176.   
  177.   def 最开始对话框
  178.     setup_help( 160 , 0 )
  179.    
  180.     if @allow_save
  181.         @option_window = Window_Command.new(160, ["读取", "存储"] , 2 )
  182.       
  183.         @option_window.index = $last_savefile_index
  184.         @help_window.set_text(SCR_AUTO_SAVE_LOAD::SAve_help)
  185.       else
  186.         #为了稍微统一,这里特别做了设定
  187.         @option_window = Window_Command.new(160, ["读取", "删除"] , 2 )
  188.         @option_window.index = 0
  189.         @help_window.set_text(SCR_AUTO_SAVE_LOAD::LOad_help)
  190.       end
  191.     #———————————————————————#
  192.     @option_window.height = 64
  193.   end



  194. #--------------------------------------------------------------------------
  195. #  读取记录文件
  196. #     filename  : 被读取文件
  197. #--------------------------------------------------------------------------
  198.   def load_file
  199.       # 文件不存在的情况下
  200.       unless FileTest.exist?(SCR_AUTO_SAVE_LOAD::DIR+"Save#{@存档列表.index}.rxdata")
  201.         # 演奏冻结 SE
  202.         $game_system.se_play($data_system.buzzer_se)
  203.         return
  204.       end
  205.       # 演奏读档 SE
  206.       $game_system.se_play($data_system.load_se)
  207.       # 写入存档数据
  208.       file = File.open(SCR_AUTO_SAVE_LOAD::DIR+"Save#{@存档列表.index}.rxdata", "rb")
  209.       read_save_data(file)
  210.       file.close
  211.       # 还原 BGM、BGS
  212.       $game_system.bgm_play($game_system.playing_bgm)
  213.       $game_system.bgs_play($game_system.playing_bgs)
  214.       # 刷新地图 (执行并行事件)
  215.       $game_map.update
  216.       # 切换到地图画面
  217.       $scene = Scene_Map.new
  218.   end
  219. #--------------------------------------------------------------------------
  220. # ● 读取存档数据
  221. #     file : 读取用文件对像 (已经打开)
  222. #--------------------------------------------------------------------------
  223.   def read_save_data(file)
  224.     # 读取描绘存档文件用的角色数据
  225.     characters = Marshal.load(file)
  226.     # 读取测量游戏时间用画面计数
  227.     Graphics.frame_count = Marshal.load(file)
  228.     # 读取各种游戏对像
  229.     $game_system        = Marshal.load(file)
  230.     $game_switches      = Marshal.load(file)
  231.     $game_variables     = Marshal.load(file)
  232.     $game_self_switches = Marshal.load(file)
  233.     $game_screen        = Marshal.load(file)
  234.     $game_actors        = Marshal.load(file)
  235.     $game_party         = Marshal.load(file)
  236.     $game_troop         = Marshal.load(file)
  237.     $game_map           = Marshal.load(file)
  238.     $game_player        = Marshal.load(file)
  239.     # 魔法编号与保存时有差异的情况下
  240.     # (加入编辑器的编辑过的数据)
  241.     if $game_system.magic_number != $data_system.magic_number
  242.       # 重新装载地图
  243.       $game_map.setup($game_map.map_id)
  244.       $game_player.center($game_player.x, $game_player.y)
  245.     end
  246.     # 刷新同伴成员
  247.     $game_party.refresh
  248.   end
  249.   #--------------------------------------------------------------------------
  250.   # ● 写入存档文件
  251.   #--------------------------------------------------------------------------
  252.   def save_file(s=false)
  253.     #半仙改
  254.     if Input.trigger?(Input::C) && !FileTest.exist?(SCR_AUTO_SAVE_LOAD::DIR+"Save#{@存档列表.index}.rxdata") or s
  255.         # 演奏冻结 SE
  256.         # 演奏存档 SE
  257.           $game_system.se_play($data_system.save_se)
  258.           # 写入存档数据
  259.           file = File.open(SCR_AUTO_SAVE_LOAD::DIR+"Save#{@存档列表.index}.rxdata", "wb")
  260.           write_save_data(file)
  261.           if FileTest.exist?(SCR_AUTO_SAVE_LOAD::DIR+"shot.jpg")
  262.             File.rename(SCR_AUTO_SAVE_LOAD::DIR+"shot.jpg", SCR_AUTO_SAVE_LOAD::DIR+"Save#{@存档列表.index}.jpg")
  263.           end
  264.           file.close
  265.           $game_temp.last_file_index = @存档列表.index
  266. =begin  解除只能存一个档的限制        # 如果被事件调用
  267.           if $game_temp.save_calling
  268.             # 清除存档调用标志
  269.             $game_temp.save_calling = false
  270.             # 切换到地图画面
  271.             $scene = Scene_Map.new   
  272.             return
  273.           end
  274.         # 切换到菜单画面
  275. =end #         $scene = Scene_Map.new  
  276.          
  277.     end
  278.     #———————————————————————#
  279.     @content_window.refresh
  280.   end
  281.   #-------------------------------------------------------------------
  282.   def confirm_update
  283.     @command_index = @存档列表.index
  284.     @option_window = Window_Command.new(160, ["确认", "取消"] , 2 )
  285.     if Input.trigger?(Input::C)
  286.       if @option_window.index == 0
  287.           #######################################################
  288.           # 演奏存档 SE
  289.           $game_system.se_play($data_system.save_se)
  290.           # 写入存档数据
  291.           file = File.open(SCR_AUTO_SAVE_LOAD::DIR+"Save#{@存档列表.index}.rxdata", "wb")
  292.           write_save_data(file)
  293.           if FileTest.exist?(SCR_AUTO_SAVE_LOAD::DIR+"shot.jpg")
  294.             File.rename(SCR_AUTO_SAVE_LOAD::DIR+"shot.jpg", SCR_AUTO_SAVE_LOAD::DIR+"Save#{@存档列表.index}.jpg")
  295.           end
  296.           file.close
  297.           $game_temp.last_file_index = @存档列表.index
  298.           # 如果被事件调用
  299.           if $game_temp.save_calling
  300.             # 清除存档调用标志
  301.             $game_temp.save_calling = false
  302.             @content_window.dispose
  303.             # 切换到地图画面
  304.             $scene = Scene_Map.new
  305.    
  306.             return
  307.           end
  308.         # 切换到菜单画面
  309.           $scene = Scene_Map.new        
  310.         else
  311.         $game_system.se_play($data_system.cancel_se)
  312.         @存档列表.active = true
  313.         end
  314.     end
  315.     if Input.trigger?(Input::B)
  316.       $game_system.se_play($data_system.cancel_se)

  317.         @存档列表.active = true
  318.     end
  319.   end
  320.   #--------------------------------------------------------------------------
  321.   # ● 写入存档数据
  322.   #     file : 写入用文件对像 (已经打开)
  323.   #--------------------------------------------------------------------------
  324.   def write_save_data(file)
  325.     # 生成描绘存档文件用的角色图形
  326.     characters = []
  327.     for i in 0...$game_party.actors.size
  328.       actor = $game_party.actors[i]
  329.       characters.push([actor.character_name, actor.character_hue, actor])
  330.     end
  331.     # 写入描绘存档文件用的角色数据
  332.     #characters.push($data_mapnames[$game_map.map_id].name)
  333.     Marshal.dump(characters, file)
  334.     # 写入测量游戏时间用画面计数
  335.     Marshal.dump(Graphics.frame_count, file)
  336.     # 增加 1 次存档次数
  337.     $game_system.save_count += 1
  338.     # 保存魔法编号
  339.     # (将编辑器保存的值以随机值替换)
  340.     $game_system.magic_number = $data_system.magic_number
  341.     # 写入各种游戏对像
  342.     Marshal.dump($game_system, file)
  343.     Marshal.dump($game_switches, file)
  344.     Marshal.dump($game_variables, file)
  345.     Marshal.dump($game_self_switches, file)
  346.     Marshal.dump($game_screen, file)
  347.     Marshal.dump($game_actors, file)
  348.     Marshal.dump($game_party, file)
  349.     Marshal.dump($game_troop, file)
  350.     Marshal.dump($game_map, file)
  351.     Marshal.dump($game_player, file)
  352.   end
  353.   
  354.   
  355. =begin --------------------------------------------
  356.   ★ 释放窗口

  357. =end #------------------------------
  358.   def 释放部分窗口
  359.     if @option_window != nil
  360.       @option_window.dispose
  361.       @option_window = nil
  362.    
  363.     end
  364.     if @help_window != nil
  365.       @help_window.dispose
  366.       @help_window = nil
  367.     end
  368.    
  369.   end  
  370.   def main_dispose
  371.     释放部分窗口

  372.     # 释放剩下的窗口
  373.     @存档列表.dispose
  374.    
  375.    
  376.     @content_window.dispose
  377.    
  378.   end
  379.   #--------------------------------------------------------------------------
  380.   # ● 删除存档
  381.   #--------------------------------------------------------------------------
  382.   def do_delete
  383.     if FileTest.exist?(SCR_AUTO_SAVE_LOAD::DIR + "Save#{@存档列表.index}.rxdata")
  384.       File.delete(SCR_AUTO_SAVE_LOAD::DIR + "Save#{@存档列表.index}.rxdata")
  385.     else
  386.       Sound.play_buzzer
  387.     end
  388.    
  389.     if FileTest.exist?(SCR_AUTO_SAVE_LOAD::DIR + "Save#{@存档列表.index}.jpg")
  390.       File.delete(SCR_AUTO_SAVE_LOAD::DIR + "Save#{@存档列表.index}.jpg")
  391.    
  392.     end
  393.     @content_window.refresh#半仙改
  394.   end
  395.   
  396.   
  397.   
  398.   
  399.   
  400. end
复制代码
ps:话说读档在前,存档在后很容易误操作啊有木有,反正你喜欢就好- -b
作者: eve592370698    时间: 2013-1-8 14:35
zhangbanxian 发表于 2013-1-8 13:45
最大的bug就是存档覆盖不能吧,帮你改好了- -bps:话说读档在前,存档在后很容易误操作啊有木有,反正你喜 ...

已经转账了一些,谢了。我最头疼的是截图问题,我把每次存档返回地图代码屏蔽了,可是如不返回地图再存档会截图失败,挺麻烦。不知克服这个困难不,如果实在困难再修复别的bug就给您奖赏。
作者: eve592370698    时间: 2013-1-8 15:59
标题: 真不是我写的
zhangbanxian 发表于 2013-1-8 15:01
汗,原脚本不是你写的?

脚本是不是马甲推荐给我的,我也仅仅是照搬方法,至于截图原理自己真不清楚。
我现在上班,晚上回家用电脑看看。




欢迎光临 Project1 (https://rpg.blue/) Powered by Discuz! X3.1