查看: 6314|回复: 8

[通用发布] 癫狂侠客的RMXP脚本探索之旅Scene基础篇

[复制链接]

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

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

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

×
本帖最后由 eve592370698 于 2013-1-21 21:48 编辑
脚本不是高手专利,你我也能创造奇迹

这是我的师父癫狂侠客说出来的话。如今他正在忙于工作,看到@疯狂异形 给出这么多探索之旅,我也想把我和他一起探索脚本的一些心得体会发给大家。我们决定发布这个脚本探索之旅主要目的是为了让大家通过优化精简自己的脚本,让RMXP的RGSS1吸收VX的RGSS2以及VX ACE的RGSS3里面一些优点,让脚本更容易理解,顺利理清自己的思路,为以后制作脚本力争用最少量简单的代码尽可能实现庞大复杂的功能。
为啥我们上来开始探索Scene这个类呢?虽然这个类位置比较靠后,但是和游戏的运行却最为紧密!而且针对XP来说,也有很多嘈点。想必看脚本的时候,很多类里面上来给出的第一个方法是
def initialize
这个是加载的该方法的初始初始化状态。但是一到Scene里面,却成了
def main
很多Scene里面竟然没有initialize这个方法,这里头不禁有人会不明白了。经过一番探索,其实答案就在Main这个标签中(注意这里头修改过了!)
[pre lang="ruby" line="1"]begin
  # 准备过渡
  # 设置系统默认字体
  Font.default_name = (["黑体"])
  Graphics.freeze
  # 生成场景对像 (↓生成游戏开始)
  $scene = Scene_Start.new
  # $scene 为有效的情况下调用 main 过程
  while $scene != nil
    $scene.main
  end
  # 淡入淡出
  Graphics.transition(20)
rescue Errno::ENOENT
  # 补充 Errno::ENOENT 以外错误
  # 无法打开文件的情况下、显示信息后结束
  filename = $!.message.sub("No such file or directory - ", "")
  print("找不到文件 #{filename}。 ")
end[/pre]也就是说当您打开这个游戏的时候,首先读取的就是Scene_Start这个类,随后呢,按照执行的先后顺序下一个执行的就是[pre lang="ruby" line="1"]  while $scene != nil
    $scene.main
  end[/pre]说白了,整个游戏过程无外乎就是Scene这一套类的main这个方法的执行过程。以上的内容,在RMXP帮助文件的场景类里面会有详细的描述,但是下面呢?这帮助文件就有点不够意思了。打开一个Scene类,就举个例子吧,例如RM默认的Scene_Skill[pre lang="ruby" line="1"]  def main
    # 获取角色
    @actor = $game_party.actors[@actor_index]
    # 生成帮助窗口、状态窗口、特技窗口
    @help_window = Window_Help.new
    @status_window = Window_SkillStatus.new(@actor)
    @skill_window = Window_Skill.new(@actor)
    # 关联帮助窗口
    @skill_window.help_window = @help_window
    # 生成目标窗口 (设置为不可见?不活动)
    @target_window = Window_Target.new
    @target_window.visible = false
    @target_window.active = false
    # 执行过渡
    Graphics.transition
    # 主循环
    loop do
      # 刷新游戏画面
      Graphics.update
      # 刷新输入信息
      Input.update
      # 刷新画面
      update
      # 如果画面切换的话就中断循环
      if $scene != self
        break
      end
    end
    # 准备过渡
    Graphics.freeze
    # 释放窗口
    @help_window.dispose
    @status_window.dispose
    @skill_window.dispose
    @target_window.dispose
  end[/pre]我们可以看到一开始是各种变量赋值,下面呢,除了少数Scene之外,基本上就进入[pre lang="ruby" line="1"]    # 执行过渡
    Graphics.transition
    # 主循环
    loop do
      # 刷新游戏画面
      Graphics.update
      # 刷新输入信息
      Input.update
      # 刷新画面
      update
      # 如果画面切换的话就中断循环
      if $scene != self
        break
      end
    end
    # 准备过渡
    Graphics.freeze[/pre]接下来就是各种dispose了。
接下来,不禁要对比一下VX(包括VX ACE)了,看看它们的Scene,首先加入了一个Scene_Base,以VX为例,[pre lang="ruby" line="1"]  def main
    start                         # 開始処理
    perform_transition            # トランジション実行
    post_start                    # 開始後処理
    Input.update                  # 入力情報を更新
    loop do
      Graphics.update             # ゲーム画面を更新
      Input.update                # 入力情報を更新
      update                      # フレーム更新
      break if $scene != self     # 画面が切り替わったらループを中断
    end
    Graphics.update
    pre_terminate                 # 終了前処理
    Graphics.freeze               # トランジション準備
    terminate                     # 終了処理
  end[/pre]下面的呢?其实都是继承了Scene_Base这个类的main,而子类说白了就是分别对这里的各个方法进行具体而详细的定义,考虑到这里重点是在探究RMXP,所以不赘述,这么做的好处的确是精简了不少代码,咱们不妨从XP尝试一下精简合并。经过一些摸索,我们终于发现除了Scene_Battle等少数类以外,都是按照Graphics.transition完了循环,然后Graphics.freeze。
为了便于理解,我也建立一个Scene_Base这个类并定义几个重要方法[pre lang="ruby" line="1"]  def main
    #↓首先是加载
    main_setup
    #↓为了便于扩展,这里填补空白
    main_add
    # 执行过渡
    Graphics.transition
    #更新
    main_update
    # 更新完毕装备过渡
    Graphics.freeze
    #↓最后是释放
    main_dispose
  end[/pre]当然名字可能有点不太准确,但是从业余脚本爱好者来看,适合自己理解即可,看下面一段代码[pre lang="ruby" line="1"]# 主循环
    loop do
      # 刷新游戏画面
      Graphics.update
      # 刷新输入信息
      Input.update
      # 刷新画面
      update
      # 如果画面切换的话就中断循环
      if $scene != self
        break
      end
    end[/pre]将此方法定义到main_update这个方法里面,找到凡是符合这个规律的Scene类,继承了Base之后main都可以拆分成两个main_setup和main_dispose。
估计有人会问为什么不把Graphics.freeze和Graphics.transition定义到main_update里面,另外那么像Scene_Battle怎么处理呢?
其实,为了进一步精简代码,我要在Scene_Base类上面再加一个父类Scene,把main_update定义到最顶端的父类Scene里面,这样一来让Scene_Battle直接继承下来,不是很好吗?例如Scene_Title优化之后[pre lang="ruby" line="1"]class Scene_Title < Scene_Base
  #--------------------------------------------------------------------------
  # ● 主处理【受到继承影响】
  def main_setup
    # 战斗测试的情况下
   
   
   
    # 生成标题图形
    @sprite = Sprite.new
    @sprite.bitmap = RPG::Cache.title($data_system.title_name)
    # 生成命令窗口
    s1 = DKRM::NEWGAME_STR
    s2 = DKRM::LOADGAME_STR
    s3 = DKRM::EXITGAME_STR
    @command_window = Window_Command.new(192, [s1, s2, s3])
    @command_window.back_opacity = 160
    @command_window.x = 320 - @command_window.width / 2
    @command_window.y = 288
    # 判定继续的有效性
    # 存档文件一个也不存在的时候也调查
    # 有効为 @continue_enabled 为 true、无效为 false
    @continue_enabled = false
    for i in 0..DKRM::FILESAVE_MAX
      if FileTest.exist?("Save/Save#{i+1}.rxdata")
        @continue_enabled = true
      end
    end
    # 继续为有效的情况下、光标停止在继续上
    # 无效的情况下、继续的文字显示为灰色
    if @continue_enabled
      @command_window.index = 1
    else
      @command_window.disable_item(1)
    end
    # 演奏标题 BGM
    $game_system.bgm_play($data_system.title_bgm)
    # 停止演奏 ME、BGS
    Audio.me_stop
    Audio.bgs_stop
  end
  #--------------------------------------------------------------------------
  def main_dispose
    # 释放命令窗口
    @command_window.dispose
    # 释放标题图形
    @sprite.bitmap.dispose
    @sprite.dispose
  end
end[/pre]

本探索暂时到这里在Scene_Base上再建立一个父类Scene除了精简代码,难道还有别的企图不成?我会在下一帖子里面开贴分享,如有不用意见尽管回帖提出。
  

Scripts.rxdata

320.08 KB, 下载次数: 41

评分

参与人数 1星屑 +12 收起 理由
sai90306 + 12 塞糖

查看全部评分

醉啸 长风万里

梦石
0
星屑
6512
在线时间
6616 小时
注册时间
2007-12-16
回帖
4301

贵宾

发表于 2013-1-21 18:54:54 | 显示全部楼层
XP脚本啊……
虽然不会,但是来捧个场

还在龟速填坑中
回复

使用道具 举报

水月·镜花

梦石
10
星屑
403
在线时间
1181 小时
注册时间
2005-10-22
回帖
1118

开拓者

发表于 2013-1-21 19:27:16 | 显示全部楼层
嘛,其實任何遊戲引擎都脫不開這個基本流程

視口準備——刷新畫面——讀入指令——是否結束—(是)—關閉進程
              |                                       |(否)
                      —————循環——————
回复

使用道具 举报

Assassin-K

梦石
0
星屑
4138
在线时间
2281 小时
注册时间
2012-5-23
回帖
3964

贵宾

发表于 2013-1-21 19:39:50 | 显示全部楼层
不会脚本的洛子路过~
看到是XP的就进来打个酱油~
支持一下~

◆ROZONE◆
>洛子又要去流浪地球了……
>如果你看到我在线,又没动静,那只能说明我在挂机……
回复

使用道具 举报

梦石
0
星屑
10219
在线时间
971 小时
注册时间
2010-10-10
回帖
2379
发表于 2013-1-29 13:03:38 | 显示全部楼层
哈哈,这年头大家都挺个性啊,对吧。

EVE真的辛苦了!
  好质量才是未来。
2014.7.6,晚上03.41分,他死于脑癌。
回复

使用道具 举报

梦石
0
星屑
3905
在线时间
1972 小时
注册时间
2013-1-3
回帖
9146
发表于 2013-1-29 13:12:56 | 显示全部楼层
癫狂侠客的教程很久都没发了
支持LZ,但scene类我从没改过
《宿愿·寻剑篇》正式版已经发布!快去看看!点击进入论坛发布贴
回复

使用道具 举报

梦石
0
星屑
50
在线时间
270 小时
注册时间
2010-2-4
回帖
1296
发表于 2013-1-29 14:22:07 来自手机 | 显示全部楼层
疯狂异形,癫狂侠客,再下来应该是痴狂兄贵的探索之旅了吧- -b
回复

使用道具 举报

梦石
0
星屑
9292
在线时间
2504 小时
注册时间
2011-5-20
回帖
14521

开拓者

发表于 2013-3-24 22:02:44 | 显示全部楼层
侠客他人感觉跟人间蒸发了一样···你没经过允许就发出来的吗?

点评

还是做DKRM吗?  发表于 2013-3-27 20:36
人家早就允许我了。他得忙着做软件,所以不能有太多杂念。  发表于 2013-3-24 22:20
[img]http://service.t.sina.com.cn/widget/qmd/5339802982/c02e16bd/7.png
回复

使用道具 举报

梦石
0
星屑
2278
在线时间
1375 小时
注册时间
2011-2-10
回帖
565

开拓者

发表于 2013-5-19 13:53:01 | 显示全部楼层
不错,继续发挥
回复

使用道具 举报

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

本版积分规则

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

在本版发帖返回顶部