不知道有没有别人做过这个东西呢……自己花一晚上写的这些,拿出来跟大家分享一下。
具体的说明都在代码里面了,有什么地方不明白的尽管在帖子里面问啊!
- #==============================================================================# 技能树系统 Ver 1.0# 作者:RyanBern#------------------------------------------------------------------------------# 功能特色:# 开放技能点增加系统,每一个角色都有自己独特的技能成长历程。# 通过获得技能点来让技能变得更加强大。在学习技能的过程中,可以解锁同种技能# 的更高级别,也可以解锁威力更大的技能。# 主角的一切技能成长都遵循您的意愿!#==============================================================================# 使用方法# 在脚本的第 88 行起定义你的自定义技能树。# 注意,要一个一个角色的定义,因为不同角色的技能树肯定不同。# 核心定义脚本actor.set_data(id,ar1,ar2)# id :你要定义的技能ID# ar1 :是一个数组,记录着该技能的前置技能的ID(这就意味着一个技能的前置技能# 可以有多个),角色必须学会这个技能的所有前置技能才可以学习该技能。# ar2 :是一个数组,记录着该技能学会之后,可能开启的后置技能。# 设置ar2主要是为了描绘方便,但是会增加使用者的工作量。# ar1和ar2可以为空,表示该技能没有前置技能或后置技能,用空的方括号[]表示#------------------------------------------------------------------------------# 定义范例:# # 1号角色# actor = Game_Skill_Tree.new# actor.set_data(1,[],[2]) # 定义ID为1的技能,不需要前置技能,可能开启ID为2的技能# actor.set_data(2,[1],[3,4])# actor.set_data(3,[2],[4]) # 定义ID为3的技能,前置技能为ID 2,后置技能为ID 4# actor.set_data(4,[2,3],[])# actor.skills.sort!# data.push(actor)# # 1号角色定义完毕#------------------------------------------------------------------------------# ※ 默认每个人升5级就能获得1技能点,即角色在5,10,15...级会得到技能点,如果想# 改变获得技能点的级数,请改下面的 SKILLS_PTS_STEP = 5# ※ 默认每次打到规定登记会获得1个技能点,如果想改变每次获得的技能点个数,请# 改下面的 UPGRADE_GAIN = 1# ※ 默认每个技能学习消耗1个技能点,这个暂时不支持更改-_-||# ※ 角色各自的技能点保存在游戏的变量当中(也就是$game_variables中),默认保存# 的位置是 NUMBER_SHIFT + 角色的ID,即如果NUMBER_SHIFT == 0,则ID为1的角色# 的技能点数保存在1号变量中,以此类推。当然考虑到这个位置可能实现保存了编者# 的其它数据,固设置数据位移量NUMBER_SHIFT,如果你想从101号变量开始保存,# 只需要改 NUMBER_SHIFT = 100#------------------------------------------------------------------------------# ※ 考虑到主菜单场景大家改起来不方便,可以用事件在地图上进行调用。# ※ 方法是建立一个新事件,使用脚本$scene = Scene_Skill_Tree.new即可。# ※ 当然会写脚本的同学可以把它融入到主菜单中。# ※ 使用PageUP和PageDown可以在不同角色之间进行切换#==============================================================================# 界面说明:# 玩家已经习得的技能用黄色字体表示# 玩家能够学习的技能用白色表示# 没有达到学习条件的技能用灰色表示# 已经达到学习条件的,但是技能点不足,无法学习的技能,用红色表示# 在前置技能中,已经学到的技能用白色表示,并且后面有个“√”# 在前置技能中,没有学到的技能用灰色表示#==============================================================================SKILL_PTS_STEP = 5UPGRADE_GAIN = 1NUMBER_SHIFT = 0class Game_Skill_Tree attr_accessor :skills attr_reader :prev_skills attr_reader :next_skills def initialize @skills = [] @prev_skills = {} @next_skills = {} end #---------------------------------------------------------------------------- # 定义数据类型 # skill_id :要定义的技能id # pre_skills :要定义技能之前置技能,是一个数组 # post_skills :要定义技能之后置技能,是一个数组 #---------------------------------------------------------------------------- def set_data(skill_id,pre_skills,post_skills) @skills.push(skill_id) @prev_skills[skill_id] = pre_skills @next_skills[skill_id] = post_skills endenddef get_skill_tree data = [nil] # 开始定义各个主角的技能树 # 1号角色 # 1号角色定义完毕 return data endclass Game_Actor #-------------------------------------------------------------------------- # ● 更改 EXP # exp : 新的 EXP #-------------------------------------------------------------------------- def exp=(exp) [url=home.php?mod=space&uid=13302]@exp[/url] = [[exp, 9999999].min, 0].max # 升级 while [url=home.php?mod=space&uid=13302]@exp[/url] >= @exp_list[@level+1] and @exp_list[@level+1] > 0 [url=home.php?mod=space&uid=22147]@level[/url] += 1 # 学会特技 for j in $data_classes[@class_id].learnings if j.level == @level learn_skill(j.skill_id) end end # 达到技能点要求就增加技能点 if [url=home.php?mod=space&uid=22147]@level[/url] % SKILL_PTS_STEP == 0 $game_variables[NUMBER_SHIFT + self.id] += UPGRADE_GAIN end end # 降级 while @exp < @exp_list[@level] @level -= 1 end # 修正当前的 HP 与 SP 超过最大值 @hp = [@hp, self.maxhp].min @sp = [@sp, self.maxsp].min end def skill_can_learn?(skill_id) skill_tree = $data_skilltree[self.id] # 没有对应设置,返回false if skill_tree == nil return false end skills_need = skill_tree.prev_skills[skill_id] # 不在技能树中的技能无法习得 if skills_need == nil return false end # 逐个检查 for i in skills_need # 如果有前置技能没有学习 unless skill_learn?(i) return false end end # 前置技能全部都学习了 return true endend#==============================================================================# ■ Window_Skill_Tree#------------------------------------------------------------------------------# 技能树场景中,显示所有技能的窗口。#==============================================================================class Window_Skill_Tree < Window_Selectable #-------------------------------------------------------------------------- # ● 初始化对像 # actor : 角色 #-------------------------------------------------------------------------- def initialize(actor) super(0, 128, 180, 352) [url=home.php?mod=space&uid=95897]@actor[/url] = actor @skill_tree = $data_skilltree[@actor.id] @column_max = 1 refresh self.index = 0 end #-------------------------------------------------------------------------- # ● 获取特技 #-------------------------------------------------------------------------- def skill return @data[self.index] end #-------------------------------------------------------------------------- # ● 刷新 #-------------------------------------------------------------------------- def refresh if self.contents != nil self.contents.dispose self.contents = nil end @data = [] # 没有技能树,返回 if @skill_tree == nil return end for i in 0...@skill_tree.skills.size skill = $data_skills[@skill_tree.skills[i]] if skill != nil @data.push(skill) end end # 如果项目数不是 0 就生成位图、重新描绘全部项目 @item_max = @data.size if @item_max > 0 self.contents = Bitmap.new(width - 32, row_max * 32) for i in 0...@item_max draw_item(i) end end end #-------------------------------------------------------------------------- # ● 描绘项目 # index : 项目编号 #-------------------------------------------------------------------------- def draw_item(index) skill = @data[index] if @actor.skill_learn?(skill.id) self.contents.font.color = crisis_color elsif @actor.skill_can_learn?(skill.id) if $game_variables[NUMBER_SHIFT + @actor.id] > 0 self.contents.font.color = normal_color else self.contents.font.color = knockout_color end else self.contents.font.color = disabled_color end x = 4 y = index * 32 rect = Rect.new(x, y, self.width / @column_max - 32, 32) self.contents.fill_rect(rect, Color.new(0, 0, 0, 0)) bitmap = RPG::Cache.icon(skill.icon_name) opacity = self.contents.font.color == disabled_color ? 128 : 255 self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity) self.contents.draw_text(x + 28, y, 140, 32, skill.name, 0) end #-------------------------------------------------------------------------- # ● 刷新帮助文本 #-------------------------------------------------------------------------- def update_help @help_window.set_text(self.skill == nil ? "" : self.skill.description) endend#==============================================================================# ■ Window_Skill_Tree_Status#------------------------------------------------------------------------------# 技能树界面中,显示特技画面、特技使用者的窗口。#==============================================================================class Window_Skill_Tree_Status < Window_Base #-------------------------------------------------------------------------- # ● 初始化对像 # actor : 角色 #-------------------------------------------------------------------------- def initialize(actor) super(0, 64, 640, 64) self.contents = Bitmap.new(width - 32, height - 32) [url=home.php?mod=space&uid=95897]@actor[/url] = actor refresh end #-------------------------------------------------------------------------- # ● 刷新 #-------------------------------------------------------------------------- def refresh self.contents.clear draw_actor_name(@actor, 4, 0) draw_actor_state(@actor, 140, 0) self.contents.font.color = system_color self.contents.draw_text(360, 0, 160, 32, "可用技能点:") skill_pt = $game_variables[NUMBER_SHIFT + @actor.id] if skill_pt == 0 self.contents.font.color = knockout_color else self.contents.font.color = normal_color end self.contents.draw_text(496, 0, 64, 32, skill_pt.to_s, 2) endendclass Window_Skill_Prev < Window_Base def initialize(actor,skill) super(180, 192, 230, 288) self.contents = Bitmap.new(width - 32, height - 32) @actor = actor [url=home.php?mod=space&uid=260100]@skill[/url] = skill refresh end def skill=(skill) if [url=home.php?mod=space&uid=260100]@skill[/url] != skill @skill = skill refresh end end def refresh self.contents.clear skill_tree = $data_skilltree[@actor.id] # 没有技能树,结束描绘 if skill_tree == nil or @skill == nil return end skills_need = skill_tree.prev_skills[@skill.id] skills_need.sort! for i in 0...skills_need.size x = 4 y = i * 32 skill = $data_skills[skills_need[i]] if @actor.skill_learn?(skills_need[i]) self.contents.font.color = normal_color tag = "√" opacity = 255 else self.contents.font.color = disabled_color tag = "" opacity = 128 end bitmap = RPG::Cache.icon(skill.icon_name) self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity) self.contents.draw_text(x + 28, y, 166, 32, skill.name + tag, 0) end endendclass Window_Skill_Next < Window_Base def initialize(actor,skill) super(410, 192, 230, 288) self.contents = Bitmap.new(width - 32, height - 32) @actor = actor @skill = skill refresh end def skill=(skill) if @skill != skill @skill = skill refresh end end def refresh self.contents.clear skill_tree = $data_skilltree[@actor.id] # 没有技能树,结束描绘 if skill_tree == nil or @skill == nil return end skills_next = skill_tree.next_skills[@skill.id] skills_next.sort! for i in 0...skills_next.size x = 4 y = i * 32 skill = $data_skills[skills_next[i]] self.contents.font.color = normal_color bitmap = RPG::Cache.icon(skill.icon_name) self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), 255) self.contents.draw_text(x + 28, y, 166, 32, skill.name, 0) end endend#==============================================================================# ■ Window_Tip#------------------------------------------------------------------------------# 技能树画面提示窗口#==============================================================================class Window_Tip < Window_Selectable #-------------------------------------------------------------------------- # ● 初始化对像 #-------------------------------------------------------------------------- def initialize super(160, 176, 320, 128) self.contents = Bitmap.new(width - 32, height - 32) @item_max = 2 @column_max = 2 @commands = ["是的", "不要"] refresh self.index = 0 self.z = 1000 end #-------------------------------------------------------------------------- # ● 刷新 #-------------------------------------------------------------------------- def refresh self.contents.clear self.contents.font.color = system_color self.contents.draw_text(4, 0, 328, 32, "您确定要学习该技能吗?") self.contents.draw_text(4, 32, 328, 32, "本次学习将消耗1个技能点。") self.contents.font.color = normal_color for i in 0...@item_max draw_item(i) end end #-------------------------------------------------------------------------- # ● 描绘项目 # index : 项目编号 #-------------------------------------------------------------------------- def draw_item(index) x = 4 + index * 144 self.contents.draw_text(x, 64, 128, 32, @commands[index]) end def update_cursor_rect if [url=home.php?mod=space&uid=370741]@Index[/url] < 0 self.cursor_rect.empty else self.cursor_rect.set(@index * 144, 64, (self.width - 32) / 2, 32) end endend#==============================================================================# ■ Scene_Skill_Tree#------------------------------------------------------------------------------# 处理特技树画面的类。#==============================================================================class Scene_Skill_Tree #-------------------------------------------------------------------------- # ● 初始化对像 # actor_index : 角色索引 #-------------------------------------------------------------------------- def initialize(actor_index = 0) @actor_index = actor_index end #-------------------------------------------------------------------------- # ● 主处理 #-------------------------------------------------------------------------- def main # 获取角色 @actor = $game_party.actors[@actor_index] # 生成帮助窗口、状态窗口、特技窗口 @title1 = Window_Base.new(180, 128, 230, 64) @title2 = Window_Base.new(410, 128, 230, 64) @title1.contents = Bitmap.new(198, 32) @title1.contents.draw_text(4, 0, 120, 32, "前置技能") @title2.contents = Bitmap.new(198, 32) @title2.contents.draw_text(4, 0, 120, 32, "后置技能") @help_window = Window_Help.new @status_window = Window_Skill_Tree_Status.new(@actor) @skill_window = Window_Skill_Tree.new(@actor) @prev_window = Window_Skill_Prev.new(@actor,nil) @next_window = Window_Skill_Next.new(@actor,nil) # 关联帮助窗口 @skill_window.help_window = @help_window # 生成信息提示窗口 (设置为不可见・不活动) @tip_window = Window_Tip.new @tip_window.visible = false @tip_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 @tip_window.dispose @prev_window.dispose @next_window.dispose @title1.dispose @title2.dispose end #-------------------------------------------------------------------------- # ● 刷新画面 #-------------------------------------------------------------------------- def update # 刷新窗口 @help_window.update @status_window.update @skill_window.update @tip_window.update @prev_window.update @next_window.update @skill = @skill_window.skill @prev_window.skill = @skill @next_window.skill = @skill # 特技窗口被激活的情况下: 调用 update_skill if @skill_window.active update_skill return end # 目标窗口被激活的情况下: 调用 update_target if @tip_window.active update_tip return end end #-------------------------------------------------------------------------- # ● 刷新画面 (特技窗口被激活的情况下) #-------------------------------------------------------------------------- def update_skill # 按下 B 键的情况下 if Input.trigger?(Input::B) # 演奏取消 SE $game_system.se_play($data_system.cancel_se) # 切换到菜单画面 $scene = Scene_Map.new return end # 按下 C 键的情况下 if Input.trigger?(Input::C) # 获取特技窗口现在选择的特技的数据 @skill = @skill_window.skill # 不能使用的情况下 if @skill == nil or not @actor.skill_can_learn?(@skill.id) or $game_variables[NUMBER_SHIFT + @actor.id] == 0 or @actor.skill_learn?(@skill.id) # 演奏冻结 SE $game_system.se_play($data_system.buzzer_se) return else # 演奏确定 SE $game_system.se_play($data_system.decision_se) @tip_window.visible = true @skill_window.active = false @tip_window.active = true return end end # 按下 R 键的情况下 if Input.trigger?(Input::R) # 演奏光标 SE $game_system.se_play($data_system.cursor_se) # 移至下一位角色 @actor_index += 1 @actor_index %= $game_party.actors.size # 切换到别的特技画面 $scene = Scene_Skill_Tree.new(@actor_index) return end # 按下 L 键的情况下 if Input.trigger?(Input::L) # 演奏光标 SE $game_system.se_play($data_system.cursor_se) # 移至上一位角色 @actor_index += $game_party.actors.size - 1 @actor_index %= $game_party.actors.size # 切换到别的特技画面 $scene = Scene_Skill_Tree.new(@actor_index) return end end #-------------------------------------------------------------------------- # ● 刷新画面 (目标窗口被激活的情况下) #-------------------------------------------------------------------------- def update_tip # 按下 B 键的情况下 if Input.trigger?(Input::B) # 演奏取消 SE $game_system.se_play($data_system.cancel_se) # 删除目标窗口 @skill_window.active = true @tip_window.visible = false @tip_window.active = false @tip_window.index = 0 return end # 按下 C 键的情况下 if Input.trigger?(Input::C) $game_system.se_play($data_system.decision_se) if @tip_window.index == 0 id = @skill_window.skill.id @actor.learn_skill(id) $game_variables[NUMBER_SHIFT + @actor.id] -= 1 end @tip_window.active = false @tip_window.visible = false @skill_window.active = true @status_window.refresh @skill_window.refresh @tip_window.index = 0 end endendclass Scene_Title alias m main def main $data_skilltree = get_skill_tree m endend复制代码
复制代码如果什么地方乱码了请及时告诉我,懂代码的朋友们请多帮帮忙。
下面是界面,感觉比较烂,不过还能用……
还有一个新工程的附件范例,都一并拿去吧……
刚才看了一下,脚本第99 102 158 273 388行都出现了不该出现的东西,大家把那个什么url的删掉就好,或者直接下范例附件。
本帖来自P1论坛作者我是羊羽我骄傲,因Project1站服务器在国外有时候访问缓慢不方便作者交流学习,经联系P1站长fux2同意署名转载一起分享游戏制作经验,共同为国内独立游戏作者共同创造良好交流环境,原文地址:
https://rpg.blue/forum.php?mod=viewthread&tid=333339 若有侵权,发帖作者可联系底部站长QQ在线咨询功能删除,谢谢。