# @taroxd metadata 1.0
# @require taroxd_core
# @display 按键事件
# @id input_event
class << Taroxd::InputEvent = Module.new
attr_accessor :event # 当前事件,作用类似于全局变量
end
class Taroxd::InputEvent::Base
# 各属性与默认值列表
@options = {}
@option_blocks = {}
# 事件是否成功
attr_accessor :result
# 建立简单的事件,返回事件的结果
def self.main(*args)
Taroxd::InputEvent.event = event = new(*args)
event.main
Taroxd::InputEvent.event = nil
event.result
end
# option opt1: default1, opt2: default2, ...
# option(:opt) { |option_name| value }
#
# 定义属性。
# 该属性会在实例生成时定义一个名称对应的实例变量,值为默认的值。
# 在调用可以通过 InputEvent.new(option: value) 的形式进行覆盖。
# 该方法包含了 attr_reader 的效果。
def self.option(name_pair, &block)
if block
attr_reader name_pair
option_blocks[name_pair] = block
else
attr_reader(*name_pair.keys)
options.merge!(name_pair)
end
end
# 获取属性列表(默认值)
def self.options
@options ||= superclass.options.dup
end
# 获取属性列表(default_proc)
def self.option_blocks
@option_blocks ||= superclass.option_blocks
end
# 要按下的键
option key: :C
# 值槽被填充的比例
option rate: 0
# 是否显示
option visible: true
# 显示位置(当然,你一定想要重定义)
option x: 0, y: 0, z: 0, width: Graphics.width, height: Graphics.height
# 值槽方向
option vertical: false
# 填充颜色
option color: Color.new(255, 255, 255)
# InputEventClass.new([opt1: value1, opt2: value2, ... ]) -> event
#
# 生成实例。可选的 options 参数可以覆盖默认的设置。
def initialize(options = {})
self.class.options.each do |name, default|
instance_variable_set :"@#{name}", options.fetch(name, default)
end
self.class.option_blocks.each do |name, default|
instance_variable_set :"@#{name}", options.fetch(name, &default)
end
end
# 暂时以该事件的主逻辑代替场景
def main
update_scene while update
end
# 更新事件。如果事件结束,返回 false,否则返回 true。
def update
hit? ? on_hit : on_not_hit
update_common
@result.nil?
end
private
# 事件调用 main 时,更新场景的方式。
def update_scene
SceneManager.scene.update_for_input_event
end
# 是否按下按键。
def hit?
Input.trigger?(key)
end
# 更新方式。在子类定义。
def on_hit; end
alias_method :on_not_hit, :on_hit
alias_method :update_common, :on_hit
# 终止事件,并返回结果。
alias_method :terminate, :result=
end
class Taroxd::InputEvent::Sprite < Sprite
include Taroxd::DisposeBitmap
# 更新
def update
update_event_change
update_property if @event
end
private
# 获取当前事件
def event
Taroxd::InputEvent.event
end
# 判断事件改变
def update_event_change
return if @event.equal?(event)
@event = event
update_bitmap
end
# 事件改变时的刷新
def update_bitmap
bitmap.dispose if bitmap
return unless @event
self.bitmap = Bitmap.new(width, height)
bitmap.fill_rect(0, 0, width, height, @event.color)
end
# 更新属性
def update_property
self.visible = @event.visible
update_position
update_src_rect
end
# 更新位置
def update_position
self.x = @event.x
self.y = @event.y
self.z = @event.z
end
# 更新值槽
def update_src_rect
if @event.vertical
src_rect.y = height * (1 - rate)
src_rect.height = height * rate
else
src_rect.width = width * rate
end
end
# 总宽度。覆盖了父类的方法!
def width
@event.width
end
# 总高度
def height
@event.height
end
# 值槽填充程度
def rate
@event.rate
end
end
class Scene_Base
# 对事件调用 main 时,场景的更新方式
def update_for_input_event
update_basic
end
end
class Scene_Map < Scene_Base
# 对事件调用 main 时,场景的更新方式
def update_for_input_event
update_basic
@spriteset.update
end
end
# 导入 Spriteset_Map
Spriteset_Map.use_sprite(Taroxd::InputEvent::Sprite) { @viewport2 }