RMXP脚本解析(二):Scene_Title

目录

Scene_Title类代码解析

类变量表

总结


上文我们解析了Main,其中除了调用RGSS自带的模块和方法之外还调用了唯一一个自建类Scene_Title,创建了一个此类的对象$scene,且在$scene不为nil时调用$scene.main方法。所以本节我们就从Scene_Title开始。

Scene_Title类代码解析

#==============================================================================

# ■ Scene_Title

#------------------------------------------------------------------------------

#  处理标题画面的类。

#==============================================================================

class Scene_Title

    #--------------------------------------------------------------------------

    # ● 主处理

    #--------------------------------------------------------------------------

    def main #此方法在全局变量$BTEST为真时执行本类的方法battle_test(我不得不说这种写法很有迷惑性...)然后返回

      # 战斗测试的情况下

      if $BTEST #这个全局变量表示是否为战斗测试(战斗测试应该是数据库那里战斗一次就退出游戏的类型)

        battle_test

        return

      end

      # 载入数据库 #注意这些是全局变量

      #load_data(filename)是RGSS的内部函数,读取 filename 指定的数据文件,使用Marshal.load()重建对象。不加密数据的情况下就是普通的读取。

      #还有一句闲话,Marshal属于序列化数据,所以即使我们知道rxdata文件的编码是UTF-8也不能直接读取它们。

      #未加密的数据文件采取一行一个对象的方法。

      $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类

      # 生成标题图形

      @sprite = Sprite.new

      @sprite.bitmap = RPG::Cache.title($data_system.title_name)

      #RPG::Cache 是RGSS的自建模块 内部title(filename)方法取得参数所指的标题图像。 $data_system在上方被初始化,其值为System.rxdata的内容。 

      # 生成命令窗口 #s1s2s3就是三个变量

      s1 = "新游戏"

      s2 = "继续"

      s3 = "退出"

      #设置几个类变量的值 #从这里可以很明显的看出初代RM固定了窗口的位置和大小

      @command_window = Window_Command.new(192, [s1, s2, s3]) #Window_Command是游戏内部类

      @command_window.back_opacity = 160 #opacity明显指的是透明度,我猜它的取值范围为0~256

      @command_window.x = 320 - @command_window.width / 2 

      @command_window.y = 288

      # 判定继续的有效性

      # 存档文件一个也不存在的时候也调查

      # 有効为 @continue_enabled 为 true、无效为 false

      @continue_enabled = false

      for i in 0..3 #这里i的范围为一次读取的存档文件数量

        if FileTest.exist?("Save#{i+1}.rxdata")

          @continue_enabled = true 

        end #如果存在任意的Save文件,就设置@continue_enabled为真 这个变量决定了“继续”是否可选

      end

      # 继续为有效的情况下、光标停止在继续上

      # 无效的情况下、继续的文字显示为灰色

      if @continue_enabled

        @command_window.index = 1 #这个属性来自Window_Command的父类Window_Selectabled,决定了光标所在位置

      else

        @command_window.disable_item(1) #调用Window_Command的方法disable_item(index),将index指向的选项用禁用颜色绘制

      end

      # 演奏标题 BGM

      $game_system.bgm_play($data_system.title_bgm) #RGSS内部类Audio的方法bgm_play,播放指向的文件 

      # 停止演奏 ME、BGS

      Audio.me_stop #停止播放me

      Audio.bgs_stop #停止播放bgs #这两句是不是应该放在前面..

      # 执行过渡

      Graphics.transition 

      # 主循环

      loop do #这是个死循环哦

        # 刷新游戏画面

        Graphics.update

        # 刷新输入信息

        Input.update

        # 刷新画面

        update #本类的方法update

        # 如果画面被切换就中断循环

        if $scene != self #如果全局变量$scene所指向的不是现在这个调用main方法的对象

          break 

        end

      end

      # 装备过渡

      Graphics.freeze

      # 释放命令窗口

      @command_window.dispose #RGSS内部方法,很多内部类都有这个方法,比如说这三行里的dispose其实来自三个不同的类

      # 释放标题图形

      @sprite.bitmap.dispose

      @sprite.dispose

    end

    #--------------------------------------------------------------------------

    # ● 刷新画面

    #--------------------------------------------------------------------------

    def update

      # 刷新命令窗口

      @command_window.update

      # 按下 C 键的情况下

      if Input.trigger?(Input::C) #就是键盘上的“c”

        # 命令窗口的光标位置的分支

        case @command_window.index

        when 0  # 新游戏

          command_new_game #这三个看着像是变量的东西无疑是本类内方法 

          #为什么要给方法和变量取这么容易混淆的名字呢,贯彻Ruby“一切皆对象”的思想吗...

        when 1  # 继续

          command_continue

        when 2  # 退出

          command_shutdown

        end

      end

    end

    #--------------------------------------------------------------------------

    # ● 命令 : 新游戏

    #--------------------------------------------------------------------------

    def command_new_game

      # 演奏确定 SE

      $game_system.se_play($data_system.decision_se) #选择时候的se

      # 停止 BGM

      Audio.bgm_stop

      # 重置测量游戏时间用的画面计数器

      Graphics.frame_count = 0

      # 生成各种游戏对像

      $game_temp          = Game_Temp.new #所有临时数据类

      $game_system        = Game_System.new #记录和处理BGM等音乐、记录计时器等其他临时数据的类

      $game_switches      = Game_Switches.new #记录游戏内开关的状态的类

      $game_variables     = Game_Variables.new #处理变量的类

      $game_self_switches = Game_SelfSwitches.new #处理独立开关(ABCD)的类

      $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_party.setup_starting_members #游戏内部类Game_Party类内方法

      # 设置初期位置的地图

      $game_map.setup($data_system.start_map_id) #同名游戏内部类内方法,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

      # 切换地图画面

      $scene = Scene_Map.new

    end

    #--------------------------------------------------------------------------

    # ● 命令 : 继续

    #--------------------------------------------------------------------------

    def command_continue

      # 继续无效的情况下

      unless @continue_enabled #除非类变量@continue_enabled为真

        # 演奏无效 SE

        $game_system.se_play($data_system.buzzer_se) #也就是说,继续在无效的情况下也可以被选中

        return

      end

      # 演奏确定 SE

      $game_system.se_play($data_system.decision_se)

      # 切换到读档画面

      $scene = Scene_Load.new #有效的时候才跳转(也就是把$scene指向新的窗口实例)

    end

    #--------------------------------------------------------------------------

    # ● 命令 : 退出

    #--------------------------------------------------------------------------

    def command_shutdown

      # 演奏确定 SE

      $game_system.se_play($data_system.decision_se)

      # BGM、BGS、ME 的淡入淡出 #渐隐所有声效

      Audio.bgm_fade(800)

      Audio.bgs_fade(800)

      Audio.me_fade(800)

      # 退出

      $scene = nil #画面跳转到nil

    end

    #--------------------------------------------------------------------------

    # ● 战斗测试

    #--------------------------------------------------------------------------

    def battle_test #这里的一些步骤跟上面的一些差不多,就不写注释了

      # 载入数据库 (战斗测试用)

      $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")

      # 重置测量游戏时间用的画面计数器

      Graphics.frame_count = 0

      # 生成各种游戏对像

      $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_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

类变量表

说实话本类基本都在实例化全局变量,类变量也就几个。

总结

-本类揭示了$scene全局变量的用法:它指向的永远是当前的窗口,当其更改时对游戏窗口进行更新。

-本类中的main方法载入了数据库文件。

-RMXP游戏脚本中很鲜明的一点是,其先改变全局变量实例的属性值,然后进行update。整个游戏直到$scene==nil时一直处于update中。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值