제가 만드는 SRPG의 케릭터 선택 시 표시할 커맨드용 스크립트입니다.
아 물론 어렵지도 않은 간단한 겁니다만 (. . ; 귀찮으신 분들을 위해
물론 SRPG 스크립트도 직접 짜고 있습니다만. 완성할 가능성은 제로에 가까우므로
공개는 패스하고 생긴건
요런 느낌...
크게 3가지로 나뉩니다.
Raon_WindowSelectable
- Window_Selectable 의 불필요한 부분을 삭제하고 제꺼에 맞게 추가적인 함수와 구현이 있습니다.( 별로 안바뀌었음 )
Raon_WindowRingCmd
- Window_Command 를 참고해 만들었어요. 이부분은 링메뉴 핵심으로 위치 선정 및 동작이 구현되었습니다.
참고로 그냥은 쓸 수 없습니다. 1차 상속에 의한 오버라이드가 필요한 함수가 있습니다.
Raon_SrpgWindowPlayerCmd
- 이부분이 실제 Raon_WindowRingCmd 상속을 통해 구현을 한 스크립트 입니다.
오버라이드할 함수는
item_width, item_height, make_command_list, 세가지고
setup은 편의상 구현되어있는 함수로 있어도 그만 없으면 귀찮은 함수 입니다.
(VX Ace의 스크립트가 이런식으로 구현합니다, 범용적으로 바꾸기 귀찮아서 Ace 기존구현 룰을 따랐습니다. )
#==============================================================================
# ■ Raon_WindowSelectable
#------------------------------------------------------------------------------
# 기존 Window_Selectable 복제 - 불필요 부분 삭제 및 필요 부분 추가
#==============================================================================
class Raon_WindowSelectable < Window_Base
#--------------------------------------------------------------------------
# ● 공개 인스턴스 변수
#--------------------------------------------------------------------------
attr_reader :index # 커서 위치
attr_reader :help_window # 도움말 창
attr_accessor :cursor_fix # 커서 고정 플래그
attr_accessor :cursor_all # 커서 전체 선택 플래그
#--------------------------------------------------------------------------
# ● 오브젝트 초기화
#-------------------------------------------------------------------------
def initialize(x, y, width, height)
super
@index = -1
@handler = {}
@cursor_fix = false
@cursor_all = false
deactivate
end
#--------------------------------------------------------------------------
# ● 항목수
#--------------------------------------------------------------------------
def item_max
return 0
end
#--------------------------------------------------------------------------
# ● 항목의 너비
#--------------------------------------------------------------------------
def item_width
return 0
end
#--------------------------------------------------------------------------
# ● 항목 높이
#--------------------------------------------------------------------------
def item_height
return 0
end
#--------------------------------------------------------------------------
# ● 활성 상태 변경
#--------------------------------------------------------------------------
def active=(active)
super
update_cursor
call_update_help
end
#--------------------------------------------------------------------------
# ● 커서 위치 설정
#--------------------------------------------------------------------------
def index=(index)
@index = index
update_cursor
call_update_help
end
#--------------------------------------------------------------------------
# ● 항목 선택
#--------------------------------------------------------------------------
def select(index)
self.index = index if index
end
#--------------------------------------------------------------------------
# ● 항목의 선택 해제
#--------------------------------------------------------------------------
def unselect
self.index = -1
end
#--------------------------------------------------------------------------
# ● 항목을 그릴 사각형
#--------------------------------------------------------------------------
def item_rect(index)
rect = Rect.new
rect.width = item_width
rect.height = item_height
rect.x = 0
rect.y = index * item_height
rect
end
#--------------------------------------------------------------------------
# ● 항목을 그릴 사각형(텍스트)
#--------------------------------------------------------------------------
def item_rect_for_text(index)
rect = item_rect(index)
rect.x += 4
rect.width -= 8
rect
end
#--------------------------------------------------------------------------
# ● 도움말 창의 설정
#--------------------------------------------------------------------------
def help_window=(help_window)
@help_window = help_window
call_update_help
end
#--------------------------------------------------------------------------
# ● 동작에 대한 처리기 설정
# method : 처리기로 설정하는 메소드 (Method 개체)
#--------------------------------------------------------------------------
def set_handler(symbol, method)
@handler[symbol] = method
end
#--------------------------------------------------------------------------
# ● 처리기의 존재 확인
#--------------------------------------------------------------------------
def handle?(symbol)
@handler.include?(symbol)
end
#--------------------------------------------------------------------------
# ● 처리기 호출
#--------------------------------------------------------------------------
def call_handler(symbol)
@handler[symbol].call if handle?(symbol)
end
#--------------------------------------------------------------------------
# ● 커서의 이동 가능 판정
#--------------------------------------------------------------------------
def cursor_movable?
active && open? && !@cursor_fix && !@cursor_all && item_max > 0
end
#--------------------------------------------------------------------------
# ● 커서를 위로 이동
#--------------------------------------------------------------------------
def cursor_up(wrap = false)
end
#--------------------------------------------------------------------------
# ● 커서를 아래로 이동
#--------------------------------------------------------------------------
def cursor_down(wrap = false)
end
#--------------------------------------------------------------------------
# ● 커서를 왼쪽으로 이동
#--------------------------------------------------------------------------
def cursor_left(wrap = false)
end
#--------------------------------------------------------------------------
# ● 커서를 오른쪽으로 이동
#--------------------------------------------------------------------------
def cursor_right(wrap = false)
end
#--------------------------------------------------------------------------
# ● 프레임 갱신
#--------------------------------------------------------------------------
def update
super
process_cursor_move
process_handling
end
#--------------------------------------------------------------------------
# ● 커서 이동 작업
#--------------------------------------------------------------------------
def process_cursor_move
return unless cursor_movable?
last_index = @index
cursor_down (Input.trigger?(:DOWN)) if Input.repeat?(:DOWN)
cursor_up (Input.trigger?(:UP)) if Input.repeat?(:UP)
cursor_right(Input.trigger?(:RIGHT)) if Input.repeat?(:RIGHT)
cursor_left (Input.trigger?(:LEFT)) if Input.repeat?(:LEFT)
Sound.play_cursor if @index != last_index
end
#--------------------------------------------------------------------------
# ● 결정 나 취소 등을 핸들링 처리
#--------------------------------------------------------------------------
def process_handling
return unless open? && active
return process_ok if ok_enabled? && Input.trigger?(:C)
return process_cancel if cancel_enabled? && Input.trigger?(:B)
end
#--------------------------------------------------------------------------
# ● 결정 처리 유효 상태를 취득
#--------------------------------------------------------------------------
def ok_enabled?
handle?(:ok)
end
#--------------------------------------------------------------------------
# ● 취소 후 유효 상태를 취득
#--------------------------------------------------------------------------
def cancel_enabled?
handle?(:cancel)
end
#--------------------------------------------------------------------------
# ● 결정 버튼을 눌렀을 때의 처리
#--------------------------------------------------------------------------
def process_ok
if current_item_enabled?
Sound.play_ok
Input.update
deactivate
call_ok_handler
else
Sound.play_buzzer
end
end
#--------------------------------------------------------------------------
# ● 결정 처리기 호출
#--------------------------------------------------------------------------
def call_ok_handler
call_handler(:ok)
end
#--------------------------------------------------------------------------
# ● 취소 버튼을 눌렀을 때의 처리
#--------------------------------------------------------------------------
def process_cancel
Sound.play_cancel
Input.update
deactivate
call_cancel_handler
end
#--------------------------------------------------------------------------
# ● 취소 처리기 호출
#--------------------------------------------------------------------------
def call_cancel_handler
call_handler(:cancel)
end
#--------------------------------------------------------------------------
# ● 커서 업데이트
#--------------------------------------------------------------------------
def update_cursor
if @cursor_all
cursor_rect.set(0, 0, contents.width, contents.height)
elsif @index < 0
cursor_rect.empty
else
cursor_rect.set(item_rect(@index))
end
end
#--------------------------------------------------------------------------
# ● 도움말 윈도우 업데이트 메서드 호출
#--------------------------------------------------------------------------
def call_update_help
update_help if active && @help_window
end
#--------------------------------------------------------------------------
# ● 도움말 창 업데이트
#--------------------------------------------------------------------------
def update_help
@help_window.clear
end
#--------------------------------------------------------------------------
# ● 선택의 유효 상태를 취득
#--------------------------------------------------------------------------
def current_item_enabled?
return true
end
#--------------------------------------------------------------------------
# ● 모든 항목 그리기
#--------------------------------------------------------------------------
def draw_all_items
item_max.times {|i| draw_item(i) }
end
#--------------------------------------------------------------------------
# ● 항목 그리기
#--------------------------------------------------------------------------
def draw_item(index)
end
#--------------------------------------------------------------------------
# ● 항목 제거
#--------------------------------------------------------------------------
def clear_item(index)
contents.clear_rect(item_rect(index))
end
#--------------------------------------------------------------------------
# ● 항목을 다시 그리기
#--------------------------------------------------------------------------
def redraw_item(index)
clear_item(index) if index >= 0
draw_item(index) if index >= 0
end
#--------------------------------------------------------------------------
# ● 선택 항목을 다시 그리기
#--------------------------------------------------------------------------
def redraw_current_item
redraw_item(@index)
end
#--------------------------------------------------------------------------
# ● 백그라운드 그리기( 링메뉴 뒤에 그릴 무언가를 위해 )
#--------------------------------------------------------------------------
def draw_background
end
#--------------------------------------------------------------------------
# ● 재생
#--------------------------------------------------------------------------
def refresh
contents.clear
draw_background
draw_all_items
end
end
그리고 구현은
#==============================================================================
# ■ Raon_WindowRingCmd
#------------------------------------------------------------------------------
# 이건 링 메뉴요.
#==============================================================================
class Raon_WindowRingCmd < Raon_WindowSelectable
#--------------------------------------------------------------------------
# ● 객체 초기화
#--------------------------------------------------------------------------
def initialize(x, y, radius)
clear_command_list
make_command_list
@radius = radius
super(draw_x(x), draw_y(y), win_width, win_height)
refresh
select(0)
activate
end
#--------------------------------------------------------------------------
# ● 위치 재설정 ( 이건 중점임, 절대 윈도우의 표시 x,y, 좌표 아님. )
#--------------------------------------------------------------------------
def location(x, y)
move(draw_x(x), draw_y(y), win_width, win_height)
refresh
end
#--------------------------------------------------------------------------
# ● 실제 x좌표( 이건 그리기 시작하는 X 좌표, 기본적으로 화면 못넘어가게 막아놨음 )
#--------------------------------------------------------------------------
def draw_x(new_x)
return [[new_x - half_width, Graphics.width - half_width].min, 0].max
end
#--------------------------------------------------------------------------
# ● 실제 y좌표
#--------------------------------------------------------------------------
def draw_y(new_y)
return [[new_y - half_height, Graphics.height - half_height].min, 0].max
end
#--------------------------------------------------------------------------
# ● 링메뉴 x 좌표 ( 이건 링메뉴 표시 원점, 이점을 기준으로 회전함 )
#--------------------------------------------------------------------------
def ring_center_x
return radius + (item_width / 2)
end
#--------------------------------------------------------------------------
# ● 링메뉴 y 좌표
#--------------------------------------------------------------------------
def ring_center_y
return radius + (item_height / 2)
end
#--------------------------------------------------------------------------
# ● 반지름
#--------------------------------------------------------------------------
def radius
return @radius
end
#--------------------------------------------------------------------------
# ● 창 반토막 너비
#--------------------------------------------------------------------------
def half_width(peg_ring = true)
return ring_center_x + standard_padding if peg_ring
return win_width / 2
end
#--------------------------------------------------------------------------
# ● 창 반토막 높이
#--------------------------------------------------------------------------
def half_height(peg_ring = true)
return ring_center_y + standard_padding if peg_ring
return win_height / 2
end
#--------------------------------------------------------------------------
# ● 창 너비( ( 반지름 + 윈도우 패팅 ) * 2 + 아이템 너비 + 확장 너비 ) 높이도 마찬가지임
#--------------------------------------------------------------------------
def win_width
return (radius + standard_padding) * 2 + item_width + addon_width
end
#--------------------------------------------------------------------------
# ● 창 높이
#--------------------------------------------------------------------------
def win_height
return (radius + standard_padding) * 2 + item_height + addon_height
end
#--------------------------------------------------------------------------
# ● 아이템 너비
#--------------------------------------------------------------------------
def item_width
0
end
#--------------------------------------------------------------------------
# ● 아이템 높이
#--------------------------------------------------------------------------
def item_height
0
end
#--------------------------------------------------------------------------
# ● 확장 너비
#--------------------------------------------------------------------------
def addon_width
5
end
#--------------------------------------------------------------------------
# ● 확장 높이
#--------------------------------------------------------------------------
def addon_height
5
end
#--------------------------------------------------------------------------
# ● 항 목 수
#--------------------------------------------------------------------------
def item_max
@list.size
end
#--------------------------------------------------------------------------
# ● 명령 목록 지우기
#--------------------------------------------------------------------------
def clear_command_list
@list = []
end
#--------------------------------------------------------------------------
# ● 명령 목록 만들기
#--------------------------------------------------------------------------
def make_command_list
end
#--------------------------------------------------------------------------
# ● 명령 추가
# name : 이름
# symbol : 심볼
# icon : 아이콘
# enabled : 활성
#--------------------------------------------------------------------------
def add_command(name, symbol, icon = 0, enabled = true)
@list.push({:name=>name, :symbol=>symbol, :icon=>icon, :enabled=>enabled})
end
#--------------------------------------------------------------------------
# ● 명령 이름
#--------------------------------------------------------------------------
def command_name(index)
@list[index][:name]
end
#--------------------------------------------------------------------------
# ● 명령 심볼
#--------------------------------------------------------------------------
def command_symbol(index)
@list[index][:symbol]
end
#--------------------------------------------------------------------------
# ● 명령 활성?
#--------------------------------------------------------------------------
def command_enabled?(index)
@list[index][:enabled]
end
#--------------------------------------------------------------------------
# ● 명령 데이타
#--------------------------------------------------------------------------
def command_icon(index)
@list[index][:icon]
end
#--------------------------------------------------------------------------
# ● 선택 명령
#--------------------------------------------------------------------------
def current_data
index >= 0 ? @list[index] : nil
end
#--------------------------------------------------------------------------
# ● 선택 명령 활성?
#--------------------------------------------------------------------------
def current_item_enabled?
current_data ? current_data[:enabled] : false
end
#--------------------------------------------------------------------------
# ● 선택 명령 심볼
#--------------------------------------------------------------------------
def current_symbol
current_data ? current_data[:symbol] : nil
end
#--------------------------------------------------------------------------
# ● 선택 명령 데이타
#--------------------------------------------------------------------------
def current_icon
current_data ? current_data[:icon] : 0
end
#--------------------------------------------------------------------------
# ● 심볼로 명령 선택
#--------------------------------------------------------------------------
def select_symbol(symbol)
@list.each_index {|i| select(i) if @list[i][:symbol] == symbol }
end
#--------------------------------------------------------------------------
# ● 항목을 그릴 사각형 가져오기 ( 여기가 핵심 )
#--------------------------------------------------------------------------
def item_rect(index)
rect = Rect.new
rect.width = item_width
rect.height = item_height
deg = Math::PI * 1.5 / item_max
start_deg = -(deg * @index) + deg * index
new_x = Math.cos(start_deg) * radius
new_y = Math.sin(start_deg) * radius
rect.x = ring_center_x + new_x - (item_width / 2)
rect.y = ring_center_y + new_y - (item_height / 2)
rect
end
#--------------------------------------------------------------------------
# ● 항목을 그릴 사각형 가져오기 (텍스트)
#--------------------------------------------------------------------------
def item_rect_for_text(index)
rect = item_rect(index)
rect.x -= radius
rect.width = radius
rect
end
#--------------------------------------------------------------------------
# ● 아이템 그리기( 기본적으로 텍스트는 우측 중앙 선택 영역의 좌측으로 표시됨 )
#--------------------------------------------------------------------------
def draw_item(index)
change_color(normal_color, command_enabled?(index))
rect = item_rect(index)
draw_icon(command_icon(index), rect.x, rect.y)
if @index == index
draw_text(item_rect_for_text(index), command_name(index), alignment)
end
end
#--------------------------------------------------------------------------
# ● 커서를 위로 이동
#--------------------------------------------------------------------------
def cursor_up(wrap = false)
if index <= 0
return if !wrap
select(item_max - 1)
else
select(index - 1)
end
refresh
end
#--------------------------------------------------------------------------
# ● 커서를 아래로 이동
#--------------------------------------------------------------------------
def cursor_down(wrap = false)
if index >= item_max - 1
return if !wrap
select(0)
else
select(index + 1)
end
refresh
end
#--------------------------------------------------------------------------
# ● 커서를 왼쪽으로 이동( 좌 우 커서 쓰려면 이거랑 밑에꺼 구현하셈 )
#--------------------------------------------------------------------------
def cursor_left(wrap = false)
end
#--------------------------------------------------------------------------
# ● 커서를 오른쪽으로 이동
#--------------------------------------------------------------------------
def cursor_right(wrap = false)
end
#--------------------------------------------------------------------------
# ● 정렬
#--------------------------------------------------------------------------
def alignment
return 0
end
#--------------------------------------------------------------------------
# ● 결정 활성화
#--------------------------------------------------------------------------
def ok_enabled?
return true
end
#--------------------------------------------------------------------------
# ● 결정 호출
#--------------------------------------------------------------------------
def call_ok_handler
if handle?(current_symbol)
call_handler(current_symbol)
elsif handle?(:ok)
super
else
activate
end
end
#--------------------------------------------------------------------------
# ● 프레임 갱신
#--------------------------------------------------------------------------
def refresh
clear_command_list
make_command_list
create_contents
super
end
end
그리고 실제 사용은 상속해서 ( VX Ace 기본 룰에 맞춰 짜서 귀찮음 )
#==============================================================================
# ■ Raon_SrpgWindowPlayerCmd
#------------------------------------------------------------------------------
# 플레이어 커맨드 구현
#==============================================================================
class Raon_SrpgWindowPlayerCmd < Raon_WindowRingCmd
#--------------------------------------------------------------------------
# ● 객체 초기화
#--------------------------------------------------------------------------
def initialize(radius)
super(0, 0, radius)
self.opacity = 0
self.openness = 0
end
#--------------------------------------------------------------------------
# ● 아이템 너비
#--------------------------------------------------------------------------
def item_width
24
end
#--------------------------------------------------------------------------
# ● 아이템 높이
#--------------------------------------------------------------------------
def item_height
24
end
#--------------------------------------------------------------------------
# ● 명령 목록( 이거 중요 : 1번은 커맨드 이름, 2번은 키워드(핸들러 작성시 넣는거, 3번은 아이콘 인덱스, 4번은 활성이냐?)
#--------------------------------------------------------------------------
def make_command_list
add_command( 커맨드 이름, 키워드, 아이콘 인덱스, 활성이냐)
end
#--------------------------------------------------------------------------
# ● 정렬(이거 글자 정렬 기준임 0 왼쪽 1중앙 2왼쪽)
#--------------------------------------------------------------------------
def alignment
return 1
end
#--------------------------------------------------------------------------
# ● 초기화
#--------------------------------------------------------------------------
def setup
self.openness = 0
clear_command_list
make_command_list
select(0)
refresh
activate
open
end
#--------------------------------------------------------------------------
# ● 백그라운드 그리기(Raon_WindowSelectable에 함수 원형있음 오버라이드 해서 필요한거 그리면됨
#--------------------------------------------------------------------------
def draw_background
각자 구현( 위 스샷에 우측 네모 박스를 여기서 그렸음 )
end
end
이제 실제 사용은
@player_cmd = Raon_SrpgWindowPlayerCmd.new( 반지름 )
----------------------------------------------------------
핸들러 연결 하시고...( @player_cmd.set_handler(:move, method(:player_move)) << 요로코롬 생겨 먹은거
----------------------------------------------------------
@player_cmd.location( 센터 위치 X 좌표, 센터 위치 Y 좌표 )
@player_cmd.setup
@player_cmd.open
불펌, 막펌 그런거 없음 다 가져가도됩니다만 자기꺼라고 우기지 맙시다.
써니 소프트 선투척 후 투척...
PS : 쯔끄루 관련 커뮤니티는 몽창 다운됬네요? 이제 죽어가는 컨텐츤가 봐요 아쉽.