#=============================================================================
# 环形菜单(仿3D)1.1
#-----------------------------------------------------------------------------
# 作者: Gab (2012.12.18)
#
#=============================================================================
# 修改:褐衣
#------------------------
# 2012.12.20 [1.0] 版修改说明:
# 1.修正了在整队画面选中一个角色后不能撤销的问题。
# 2.将MenuWindow类移出
# 3.取消了背景音乐(因为不能完全控制它)
# 4.添加中文注释
# 5.依照公式 x=h+a*cos(t),y=k+b*sin(t)修改了安置图标的方法。
# 5.重命名了一些变量明
# 6.从道具、技能、状态画面返回时,留在对应的图标处,而不是回到物品图标。
# ----------------------
# 2012.12.23 [1.1] 版修改说明
# 1.加入自定义菜单图标功能。使用时须将图片保存在Graphics\Pictures目录里。
# 图片尺寸不宜过大,建议使用32*32像素左右的尺寸,并根据图片的大小适当
# 调整椭圆的半长轴(SMAA)和半短轴(SMIA)。
# 此功能默认状态为不开启。使用此功能请讲 USECUSTOMICONS 设置为 true ,并
# 将对应的自定义图片名称写进 CUSTOMICONS 数组中。
# 2.修改了标题的显示以及调整显示位置的公式。(为了配合自定义图标的使用)
# 3. 1.1 版可以取代 1.0 版使用。
# <span style="background-color: rgb(255, 255, 255);">4. 清理多余代码 (2012.12.26)</span>
# 以上修改皆针对脚本功能的实用性,以及脚本自身的可读性。
#=============================================================================
$imported = {} if $imported.nil?
$imported["Gab_Ellipse_Menu"] = true
#=============================================================================
# * 设定
#=============================================================================
module Gab
module Ellipse_Menu
USECUSTOMICONS = false # 要使用自定义图标,请改为 true ,并修改下面的CUSTOMICONS
# Graphics\Pictures目录中的自定义图标的名称 (Name of custom icons in Graphics\Pictures folder.)
# 依照次序,在引号中填写自定义图标的名称
CUSTOMICONS = [
"Items Icon", # Items 道具
"Skills Icon", # Skills 技能
"Equipment Icon", # Equipment 装备
"Status Icon", # Status 状态
"Formation Icon", # formation 队列
"Save Icon", # Save 记录
"Game End Icon" # Game End 退出游戏
]
# 从IconSet.png中的选择要用的图标的序号 (ID of icons)
ICONS = [
192, # Items 道具
112, # Skills 技能
169, # Equipment 装备
14, # Status 状态
12, # formation 队列
117, # Save 记录
121 # Game End 退出游戏
]
# 菜单字体 (Menu font)
USENEWFONT = false # 如果要使用新字体,改为true ,并给FNAME指定字体名称
FNAME = "" # 通过在引号中填写字体名称,来指定菜单所用的字体。(Name of font. )
FSIZE = 19 # 字体大小 (font size)
FCOLOR = [255, 255, 255, 200] # 字体颜色,格式 R(red)红,G(green)绿,B(blue)蓝,A(alpha)可见度 (color of the font(R,G,B,A).)
# 椭圆形菜单的轴长 (axises of the ellipse menu)
SMAA = 90 # 半长轴 (semi-major axis)
SMIA = 25 # 半短轴 (semi-minor axis),半长轴必须长于半短轴。 It is necessary that SMAA > SMIA.
# 图标移动精细度,数值越大越精细,但速度也越慢 (Frequency of the icons movement. The bigger,the slower)
# 建议数值:(Suggested values:)
# 1 = 简略 (snapshot)
# 5 = 快速 (fast)
# 10 = 中速 (median)
# 20 = 慢速 (slow)
MV = 10
# 角色移动频率,数值越大越精细,但速度也越慢 (Frequency of the characters movement. The bigger,the slower)
CFREQ = 15
# 用来显示地图名称,游戏时间,和金钱数量的额外的窗口的参数设置。additional windows
Windows = {
mapName: [ # 地图名称 Map Name
true, # 是否显示 display?
0, # 窗口的X轴坐标 Position X
0, # 窗口的Y轴坐标 Position Y
400, # 窗口宽度 width
231, # 显示图标的ID icon id
0, # 窗口的透明度 Opacity
],
time: [ # 游戏时间 Game time
true, # 是否显示 display?
0, # 窗口的X轴坐标 Position X
34, # 窗口的Y轴坐标 Position Y
160, # 窗口宽度 width
280, # 显示图标的ID icon id
0, # 窗口的透明度 Opacity
],
gold: [ # 金钱 Money
true, # 是否显示 display?
0, # 窗口的X轴坐标 Position X
68, # 窗口的Y轴坐标 Position Y
160, # 窗口宽度 width
361, # 显示图标的ID icon id
0, # 窗口的透明度 Opacity
]
}
end
end # 设置结束 (End of the configuration)
#--------------------------------------------------------------------------
# ** 窗口菜单的基类 (Basis of the menu window)
#--------------------------------------------------------------------------
class MenuWindow < Window_Base
def initialize(x, y, width, icon, opacity)
super(x, y, width, fitting_height(1))
@icon = icon
self.opacity = opacity
self.contents.font.name = Gab::Ellipse_Menu::FNAME if Gab::Ellipse_Menu::USENEWFONT
self.contents.font.size = Gab::Ellipse_Menu::FSIZE
self.contents.font.color = Color.new(*Gab::Ellipse_Menu::FCOLOR)
self.contents.font.outline = false
self.contents.font.shadow = true
draw_icon(@icon, 0, 0)
@clear_rect = Rect.new(30, 0, contents.width - 31, contents.height)
refresh
end
def refresh
self.contents.clear_rect(@clear_rect)
text_size = self.contents.width - 32
self.contents.draw_text(30, 0, text_size, self.contents.height, text, align)
end
def align
return 0
end
def update
super
refresh if (Graphics.frame_count % Graphics.frame_rate) == 0
end
def text
return ""
end
end
#--------------------------------------------------------------------------
# ** 地图名称窗口 (Map name window)
#--------------------------------------------------------------------------
class MenuWindowMapName < MenuWindow
def text
$game_map.display_name
end
def align
return 0
end
end
#--------------------------------------------------------------------------
# ** 游戏时间窗口 (Game time window)
#--------------------------------------------------------------------------
class MenuWindowTime < MenuWindow
def text
total_sec = Graphics.frame_count / Graphics.frame_rate
hour = total_sec / 60 / 60
min = total_sec / 60 % 60
sec = total_sec % 60
sprintf("%03d:%02d:%02d", hour, min, sec)
end
end
#--------------------------------------------------------------------------
# ** 金钱窗口 (Money window)
#--------------------------------------------------------------------------
class MenuWindowGold < MenuWindow
def text
$game_party.gold.to_s
end
end
#=============================================================================
# * 重定义Scene_Menu类 (rewrite Scene_Menu class)
#=============================================================================
class Scene_Menu < Scene_MenuBase
@@iconIndex = 0 #图标索引
@@addIcons = 0 #图标移动量
#--------------------------------------------------------------------------
# * 定义开始运行方法 (Redefine start method)
#--------------------------------------------------------------------------
def start
super
# 术语表,其顺序与 ICONS 相对应
@vocabulary = [
Vocab::item,
Vocab::skill,
Vocab::equip,
Vocab::status,
Vocab::formation,
Vocab::save,
Vocab::game_end
]
@actorsNames = $game_party.members.map{|actor| actor.name}
create_background
[url=home.php?mod=space&uid=114926]@sprite[/url] = Sprite_Character.new(@main_viewport, $game_player)
@actorIndex = 0
@stage = 0
@pattern = 1
@actor1 = nil
precaculate
if Gab::Ellipse_Menu::USECUSTOMICONS
create_custom_icons
else
create_icons
end
create_caption
create_actor_selection
create_windows
end
#--------------------------------------------------------------------------
# * 退出菜单时的处理 (Termination of the process)
#--------------------------------------------------------------------------
def terminate
super
@icons.each(&:dispose)
@actors.each(&:dispose)
@windows.each(&:dispose)
@sprite.dispose
@caption.dispose
Input.update
$game_map.autoplay
end
#--------------------------------------------------------------------------
# * 预演算(Precaculate)
#--------------------------------------------------------------------------
def precaculate
@iconElRa = 2 * Math::PI / Gab::Ellipse_Menu::ICONS.size # icon ellpise radian
@iconBasePoint = @sprite.y + Gab::Ellipse_Menu::SMIA * (Math.sin(-@iconElRa) - 0.5)
@iconMaxDis = @sprite.y + Gab::Ellipse_Menu::SMIA * Math.sin(@iconElRa) - @iconBasePoint #前排图标与背景图标的Y轴距离
@iconMoveRadian = @iconElRa / Gab::Ellipse_Menu::MV # 图标旋转时,每次所移动弧度
@actorElRa = 2 * Math::PI / $game_party.members.size # actor ellpise radian
@basePointActors = @sprite.y + (Gab::Ellipse_Menu::SMIA + 24) * Math.sin(-@iconElRa)
@actorMaxDis = @sprite.y + (Gab::Ellipse_Menu::SMIA + 24) * Math.sin(@actorElRa) - @basePointActors
@moveTimesActors = @actorElRa / Gab::Ellipse_Menu::MV
@addActors = 0
end
#--------------------------------------------------------------------------
# * 用自定义图片生成图标 (Creat icons)
#--------------------------------------------------------------------------
def create_custom_icons
@icons = []
Gab::Ellipse_Menu::CUSTOMICONS.each_with_index {|icon_name, index|
sprite = Sprite.new
sprite.bitmap = Cache.picture(icon_name)
rect = Rect.new(0, 0, sprite.width, sprite.height)
sprite.ox = sprite.width / 2
sprite.oy = sprite.height / 2
@icons << sprite
}
@icons[5].tone = Tone.new(0, 0, 0, 255) if $game_system.save_disabled
adjust_icons
end
#--------------------------------------------------------------------------
# * 从Iconset.png生成图标 (Creat icons)
#--------------------------------------------------------------------------
def create_icons
iconset = Cache.system("Iconset")
@icons = []
Gab::Ellipse_Menu::ICONS.each_with_index {|icon_index, index|
sprite = Sprite.new
sprite.bitmap = iconset
sprite.src_rect = Rect.new(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24)
sprite.ox = sprite.width / 2
sprite.oy = sprite.height / 2
@icons << sprite
}
@icons[5].tone = Tone.new(0, 0, 0, 255) if $game_system.save_disabled
adjust_icons
end
#--------------------------------------------------------------------------
# * 显示标题 (Create caption)
#--------------------------------------------------------------------------
def create_caption
base, c = Bitmap.new(1, 1), nil
base.font.name = Gab::Ellipse_Menu::FNAME if Gab::Ellipse_Menu::USENEWFONT
base.font.size = Gab::Ellipse_Menu::FSIZE
base.font.color = Color.new(*Gab::Ellipse_Menu::FCOLOR)
maxLen = (@vocabulary + @actorsNames).inject(0){|a, b|
c = base.text_size(b)
c.width > a ? c.width : a
}
@caption = Sprite.new
@caption.bitmap = Bitmap.new(maxLen + 5, c.height)
@caption.bitmap.font.name = Gab::Ellipse_Menu::FNAME if Gab::Ellipse_Menu::USENEWFONT
@caption.bitmap.font.size = Gab::Ellipse_Menu::FSIZE
@caption.bitmap.font.color = Color.new(*Gab::Ellipse_Menu::FCOLOR)
@caption.ox = @caption.width / 2
@caption.oy = @caption.height / 2
@caption.x = @icons[@@iconIndex].x
@caption.y = @icons[@@iconIndex].y + @icons[@@iconIndex].height / 2 + 10 ###########
base.dispose
caption_refresh
end
#--------------------------------------------------------------------------
# * 建立角色选择画面 (Create actor selection scene)
#--------------------------------------------------------------------------
def create_actor_selection
@actors = $game_party.members.map{|char|
actor = Sprite.new
actor.bitmap = Cache.character(char.character_name)
sign = char.character_name[/^[\!\$]./]
if sign && sign.include?(''
)
cw = actor.bitmap.width / 3
ch = actor.bitmap.height / 4
else
cw = actor.bitmap.width / 12
ch = actor.bitmap.height / 8
end
actor.ox = cw / 2
actor.oy = ch
actor.x = @sprite.x + 1.5 * Gab::Ellipse_Menu::SMAA
actor.instance_variable_set(:@charData, [char, cw, ch])
actor
}
adjust_actors
update_actors_src
end
#--------------------------------------------------------------------------
# * 建立地图名称、游戏时间、金钱窗口 (Create map_name window,game_time window and Gold window)
#--------------------------------------------------------------------------
def create_windows
windows = Gab::Ellipse_Menu::Windows
@windows = []
@windows << MenuWindowMapName.new(*windows[:mapName][1,5]) if windows[:mapName][0]
@windows << MenuWindowTime.new(*windows[:time][1,5]) if windows[:time][0]
@windows << MenuWindowGold.new(*windows[:gold][1,5]) if windows[:gold][0]
end
#--------------------------------------------------------------------------
# * 调节图标的位置并调整图标的可见度和缩放比例(position icons and adjust opacity and zoom of the icons)
#--------------------------------------------------------------------------
def adjust_icons
t = 90/57.3 + @@addIcons
@icons.each{|sprite|
sprite.x =@sprite.x + Gab::Ellipse_Menu::SMAA * Math.cos(t)
sprite.y =@sprite.y + Gab::Ellipse_Menu::SMIA * (Math.sin(t) - 0.5)
t += @iconElRa
dif = (sprite.y - @iconBasePoint) / @iconMaxDis
sprite.opacity = @stage == 0 ? 127 + 255 * dif : 0
sprite.zoom_x = sprite.zoom_y = [0.55 + dif, 1].min
}
end
#--------------------------------------------------------------------------
# * 调节角色图标的位置并调整图标的可见度和缩放比例(position actors and adjust opacity and zoom of the actors)
#--------------------------------------------------------------------------
def adjust_actors
t = 90/57.3 + @addActors
@actors.each{|sprite|
sprite.x = @sprite.x + (Gab::Ellipse_Menu::SMAA + 24) * Math.cos(t)
sprite.y = @sprite.y + (Gab::Ellipse_Menu::SMIA + 26) * Math.sin(t)
dif = (sprite.y - @basePointActors) / (@actorMaxDis+26)
sprite.opacity = @stage != 0 ? 127 + 255 * dif : 0
sprite.zoom_x = sprite.zoom_y = [0.6 + dif, 1].min
t += @actorElRa
}
end
#--------------------------------------------------------------------------
# * 旋转图标 (Movement of icons)
#--------------------------------------------------------------------------
def rotateIcons(dir)
@iconMoveRadian *= -1 if dir == :right
Sound.play_cursor
Gab::Ellipse_Menu::MV.times{|sprite|
@@addIcons += @iconMoveRadian
@@addIcons %= Math::PI * 2
adjust_icons
Graphics.update
}
if dir == :right
@iconMoveRadian *= -1
@@iconIndex += 1
else
@@iconIndex -= 1
end
@@iconIndex %= @icons.size
caption_refresh
end
#--------------------------------------------------------------------------
# * 旋转角色图标 (Movement of actors)
#--------------------------------------------------------------------------
def rotateActors(dir)
@moveTimesActors *= -1 if dir == :right
Sound.play_cursor
Gab::Ellipse_Menu::MV.times{|sprite|
@addActors += @moveTimesActors
@addActors %= Math::PI * 2
adjust_actors
Graphics.update
}
if dir == :right
@moveTimesActors *= -1
@actorIndex += 1
else
@actorIndex -= 1
end
@actorIndex %= @actors.size
caption_refresh
end
#--------------------------------------------------------------------------
# * 更新标题 (Update caption)
#--------------------------------------------------------------------------
def caption_refresh
@caption.bitmap.clear
text = @stage == 0 ? @vocabulary[@@iconIndex] : @actorsNames[@actorIndex]
@caption.bitmap.draw_text(@caption.bitmap.rect, text, 1)
@caption.update
end
#--------------------------------------------------------------------------
# * 初级更新(Update base)
#--------------------------------------------------------------------------
def update
super
@windows.each(&:update)
case @stage
when 0
update_main_input
when 1, 2
@stage == 1 ? update_actors_input : update_formation_input
if (Graphics.frame_count % Gab::Ellipse_Menu::CFREQ) == 0
@pattern = (@pattern + 1) % 3
end
update_actors_src
end
end
#--------------------------------------------------------------------------
# * 更新初级指令输入 (Update standard input)
#--------------------------------------------------------------------------
def update_main_input
if Input.repeat?(:LEFT)
rotateIcons(:left)
elsif Input.repeat?(:RIGHT)
rotateIcons(:right)
elsif Input.trigger?(:B)
Sound.play_cancel
process_return
elsif Input.trigger?(:C)
process_confirm
end
end
#--------------------------------------------------------------------------
# * 更新角色选择画面的输入 (Update input in the actor selection scene)
#--------------------------------------------------------------------------
def update_actors_input
if Input.repeat?(:LEFT)
rotateActors(:left)
elsif Input.repeat?(:RIGHT)
rotateActors(:right)
elsif Input.trigger?(:B)
Sound.play_cancel
process_return
elsif Input.trigger?(:C)
Sound.play_ok
process_special_confirm
end
end
#--------------------------------------------------------------------------
# * 更新队列变换(Update formation exchanging )
#--------------------------------------------------------------------------
def update_formation_input
if Input.repeat?(:LEFT)
rotateActors(:left)
elsif Input.repeat?(:RIGHT)
rotateActors(:right)
elsif Input.trigger?(:B)
Sound.play_cancel
process_return
elsif Input.trigger?(:C)
process_formation_confirm
end
end
#--------------------------------------------------------------------------
# * 处理玩家输入的“确定”指令 (Process confirm)
#--------------------------------------------------------------------------
def process_confirm
case @@iconIndex
when 0 # Item 物品
Sound.play_ok
SceneManager.call(Scene_Item)
when 1, 2, 3, 4 # Skill 技能, Equip 装备, Status 状态, Formation 整队
Sound.play_ok
@stage = @@iconIndex == 4 ? 2 : 1
adjust_actors
adjust_icons
caption_refresh
@caption.y -= @icons[@@iconIndex].height / 2 + 14
when 5 # Save 保存
if ($game_system.save_disabled)
Sound.play_buzzer
else
SceneManager.call(Scene_Save)
Sound.play_ok
end
when 6 # Game End 退出游戏
Sound.play_ok
SceneManager.call(Scene_End)
end
end
#--------------------------------------------------------------------------
# * 处理针对某一被选定的角色的技能、装备或状态窗口的请求(Processes the required confirmation of the specific actor)
#--------------------------------------------------------------------------
def process_special_confirm
$game_party.menu_actor = $game_party.members[@actorIndex]
case @@iconIndex
when 1 # Skill
SceneManager.call(Scene_Skill)
when 2 # Equip
SceneManager.call(Scene_Equip)
when 3 # Status
SceneManager.call(Scene_Status)
end
end
#--------------------------------------------------------------------------
# * 处理玩家在整队画面输入的“确定”指令 (Processes formation switching confirmation )
#--------------------------------------------------------------------------
def process_formation_confirm
if @actor1.nil?
@actor1 = @actorIndex
@actors[@actor1].tone = Tone.new(150, 150, 150, 0)
Sound.play_ok
return
end
if @actor1 == @actorIndex
return Sound.play_buzzer
else
Sound.play_ok
$game_party.swap_order(@actor1,@actorIndex)
@actorsNames = $game_party.members.map{|actor| actor.name}
@stage = 0
@actors.each {|sprite| sprite.bitmap.dispose }
@actors.each(&:dispose)
@sprite.dispose
@sprite = Sprite_Character.new(@main_viewport, $game_player)
@addActors = 0
@actorIndex = 0
create_actor_selection
@actors[@actor1].tone = Tone.new(0, 0, 0, 0)
@actor1 = nil
adjust_icons
caption_refresh
@caption.y += @icons[@@iconIndex].height / 2 + 14
end
end
#--------------------------------------------------------------------------
# * 处理玩家的输入的“返回”指令 (Process return)
#--------------------------------------------------------------------------
def process_return
case @stage
when 0
@@iconIndex = 0
@@addIcons = 0
return_scene
when 1,2
case @@iconIndex
when 1, 2, 3
@stage = 0
adjust_actors
adjust_icons
caption_refresh
@caption.y += @icons[@@iconIndex].height / 2 + 14
when 4
if !@actor1.nil?
@actors[@actor1].tone = Tone.new(0, 0, 0, 0)
return @actor1 = nil
end
@stage = 0
adjust_actors
adjust_icons
caption_refresh
@caption.y += @icons[@@iconIndex].height / 2 + 14
end
end
end
#--------------------------------------------------------------------------
# * 更新角色踏步动画 (Update character step_anime)
#--------------------------------------------------------------------------
def update_actors_src
@actors.each{|sprite|
char, cw, ch = sprite.instance_variable_get(:@charData)
index = char.character_index
sx = (index % 4 * 3 + @pattern) * cw
sy = (index / 4 * 4) * ch
sprite.src_rect.set(sx, sy, cw, ch)
}
end
end
#=============================================================================
# 完 end of script
#=============================================================================