| 
本帖最后由 eve592370698 于 2013-1-21 21:50 编辑
x
加入我们,或者,欢迎回来。您需要 登录 才可以下载或查看,没有帐号?注册会员  
 想必有不少新手看到了一些人做出来的动态标题以及跳过标题等,说真的,动态标题我看了就头大啊!而跳过标题呢?我也使用过,有些出现这种情况:使用RMXP做战斗测试结果失效了!
 还有,当我在一些脚本里面使用$game_switches和$game_variables作为条件判定的时候,脚本也会出现各种各样的错误,为啥呢?
 友情提示,探索之负责游戏运行的开始,并不涉及到游戏的重启,主要是探索从启动游戏到真正弹出标题画面菜单之前这一瞬间游戏在做什么。
 当然,首先是把游戏的各个脚本预读以便,然后确定常量赋值,然后呢?废话不说,先上原版的Scene_Title查看main的前面那几行
 # 战斗测试的情况下    if $BTEST      battle_test      return    end    # 载入数据库    $data_actors        = load_data("Data/Actors.rxdata")    $data_classes       = load_data("Data/Classes.rxdata")    $data_skills        = load_data("Data/Skills.rxdata")    $data_items         = load_data("Data/Items.rxdata")    $data_weapons       = load_data("Data/Weapons.rxdata")    $data_armors        = load_data("Data/Armors.rxdata")    $data_enemies       = load_data("Data/Enemies.rxdata")    $data_troops        = load_data("Data/Troops.rxdata")    $data_states        = load_data("Data/States.rxdata")    $data_animations    = load_data("Data/Animations.rxdata")    $data_tilesets      = load_data("Data/Tilesets.rxdata")    $data_common_events = load_data("Data/CommonEvents.rxdata")    $data_system        = load_data("Data/System.rxdata")    # 生成系统对像    $game_system = Game_System.new
这是在生成标题菜单之前,游戏先判定,如果开启了战斗测试,那么就跳过这些读取数据,转而运行战斗测试,反之读取数据。这就不难看出,上面只有可怜的一个# 战斗测试的情况下 
    if $BTEST 
      battle_test 
      return 
    end 
    # 载入数据库 
    $data_actors        = load_data("Data/Actors.rxdata") 
    $data_classes       = load_data("Data/Classes.rxdata") 
    $data_skills        = load_data("Data/Skills.rxdata") 
    $data_items         = load_data("Data/Items.rxdata") 
    $data_weapons       = load_data("Data/Weapons.rxdata") 
    $data_armors        = load_data("Data/Armors.rxdata") 
    $data_enemies       = load_data("Data/Enemies.rxdata") 
    $data_troops        = load_data("Data/Troops.rxdata") 
    $data_states        = load_data("Data/States.rxdata") 
    $data_animations    = load_data("Data/Animations.rxdata") 
    $data_tilesets      = load_data("Data/Tilesets.rxdata") 
    $data_common_events = load_data("Data/CommonEvents.rxdata") 
    $data_system        = load_data("Data/System.rxdata") 
    # 生成系统对像 
    $game_system = Game_System.new 
$game_system = Game_System.new
 也就是说剩下的游戏全局变量组例如$game_switches和$game_variables它们根本没有被读取识别!所以如果此时草率地在Window_Base、Window_Command等类里面使用开关或者变量作为条件,就会出错!接下来就正式进入游戏菜单了。我们探索的目的首先一个就是把它从Scene_Title里面分离出来,进而为后面的标题扩展做准备。看看这段脚本
 # 生成各种游戏对像    $game_temp          = Game_Temp.new    $game_system        = Game_System.new    $game_switches      = Game_Switches.new    $game_variables     = Game_Variables.new    $game_self_switches = Game_SelfSwitches.new    $game_screen        = Game_Screen.new    $game_actors        = Game_Actors.new    $game_party         = Game_Party.new    $game_troop         = Game_Troop.new    $game_map           = Game_Map.new    $game_player        = Game_Player.new
这里$game_system = Game_System.new又出现了一次。再对比一下RMVA,它的数据读取相关的脚本全集中到了模块DataManager相对比较集中而且都作了方法归类,更重要的是和VX一样$game_system = Game_System.new它只做了一次赋值,和别的变量一起在运行开始的时候就赋值完毕。# 生成各种游戏对像 
    $game_temp          = Game_Temp.new 
    $game_system        = Game_System.new 
    $game_switches      = Game_Switches.new 
    $game_variables     = Game_Variables.new 
    $game_self_switches = Game_SelfSwitches.new 
    $game_screen        = Game_Screen.new 
    $game_actors        = Game_Actors.new 
    $game_party         = Game_Party.new 
    $game_troop         = Game_Troop.new 
    $game_map           = Game_Map.new 
    $game_player        = Game_Player.new 
如果考虑到RMXP的帧数低,可能读取标题需要的时间比较长,经过充分考虑,将这段脚本分裂成两个方法:
 def create_basic_objects     $game_system        = Game_System.new    $game_temp          = Game_Temp.new    $game_message       = Game_Message.new    $game_switches      = Game_Switches.new    $game_variables     = Game_Variables.new  end  #在玩家现身时,生成  def create_game_objects    $game_self_switches = Game_SelfSwitches.new    $game_screen        = Game_Screen.new    $game_actors        = Game_Actors.new    $game_party         = Game_Party.new    $game_troop         = Game_Troop.new    $game_map           = Game_Map.new    $game_player        = Game_Player.new  end
这样一来就正是开始游戏之前先赋值一部分,然后开始游戏的时候赋值另一部分,这样岂不是很好?def create_basic_objects  
    $game_system        = Game_System.new 
    $game_temp          = Game_Temp.new 
    $game_message       = Game_Message.new 
    $game_switches      = Game_Switches.new 
    $game_variables     = Game_Variables.new 
  end 
  #在玩家现身时,生成 
  def create_game_objects 
    $game_self_switches = Game_SelfSwitches.new 
    $game_screen        = Game_Screen.new 
    $game_actors        = Game_Actors.new 
    $game_party         = Game_Party.new 
    $game_troop         = Game_Troop.new 
    $game_map           = Game_Map.new 
    $game_player        = Game_Player.new 
  end 
为了让标题更为灵活,同时避免不必要的重复赋值,我们引入了一个特殊的Scene:Scene_Start上一讲大家看到了,在mian里面,我将原来的$scene = Scene_Title.new换成了$scene = Scene_Start.new!看看我的这个脚本
 class Scene_Start < Scene=begin =end    # 载入数据库  def initialize   end  def main    # 生成游戏系统    create_basic_objects if $game_temp == nil        start      end  def start    load_game_data    if $BTEST      battle_test      return    elsif DKRM::No_Title > 1 or ( DKRM::No_Title == 1 and $DEBUG)      #↓跳过标题菜单      command_new_game          else        #↓进入标题菜单      $scene = Scene_Title.new    end      end   #--------------------------------------------------------------------------  # ● 战斗测试  #--------------------------------------------------------------------------  def battle_test     # 重置测量游戏时间用的画面计数器    Graphics.frame_count = 0    # 生成各种游戏对像    create_game_objects    # 设置战斗测试用同伴    $game_party.setup_battle_test_members    # 设置队伍 ID、可以逃走标志、战斗背景    $game_temp.battle_troop_id = $data_system.test_troop_id    $game_temp.battle_can_escape = true    $game_map.battleback_name = $data_system.battleback_name    # 演奏战斗开始 BGM    $game_system.se_play($data_system.battle_start_se)    # 演奏战斗 BGM    $game_system.bgm_play($game_system.battle_bgm)    # 切换到战斗画面    $scene = Scene_Battle.new  end       end
没有太多东西,因为这里不需要释放什么通过条件分歧来判定是进入战斗测试、进入游戏标题还是跳过游戏标题直接开始新游戏。当然了,这里我得先补充点东西:class Scene_Start < Scene 
=begin  
=end   
  # 载入数据库 
  def initialize 
  
  end 
  def main 
    # 生成游戏系统 
    create_basic_objects if $game_temp == nil     
    start     
  end 
  def start 
    load_game_data 
    if $BTEST 
      battle_test 
      return 
    elsif DKRM::No_Title > 1 or ( DKRM::No_Title == 1 and $DEBUG) 
      #↓跳过标题菜单 
      command_new_game       
    else   
      #↓进入标题菜单 
      $scene = Scene_Title.new 
    end     
  end 
  
  #-------------------------------------------------------------------------- 
  # ● 战斗测试 
  #-------------------------------------------------------------------------- 
  def battle_test 
  
    # 重置测量游戏时间用的画面计数器 
    Graphics.frame_count = 0 
    # 生成各种游戏对像 
    create_game_objects 
    # 设置战斗测试用同伴 
    $game_party.setup_battle_test_members 
    # 设置队伍 ID、可以逃走标志、战斗背景 
    $game_temp.battle_troop_id = $data_system.test_troop_id 
    $game_temp.battle_can_escape = true 
    $game_map.battleback_name = $data_system.battleback_name 
    # 演奏战斗开始 BGM 
    $game_system.se_play($data_system.battle_start_se) 
    # 演奏战斗 BGM 
    $game_system.bgm_play($game_system.battle_bgm) 
    # 切换到战斗画面 
    $scene = Scene_Battle.new 
  end        
end 
首先,在这之前必须要进行的是
 def load_game_data    if $BTEST      # 载入数据库 (战斗测试用)      $data_actors        = load_data("Data/BT_Actors.rxdata")      $data_classes       = load_data("Data/BT_Classes.rxdata")      $data_skills        = load_data("Data/BT_Skills.rxdata")      $data_items         = load_data("Data/BT_Items.rxdata")      $data_weapons       = load_data("Data/BT_Weapons.rxdata")      $data_armors        = load_data("Data/BT_Armors.rxdata")      $data_enemies       = load_data("Data/BT_Enemies.rxdata")      $data_troops        = load_data("Data/BT_Troops.rxdata")      $data_states        = load_data("Data/BT_States.rxdata")      $data_animations    = load_data("Data/BT_Animations.rxdata")      $data_tilesets      = load_data("Data/BT_Tilesets.rxdata")      $data_common_events = load_data("Data/BT_CommonEvents.rxdata")      $data_system        = load_data("Data/BT_System.rxdata")      else      $data_actors        = load_data("Data/Actors.rxdata")      $data_classes       = load_data("Data/Classes.rxdata")      $data_skills        = load_data("Data/Skills.rxdata")      $data_items         = load_data("Data/Items.rxdata")      $data_weapons       = load_data("Data/Weapons.rxdata")      $data_armors        = load_data("Data/Armors.rxdata")      $data_enemies       = load_data("Data/Enemies.rxdata")      $data_troops        = load_data("Data/Troops.rxdata")      $data_states        = load_data("Data/States.rxdata")      $data_animations    = load_data("Data/Animations.rxdata")      $data_tilesets      = load_data("Data/Tilesets.rxdata")      $data_common_events = load_data("Data/CommonEvents.rxdata")      $data_system        = load_data("Data/System.rxdata")      #GTBS特别添加了这个功能      $data_map_info      = load_data("Data/MapInfos.rxdata")    end  end
这个正好根据是否开启战斗测试提前读取需要的脚本,避免了数据的第二次读取,很是方便。然后呢?def load_game_data 
    if $BTEST 
      # 载入数据库 (战斗测试用) 
      $data_actors        = load_data("Data/BT_Actors.rxdata") 
      $data_classes       = load_data("Data/BT_Classes.rxdata") 
      $data_skills        = load_data("Data/BT_Skills.rxdata") 
      $data_items         = load_data("Data/BT_Items.rxdata") 
      $data_weapons       = load_data("Data/BT_Weapons.rxdata") 
      $data_armors        = load_data("Data/BT_Armors.rxdata") 
      $data_enemies       = load_data("Data/BT_Enemies.rxdata") 
      $data_troops        = load_data("Data/BT_Troops.rxdata") 
      $data_states        = load_data("Data/BT_States.rxdata") 
      $data_animations    = load_data("Data/BT_Animations.rxdata") 
      $data_tilesets      = load_data("Data/BT_Tilesets.rxdata") 
      $data_common_events = load_data("Data/BT_CommonEvents.rxdata") 
      $data_system        = load_data("Data/BT_System.rxdata") 
  
  
    else 
      $data_actors        = load_data("Data/Actors.rxdata") 
      $data_classes       = load_data("Data/Classes.rxdata") 
      $data_skills        = load_data("Data/Skills.rxdata") 
      $data_items         = load_data("Data/Items.rxdata") 
      $data_weapons       = load_data("Data/Weapons.rxdata") 
      $data_armors        = load_data("Data/Armors.rxdata") 
      $data_enemies       = load_data("Data/Enemies.rxdata") 
      $data_troops        = load_data("Data/Troops.rxdata") 
      $data_states        = load_data("Data/States.rxdata") 
      $data_animations    = load_data("Data/Animations.rxdata") 
      $data_tilesets      = load_data("Data/Tilesets.rxdata") 
      $data_common_events = load_data("Data/CommonEvents.rxdata") 
      $data_system        = load_data("Data/System.rxdata") 
      #GTBS特别添加了这个功能 
      $data_map_info      = load_data("Data/MapInfos.rxdata") 
    end 
  end 
def command_new_game    # 演奏确定 SE    $game_system.se_play($data_system.decision_se)    # 停止 BGM    Audio.bgm_stop    # 重置测量游戏时间用的画面计数器    Graphics.frame_count = 0    #生成游戏对象    create_game_objects    # 设置初期同伴位置    $game_party.setup_starting_members    # 设置初期位置的地图    $game_map.setup($data_system.start_map_id)    # 主角向初期位置移动    $game_player.moveto($data_system.start_x, $data_system.start_y)    # 刷新主角    $game_player.refresh    # 执行地图设置的 BGM 与 BGS 的自动切换    $game_map.autoplay    # 刷新地图 (执行并行事件)    $game_map.update    # 切换地图画面        $game_temp.to_title = false    $scene = Scene_Map.new  end
以及上面两个变量组定义赋值的脚本为了便于调用,我挪动到了它的父类Scene这个类里面,也就类似于VX ACE的模块那样,def command_new_game 
    # 演奏确定 SE 
    $game_system.se_play($data_system.decision_se) 
    # 停止 BGM 
    Audio.bgm_stop 
    # 重置测量游戏时间用的画面计数器 
    Graphics.frame_count = 0 
    #生成游戏对象 
    create_game_objects 
    # 设置初期同伴位置 
    $game_party.setup_starting_members 
    # 设置初期位置的地图 
    $game_map.setup($data_system.start_map_id) 
    # 主角向初期位置移动 
    $game_player.moveto($data_system.start_x, $data_system.start_y) 
    # 刷新主角 
    $game_player.refresh 
    # 执行地图设置的 BGM 与 BGS 的自动切换 
    $game_map.autoplay 
    # 刷新地图 (执行并行事件) 
    $game_map.update 
    # 切换地图画面     
    $game_temp.to_title = false 
    $scene = Scene_Map.new 
  end 
@DeathKing 曾经说过,他可以像变魔术那样修改Scene_Title使用不到4行代码即可跳过标题,我在这里就揭开这精简代码背后庞大复杂的具体内容,依靠的说白了无外乎这种继承关系
 
 
 通过这种修改,我们将Scene_Title从加载游戏的沉重任务中解救出来,进而让它可以轻装上阵。下一个探索之旅,我们将给大家揭示如何和Scene_Title绕圈圈,为事件标题、二周目游戏提供快捷省脑筋的方法。 透漏一下,我下一探索就是告诉大家怎么让Scene_Title的这个执行新游戏变成假的!
 |