2 hours ago
(This post was last modified: 2 hours ago by DerVVulfman.)
XRXS_MP 6. Ring Menu Implementation
Version: 1.2
by Kazuki
© 2007
Version 1.0 Release © 2005
Yes, the creator's name is Kazuki, NOT XRXS
Version: 1.2
by Kazuki
© 2007
Version 1.0 Release © 2005
Yes, the creator's name is Kazuki, NOT XRXS
Introduction
For years, I've seen the XRXS Ring Menu with additions by Dubealex and others. But never a pure version of the original version. So I decided to use my lycanthropic werewolf hunting skills to track down a pure version untouched by western editors.
And here it is.
Features
- Its a RING menu
- Contains a compact actor menu when selecting choices like Equip or Skill
- Able to customize the icons
Script
I am providing BOTH the original version 1.2 (circa 2007 which Kazuki stated was abandoned) and an English version thanks to an hour's worth of wolfish translation.
Japanese Original Version
Code:
# ▼▲▼ XRXS_MP 6. リングメニュー導入 ver.1.2 ▼▲▼
# by 和希
#==============================================================================
# □ カスタマイズポイント
#==============================================================================
class Window_RingMenu < Window_Base
STARTUP_FRAMES = 20 # 初期アニメーションのフレーム数
MOVING_FRAMES = 5 # リングを回した時のフレーム数
RING_R = 64 # リングの半径
SE_STARTUP = "056-Right02" # メニューを開いたときに鳴らすSE
ICON_ITEM = RPG::Cache.icon("034-Item03") # 「 アイテム 」メニューのアイコン
ICON_SKILL = RPG::Cache.icon("044-Skill01") # 「 スキル 」メニューのアイコン
ICON_EQUIP = RPG::Cache.icon("001-Weapon01") # 「 装備 」メニューのアイコン
ICON_STATUS = RPG::Cache.icon("050-Skill07") # 「ステータス」メニューのアイコン
ICON_SAVE = RPG::Cache.icon("038-Item07") # 「 セーブ 」メニューのアイコン
ICON_EXIT = RPG::Cache.icon("046-Skill03") # 「 終了 」メニューのアイコン
ICON_DISABLE= RPG::Cache.icon("") # 使用禁止項目に付くアイコン
BACKGROUND_COLOR = Color.new(0xcc,0x99,0x33,0x3f)
end
###############################################################################
# リングメニュー導入スクリプト Ver. 1.2
# writen by 和希
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# ▽導入
# 0.先に XRXL 2. ビットマップ/アイコン描写 を入れて置いてください。
# 1.このスクリプトをMainセクションの上に作った新しいセクションにコピーする
# 2.Window_RingMenuの上部にある7つの RPG::Cache.icon("") の "" の中に
# 右の説明に書いてあるコマンド用のアイコン名を書く。
# (一番下の使用禁止は選べないメニューに重ねるアイコンです。
# こんなのがいいかも→ φ )
# 3.アイコン設定のすぐ下にある SE_STARTUP = "" の "" の中にメニューを
# 開いたときに鳴らしたいのSEの名前を書く。
# ▽スクリプト触れる人へ
# とりあえず動く物を目標に作ったものなので(志低いw)、座標の調整などが不完全です。
# より正確にアクターの画面座標を取得する処理を追加したり、アクター一覧の位置を
# 変えたり、文字表示などなどを調整するといい感じに仕上がる気がします。
###############################################################################
#==============================================================================
# ■ Window_RingMenu
#==============================================================================
class Window_RingMenu < Window_Base
#--------------------------------------------------------------------------
# ○ クラス定数
#--------------------------------------------------------------------------
MODE_START = 1 # スタートアップアニメーション
MODE_WAIT = 2 # 待機
MODE_MOVER = 3 # 時計回り回転アニメーション
MODE_MOVEL = 4 # 反時計回り回転アニメーション
#--------------------------------------------------------------------------
# ○ アクセサ
#--------------------------------------------------------------------------
attr_accessor :index
attr_reader :commands
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize( center_x, center_y )
super(-16, -16, 640+32, 480+32)
self.contents = Bitmap.new(width-32, height-32)
self.opacity = 0
self.back_opacity = 0
s1 = $data_system.words.item
s2 = $data_system.words.skill
s3 = $data_system.words.equip
s4 = "ステータス"
s5 = "セーブ"
s6 = "ゲーム終了"
@commands = [ s1, s2, s3, s4, s5, s6 ]
@item_max = 6
@index = 0
@items = [ ICON_ITEM, ICON_SKILL, ICON_EQUIP, ICON_STATUS, ICON_SAVE, ICON_EXIT ]
@disabled = [ false, false, false, false, false, false ]
@cx = center_x
@cy = center_y
setup_move_start
refresh
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
super
refresh
end
#--------------------------------------------------------------------------
# ● 画面再描画
#--------------------------------------------------------------------------
def refresh
self.contents.clear
# 背景描画
if BACKGROUND_COLOR.alpha > 0
self.contents.fill_rect(0,0,640,480,BACKGROUND_COLOR)
end
# アイコンを描画
case @mode
when MODE_START
refresh_start
when MODE_WAIT
refresh_wait
when MODE_MOVER
refresh_move(1)
when MODE_MOVEL
refresh_move(0)
end
end
#--------------------------------------------------------------------------
# ○ 画面再描画(初期化時)
#--------------------------------------------------------------------------
def refresh_start
d1 = 2.0 * Math::PI / @item_max
d2 = 1.0 * Math::PI / STARTUP_FRAMES
r = RING_R - 1.0 * RING_R * @steps / STARTUP_FRAMES
for i in 0...@item_max
j = i - @index
d = d1 * j + d2 * @steps
x = @cx + ( r * Math.sin( d ) ).to_i
y = @cy - ( r * Math.cos( d ) ).to_i
draw_item(x, y, i)
end
@steps -= 1
if @steps < 1
@mode = MODE_WAIT
end
end
#--------------------------------------------------------------------------
# ○ 画面再描画(待機時)
#--------------------------------------------------------------------------
def refresh_wait
d = 2.0 * Math::PI / @item_max
for i in 0...@item_max
j = i - @index
x = @cx + ( RING_R * Math.sin( d * j ) ).to_i
y = @cy - ( RING_R * Math.cos( d * j ) ).to_i
draw_item(x, y, i)
end
end
#--------------------------------------------------------------------------
# ○ 画面再描画(回転時)
# mode : 0=反時計回り 1=時計回り
#--------------------------------------------------------------------------
def refresh_move( mode )
d1 = 2.0 * Math::PI / @item_max
d2 = d1 / MOVING_FRAMES
d2 *= -1 if mode != 0
for i in 0...@item_max
j = i - @index
d = d1 * j + d2 * @steps
x = @cx + ( RING_R * Math.sin( d ) ).to_i
y = @cy - ( RING_R * Math.cos( d ) ).to_i
draw_item(x, y, i)
end
@steps -= 1
if @steps < 1
@mode = MODE_WAIT
end
end
#--------------------------------------------------------------------------
# ● 項目の描画
# x :
# y :
# i : 項目番号
#--------------------------------------------------------------------------
def draw_item(x, y, i)
rect = Rect.new(0, 0, @items[i].width, @items[i].height)
x -= rect.width/2
y -= rect.height/2
if @index == i
self.contents.blt( x, y, @items[i], rect )
if @disabled[@index]
self.contents.blt( x, y, ICON_DISABLE, rect )
end
else
self.contents.blt( x, y, @items[i], rect, 128 )
if @disabled[@index]
self.contents.blt( x, y, ICON_DISABLE, rect, 128 )
end
end
end
#--------------------------------------------------------------------------
# ● 項目を無効にする
# index : 項目番号
#--------------------------------------------------------------------------
def disable_item(index)
@disabled[index] = true
end
#--------------------------------------------------------------------------
# ○ 初期化アニメーションの準備
#--------------------------------------------------------------------------
def setup_move_start
@mode = MODE_START
@steps = STARTUP_FRAMES
if SE_STARTUP != nil and SE_STARTUP != ""
Audio.se_play("Audio/SE/" + SE_STARTUP, 80, 100)
end
end
#--------------------------------------------------------------------------
# ○ 回転アニメーションの準備
#--------------------------------------------------------------------------
def setup_move_move(mode)
if mode == MODE_MOVER
@index -= 1
@index = @items.size - 1 if @index < 0
elsif mode == MODE_MOVEL
@index += 1
@index = 0 if @index >= @items.size
else
return
end
@mode = mode
@steps = MOVING_FRAMES
end
#--------------------------------------------------------------------------
# ○ アニメーション中かどうか
#--------------------------------------------------------------------------
def animation?
return @mode != MODE_WAIT
end
end
#==============================================================================
# ■ Window_MenuStatus
#------------------------------------------------------------------------------
# メニュー画面でパーティメンバーのステータスを表示するウィンドウです。
#==============================================================================
class Window_RingMenuStatus < Window_Selectable
attr_reader :max_index
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
@max_index = $game_party.actors.size - 1
h = 32 * (@max_index + 1) + 32
h = 416 if h > 416
x = 0
x = 456 if $game_player.screen_x < 200 + Window_RingMenu::RING_R
super(x, 64, 184, h)
self.contents = Bitmap.new(width - 32, $game_party.actors.size * 32)
refresh
self.active = false
self.index = -1
end
#--------------------------------------------------------------------------
# ● リフレッシュ
#--------------------------------------------------------------------------
def refresh
self.contents.clear
@item_max = $game_party.actors.size
for i in 0...$game_party.actors.size
x = 32
y = 32 * i
actor = $game_party.actors[i]
self.contents.draw_facesquare(actor.character_name, actor.character_hue,
4, y + 4 )
draw_actor_name(actor, x, y)
end
end
end
#==============================================================================
# ■ Scene_Menu
#------------------------------------------------------------------------------
# メニュー画面の処理を行うクラスです。
#==============================================================================
class Scene_Menu
#--------------------------------------------------------------------------
# ● オブジェクト初期化
# menu_index : コマンドのカーソル初期位置
#--------------------------------------------------------------------------
def initialize(menu_index = 0)
@menu_index = menu_index
end
#--------------------------------------------------------------------------
# ● メイン処理
#--------------------------------------------------------------------------
def main
# スプライトセットを作成
@spriteset = Spriteset_Map.new
# コマンドウィンドウを作成
bmp = RPG::Cache.character($game_party.actors[0].character_name, 0)
px = $game_player.screen_x
py = $game_player.screen_y - bmp.rect.height / 4 / 2
@command_window = Window_RingMenu.new(px,py)
@command_window.index = @menu_index
# パーティ人数が 0 人の場合
if $game_party.actors.size == 0
# アイテム、スキル、装備、ステータスを無効化
@command_window.disable_item(0)
@command_window.disable_item(1)
@command_window.disable_item(2)
@command_window.disable_item(3)
end
@command_window.z = 100
# セーブ禁止の場合
if $game_system.save_disabled
# セーブを無効にする
@command_window.disable_item(4)
end
# ステータスウィンドウを作成
@status_window = Window_RingMenuStatus.new
@status_window.z = 200
@status_window.visible = false
# ヘルプウィンドウを作成
@help_window = Window_Help.new
@help_window.set_text(@command_window.commands[@command_window.index],1)
# トランジション実行
Graphics.transition
# メインループ
loop do
# ゲーム画面を更新
Graphics.update
# 入力情報を更新
Input.update
# フレーム更新
update
# 画面が切り替わったらループを中断
if $scene != self
break
end
end
# トランジション準備
Graphics.freeze
# スプライトセットを解放
@spriteset.dispose
# ウィンドウを解放
@command_window.dispose
@status_window.dispose
@help_window.dispose
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
# ウィンドウを更新
@command_window.update
@status_window.update
@help_window.update
# コマンドウィンドウがアクティブの場合: update_command を呼ぶ
if @command_window.active
update_command
return
end
# ステータスウィンドウがアクティブの場合: update_status を呼ぶ
if @status_window.active
update_status
return
end
end
#--------------------------------------------------------------------------
# ● フレーム更新 (コマンドウィンドウがアクティブの場合)
#--------------------------------------------------------------------------
def update_command
# 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)
# パーティ人数が 0 人で、セーブ、ゲーム終了以外のコマンドの場合
if $game_party.actors.size == 0 and @command_window.index < 4
# ブザー SE を演奏
$game_system.se_play($data_system.buzzer_se)
return
end
# コマンドウィンドウのカーソル位置で分岐
case @command_window.index
when 0 # アイテム
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# アイテム画面に切り替え
$scene = Scene_Item.new
when 1 # スキル
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# ステータスウィンドウをアクティブにする
@command_window.active = false
@status_window.active = true
@status_window.visible = true
@status_window.index = 0
when 2 # 装備
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# ステータスウィンドウをアクティブにする
@command_window.active = false
@status_window.active = true
@status_window.visible = true
@status_window.index = 0
when 3 # ステータス
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# ステータスウィンドウをアクティブにする
@command_window.active = false
@status_window.active = true
@status_window.visible = true
@status_window.index = 0
when 4 # セーブ
# セーブ禁止の場合
if $game_system.save_disabled
# ブザー SE を演奏
$game_system.se_play($data_system.buzzer_se)
return
end
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# セーブ画面に切り替え
$scene = Scene_Save.new
when 5 # ゲーム終了
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# ゲーム終了画面に切り替え
$scene = Scene_End.new
end
return
end
# アニメーション中ならカーソルの処理を行わない
return if @command_window.animation?
# ↑or← ボタンが押された場合
if Input.press?(Input::UP) or Input.press?(Input::LEFT)
$game_system.se_play($data_system.cursor_se)
@command_window.setup_move_move(Window_RingMenu::MODE_MOVEL)
@help_window.set_text(@command_window.commands[@command_window.index],1)
return
end
# ↓or→ ボタンが押された場合
if Input.press?(Input::DOWN) or Input.press?(Input::RIGHT)
$game_system.se_play($data_system.cursor_se)
@command_window.setup_move_move(Window_RingMenu::MODE_MOVER)
@help_window.set_text(@command_window.commands[@command_window.index],1)
return
end
end
#--------------------------------------------------------------------------
# ● フレーム更新 (ステータスウィンドウがアクティブの場合)
#--------------------------------------------------------------------------
def update_status
# B ボタンが押された場合
if Input.trigger?(Input::B)
# キャンセル SE を演奏
$game_system.se_play($data_system.cancel_se)
# コマンドウィンドウをアクティブにする
@command_window.active = true
@status_window.active = false
@status_window.visible = false
@status_window.index = -1
return
end
# C ボタンが押された場合
if Input.trigger?(Input::C)
# コマンドウィンドウのカーソル位置で分岐
case @command_window.index
when 1 # スキル
# このアクターの行動制限が 2 以上の場合
if $game_party.actors[@status_window.index].restriction >= 2
# ブザー SE を演奏
$game_system.se_play($data_system.buzzer_se)
return
end
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# スキル画面に切り替え
$scene = Scene_Skill.new(@status_window.index)
when 2 # 装備
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# 装備画面に切り替え
$scene = Scene_Equip.new(@status_window.index)
when 3 # ステータス
# 決定 SE を演奏
$game_system.se_play($data_system.decision_se)
# ステータス画面に切り替え
$scene = Scene_Status.new(@status_window.index)
end
return
end
end
end
#==============================================================================
# ◇ 外部ライブラリ
#==============================================================================
class Bitmap
# ▼▲▼ XRXL 1. ライン・図形描写 ▼▲▼
#--------------------------------------------------------------------------
# ● ライン描画 by 桜雅 在土
#--------------------------------------------------------------------------
def draw_line(start_x, start_y, end_x, end_y, start_color, width = 1, end_color = start_color)
# 描写距離の計算。大きめに直角時の長さ。
distance = (start_x - end_x).abs + (start_y - end_y).abs
# 描写開始
if end_color == start_color
for i in 1..distance
x = (start_x + 1.0 * (end_x - start_x) * i / distance).to_i
y = (start_y + 1.0 * (end_y - start_y) * i / distance).to_i
if width == 1
self.set_pixel(x, y, start_color)
else
self.fill_rect(x, y, width, width, start_color)
end
end
else
for i in 1..distance
x = (start_x + 1.0 * (end_x - start_x) * i / distance).to_i
y = (start_y + 1.0 * (end_y - start_y) * i / distance).to_i
r = start_color.red * (distance-i)/distance + end_color.red * i/distance
g = start_color.green * (distance-i)/distance + end_color.green * i/distance
b = start_color.blue * (distance-i)/distance + end_color.blue * i/distance
a = start_color.alpha * (distance-i)/distance + end_color.alpha * i/distance
if width == 1
self.set_pixel(x, y, Color.new(r, g, b, a))
else
self.fill_rect(x, y, width, width, Color.new(r, g, b, a))
end
end
end
end
#--------------------------------------------------------------------------
# ● 多角形の描画(塗りつぶしなし) by 和希
# peaks : 頂点座標の配列 [[x1,y1],[x2,y2],[x3,y3], ... ]
# color : 線の色
# width : 線の幅
#--------------------------------------------------------------------------
def draw_polygon(peaks, color, width = 1)
# 辺(=頂点)の個数分だけ辺を描く
for i in 0 ... (peaks.size - 1)
# 頂点同士を線で結ぶ
draw_line( peaks[i][0], peaks[i][1], peaks[i+1][0], peaks[i+1][1], color, width )
end
# 最後の頂点と最初の頂点を結ぶ
draw_line( peaks[peaks.size - 1][0], peaks[peaks.size - 1][1], peaks[0][0], peaks[0][1], color, width )
end
# ▼▲▼ XRXL 2. ビットマップ/アイコン描写 ▼▲▼
#--------------------------------------------------------------------------
# ● 顔&枠の描画 by 桜雅 在土
# character_name : 描写に利用するキャラクターグラフィック
# character_hue : 描写の色合い
# x : 描画先 X 座標
# y : 描画先 Y 座標
#--------------------------------------------------------------------------
def draw_facesquare(character_name, character_hue, x, y, size = 24)
bitmap = RPG::Cache.character(character_name, character_hue)
src_rect = Rect.new((bitmap.width/4 - size)/2, 0, size, size)
self.blt(x, y, bitmap, src_rect)
self.draw_polygon([[x,y],[x+size,y],[x+size,y+size],[x,y+size]], Color.new(255,255,255,128))
end
end English Translated Version
Code:
# ▼▲▼ XRXS_MP 6. Ring Menu Implementation ver.1.2 ▼▲▼
# By Kazuki
#==============================================================================
# □ Customization Points
#==============================================================================
class Window_RingMenu < Window_Base
STARTUP_FRAMES = 20 # Number of frames in the initial animation
MOVING_FRAMES = 5 # The number of frames when rotating the ring
RING_R = 64 # Radius of the ring
SE_STARTUP = "056-Right02" # The sound effect played when opening the menu
ICON_ITEM = RPG::Cache.icon("034-Item03") # Icons in the "Items" Menu
ICON_SKILL = RPG::Cache.icon("044-Skill01") # Icons in the "Skills" Menu
ICON_EQUIP = RPG::Cache.icon("001-Weapon01") # "Equipment" Menu Icon
ICON_STATUS = RPG::Cache.icon("050-Skill07") # "Status" Menu Icons
ICON_SAVE = RPG::Cache.icon("038-Item07") # "Save" Menu Icon
ICON_EXIT = RPG::Cache.icon("046-Skill03") # "Exit" Menu Icon
ICON_DISABLE= RPG::Cache.icon("") # Icons for Prohibited Items
BACKGROUND_COLOR = Color.new(0xcc,0x99,0x33,0x3f)
end
###############################################################################
# Ring Menu Implementation Script Ver. 1.2
# writen by Kazuki
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# ▽ Introduction
# 0. Please install "XRXL 2. Bitmap/Icon Rendering" beforehand.
# 1. Copy this script into a new section created above the Main section.
# 2. Inside the double quotas (`""`) of the sevenRPG::Cache.icon("") entries
# located at the top of `Window_RingMenu, enter the icon for each command.
# Follow as they are described in the comments to the right.
# The "Disabled" icon at the bottom is an icon that overlays atop the
# menu icons that cannot be selected. Recommended is something like: φ
# 3. Inside the "" of the TSE_STARTUP value, place the sound effect that you
# want to sound when the menu opens
# ▽ For those comfortable working with scripts
# Since I built this with the sole goal of getting something—anything—up and
# running (yeah, I set the bar pretty low!), the coordinate alignment and
# similar details are still incomplete.
# We added a process to obtain the actor's screen coordinates more accurately,
# and the position of the actor list.
# I feel like if you tweak things—such as making changes or adjusting the text
# display—it will turn out really nicely.
###############################################################################
#==============================================================================
# ■ Window_RingMenu
#==============================================================================
class Window_RingMenu < Window_Base
#--------------------------------------------------------------------------
# ○ Class Constants
#--------------------------------------------------------------------------
MODE_START = 1 # Startup Animation
MODE_WAIT = 2 # Stand By
MODE_MOVER = 3 # Clockwise Rotation Animation
MODE_MOVEL = 4 # Counter-clockwise Rotation Animation
#--------------------------------------------------------------------------
# ○ Public Instance Variables
#--------------------------------------------------------------------------
attr_accessor :index
attr_reader :commands
#--------------------------------------------------------------------------
# ● Object Initialization
#--------------------------------------------------------------------------
def initialize( center_x, center_y )
super(-16, -16, 640+32, 480+32)
self.contents = Bitmap.new(width-32, height-32)
self.opacity = 0
self.back_opacity = 0
s1 = $data_system.words.item
s2 = $data_system.words.skill
s3 = $data_system.words.equip
s4 = "Status"
s5 = "Save"
s6 = "Game Over"
@commands = [ s1, s2, s3, s4, s5, s6 ]
@item_max = 6
@index = 0
@items = [ ICON_ITEM, ICON_SKILL, ICON_EQUIP, ICON_STATUS, ICON_SAVE, ICON_EXIT ]
@disabled = [ false, false, false, false, false, false ]
@cx = center_x
@cy = center_y
setup_move_start
refresh
end
#--------------------------------------------------------------------------
# ● Frame Update
#--------------------------------------------------------------------------
def update
super
refresh
end
#--------------------------------------------------------------------------
# ● Refresh
#--------------------------------------------------------------------------
def refresh
self.contents.clear
# Draw background
if BACKGROUND_COLOR.alpha > 0
self.contents.fill_rect(0,0,640,480,BACKGROUND_COLOR)
end
# Draw Icon
case @mode
when MODE_START
refresh_start
when MODE_WAIT
refresh_wait
when MODE_MOVER
refresh_move(1)
when MODE_MOVEL
refresh_move(0)
end
end
#--------------------------------------------------------------------------
# ○ Screen redraw (at initialization)
#--------------------------------------------------------------------------
def refresh_start
d1 = 2.0 * Math::PI / @item_max
d2 = 1.0 * Math::PI / STARTUP_FRAMES
r = RING_R - 1.0 * RING_R * @steps / STARTUP_FRAMES
for i in 0...@item_max
j = i - @index
d = d1 * j + d2 * @steps
x = @cx + ( r * Math.sin( d ) ).to_i
y = @cy - ( r * Math.cos( d ) ).to_i
draw_item(x, y, i)
end
@steps -= 1
if @steps < 1
@mode = MODE_WAIT
end
end
#--------------------------------------------------------------------------
# ○ Screen redraw (standby)
#--------------------------------------------------------------------------
def refresh_wait
d = 2.0 * Math::PI / @item_max
for i in 0...@item_max
j = i - @index
x = @cx + ( RING_R * Math.sin( d * j ) ).to_i
y = @cy - ( RING_R * Math.cos( d * j ) ).to_i
draw_item(x, y, i)
end
end
#--------------------------------------------------------------------------
# ○ Screen Redraw (on Rotation)
# mode : 0=Counter-clockwise 1=Clockwise
#--------------------------------------------------------------------------
def refresh_move( mode )
d1 = 2.0 * Math::PI / @item_max
d2 = d1 / MOVING_FRAMES
d2 *= -1 if mode != 0
for i in 0...@item_max
j = i - @index
d = d1 * j + d2 * @steps
x = @cx + ( RING_R * Math.sin( d ) ).to_i
y = @cy - ( RING_R * Math.cos( d ) ).to_i
draw_item(x, y, i)
end
@steps -= 1
if @steps < 1
@mode = MODE_WAIT
end
end
#--------------------------------------------------------------------------
# ● Draw Item
# x :
# y :
# i : Item number
#--------------------------------------------------------------------------
def draw_item(x, y, i)
rect = Rect.new(0, 0, @items[i].width, @items[i].height)
x -= rect.width/2
y -= rect.height/2
if @index == i
self.contents.blt( x, y, @items[i], rect )
if @disabled[@index]
self.contents.blt( x, y, ICON_DISABLE, rect )
end
else
self.contents.blt( x, y, @items[i], rect, 128 )
if @disabled[@index]
self.contents.blt( x, y, ICON_DISABLE, rect, 128 )
end
end
end
#--------------------------------------------------------------------------
# ● Disable Item
# index : Item number
#--------------------------------------------------------------------------
def disable_item(index)
@disabled[index] = true
end
#--------------------------------------------------------------------------
# ○ Preparing the Initialization Animation
#--------------------------------------------------------------------------
def setup_move_start
@mode = MODE_START
@steps = STARTUP_FRAMES
if SE_STARTUP != nil and SE_STARTUP != ""
Audio.se_play("Audio/SE/" + SE_STARTUP, 80, 100)
end
end
#--------------------------------------------------------------------------
# ○ Preparing the Rotation Animation
#--------------------------------------------------------------------------
def setup_move_move(mode)
if mode == MODE_MOVER
@index -= 1
@index = @items.size - 1 if @index < 0
elsif mode == MODE_MOVEL
@index += 1
@index = 0 if @index >= @items.size
else
return
end
@mode = mode
@steps = MOVING_FRAMES
end
#--------------------------------------------------------------------------
# ○ Whether currently animating
#--------------------------------------------------------------------------
def animation?
return @mode != MODE_WAIT
end
end
#==============================================================================
# ■ Window_MenuStatus
#------------------------------------------------------------------------------
# This window displays party member status on the menu screen.
#==============================================================================
class Window_RingMenuStatus < Window_Selectable
attr_reader :max_index
#--------------------------------------------------------------------------
# ● Object Initialization
#--------------------------------------------------------------------------
def initialize
@max_index = $game_party.actors.size - 1
h = 32 * (@max_index + 1) + 32
h = 416 if h > 416
x = 0
x = 456 if $game_player.screen_x < 200 + Window_RingMenu::RING_R
super(x, 64, 184, h)
self.contents = Bitmap.new(width - 32, $game_party.actors.size * 32)
refresh
self.active = false
self.index = -1
end
#--------------------------------------------------------------------------
# ● Refresh
#--------------------------------------------------------------------------
def refresh
self.contents.clear
@item_max = $game_party.actors.size
for i in 0...$game_party.actors.size
x = 32
y = 32 * i
actor = $game_party.actors[i]
self.contents.draw_facesquare(actor.character_name, actor.character_hue,
4, y + 4 )
draw_actor_name(actor, x, y)
end
end
end
#==============================================================================
# ■ Scene_Menu
#------------------------------------------------------------------------------
# This class performs menu screen processing.
#==============================================================================
class Scene_Menu
#--------------------------------------------------------------------------
# ● Object Initialization
# menu_index : command cursor's initial position
#--------------------------------------------------------------------------
def initialize(menu_index = 0)
@menu_index = menu_index
end
#--------------------------------------------------------------------------
# ● Main Processing
#--------------------------------------------------------------------------
def main
# Make spriteset
@spriteset = Spriteset_Map.new
# Make command window
bmp = RPG::Cache.character($game_party.actors[0].character_name, 0)
px = $game_player.screen_x
py = $game_player.screen_y - bmp.rect.height / 4 / 2
@command_window = Window_RingMenu.new(px,py)
@command_window.index = @menu_index
# If number of party members is 0
if $game_party.actors.size == 0
# Disable items, skills, equipment, and status
@command_window.disable_item(0)
@command_window.disable_item(1)
@command_window.disable_item(2)
@command_window.disable_item(3)
end
@command_window.z = 100
# If save is forbidden
if $game_system.save_disabled
# Disable save
@command_window.disable_item(4)
end
# Make status window
@status_window = Window_RingMenuStatus.new
@status_window.z = 200
@status_window.visible = false
# Make help window
@help_window = Window_Help.new
@help_window.set_text(@command_window.commands[@command_window.index],1)
# Execute transition
Graphics.transition
# Main loop
loop do
# Update game screen
Graphics.update
# Update input information
Input.update
# Frame update
update
# Abort loop if screen is changed
if $scene != self
break
end
end
# Prepare for transition
Graphics.freeze
# Dispose of spriteset
@spriteset.dispose
# Dispose of windows
@command_window.dispose
@status_window.dispose
@help_window.dispose
end
#--------------------------------------------------------------------------
# ● Frame Update
#--------------------------------------------------------------------------
def update
# Update windows
@command_window.update
@status_window.update
@help_window.update
# If command window is active: call update_command
if @command_window.active
update_command
return
end
# If status window is active: call update_status
if @status_window.active
update_status
return
end
end
#--------------------------------------------------------------------------
# ● Frame Update (when command window is active)
#--------------------------------------------------------------------------
def update_command
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Switch to map screen
$scene = Scene_Map.new
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# If command other than save or end game, and party members = 0
if $game_party.actors.size == 0 and @command_window.index < 4
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Branch by command window cursor position
case @command_window.index
when 0 # item
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to item screen
$scene = Scene_Item.new
when 1 # skill
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.visible = true
@status_window.index = 0
when 2 # equipment
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.visible = true
@status_window.index = 0
when 3 # status
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Make status window active
@command_window.active = false
@status_window.active = true
@status_window.visible = true
@status_window.index = 0
when 4 # save
# If saving is forbidden
if $game_system.save_disabled
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to save screen
$scene = Scene_Save.new
when 5 # Game Over
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to end game screen
$scene = Scene_End.new
end
return
end
# Do not process the cursor while an animation is in progress.
return if @command_window.animation?
# ↑or← ボタンが押された場合
if Input.press?(Input::UP) or Input.press?(Input::LEFT)
$game_system.se_play($data_system.cursor_se)
@command_window.setup_move_move(Window_RingMenu::MODE_MOVEL)
@help_window.set_text(@command_window.commands[@command_window.index],1)
return
end
# If the ↓ or → button is pressed
if Input.press?(Input::DOWN) or Input.press?(Input::RIGHT)
$game_system.se_play($data_system.cursor_se)
@command_window.setup_move_move(Window_RingMenu::MODE_MOVER)
@help_window.set_text(@command_window.commands[@command_window.index],1)
return
end
end
#--------------------------------------------------------------------------
# ● Frame Update (when status window is active)
#--------------------------------------------------------------------------
def update_status
# If B button was pressed
if Input.trigger?(Input::B)
# Play cancel SE
$game_system.se_play($data_system.cancel_se)
# Make command window active
@command_window.active = true
@status_window.active = false
@status_window.visible = false
@status_window.index = -1
return
end
# If C button was pressed
if Input.trigger?(Input::C)
# Branch by command window cursor position
case @command_window.index
when 1 # skill
# If this actor's action limit is 2 or more
if $game_party.actors[@status_window.index].restriction >= 2
# Play buzzer SE
$game_system.se_play($data_system.buzzer_se)
return
end
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to skill screen
$scene = Scene_Skill.new(@status_window.index)
when 2 # equipment
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to equipment screen
$scene = Scene_Equip.new(@status_window.index)
when 3 # status
# Play decision SE
$game_system.se_play($data_system.decision_se)
# Switch to status screen
$scene = Scene_Status.new(@status_window.index)
end
return
end
end
end
#==============================================================================
# ◇ External Libraries
#==============================================================================
class Bitmap
# ▼▲▼ XRXL 1. Line and Shape Drawing ▼▲▼
#--------------------------------------------------------------------------
# ● ライン描画 by 桜雅 在土
#--------------------------------------------------------------------------
def draw_line(start_x, start_y, end_x, end_y, start_color, width = 1, end_color = start_color)
# Calculation of rendering distance. A generous estimate for the length at a right angle.
distance = (start_x - end_x).abs + (start_y - end_y).abs
# Start drawing
if end_color == start_color
for i in 1..distance
x = (start_x + 1.0 * (end_x - start_x) * i / distance).to_i
y = (start_y + 1.0 * (end_y - start_y) * i / distance).to_i
if width == 1
self.set_pixel(x, y, start_color)
else
self.fill_rect(x, y, width, width, start_color)
end
end
else
for i in 1..distance
x = (start_x + 1.0 * (end_x - start_x) * i / distance).to_i
y = (start_y + 1.0 * (end_y - start_y) * i / distance).to_i
r = start_color.red * (distance-i)/distance + end_color.red * i/distance
g = start_color.green * (distance-i)/distance + end_color.green * i/distance
b = start_color.blue * (distance-i)/distance + end_color.blue * i/distance
a = start_color.alpha * (distance-i)/distance + end_color.alpha * i/distance
if width == 1
self.set_pixel(x, y, Color.new(r, g, b, a))
else
self.fill_rect(x, y, width, width, Color.new(r, g, b, a))
end
end
end
end
#--------------------------------------------------------------------------
# ● Drawing a Polygon (Unfilled) by Kazuki
# peaks : Array of vertex coordinates [[x1,y1],[x2,y2],[x3,y3], ... ]
# color : Line Color
# width : Line width
#--------------------------------------------------------------------------
def draw_polygon(peaks, color, width = 1)
# Draw a number of edges equal to the number of edges (or vertices).
for i in 0 ... (peaks.size - 1)
# Connect the vertices with lines.
draw_line( peaks[i][0], peaks[i][1], peaks[i+1][0], peaks[i+1][1], color, width )
end
# Connect the last vertex to the first vertex.
draw_line( peaks[peaks.size - 1][0], peaks[peaks.size - 1][1], peaks[0][0], peaks[0][1], color, width )
end
# ▼▲▼ XRXL 2. Bitmap/Icon Rendering ▼▲▼
#--------------------------------------------------------------------------
# ● Face and frame drawing by Ouga Zaitou
# character_name : Character Graphics Used for Depiction
# character_hue : The Hue of the Character
# x : Drawing Destination X-Coordinate
# y : Drawing Destination Y-Coordinate
#--------------------------------------------------------------------------
def draw_facesquare(character_name, character_hue, x, y, size = 24)
bitmap = RPG::Cache.character(character_name, character_hue)
src_rect = Rect.new((bitmap.width/4 - size)/2, 0, size, size)
self.blt(x, y, bitmap, src_rect)
self.draw_polygon([[x,y],[x+size,y],[x+size,y+size],[x,y+size]], Color.new(255,255,255,128))
end
endInstructions
From the translation:
- Please install "XRXL 2. Bitmap/Icon Rendering" beforehand.
- Copy this script into a new section created above the Main section.
- Inside the double quotas (`""`) of the sevenRPG::Cache.icon("") entries located at the top of `Window_RingMenu, enter the icon for each command.
- Follow as they are described in the comments to the right.
- The "Disabled" icon at the bottom is an icon that overlays atop the menu icons that cannot be selected. Recommended is something like: φ
- Follow as they are described in the comments to the right.
- Inside the "" of the TSE_STARTUP value, place the sound effect that you want to sound when the menu opens
Credits and Thanks
Code courtesy of Kazuki, the creator of the XRXS script.
Face and frame drawing by Ouga Zaitou
Up is down, left is right and sideways is straight ahead. - Cord "Circle of Iron", 1978 (written by Bruce Lee and James Coburn... really...)
Above are clickable links

![[Image: QrnbKlx.jpg]](https://i.imgur.com/QrnbKlx.jpg)
![[Image: sGz1ErF.png]](https://i.imgur.com/sGz1ErF.png)
![[Image: liM4ikn.png]](https://i.imgur.com/liM4ikn.png)
![[Image: fdzKgZA.png]](https://i.imgur.com/fdzKgZA.png)
![[Image: sj0H81z.png]](https://i.imgur.com/sj0H81z.png)
![[Image: QL7oRau.png]](https://i.imgur.com/QL7oRau.png)
![[Image: uSqjY09.png]](https://i.imgur.com/uSqjY09.png)
![[Image: GAA3qE9.png]](https://i.imgur.com/GAA3qE9.png)
![[Image: 2Hmnx1G.png]](https://i.imgur.com/2Hmnx1G.png)
![[Image: BwtNdKw.png%5B]](https://i.imgur.com/BwtNdKw.png%5B)