查看: 4112|回复: 1

[讨论] 癫狂侠客的脚本探索之旅——Scene之运行开始篇

[复制链接]

梦石
0
星屑
432
在线时间
4175 小时
注册时间
2010-6-26
回帖
6276
发表于 2013-1-21 21:46:47 | 显示全部楼层 |阅读模式

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

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

×
本帖最后由 eve592370698 于 2013-1-21 21:50 编辑

想必有不少新手看到了一些人做出来的动态标题以及跳过标题等,说真的,动态标题我看了就头大啊!而跳过标题呢?我也使用过,有些出现这种情况:使用RMXP做战斗测试结果失效了!
还有,当我在一些脚本里面使用$game_switches和$game_variables作为条件判定的时候,脚本也会出现各种各样的错误,为啥呢?
友情提示,探索之负责游戏运行的开始,并不涉及到游戏的重启,主要是探索从启动游戏到真正弹出标题画面菜单之前这一瞬间游戏在做什么。
当然,首先是把游戏的各个脚本预读以便,然后确定常量赋值,然后呢?废话不说,先上原版的Scene_Title查看main的前面那几行[pre lang="ruby" line="1"]# 战斗测试的情况下
    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[/pre]这是在生成标题菜单之前,游戏先判定,如果开启了战斗测试,那么就跳过这些读取数据,转而运行战斗测试,反之读取数据。这就不难看出,上面只有可怜的一个
$game_system = Game_System.new
也就是说剩下的游戏全局变量组例如$game_switches和$game_variables它们根本没有被读取识别!所以如果此时草率地在Window_Base、Window_Command等类里面使用开关或者变量作为条件,就会出错!接下来就正式进入游戏菜单了。我们探索的目的首先一个就是把它从Scene_Title里面分离出来,进而为后面的标题扩展做准备。看看这段脚本[pre lang="ruby" line="1"]# 生成各种游戏对像
    $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[/pre]这里$game_system = Game_System.new又出现了一次。再对比一下RMVA,它的数据读取相关的脚本全集中到了模块DataManager相对比较集中而且都作了方法归类,更重要的是和VX一样$game_system = Game_System.new它只做了一次赋值,和别的变量一起在运行开始的时候就赋值完毕。
如果考虑到RMXP的帧数低,可能读取标题需要的时间比较长,经过充分考虑,将这段脚本分裂成两个方法:[pre lang="ruby" line="1"]  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[/pre]这样一来就正是开始游戏之前先赋值一部分,然后开始游戏的时候赋值另一部分,这样岂不是很好?
为了让标题更为灵活,同时避免不必要的重复赋值,我们引入了一个特殊的Scene:Scene_Start上一讲大家看到了,在mian里面,我将原来的$scene = Scene_Title.new换成了$scene = Scene_Start.new!看看我的这个脚本[pre lang="ruby" line="1"]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[/pre]没有太多东西,因为这里不需要释放什么通过条件分歧来判定是进入战斗测试、进入游戏标题还是跳过游戏标题直接开始新游戏。当然了,这里我得先补充点东西:
首先,在这之前必须要进行的是[pre lang="ruby" line="1"]  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[/pre]这个正好根据是否开启战斗测试提前读取需要的脚本,避免了数据的第二次读取,很是方便。然后呢?[pre lang="ruby" line="1"]  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[/pre]以及上面两个变量组定义赋值的脚本为了便于调用,我挪动到了它的父类Scene这个类里面,也就类似于VX ACE的模块那样,
@DeathKing 曾经说过,他可以像变魔术那样修改Scene_Title使用不到4行代码即可跳过标题,我在这里就揭开这精简代码背后庞大复杂的具体内容,依靠的说白了无外乎这种继承关系


通过这种修改,我们将Scene_Title从加载游戏的沉重任务中解救出来,进而让它可以轻装上阵。下一个探索之旅,我们将给大家揭示如何和Scene_Title绕圈圈,为事件标题、二周目游戏提供快捷省脑筋的方法。 透漏一下,我下一探索就是告诉大家怎么让Scene_Title的这个执行新游戏变成假的!

Scripts.rxdata

320.13 KB, 下载次数: 45

潜水,专心忙活三次元工作了……

66RPG我的

梦石
0
星屑
220
在线时间
491 小时
注册时间
2012-1-16
回帖
1895
发表于 2013-1-22 08:12:49 来自手机 | 显示全部楼层
这样弄的结果恐怕是以往各种标题脚本不再兼容了吧?
回复

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部