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

Project1

 找回密码
 注册会员
搜索

求一个绘制技能树的算法

查看数: 2149 | 评论数: 3 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2013-4-22 04:01

正文摘要:

本帖最后由 沉滞的剑 于 2013-4-23 05:31 编辑 不求脚本,求算法。我做出来的效果是网格状的好难看,所以谁能告诉我六祈大神在http://rpg.blue/forum.php?mod=viewthread&tid=156181中的算法是什么么? ...

回复

6rp 发表于 2013-4-23 05:42:29
不是象diablo那样把整个树提前画好,然后点亮其中学会的部分吗?

点评

6rp
我是没有花时间画图的爱好,我会把技能树演化成一个地图。每个技能形象化成一个小岛,能学的就连通,不能学的就孤立。  发表于 2013-4-23 07:40
我刚刚完成这部分,无法学习的转换成灰色星星,能学习为学习的半透明,学过的点亮。  发表于 2013-4-23 06:11
沙漠点灰 发表于 2013-4-22 22:55:48
本帖最后由 沙漠点灰 于 2013-4-22 23:15 编辑

lz只要技能树的话..粗略看了下截图,先从信息读取说吧

因为lz只要算法,所以从简,而且没有测试

技能等级读取



level_x = [xx,xx]的

就是
  1. re = /level_(\d+) = (.+)/
  2. tree_level = []
  3. skill_obj.note.scan(re){|str|str[re]
  4.   tree_level[$1.to_i] = Kernel.eval($2)}
复制代码
skill_obj就是技能对象,利用正则表达式进行匹配,最后存到tree_level中
照截图的所说,没有level_0,所以,tree_level[0]就为nil值,建议初始化
  1. tree_level = [[]]
复制代码
技能节点类似,就不赘述了
  1. skill_obj.note[/.*connections = (.+).*/]
  2. skill_onnections = Kernel.eval($1)
复制代码
窗口的建立不多说,那个貌似有说明窗口,也很简单。


最主要的就是各个图标的位置了,
首先为窗口定义两个实例变量@show_x,@show_y。这是为了节约内存,
但是考虑到现在内存灰常大,可以考虑把窗口显示位图初始化很大很大,具体有多大随你便,够用就行(别用硬编码)。
坐标更新时,先更新@show_x,@show_y。
然后把图标显示的坐标分别减去@show_x,@show_y。
不用的话直接修改ox,oy就行.


lz如果善于发现的话,会发现,每个技能点占得宽度为它所有次级技能宽度之和,这就会用到递归算法了。

算法如下:
  1. def search_next(id)
  2.   skill_onnections.each{|i|yield(i[1]) if i[0] == x}
  3. end

  4. def getWidth(id)
  5.   _width = WIDTH_DUST
  6.   search_next(id){|next_id|_width += getWidth(next_id)}
  7.   _width
  8. end
复制代码
WIDTH_DUST就是一个的宽度,还是建议别用硬编码

当然,仅仅是宽度而已,后边的也要加前面,每级清零,并加上位置修正,这个后面说。
把技能图标放到中间就行,一个遍历应该就能解决,在这个遍历中,放完每一个检查有没有父技能,有的话,头上插根天线,用
fill_rect,每个用一个数组存储每个父技能的子技能天线位置,父技能的子技能天线顶端相互连起来.再检查有没有子技能,有的话,接根地线,
就不用记录了,因为子技能会帮你接的。

上面说到位置修正,其实就是父技能的前个技能(如果有的话)的位置。

说到这,也差不多了,但是这,貌似还是很麻烦,所以建议lz直接自己封装一个Game_Skill_Tree类
Game_Actor下加一个实例变量
  1. @skill_tree = []
  2. 你的遍历处理
  3.     skill_id = xxxxxxxx
  4.     @skill_tree << Game_Skill_Tree.new(skill_id)
  5.     @skill_tree[-1].father = xx
  6.     @skill_tree[-1].father_b = xx
  7.     @skill_tree[-1].width = getWidth
  8.     @skill_tree[-1].x = (@skill_tree[-1].father_b ? @skill_tree[-1].father_b.x : 0) + @skill_tree[-1].width / 2
  9.     @skill_tree[-1].y = xxxx
  10.     ....更多处理
  11. 你的遍历处理结束
复制代码
加个方法get_skill_tree(skill_id)返回@skill_tree中适当的成员



Game_Skill_Tree也是自然不会给出现成代码,不过至少得提供以下接口:
father 父技能树对象
father_b 获取父技能前个树对象
x,y,width 等可读可写数据
上面的
search_next
getWidth
因为封装成类了,所以参数自然就省了
不过说回来,成类了,search_next也可以用数组代替了.


话说这不蛋疼么,既然有现成的,还要自己写?( ̄▽ ̄")

点评

学习和应用是两个过程嘛....我主要是不太会画横着的那条线,排列图标什么的我昨天就解决了.....  发表于 2013-4-23 00:19
拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

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

GMT+8, 2024-11-7 19:19

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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