设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
楼主: 八云紫

[RMVX发布] 新手教程--从0开始学RGSS2(2013-09-21 修复索引地址)

  [复制链接]

Lv1.梦旅人

旅之愚者

梦石
0
星屑
240
在线时间
812 小时
注册时间
2007-7-28
帖子
2148

贵宾

发表于 2010-11-6 00:20:20 | 显示全部楼层
本帖最后由 六祈 于 2010-11-6 00:26 编辑

【酱油括号】
嘛,关于类的部分由愚者来写了
以前有人问,67你是RGSS党还是2党?你用的VX一定是2吧?
好吧,愚者绝对不是2,愚者其实是Ruby党,所以诸君看这篇教程的时候一定要小心
普通字色部分是初级【如果你是想学点RGSS2基础】
红色部分为高危Ruby部分【适合已经有基础的同学们】
【酱油完毕】
类:一个抽象的概念,举个例子,张三是人【类】,李四是人【类】,但是人这个【类】,在这个世界上是找不到一个对象来表达的

在Ruby中,定义一个类用class,如下:
  1. class Person
  2. end
复制代码
然后就可以创建张三和李四了~
  1. z3 = Person.new
  2. l4 = Person.new
复制代码
咦,为啥张三李四啥都没有…那咱们开始添加姓名和年龄这些属性吧
  1. class Person
  2. attr_accessor :name, :age
  3. def initialize(name,age)
  4. @name = name
  5. @age = age
  6. end
  7. end
复制代码
解说:
首先attr_accessor :name这行,attr_accessor是类方法,参数为一个或多个符号,加了这句就可以通过z3.name读取@name变量,用z3.name = xxx来设置@name变量了
其次def initialize(name,age)这行,initialize是Person.new时调用,里面放置一些对象的基础设置【initialize被称作钩子方法,类似的还有inherited方法在类被继承时调用】
第三点@name = name这行,@name是实例变量(为什么叫实例变量?因为是实例所拥有的,亦即z3和l4各自有一个@name而且不冲突),而name是通过参数传递进来的局部变量。

咱们重新创建张三和李四【这俩货一直在投胎么…大雾】
  1. z3 = Person.new('张三',20)
  2. l4 = Person.new('李四',18)
复制代码
喵,创建完毕~来试一试~
  1. p “那年#{l4.name}#{l4.age}岁,#{z3.name}#{z3.age}岁,他们相爱了”
复制代码
如果没出意外的话,会出来一段很狗血的剧情:【白字慎重】
那年李四18岁,张三20岁,他们相爱了
什么!你看不懂#{}???往回翻前面的教程吧……XD自重

咦,张三和李四怎么光有名字和年龄啊,你们俩还会干点别的么?
于是咱们得给Person类定义方法
  1. class Person
  2. def do_sth
  3. p '干!'
  4. end
  5. end
  6. z3.do_sth   #'干!'
复制代码
好吧这回张三会骂街了…大家以后可以创建一打的张三李四帮你去骂人哟~【大雾……】
当然你也可以培育他们去做很多的事情内个。。。【说多了】


以下开始大规模红字部分,大家慎重…
首先说变量:
实例变量:以@开头,由实例对象所拥有
类变量:以@@开头,【愚者以为叫做共享变量会更可靠一点】意指由一个类产生的所有实例所共享的变量,举个例子,地球上的所有生物都拥有同一个地球~而地球却只有一个,大家都要爱护呀~
全局变量:以$开头,这个在RGSS2里遍地都是,比如$game_party啊$game_variables啊等等等

类也是对象:在Ruby中一切皆为对象,所以类也是对象,是Class类的对象,比如A = Class.new,然后使用A.new就可以产生A的对象了~【请使用常量命名类或者模块】
那么类既然是对象,有没有方法和实例变量?答案是有的:
  1. class A
  2. def self.output
  3. p '我是小A不是小三'
  4. @a = 1 if @a == nil
  5. p (@a+=1)
  6. end
  7. end
  8. A.output
复制代码
这里用def self.output定义的就是类方法【也可以使用def A.output,如果这样写的话注意不要写错类名】
类方法与类变量不同,并不是共享的,而是类作为对象时的方法。
而在类方法内的@xxx变量即是类作为对象的实例变量


然后说继承
在RGSS2脚本中大量的使用了类的继承
比如Window_Command是继承Window_Selectable,而Window_Selectable则是继承Window_Base
继承链为Window_Command < Window_Selectable < Window_Base【这里不是RGSS2代码,请勿在编辑器里这样写…后果自负】
这样的好处是,如果几个类同时要用同样的一个方法【代码相同】,那么只要在它们的父类里定义即可~【子类在找不到方法时,会从继承链上回溯查找方法定义】

关于super:
在方法里写上super会调用继承链上一级的同名方法【如果没有继续回溯直到找到第一个为止】
而super有两种写法:
super【不带括号】:会将参数传递给父类的同名方法
super()【带括号】:则参数必须手动传递

关于Module的混入改变继承链:
  1. class Class_B
  2. def initiazlie
  3. p 'B'
  4. end
  5. end
  6. class Class_A < Class_B
  7. def initialize
  8. super
  9. p 'A'
  10. end
  11. end
复制代码
这时候继承链为Class_A < Class_B,输入Class_A.new会依次输出'B','A'
  1. module A
  2. def initialize
  3. super
  4. p 'module A'
  5. end
  6. end
  7. module B
  8. def initialize
  9. super
  10. p 'module B'
  11. end
  12. end
  13. class Class_A
  14. include A
  15. include B
  16. end
复制代码
这时的继承链为Class_A < B < A < Class_B【混入的Module会插入继承链,并且后混入的Module更靠近子类】
这时输入Class_A.new会依次输出'A','module A','module B','B'【很神奇不是么~】

点评

弱弱的求教怎么看出它们的继承链的  发表于 2013-10-1 18:02
最后一段晕  发表于 2013-6-11 20:10
确实就是钩子方法。和VB中的Form_Load或者Form_Initialize事件。(构造方法?)  发表于 2012-8-12 19:12
话说,有没有错别字啊?钩子方法还是构造方法?或者就是钩子方法,也是我所熟悉的构造方法?  发表于 2012-7-20 14:48
最后一段直接看不懂额 前面还可以  发表于 2012-7-5 12:37

评分

参与人数 1星屑 +1600 收起 理由
八云紫 + 1600 迟到的祝福

查看全部评分

回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
43 小时
注册时间
2010-6-16
帖子
21
发表于 2010-11-6 05:02:19 | 显示全部楼层
看的头都大了。。。不容易啊这东西。
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
50
在线时间
234 小时
注册时间
2010-10-6
帖子
768
发表于 2010-11-6 17:59:13 | 显示全部楼层
回复 Rachel_Alucard 的帖子

八云大大可以说明一下哈希是什么吗?有什么作用?
回复 支持 反对

使用道具 举报

Lv2.观梦者

神隐的主犯

梦石
0
星屑
258
在线时间
271 小时
注册时间
2008-2-22
帖子
7691

贵宾

 楼主| 发表于 2010-11-6 19:23:50 | 显示全部楼层
本帖最后由 铃仙·优昙华院·因幡 于 2010-11-6 19:25 编辑

回复 壬穹雷光 的帖子

哈希表依靠的其实是类似函数的映射关系.  某个 Key 通过某种运算 f(Key) , 可以映射到唯一的一个 Value 上. 如果不能的话, 需要将这个 hash 进行重排, 消去冲突.

另外一个就是哈希算法, 把任意长度的输入通过算法, 变换成固定长度的输出.


作用的话, 就是类似 数组 了. 数组的 映射关系是  偏移序号 => 值 .  这样其实可以看成是 特殊的 hash 表.

《天空之城 —— 破碎的命运》
回复 支持 反对

使用道具 举报

头像被屏蔽

Lv2.观梦者 (禁止发言)

梦石
0
星屑
775
在线时间
15 小时
注册时间
2010-10-17
帖子
35
发表于 2010-11-6 21:33:21 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

Lv2.观梦者

神隐的主犯

梦石
0
星屑
258
在线时间
271 小时
注册时间
2008-2-22
帖子
7691

贵宾

 楼主| 发表于 2010-11-7 22:19:00 | 显示全部楼层
本帖最后由 铃仙·优昙华院·因幡 于 2010-11-7 23:04 编辑

RPG 模块

      RPG 模块 只在 *.rvdata 这些数据库文件里使用过. 具体的每个子模块的属性什么的, 都可以查看 F1 帮助电子档. 这里就不细说了.
      这里具体先说说一个主意事项. 就是在 VX 里 , RPG 模块的所有 initialize 初始化方法都是无效的. 为什么? 看脚本的 Scene_Title 就知道了. 脚本里事先读取了 *.rvdata 文件. 所以, 脚本里使用的 $data_XXX 变量都是事先声明好的. so , 脚本里是不会调用 initialize 方法的. 那么? 怎么有效的添加一个属性呢?? 其实可以在那个属性的读取方法上的做文章. 比如
  1. def cp
  2.    @cp = 10  if @cp == nil
  3.    return @cp
  4. end
复制代码
这样就可以防止出现 NoMethodError .

各个文件对应的资料:


文件名                           数据类型 对应的 RPG 模块                   变量类型                     对应脚本里的变量


Actors.rvdata                 角色数据  RPG::Actor .                         数组                                 $data_actors


Classes.rvdata                职业数据  RPG::Class .                          数组                                 $data_classes


Skills.rvdata                    技能数据  RPG::Skill .                            数组                                 $data_skills


Items.rvdata                   物品数据  RPG::Item .                          数组                                 $data_items


Weapons.rvdata             武器数据  RPG::Weapon .                    数组                                $data_weapons


Armors.rvdata                防具数据  RPG::Armor .                        数组                                $data_armors


Enemies.rvdata               敌人数据  RPG::Enemy.                       数组                                $data_enemies


Troops.rvdata                 敌人队伍数据   RPG::Troop.                 数组                               $data_troops


States.rvdata                  状态数据   RPG::State.                         数组                                $data_states


Animations.rvdata           动画数据   RPG::Animation.                  数组                                $data_animations


CommonEvents.rvdata   公共事件数据   RPG::CommonEvent.   数组                                $data_common_events


System.rvdata                系统数据   RPG::System.                      单个类实例                      $data_system


Areas.rvdata                   区域数据   RPG::Area.                           Hash                                $data_areas


MapXXX.rvdata               地图数据 RPG::Map.                             单个类实例                       $game_map.map


MapInfos.rvdata             地图信息数据,  RPG::MapInfo.            Hash                                 需手动加载


Scripts.rvdata                 脚本文件 数组 对应三个值 [可能是ID, 脚本名字, 脚本内容]          $RGSS_SCRIPTS



《天空之城 —— 破碎的命运》
回复 支持 反对

使用道具 举报

Lv2.观梦者

神隐的主犯

梦石
0
星屑
258
在线时间
271 小时
注册时间
2008-2-22
帖子
7691

贵宾

 楼主| 发表于 2010-11-8 18:12:47 | 显示全部楼层
本帖最后由 铃仙·优昙华院·因幡 于 2010-11-8 19:20 编辑

Game 类集

      VX 里处理所有游戏数据的类集合. 本身 Game 类的写法没什么具体要求.
      注意的是, Game 类都不处理图像数据.


01. Game_Temp($game_temp)
      和名字的意思一样, 处理缓存的. 在每次游戏开始的时候, 都会重新生成. 不会写如存档.


02. Game_System($game_system)
      处理系统数据的类. 处理诸如 计时器, 版本ID, 遇敌标志等. 会写入存档.  


03. Game_Message($game_message)
      处理信息的类. 包括 对话设定, 头像, 对话内容, 选项等属性. 会写入存档.


04. Game_Switches($game_switches)
      处理开关的类. 其实开关就是一个数组 @data . 对这个数组的读取写入就是对开关的操作.  
      比如打开第 10 号开关: $game_switches[10] = true .
      不过需要注意的是, 默认脚本限制开关ID在 5000 之内. 脚本 31 行有说明


05. Game_Variables($game_variables)
      处理变量. 与 Game_Switches 写法相同.


06. Game_SelfSwitches($game_self_switches)
      处理独立开关的类. 本质上是一个 Hash . 其 Key 结构是这样的一个数组:
  1. [地图ID, 事件ID, 开关ID]
复制代码
其中的 开关ID 就是 "A" "B" "C" "D" 这四个. 想扩展的话, 可以修改这里.


07. Game_Screen($game_map.screen(地图), $game_troop.screen(战斗))
      可以看成是处理画面效果数据的类. 画面震动, 画面亮度, 显示事件图片, 淡入淡出等等效果都是这个类处理的.


08. Game_Picture($game_map.screen.pictures(地图), $game_troop.screen(战斗).pictures)
     处理图片数据的类. 需要注意的是, 无论是在地图或者是战斗, 图片的 ID 都是在 1 到 20 之间. 一共 40 张图片. 这个和 XP 不同.(VX)


09. Game_Battler
     所有战斗者的父类(超类). 处理 HP MP , 不死身标志等数据.


10. Game_BattleAction
     处理行动的类. 包括战斗者使用的技能 ID , 物品 ID, 速度等数据. 在  Game_Battler 内部使用.


11. Game_Actor
     处理单个我方角色的类. 一切我方的数据都包含在这个类里. 默认是 Game_Actors 外壳的数据.


12. Game_Actors($game_actors)
     处理角色的外壳类. 和 Game_Switches 类似写法. 真正使用的是 Game_Actor 数据.


13. Game_Enemy
     处理敌人数据的类。在 Game_Troop 的 内部使用.


14. Game_Unit
     处理单位数据的类. 是 Game_Troop 和 Game_Party 的超类.


15. Game_Party($game_party)
     处理队伍数据的类. 一些比较常见的用法:
  1. $game_party.gain_gold # 获得金钱
  2. $game_party.steps # 步数
  3. $game_party.gain_item# 获得物品
复制代码


16. Game_Troop($game_troop)
     处理敌人队伍数据的类. 具体的看脚本注释就可以了.


17. Game_Map($game_map)
     处理地图数据的类. 几乎所有的地图数据都包含在这里, 比如事件, 远景图, 公共事件等. 比较常见的有:
  1. $game_map.need_refresh # 刷新地图
  2. $game_map.map  # 地图数据
复制代码
等.


18. Game_CommonEvent
     处理公共事件的类. 可以看成是 公共事件数据 的外壳类, 真正的数据在 $data_common_events 里.


19. Game_Character
     处理地图上角色数据的类. 和 Game_Actor 不同的是, Game_Character 处理的是地图上行走图的数据. 是 Game_Player  Game_Event 和 Game_Vehicle 的超类.


20. Game_Event
     事件类. 所有事件的处理都是在这个类中. 包括事件页切换, 事件 ID, 事件启动判断等.


21. Game_Vehicle
     交通工具类. 需要注意的是, 每张地图都是有交通工具的, 只是在没有设定的情况下, 交通工具的坐标是 (-1, -1)


22. Game_Player($game_player)
     处理地图上的角色的类. 我们控制的角色其实就是这个类在管理.


23. Game_Interpreter
     事件命令解析类. 一切事件的核心类. 处理事件的解析和执行. 所有的事件在这里都可以找到.




存档结构
VX 的存档数据结构如下:
01. 我方角色的数组, 结构是 [ 行走图文件名,  行走图序号]
02. 刷新次数的计数值, 其实可以认为是游戏时间(这个值除以 FPS 值就是游戏时间)
03. 正在播放的 BGM
04. 正在播放的 BGS
05. $game_system
06. $game_message
07. $game_switches
08. $game_variables
09. $game_self_switches
10. $game_actors
11. $game_party
12. $game_troop
13. $game_map
14. $game_player

点评

如果想查询XP的数据库的话,请参阅以前Sailcat大写的《运行时修改数据库》一文。  发表于 2010-11-12 08:52

《天空之城 —— 破碎的命运》
回复 支持 反对

使用道具 举报

Lv2.观梦者

神隐的主犯

梦石
0
星屑
258
在线时间
271 小时
注册时间
2008-2-22
帖子
7691

贵宾

 楼主| 发表于 2010-11-8 21:07:31 | 显示全部楼层
修改存档位置

      目标: 修改存档位置, 做到自定义存档的保存位置.
      修改过程:
01. 明确修改目的.
      默认的存档文件是保存在根目录下的(也就是和 Game.exe 同一个目录), 现在的目标是保存在 Save 文件夹里. 然后再读取的时候也可以找到.
02. 当前已知
     存档的文件名是 SaveXXX.rvdata , 保存在根目录. 并且在进入标题的时候, 有存档的情况下, 光标会停留在 "继续游戏" 的选项上.
03. 开始修改
     先全局搜索 Save . 可以找到一些信息:
QQ截图未命名.jpg
先关注 Scene_File(158) , 点进去后可以看到注释: 生成文件名称. 那么就是这里了, 修改成
  1. return "Save/Save#{file_index + 1}.rvdata"
复制代码
之前的 Save 是文件夹的名称. 可任意.

     然后注意, Scene_Title(131), 可以看到这里是查找存档的,  那么就继续改:
  1. @continue_enabled = (Dir.glob('Save/Save*.rvdata').size > 0)
复制代码
OK.
04. 测试.
    测试开始. 进入存档, 保存. 然后就出现:
  1. 无法找到文件 No such file or directory - Save/Save1.rvdata.
复制代码
好吧, 出问题了. 找不到文件.
    其实不要被错误提示迷惑了. 找不到文件是因为我们没有创建 Save 这个文件夹. 新建后测试正常.

附上工程:
修改存档位置.rar (242.82 KB, 下载次数: 305)

点评

在你的脚本Main之前添加 Dir.mkdir "Save" unless File.directory? "Save" 就可以了  发表于 2010-11-12 09:14
如果不想出现这个错误的话可以在检测不到文件夹的时候自动创建文件夹。  发表于 2010-11-12 08:52

《天空之城 —— 破碎的命运》
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1035
在线时间
1564 小时
注册时间
2008-7-30
帖子
4418

贵宾

发表于 2010-11-8 22:23:33 | 显示全部楼层
本帖最后由 DeathKing 于 2010-11-8 22:38 编辑

有关方法的一些补充:http://rpg.blue/thread-142147-1-1.html
反射机制用于查错很有用,稍后将会补上。反射机制(元编程)也是我很乐意讨论的。


老板的MSN Space上面有一些讨论的文章,可以查阅一下:
1、正则表达式:http://szsu.spaces.live.com/blog/cns!D57D0E50BE1820CF!225.entry
2、论 Ruby 顶层及 Object、Kernel 的关系:http://szsu.spaces.live.com/blog/cns!D57D0E50BE1820CF!185.entry
3、Ruby 对象的引用、克隆、污染和冻结:http://szsu.spaces.live.com/blog/cns!D57D0E50BE1820CF!170.entry

点评

你的 BOSS 允许引用么??  发表于 2010-11-9 07:05

See FScript Here:https://github.com/DeathKing/fscript
潜心编写URG3中。
所有对URG3的疑问和勘误或者建议,请移步至发布页面。
欢迎萌妹纸催更
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
239
在线时间
2399 小时
注册时间
2008-4-11
帖子
12326

贵宾第6届短篇游戏比赛季军

发表于 2010-11-11 04:07:26 | 显示全部楼层
good thing! i want zhichi you !
回复 支持 反对

使用道具 举报

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

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2024-4-18 16:11

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表