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

Project1

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

[已经解决] 求一个绘制技能树的算法

[复制链接]

Lv3.寻梦者

梦石
0
星屑
1912
在线时间
1554 小时
注册时间
2013-4-13
帖子
917
跳转到指定楼层
1
发表于 2013-4-22 04:01:39 | 只看该作者 |只看大图 回帖奖励 |正序浏览 |阅读模式

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

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

x
本帖最后由 沉滞的剑 于 2013-4-23 05:31 编辑

不求脚本,求算法。我做出来的效果是网格状的好难看,所以谁能告诉我六祈大神在http://rpg.blue/forum.php?mod=viewthread&tid=156181中的算法是什么么?
夏普的道具店

塞露提亚-道具屋的经营妙方同人作品
发布帖:点击这里

Lv1.梦旅人

梦石
0
星屑
55
在线时间
1119 小时
注册时间
2012-7-24
帖子
600
4
发表于 2013-4-23 05:42:29 | 只看该作者
不是象diablo那样把整个树提前画好,然后点亮其中学会的部分吗?

点评

6rp
我是没有花时间画图的爱好,我会把技能树演化成一个地图。每个技能形象化成一个小岛,能学的就连通,不能学的就孤立。  发表于 2013-4-23 07:40
我刚刚完成这部分,无法学习的转换成灰色星星,能学习为学习的半透明,学过的点亮。  发表于 2013-4-23 06:11
怕鼠的猫
回复 支持 反对

使用道具 举报

Lv3.寻梦者

梦石
0
星屑
1912
在线时间
1554 小时
注册时间
2013-4-13
帖子
917
3
 楼主| 发表于 2013-4-23 05:31:21 | 只看该作者
沙漠点灰 发表于 2013-4-22 22:55
lz只要技能树的话..粗略看了下截图,先从信息读取说吧

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

感谢大神,虽然没有用你的方法构建树,因为我已经构建一个了不想重新推翻,所以算法稍稍有一点改动,但是思路还是很有帮助的~
太感谢了!!!终于做出来了。
虽然最后的代码让人看着有点想吐,但是绝对是一像素一像素对齐的,好不容易啊....
夏普的道具店

塞露提亚-道具屋的经营妙方同人作品
发布帖:点击这里
回复 支持 反对

使用道具 举报

Lv1.梦旅人

梦石
0
星屑
55
在线时间
323 小时
注册时间
2010-8-21
帖子
666
2
发表于 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
>>猛戳>>MetalSagaR游戏主页<<这里<<
欢迎提供您的意见
回复 支持 反对

使用道具 举报

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

本版积分规则

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

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

GMT+8, 2024-11-28 01:24

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

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