标签:des blog color 使用 os io 2014 for
物品与技能画面剖析#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?
end
end
在生成物品窗口的最后,将生成的物品窗口实例传递给了分类窗口。
#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
end
end
#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
end
end
它在初始化时默认为占用两行。
它用 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)
end
end
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
end
end
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
end
end
显示技能的窗口 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
end
end
它有自动生成的指令列表,遍历角色的所有技能,然后将技能种类生成指令。
在更新画面时,它不停的将技能窗口的技能类型设为当前选中的种类。
#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
end
end
如何优雅的研究 RGSS3 (六) 技能与物品画面剖析,布布扣,bubuko.com
标签:des blog color 使用 os io 2014 for
原文地址:http://blog.csdn.net/cyendra/article/details/38184705