如何优雅的研究 RGSS3 (六) 技能与物品画面剖析
来源:互联网 发布:外国人用什么软件 编辑:程序博客网 时间:2024/05/17 03:15
物品与技能画面剖析
物品画面和技能画面有共同的父类 Scene_ItemBase,而 Scene_ItemBase 继承自 Scene_MenuBase。
Scene_ItemBase 在开始时用 create_actor_window 生成了显示角色的窗口备用。
Scene_ItemBase 中定义了若干方法作为处理画面的工具。
其中 show_sub_window、hide_sub_window 可以显示、隐藏一个窗口。
item、user用于获取选中的物品与使用者。
on_actor_ok、on_actor_cancel 确定或取消选择角色。
以及一整套判断与处理物品的方法。
其使用物品的子类 Scene_Item 中在 start 中生成了自己独立的帮助窗口分类窗口与物品窗口。
使用技能的子类 Scene_Skill 中多了指令窗口与状态窗口。物品窗口与 Scene_Item 中的是不同的。
可见各种各样的窗口占了代码的大部分。
Window_Help 是显示说明的小窗口。
技能画面中有一个指令窗口 Window_SkillCommand,用来选取特技还是魔法。
技能与物品画面的工作原理大致就是如此了。
物品画面和技能画面有共同的父类 Scene_ItemBase,而 Scene_ItemBase 继承自 Scene_MenuBase。
Scene_ItemBase 在开始时用 create_actor_window 生成了显示角色的窗口备用。
Scene_ItemBase 中定义了若干方法作为处理画面的工具。
其中 show_sub_window、hide_sub_window 可以显示、隐藏一个窗口。
item、user用于获取选中的物品与使用者。
on_actor_ok、on_actor_cancel 确定或取消选择角色。
以及一整套判断与处理物品的方法。
#encoding:utf-8#==============================================================================# ■ Scene_ItemBase#------------------------------------------------------------------------------# 物品画面和技能画面的共同父类#==============================================================================class Scene_ItemBase < Scene_MenuBase #-------------------------------------------------------------------------- # ● 开始处理 #-------------------------------------------------------------------------- def start super create_actor_window end #-------------------------------------------------------------------------- # ● 生成角色窗口 #-------------------------------------------------------------------------- def create_actor_window @actor_window = Window_MenuActor.new @actor_window.set_handler(:ok, method(:on_actor_ok)) @actor_window.set_handler(:cancel, method(:on_actor_cancel)) end #-------------------------------------------------------------------------- # ● 获取当前选中的物品 #-------------------------------------------------------------------------- def item @item_window.item end #-------------------------------------------------------------------------- # ● 获取物品的使用者 #-------------------------------------------------------------------------- def user $game_party.movable_members.max_by {|member| member.pha } end #-------------------------------------------------------------------------- # ● 判定光标是否在左列 #-------------------------------------------------------------------------- def cursor_left? @item_window.index % 2 == 0 end #-------------------------------------------------------------------------- # ● 显示子窗口 #-------------------------------------------------------------------------- def show_sub_window(window) width_remain = Graphics.width - window.width window.x = cursor_left? ? width_remain : 0 @viewport.rect.x = @viewport.ox = cursor_left? ? 0 : window.width @viewport.rect.width = width_remain window.show.activate end #-------------------------------------------------------------------------- # ● 隐藏子窗口 #-------------------------------------------------------------------------- def hide_sub_window(window) @viewport.rect.x = @viewport.ox = 0 @viewport.rect.width = Graphics.width window.hide.deactivate activate_item_window end #-------------------------------------------------------------------------- # ● 角色“确定” #-------------------------------------------------------------------------- def on_actor_ok if item_usable? use_item else Sound.play_buzzer end end #-------------------------------------------------------------------------- # ● 角色“取消” #-------------------------------------------------------------------------- def on_actor_cancel hide_sub_window(@actor_window) end #-------------------------------------------------------------------------- # ● 确定物品 #-------------------------------------------------------------------------- def determine_item if item.for_friend? show_sub_window(@actor_window) @actor_window.select_for_item(item) else use_item activate_item_window end end #-------------------------------------------------------------------------- # ● 启用物品窗口 #-------------------------------------------------------------------------- def activate_item_window @item_window.refresh @item_window.activate end #-------------------------------------------------------------------------- # ● 获取物品的使用目标数组 #-------------------------------------------------------------------------- def item_target_actors if !item.for_friend? [] elsif item.for_all? $game_party.members else [$game_party.members[@actor_window.index]] end end #-------------------------------------------------------------------------- # ● 判定物品是否可以使用 #-------------------------------------------------------------------------- def item_usable? user.usable?(item) && item_effects_valid? end #-------------------------------------------------------------------------- # ● 判定物品的效果是否有效 #-------------------------------------------------------------------------- def item_effects_valid? item_target_actors.any? do |target| target.item_test(user, item) end end #-------------------------------------------------------------------------- # ● 对角色使用物品 #-------------------------------------------------------------------------- def use_item_to_actors item_target_actors.each do |target| item.repeats.times { target.item_apply(user, item) } end end #-------------------------------------------------------------------------- # ● 使用物品 #-------------------------------------------------------------------------- def use_item play_se_for_item user.use_item(item) use_item_to_actors check_common_event check_gameover @actor_window.refresh end #-------------------------------------------------------------------------- # ● 公共事件预定判定 # 如果预约了事件的调用,则切换到地图画面。 #-------------------------------------------------------------------------- def check_common_event SceneManager.goto(Scene_Map) if $game_temp.common_event_reserved? endend
其使用物品的子类 Scene_Item 中在 start 中生成了自己独立的帮助窗口分类窗口与物品窗口。
在生成物品窗口的最后,将生成的物品窗口实例传递给了分类窗口。
#encoding:utf-8#==============================================================================# ■ Scene_Item#------------------------------------------------------------------------------# 物品画面#==============================================================================class Scene_Item < Scene_ItemBase #-------------------------------------------------------------------------- # ● 开始处理 #-------------------------------------------------------------------------- def start super create_help_window create_category_window create_item_window end #-------------------------------------------------------------------------- # ● 生成分类窗口 #-------------------------------------------------------------------------- def create_category_window @category_window = Window_ItemCategory.new @category_window.viewport = @viewport @category_window.help_window = @help_window @category_window.y = @help_window.height @category_window.set_handler(:ok, method(:on_category_ok)) @category_window.set_handler(:cancel, method(:return_scene)) end #-------------------------------------------------------------------------- # ● 生成物品窗口 #-------------------------------------------------------------------------- def create_item_window wy = @category_window.y + @category_window.height wh = Graphics.height - wy @item_window = Window_ItemList.new(0, wy, Graphics.width, wh) @item_window.viewport = @viewport @item_window.help_window = @help_window @item_window.set_handler(:ok, method(:on_item_ok)) @item_window.set_handler(:cancel, method(:on_item_cancel)) @category_window.item_window = @item_window end #-------------------------------------------------------------------------- # ● 分类“确定” #-------------------------------------------------------------------------- def on_category_ok @item_window.activate @item_window.select_last end #-------------------------------------------------------------------------- # ● 物品“确定” #-------------------------------------------------------------------------- def on_item_ok $game_party.last_item.object = item determine_item end #-------------------------------------------------------------------------- # ● 物品“取消” #-------------------------------------------------------------------------- def on_item_cancel @item_window.unselect @category_window.activate end #-------------------------------------------------------------------------- # ● 播放使用物品声效 #-------------------------------------------------------------------------- def play_se_for_item Sound.play_use_item end #-------------------------------------------------------------------------- # ● 使用物品 #-------------------------------------------------------------------------- def use_item super @item_window.redraw_current_item endend
使用技能的子类 Scene_Skill 中多了指令窗口与状态窗口。物品窗口与 Scene_Item 中的是不同的。
#encoding:utf-8#==============================================================================# ■ Scene_Skill#------------------------------------------------------------------------------# 技能画面# 为了方便共通化处理,这里把技能也称为“物品”。#==============================================================================class Scene_Skill < Scene_ItemBase #-------------------------------------------------------------------------- # ● 开始处理 #-------------------------------------------------------------------------- def start super create_help_window create_command_window create_status_window create_item_window end #-------------------------------------------------------------------------- # ● 生成指令窗口 #-------------------------------------------------------------------------- def create_command_window wy = @help_window.height @command_window = Window_SkillCommand.new(0, wy) @command_window.viewport = @viewport @command_window.help_window = @help_window @command_window.actor = @actor @command_window.set_handler(:skill, method(:command_skill)) @command_window.set_handler(:cancel, method(:return_scene)) @command_window.set_handler(:pagedown, method(:next_actor)) @command_window.set_handler(:pageup, method(:prev_actor)) end #-------------------------------------------------------------------------- # ● 生成状态窗口 #-------------------------------------------------------------------------- def create_status_window y = @help_window.height @status_window = Window_SkillStatus.new(@command_window.width, y) @status_window.viewport = @viewport @status_window.actor = @actor end #-------------------------------------------------------------------------- # ● 生成物品窗口 #-------------------------------------------------------------------------- def create_item_window wx = 0 wy = @status_window.y + @status_window.height ww = Graphics.width wh = Graphics.height - wy @item_window = Window_SkillList.new(wx, wy, ww, wh) @item_window.actor = @actor @item_window.viewport = @viewport @item_window.help_window = @help_window @item_window.set_handler(:ok, method(:on_item_ok)) @item_window.set_handler(:cancel, method(:on_item_cancel)) @command_window.skill_window = @item_window end #-------------------------------------------------------------------------- # ● 获取技能的使用者 #-------------------------------------------------------------------------- def user @actor end #-------------------------------------------------------------------------- # ● 指令“技能” #-------------------------------------------------------------------------- def command_skill @item_window.activate @item_window.select_last end #-------------------------------------------------------------------------- # ● 物品“确定” #-------------------------------------------------------------------------- def on_item_ok @actor.last_skill.object = item determine_item end #-------------------------------------------------------------------------- # ● 物品“取消” #-------------------------------------------------------------------------- def on_item_cancel @item_window.unselect @command_window.activate end #-------------------------------------------------------------------------- # ● 播放物品使用声效 #-------------------------------------------------------------------------- def play_se_for_item Sound.play_use_skill end #-------------------------------------------------------------------------- # ● 使用物品 #-------------------------------------------------------------------------- def use_item super @status_window.refresh @item_window.refresh end #-------------------------------------------------------------------------- # ● 切换角色 #-------------------------------------------------------------------------- def on_actor_change @command_window.actor = @actor @status_window.actor = @actor @item_window.actor = @actor @command_window.activate endend
可见各种各样的窗口占了代码的大部分。
Window_Help 是显示说明的小窗口。
它在初始化时默认为占用两行。
它用 set_item(item) 将内容设置为指定物品或技能的描述。
#encoding:utf-8#==============================================================================# ■ Window_Help#------------------------------------------------------------------------------# 显示特技和物品等的说明、以及角色状态的窗口#==============================================================================class Window_Help < Window_Base #-------------------------------------------------------------------------- # ● 初始化对象 #-------------------------------------------------------------------------- def initialize(line_number = 2) super(0, 0, Graphics.width, fitting_height(line_number)) end #-------------------------------------------------------------------------- # ● 设置内容 #-------------------------------------------------------------------------- def set_text(text) if text != @text @text = text refresh end end #-------------------------------------------------------------------------- # ● 清除 #-------------------------------------------------------------------------- def clear set_text("") end #-------------------------------------------------------------------------- # ● 设置物品 # item : 技能、物品等 #-------------------------------------------------------------------------- def set_item(item) set_text(item ? item.description : "") end #-------------------------------------------------------------------------- # ● 刷新 #-------------------------------------------------------------------------- def refresh contents.clear draw_text_ex(4, 0, @text) endend
Window_ItemCategory 是将物品分类的窗口。
我们的物品被分为4类:物品、武器、防具、关键道具。
在分类窗口更新画面的过程中,不停的将物品窗口的分类设为当前选中的分类。
当分类被选中时 Scene_Item 中的 on_category_ok 被执行,激活了物品窗口。
#encoding:utf-8#==============================================================================# ■ Window_ItemCategory#------------------------------------------------------------------------------# 物品画面和商店画面中,显示装备、所持物品等项目列表的窗口。#==============================================================================class Window_ItemCategory < Window_HorzCommand #-------------------------------------------------------------------------- # ● 定义实例变量 #-------------------------------------------------------------------------- attr_reader :item_window #-------------------------------------------------------------------------- # ● 初始化对象 #-------------------------------------------------------------------------- def initialize super(0, 0) end #-------------------------------------------------------------------------- # ● 获取窗口的宽度 #-------------------------------------------------------------------------- def window_width Graphics.width end #-------------------------------------------------------------------------- # ● 获取列数 #-------------------------------------------------------------------------- def col_max return 4 end #-------------------------------------------------------------------------- # ● 更新画面 #-------------------------------------------------------------------------- def update super @item_window.category = current_symbol if @item_window end #-------------------------------------------------------------------------- # ● 生成指令列表 #-------------------------------------------------------------------------- def make_command_list add_command(Vocab::item, :item) add_command(Vocab::weapon, :weapon) add_command(Vocab::armor, :armor) add_command(Vocab::key_item, :key_item) end #-------------------------------------------------------------------------- # ● 设置物品窗口 #-------------------------------------------------------------------------- def item_window=(item_window) @item_window = item_window update endend
Window_ItemList 显示持有的物品。
设置分类的方法 category 被用于在分类窗口中设置类别。
这个窗口在调用刷新 refresh 时,首先用 make_item_list 遍历物品栏中的所有物品,如果属于目前的分类就将其加入物品列表。
最后将一个空物品加入了列表。然后调用 create_contents 生成窗口内容。
draw_all_items 绘制所有项目。后面两个方法都是在父类中定义的。
在绘制每个项目时,draw_item 会将物品的名字与数量绘制到画面上。
#encoding:utf-8#==============================================================================# ■ Window_ItemList#------------------------------------------------------------------------------# 物品画面中,显示持有物品的窗口。#==============================================================================class Window_ItemList < Window_Selectable #-------------------------------------------------------------------------- # ● 初始化对象 #-------------------------------------------------------------------------- def initialize(x, y, width, height) super @category = :none @data = [] end #-------------------------------------------------------------------------- # ● 设置分类 #-------------------------------------------------------------------------- def category=(category) return if @category == category @category = category refresh self.oy = 0 end #-------------------------------------------------------------------------- # ● 获取列数 #-------------------------------------------------------------------------- def col_max return 2 end #-------------------------------------------------------------------------- # ● 获取项目数 #-------------------------------------------------------------------------- def item_max @data ? @data.size : 1 end #-------------------------------------------------------------------------- # ● 获取物品 #-------------------------------------------------------------------------- def item @data && index >= 0 ? @data[index] : nil end #-------------------------------------------------------------------------- # ● 获取选择项目的有效状态 #-------------------------------------------------------------------------- def current_item_enabled? enable?(@data[index]) end #-------------------------------------------------------------------------- # ● 查询列表中是否含有此物品 #-------------------------------------------------------------------------- def include?(item) case @category when :item item.is_a?(RPG::Item) && !item.key_item? when :weapon item.is_a?(RPG::Weapon) when :armor item.is_a?(RPG::Armor) when :key_item item.is_a?(RPG::Item) && item.key_item? else false end end #-------------------------------------------------------------------------- # ● 查询此物品是否可用 #-------------------------------------------------------------------------- def enable?(item) $game_party.usable?(item) end #-------------------------------------------------------------------------- # ● 生成物品列表 #-------------------------------------------------------------------------- def make_item_list @data = $game_party.all_items.select {|item| include?(item) } @data.push(nil) if include?(nil) end #-------------------------------------------------------------------------- # ● 返回上一个选择的位置 #-------------------------------------------------------------------------- def select_last select(@data.index($game_party.last_item.object) || 0) end #-------------------------------------------------------------------------- # ● 绘制项目 #-------------------------------------------------------------------------- def draw_item(index) item = @data[index] if item rect = item_rect(index) rect.width -= 4 draw_item_name(item, rect.x, rect.y, enable?(item)) draw_item_number(rect, item) end end #-------------------------------------------------------------------------- # ● 绘制物品个数 #-------------------------------------------------------------------------- def draw_item_number(rect, item) draw_text(rect, sprintf(":%2d", $game_party.item_number(item)), 2) end #-------------------------------------------------------------------------- # ● 更新帮助内容 #-------------------------------------------------------------------------- def update_help @help_window.set_item(item) end #-------------------------------------------------------------------------- # ● 刷新 #-------------------------------------------------------------------------- def refresh make_item_list create_contents draw_all_items endend
显示技能的窗口 Window_SkillList 与它很类似。
在刷新 refresh 时,调用 make_item_list 遍历角色的所有技能。
而其中的角色 @actor 是在 Scene_Skill 类用切换角色的方法 on_actor_change 指定的。
技能中的项目在绘制时会把技能的消耗绘制到屏幕。
#encoding:utf-8#==============================================================================# ■ Window_SkillList#------------------------------------------------------------------------------# 技能画面中,显示技能的窗口。#==============================================================================class Window_SkillList < Window_Selectable #-------------------------------------------------------------------------- # ● 初始化对象 #-------------------------------------------------------------------------- def initialize(x, y, width, height) super @actor = nil @stype_id = 0 @data = [] end #-------------------------------------------------------------------------- # ● 设置角色 #-------------------------------------------------------------------------- def actor=(actor) return if @actor == actor @actor = actor refresh self.oy = 0 end #-------------------------------------------------------------------------- # ● 设置技能类型 ID #-------------------------------------------------------------------------- def stype_id=(stype_id) return if @stype_id == stype_id @stype_id = stype_id refresh self.oy = 0 end #-------------------------------------------------------------------------- # ● 获取列数 #-------------------------------------------------------------------------- def col_max return 2 end #-------------------------------------------------------------------------- # ● 获取项目数 #-------------------------------------------------------------------------- def item_max @data ? @data.size : 1 end #-------------------------------------------------------------------------- # ● 获取技能 #-------------------------------------------------------------------------- def item @data && index >= 0 ? @data[index] : nil end #-------------------------------------------------------------------------- # ● 获取选择项目的有效状态 #-------------------------------------------------------------------------- def current_item_enabled? enable?(@data[index]) end #-------------------------------------------------------------------------- # ● 查询列表中是否含有此技能 #-------------------------------------------------------------------------- def include?(item) item && item.stype_id == @stype_id end #-------------------------------------------------------------------------- # ● 查询此技能是否可用 #-------------------------------------------------------------------------- def enable?(item) @actor && @actor.usable?(item) end #-------------------------------------------------------------------------- # ● 生成技能列表 #-------------------------------------------------------------------------- def make_item_list @data = @actor ? @actor.skills.select {|skill| include?(skill) } : [] end #-------------------------------------------------------------------------- # ● 返回上一个选择的位置 #-------------------------------------------------------------------------- def select_last select(@data.index(@actor.last_skill.object) || 0) end #-------------------------------------------------------------------------- # ● 绘制项目 #-------------------------------------------------------------------------- def draw_item(index) skill = @data[index] if skill rect = item_rect(index) rect.width -= 4 draw_item_name(skill, rect.x, rect.y, enable?(skill)) draw_skill_cost(rect, skill) end end #-------------------------------------------------------------------------- # ● 绘制技能的使用消耗 #-------------------------------------------------------------------------- def draw_skill_cost(rect, skill) if @actor.skill_tp_cost(skill) > 0 change_color(tp_cost_color, enable?(skill)) draw_text(rect, @actor.skill_tp_cost(skill), 2) elsif @actor.skill_mp_cost(skill) > 0 change_color(mp_cost_color, enable?(skill)) draw_text(rect, @actor.skill_mp_cost(skill), 2) end end #-------------------------------------------------------------------------- # ● 更新帮助内容 #-------------------------------------------------------------------------- def update_help @help_window.set_item(item) end #-------------------------------------------------------------------------- # ● 刷新 #-------------------------------------------------------------------------- def refresh make_item_list create_contents draw_all_items endend
技能画面中有一个指令窗口 Window_SkillCommand,用来选取特技还是魔法。
它有自动生成的指令列表,遍历角色的所有技能,然后将技能种类生成指令。
在更新画面时,它不停的将技能窗口的技能类型设为当前选中的种类。
#encoding:utf-8#==============================================================================# ■ Window_SkillCommand#------------------------------------------------------------------------------# 技能画面中,选择指令(特技/魔法等)的窗口。#==============================================================================class Window_SkillCommand < Window_Command #-------------------------------------------------------------------------- # ● 定义实例变量 #-------------------------------------------------------------------------- attr_reader :skill_window #-------------------------------------------------------------------------- # ● 初始化对象 #-------------------------------------------------------------------------- def initialize(x, y) super(x, y) @actor = nil end #-------------------------------------------------------------------------- # ● 获取窗口的宽度 #-------------------------------------------------------------------------- def window_width return 160 end #-------------------------------------------------------------------------- # ● 设置角色 #-------------------------------------------------------------------------- def actor=(actor) return if @actor == actor @actor = actor refresh select_last end #-------------------------------------------------------------------------- # ● 获取显示行数 #-------------------------------------------------------------------------- def visible_line_number return 4 end #-------------------------------------------------------------------------- # ● 生成指令列表 #-------------------------------------------------------------------------- def make_command_list return unless @actor @actor.added_skill_types.sort.each do |stype_id| name = $data_system.skill_types[stype_id] add_command(name, :skill, true, stype_id) end end #-------------------------------------------------------------------------- # ● 更新画面 #-------------------------------------------------------------------------- def update super @skill_window.stype_id = current_ext if @skill_window end #-------------------------------------------------------------------------- # ● 设置技能窗口 #-------------------------------------------------------------------------- def skill_window=(skill_window) @skill_window = skill_window update end #-------------------------------------------------------------------------- # ● 返回上一个选择的位置 #-------------------------------------------------------------------------- def select_last skill = @actor.last_skill.object if skill select_ext(skill.stype_id) else select(0) end endend
技能与物品画面的工作原理大致就是如此了。
0 0
- 如何优雅的研究 RGSS3 (六) 技能与物品画面剖析
- 如何优雅的研究 RGSS3 (七) 添加LOGO画面
- 如何优雅的研究 RGSS3 (二) 为游戏结束画面添加简单的选项
- 如何优雅的研究 RGSS3 (五) 输入数字的画面
- 如何优雅的研究 RGSS3 (四) 使窗口从画面边缘弹出
- 如何优雅的研究 RGSS3 (一) 场景中窗口的工作原理
- 如何优雅的研究 RGSS3 (三) 调整窗口的细节
- 如何优雅的研究 RGSS3 番外(一) ruby 实现的后缀自动机
- 如何优雅的研究 RGSS3 番外(二) 显示文字信息的窗口中的纤程
- springboot(六):如何优雅的使用mybatis
- springboot(六):如何优雅的使用mybatis
- SpringBoot (六) :如何优雅的使用 mybatis
- springboot(六):如何优雅的使用mybatis
- springboot(六):如何优雅的使用mybatis
- springboot(六):如何优雅的使用mybatis
- 如何做研究(六)
- spring boot(六):如何优雅的使用mybatis
- Spring Boot系列(六):如何优雅的使用mybatis
- 我的这张嘴啊
- LVM2 Logical Volume Manager 详解(五)--利用快照备份
- 告别,去创造更大的世界
- 图片拖曳和缩放
- leetcode 刷题之路 19 Valid Palindrome
- 如何优雅的研究 RGSS3 (六) 技能与物品画面剖析
- 一张图让你看清Java集合类(Java集合类的总结)
- HDOJ题目2105The Center of Gravity
- 使用AOP 使C#代码更清晰
- 辟部劝吕训穆巧涛苛僮什
- 味挛战滋展唤刂趾党淌迫
- 琢辞抢磁谭喂贝砍谎员伤
- 形噬平椎滤圆旁拙椭咳防
- 旅母志眉杏踪涛懊嗜床炊