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

Project1

 找回密码
 注册会员
搜索
查看: 3246|回复: 9
打印 上一主题 下一主题

[已经解决] 请问地图事件如何读取数据库或者脚本

[复制链接]

Lv3.寻梦者

梦石
0
星屑
1156
在线时间
172 小时
注册时间
2010-10-11
帖子
23
跳转到指定楼层
1
发表于 2018-7-20 21:17:51 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
50星屑
求助各位大佬,一直有个疑问,比如我自己写ARPG系统,如何通过事件名来读取脚本?比如我写一个敌人的类,class Enemy,先用attr_accessor写好怪物的id攻击生命等属性,然后再建立各个函数,比如id是1的怪攻击xx生命xx等等。
关键是地图上的事件怎么读取Enemy这个类里的怪物数据,可以通过什么办法(比如读取事件注释,事件名等)来实现?谢谢大佬们!

最佳答案

查看完整内容

楼主的意思是通过事件里的注释,名字之类的来设置敌人的属性吧? 楼主如果想做ARPG的话,我大概能明白是什么意思。 其实这个的本质就是获取事件内容中的信息,只要会了这个想通过任何事件(注释也好、文章也好、id也好、名字也好)设置脚本数据内容都是可以的。 这种东西通常需要使用正则表达式,并且自己规定一套名称或者注释的写法,楼主可以根据自己的需要自己修改匹配的法则。 这里我可以提供大致思路,就举出获取名字和注释 ...

Lv3.寻梦者

梦石
0
星屑
995
在线时间
180 小时
注册时间
2013-2-16
帖子
176
2
发表于 2018-7-20 21:17:52 | 只看该作者
本帖最后由 clear仔 于 2018-7-25 18:47 编辑

楼主的意思是通过事件里的注释,名字之类的来设置敌人的属性吧?
楼主如果想做ARPG的话,我大概能明白是什么意思。

其实这个的本质就是获取事件内容中的信息,只要会了这个想通过任何事件(注释也好、文章也好、id也好、名字也好)设置脚本数据内容都是可以的。
这种东西通常需要使用正则表达式,并且自己规定一套名称或者注释的写法,楼主可以根据自己的需要自己修改匹配的法则。
这里我可以提供大致思路,就举出获取名字和注释。




对于地图上的敌人这种特殊的事件,我们最好给他新建一个类并从Game_Event继承下来,这样它就有了基础的事件的特性,然后我们再往里面加东西。

不同的类型的事件可能有不同的属性,我们最好分别新建类再往里面加不同的属性(不推荐全写到一个类里面然后用一个变量判断,因为会有属性的冗余(有些属性会用不到))

比如敌人新建个Game_Enemy,队友Game_Friend
往里面加攻击防御生命什么的




当然这样还不够,因为地图在初始化的时候默认都会被初始化成内置的Game_Event对象,是没有我们新加的东西的。

我们首先要获取这种特殊事件的类型(小怪、boss、队友之类的),我们可以直接通过名字获取(当然如果想都通过注释获取也可以),并把他们初始化成子类对象。

找到Game_Map的        # 设置地图事件数据
这个注释下面的循环,这个循环就是把数据库中的事件数据初始化成事件对象的语句
@events = Game_Event.new(@map_id, @map.events)
这句是生成时间对象的语句,我们新建个方法来替换它,这里我们就要开始判断事件的类型了。


首先这里,我想名字开头是enemy的就初始化成Game_Enemy对象,friend就初始化成Game_Friend对象,否则就还是默认初始化成Game_Event
最好给个data_id之类的单独的id方便区分


下面用到正则表达式
RUBY 代码复制
  1. symbol = /\D+/.match(@map.events[i].name).to_s#匹配开头的连续字母

[/pre]

然后再判断symbol:
RUBY 代码复制
  1. case symbol
  2.     when "enemy"
  3.         @events[i] = Game_Enemy.new(@map_id, @map.events[i])
  4.         @events[i].data_id = /\d+/.match(@map.events[i].name).to_s.to_i#还可以给个数据的id,这个匹配后面的数字
  5.     when "friend"
  6.         @events[i] = Game_Friend.new(@map_id, @map.events[i])
  7.         @events[i].data_id = /\d+/.match(@map.events[i].name).to_s.to_i#还可以给个数据的id,这个匹配后面的数字
  8.     else
  9.         @events[i] = Game_Event.new(@map_id, @map.events[i])
  10. end

这样比如事件名字是enemy8,就会初始化成Game_Enemy,data_id赋值成8







剩下的就照葫芦画瓢了,再这两个类的初始化里面,我们要新增初始化的代码来给事件对象赋值,这里我直接判断第一页的:
这里我直接读取第一页事件开头的连续的每一行注释,每一行单独拿出来检查执行,直到读到不是注释
RUBY 代码复制
  1. def initialize(map_id,event)
  2.     super
  3.     i = 0
  4.     while event.pages[0].list[i] != nil and (event.pages[0].list[i].code == 108 or event.pages[0].list[i].code == 408)
  5.         text = event.pages[0].list[i].paramters[0]
  6.         check_text(text)#检查并应用文本
  7.         i+=1
  8. end
  9. end


然后再实现检查文本:
RUBY 代码复制
  1. def check_text(text)
  2. sym = /\D+/.match(text).to_s
  3. num = /\d+/.match(text).to_s.to_i
  4. case sym
  5. when "atk"
  6. @atk = num
  7. when "hp"
  8. @hp = num
  9.  
  10. #bla bla bla bla
  11. #加上你自己定下的属性
  12. end
  13. end


这样,在注释里写上:
"
hp100
atk30
"
就可以把@hp赋值成100,@atk赋值成30,以此类推



这样操作的时候就可以直接判断某事件e:  
e.is_a?(Game_Enemy)来判断是不是敌人,是的话就直接
e.atk   e.hp来进行操作就好了


当然这里只是举了个栗子,想要有不同的匹配规则在不同的地方设置都是完全可以的。
上面的代码没有经过完备的测试,纯手打,可能会有bug或者笔误,大致思路就是这样,还希望楼主勤动手哦~
回复

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1156
在线时间
172 小时
注册时间
2010-10-11
帖子
23
3
 楼主| 发表于 2018-7-20 21:25:34 | 只看该作者
还有就是调用问题,比较有疑惑,比如自己建的Enemy类里的实例变量,攻击防御生命之类的,怎么调用?我的思路是ARPG战斗部分用公共事件的脚本来写,但是涉及到战斗伤害计算等数据势必要调用Enemy这个类里的数据,如果建立局部变量导入的话,不同的脚本框里的局部变量无法共用,而写脚本的话靠事件脚本里的十二行肯定不够用,有时候还要涉及到事件页的变化,全局变量也肯定不行,如果用全局变量会导致地图上多个敌人的时候存储血量的地址是共用的,会出现bug,想想最好的办法就是每个地图上的事件作为独立的对象读取class里的数据,但是没思路,不知道怎么实现......
回复

使用道具 举报

Lv5.捕梦者 (版主)

梦石
1
星屑
23999
在线时间
3339 小时
注册时间
2011-7-8
帖子
3926

开拓者

4
发表于 2018-7-20 23:24:59 | 只看该作者
在脚本编辑器里扩充 Interpreter 类:
  1. class Interpreter
  2.   def method_01
  3.     ...
  4.   end
  5. ...
  6. end
复制代码

可以在事件脚本里直接调用函数 method_01,这些数据可以用全局变量 $enemies = [Enemy.new] 存着~
熟悉rgss和ruby,xp区版主~
正在填坑:《膜拜组传奇》讲述膜拜组和学霸们的故事。
已上steam:与TXBD合作的Reformers《变革者》
* 战斗调用公共事件 *
* RGSOS 网络脚本 *
回复

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1156
在线时间
172 小时
注册时间
2010-10-11
帖子
23
5
 楼主| 发表于 2018-7-21 01:25:29 | 只看该作者
guoxiaomi 发表于 2018-7-20 23:24
在脚本编辑器里扩充 Interpreter 类:

可以在事件脚本里直接调用函数 method_01,这些数据可以用全局变量  ...

谢谢大佬!不过其实我想问的是,类似于魔塔样板,或者夜想曲那样的,通过事件名字(比如怪物001对应数据库一号的怪物),或者直接事件注释里赋予属性的,这样的脚本可以通过什么思路实现
回复

使用道具 举报

Lv5.捕梦者

梦石
0
星屑
39034
在线时间
5725 小时
注册时间
2006-11-10
帖子
6622
6
发表于 2018-7-21 10:25:25 | 只看该作者
本帖最后由 灯笼菜刀王 于 2018-7-21 10:39 编辑
719783572 发表于 2018-7-21 01:25
谢谢大佬!不过其实我想问的是,类似于魔塔样板,或者夜想曲那样的,通过事件名字(比如怪物001对应数据 ...


  可以参考game troop, 这里是读取数据库某ID的troop的资料, 然后把它里面的怪按塞到一个数组里储存, 用index来独立化同样ID的怪。


用这个思路, 可以想想, 你要的是 用事件来关联怪的数据, 那把事件ID当做key, 建个哈希表来储存就好了。

为了通用性, 用全局变量来做哈希表  

$arpg_troop={}
$arpg_troop[$game_map.events[id]] = Game_Enemy.new(0,id)

这样就让事件和敌人关联起来了 $arpg_troop[@event_id] 得到的就是这个事件的"敌人属性"

当然,直接这样做会有问题的, 你要先到game_enemy里, 把troop_id = 0 的情况定义为 读取 数据库的敌人而不是队伍敌人

然后在考虑怎么分辨地图事件, 只让需要当敌人的事件塞到哈希表里, (最直接的当然是用名字或者事件备注法来判断, 预先在脚本里设置好对应的ID和敌人然后像默认队伍一样处理更是好方法~)  

最后,考虑要在什么时候加载这个哈希表, 如何加载之类的(重定义 scene_map的初始化是一个方法, 直接在场所转移的时候加载下个地图的敌人更是一个好方法, 在每个地图用自动执行来加载是最简单的方法)
回复

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
3574
在线时间
2338 小时
注册时间
2015-8-25
帖子
960

开拓者

7
发表于 2018-7-21 14:52:33 | 只看该作者
关于怎么调用,如果是做事件arpg的话,比如是最为常见的触碰敌人掉血,被敌人的子弹打中掉血两种行为。
在接触的时候,就可以记录下对玩家产生行为的对象编号,这个时候就可以更加编号读取到敌人的攻击力,从而计算玩家的伤害值。
反之亦然。

另外说那12行其实狠一点还是能写蛮多>v<、善用 代入 \ 与 ;三招。
虽然本身是可以把里面的东西定义在解释器里面的(写多长都可以。)

点评

自己用的话,直接用变量存起来倒也挺方便。。就连初始化都可以批量处理。。  发表于 2018-7-21 15:22
啊,没发现解释器上面已经有人提到了。。另外我是感觉楼主的思路有点略复杂。特意定义好怪物属性如果是写成别人用的还好说,但是自己用的话.  发表于 2018-7-21 15:21
回复

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1156
在线时间
172 小时
注册时间
2010-10-11
帖子
23
8
 楼主| 发表于 2018-8-7 18:39:55 | 只看该作者
clear仔 发表于 2018-7-20 21:17
楼主的意思是通过事件里的注释,名字之类的来设置敌人的属性吧?
楼主如果想做ARPG的话,我大概能明白是什 ...

想通啦谢谢!
回复

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-12-1 01:32

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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