엊그제 습작님께서 알려주신 '아이템선택창'을 써보다가, 몇 가지 벽에 부딪쳐서 관련 질문을 드리려고 합니다.
좀 여러 개라서 보다가 질리실지도... 모르겠지만...... 가능한 한 해결방안을 찾고 싶어서, 들고 왔습니다.
짜주신 스크립트를 커스텀하다가 부딪친 소소한 문제가 3가지, 그 외의 것이 1가지입니다.
우선... 그 외의 것부터 말씀드릴게요.
제가 이 '아이템선택창'을... 픽쳐로 덮인 화면 위에 표시하려고 하거든요.
이 Scene_Item_Select를, 모든 픽쳐보다 상위에 표시되도록 할 수 있을까요?
(특수한 메뉴화면 중에서, 스크립트로 구현하기 너무 까다로워질 부분을 그냥 픽쳐+이벤트로 픽쳐메뉴를 만들어뒀거든요.
그 픽쳐메뉴에서의 선택에 따라, 이어지게 할 것이 이 Scene_Item_Select입니다.
근데 지금 픽쳐메뉴에서 이 Scene을 호출하면, 픽쳐들에 덮여서 아이템선택창이 안 보이게 됩니다.)
픽쳐들을 캐릭터셋 밑으로 깔리게 하는 스크립트는 본 적이 있는데, 그런 식으로 윈도우들 밑에 깔리도록 할 수도 있을까요..?
그리고, 이하는... 커스텀하다 부딪친 소소한 3가지입니다.
일단 제가 수정하느라 추가한 모든 부분을 회색글씨,(좌표 등 수치는 제외)
그 중 문제1) 관련부분을 분홍색글씨, 행끝에 #1
문제2) 관련부분을 하늘색글씨, 행끝에 #2
문제3) 관련부분을 보라색글씨, 행끝에 #3 을 붙여보겠습니다.
(회색글씨는 문제가 없었던 부분)
(이하 추가로 붙인 스크립트)
class Window_Guide < Window_Base
#--------------------------------------------------------------------------
# ● 오브젝트 초기화
#--------------------------------------------------------------------------
def initialize
super(180, 72, 280, 58)
self.contents = Bitmap.new(width - 32, height - 32)
self.back_opacity = 200
self.contents.font.color = normal_color
self.contents.font.size = 21
refresh
end
#--------------------------------------------------------------------------
def refresh
self.contents.clear
if $game_switches[27]
self.contents.draw_text(0, 0, 280, 32, "먹이로 줄 것을 선택하세요.", 1) #2
end
if $game_switches[51]
self.contents.draw_text(0, 0, 280, 32, "올려둘 물건을 선택하세요.", 1) #2
end
end
end
(이상 추가로 붙인 스크립트)
(이하 수정한 스크립트)
#==============================================================================
# ★ 아이템 선택 시스템 ★ 2009.1.29
#==============================================================================
# 제작자 : lepin@naver.com
#==============================================================================
# 수 정 : etude87@gmail.com
#==============================================================================
#
# 호출 : $scene = Scene_Item_Select.new("속성의 이름", 변수번호[, 소비여부])
#
# 예> $scene = Scene_Item_Select.new("화염", 1, true)
#
# 소비여부는 생략 가능(생략시 false)
#
#==============================================================================
#
# 아이템일 경우 : 변수 값 = 아이템의 ID
# 무기일 경우 : 변수 값 = 무기의 ID + 1000
# 방어구일 경우 : 변수 값 = 방어구의 ID + 2000
# 선택하지 않을 경우 : 변수 값 = 0
#
#==============================================================================
class Window_Item_Select < Window_Selectable
#--------------------------------------------------------------------------
def initialize(elements)
back = Spriteset_Map.new #1
@elements = elements
super(120, 120, 400, 264)
self.back_opacity = 200
@column_max = 2
refresh
self.index = 0
end
#--------------------------------------------------------------------------
def item
return @data[self.index]
end
#--------------------------------------------------------------------------
def refresh
if self.contents != nil
self.contents.dispose
self.contents = nil
end
@data = []
for i in 1...$data_items.size
if $game_party.item_number(i) > 0
if $data_items[i].element_set.include?($data_system.elements.index(@elements))
@data.push($data_items[i])
end
end
end
for i in 1...$data_weapons.size
if $game_party.weapon_number(i) > 0
if $data_weapons[i].element_set.include?($data_system.elements.index(@elements))
@data.push($data_weapons[i])
end
end
end
for i in 1...$data_armors.size
if $game_party.armor_number(i) > 0
if $data_armors[i].guard_element_set.include?($data_system.elements.index(@elements))
@data.push($data_armors[i])
end
end
end
@item_max = @data.size
if @item_max > 0
self.contents = Bitmap.new(width - 32, row_max * 32)
for i in 0...@item_max
draw_item(i)
end
end
end
#--------------------------------------------------------------------------
def draw_item(index)
item = @data[index]
case item
when RPG::Item
number = $game_party.item_number(item.id)
when RPG::Weapon
number = $game_party.weapon_number(item.id)
when RPG::Armor
number = $game_party.armor_number(item.id)
end
self.contents.font.color = normal_color
x = 4 + index % 2 * (160 + 40)
y = index / 2 * 32
rect = Rect.new(x, y, self.width / @column_max - 32, 32)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
bitmap = RPG::Cache.icon(item.icon_name)
opacity = self.contents.font.color == normal_color ? 255 : 128
self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
self.contents.draw_text(x + 32, y, 212, 32, item.name, 0)
self.contents.draw_text(x + 120, y, 16, 32, ":", 1)
self.contents.draw_text(x + 120+16, y, 16, 32, number.to_s, 2)
end
end
#==============================================================================
#==============================================================================
class Scene_Item_Select
#--------------------------------------------------------------------------
def initialize(elements, item_variable, item_lose = false)
@elements = elements
@item_variable = item_variable
@item_lose = item_lose
end
#--------------------------------------------------------------------------
def main
@item_window = Window_Item_Select.new(@elements)
if $game_switches[27]
s1 = "먹이로 준다"
s2 = "그만둔다"
else
if $game_switches[51]
s1 = "올려놓는다"
s2 = "그만둔다"
else
s1 = "선택한다"
s2 = "그만둔다"
end
end
@command_window = Window_Command.new(160, [s1, s2], 1)
@command_window.y = 240 - @command_window.height / 2
@command_window.x = 320 - @command_window.width / 2
@command_window.y = 360
@command_window.visible = false
@command_window.active = false
@guide_window = Window_Guide.new ###
@guide_window.visible = true ###
Graphics.transition
loop do
Graphics.update
Input.update
update
if $scene != self
break
end
end
Graphics.freeze
@item_window.dispose
@command_window.dispose
@guide_window.dispose ###
end
#--------------------------------------------------------------------------
def update
@item_window.update
@command_window.update
@guide_window.update ###
if @item_window.active
update_item
return
end
if @command_window.active
update_command
return
end
end
#--------------------------------------------------------------------------
def update_item # 취소하고 맵 귀환시
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
$game_variables[@item_variable] = 0
@guide_window.visible = false ###
$game_switches[27] = false # [관리화면_Food]OFF #3
$game_switches[51] = false # [책상위_Stuff]OFF #3
$scene = Scene_Map.new
return
end
if Input.trigger?(Input::C)
@item = @item_window.item
unless @item.is_a?(RPG::Item) or @item.is_a?(RPG::Weapon) or @item.is_a?(RPG::Armor)
$game_system.se_play($data_system.buzzer_se)
return
end
$game_system.se_play($data_system.decision_se)
@item_window.active = false
@command_window.index = 0
@command_window.visible = true
@command_window.active = true
@guide_window.visible = true ###
return
end
end
#--------------------------------------------------------------------------
def update_command
@command_window.update
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
@item_window.active = true
@command_window.visible = false
@command_window.active = false
@guide_window.visible = true ###
return
end
if Input.trigger?(Input::C) # 선택하고 맵 귀환시
case @command_window.index
when 0
$game_system.se_play($data_system.decision_se)
case @item
when RPG::Item
value = 0
if @item_lose == true
$game_party.lose_item(@item.id, 1)
end
when RPG::Weapon
value = 1000
if @item_lose == true
$game_party.lose_weapon(@item.id, 1)
end
when RPG::Armor
value = 2000
if @item_lose == true
$game_party.lose_armor(@item.id, 1)
end
end
$game_variables[@item_variable] = @item.id + value
$game_switches[27] = false # [관리화면_Food]OFF #3
$game_switches[51] = false # [책상위_Stuff]OFF #3
$scene = Scene_Map.new
when 1
$game_system.se_play($data_system.decision_se)
@item_window.active = true
@command_window.visible = false
@command_window.active = false
@guide_window.visible = true ###
end
return
end
if Input.trigger?(Input::UP) or Input.trigger?(Input::L)
@command_window.index = 0
end
if Input.trigger?(Input::DOWN) or Input.trigger?(Input::R)
@command_window.index = 1
end
end
end
(이상 수정한 스크립트)
(이하 문제설명)
문제1) #1
이 아이템선택창이 뜨는 동안에, 뒷배경이 검은색이 되지 않고 여태까지의 맵화면이 남아있게 하기 위해서
def initialize(elements) 밑에
back = Spriteset_Map.new
를 넣었거든요. (다른 스크립트에서 복붙했습니다..)
그랬더니 의도대로 배경에 맵화면이 유지됐습니다.
그런데 아이템을 선택하거나 / ESC로 창을 취소한 뒤, 다시 Scene을 호출했더니 게임이 얼어버려요.
또 ESC를 눌러서 메뉴화면을 보려고 해도 얼어버리고요. F9(디버그) 불러도 마찬가지...
뭔가 더 넣어줘야 하는 것 같은데...... 뭐가 더 필요한 건가요?
문제2) #2
이 부분은 제가 필요한 대로 만들어 넣어본 윈도우인데요(밝은부분).
아이템선택창에서 help_window(아이템설명 뜨는) 대신에, guide_window를 넣어서 '***를 선택하세요' 문구만 계속 떠있도록 한 겁니다. 뜨고 없어지고는 어떻게 잘 되는 것 같은데...
근데 이...... 글자를 좀, 멀쩡하게 가운데정렬할 수 없을까요?;;
커맨드윈도우에 뜨는 글자의 경우, 가운데정렬을 했습니다. Window_Command쪽에 @=align을 추가해서요.
근데 커맨드윈도우가 아닌 경우는... 어떻게 바꿔야 align이 적용되게 할 수 있을지 모르겠네요.
Window_Base쪽을 만져야 되는 게 아닌가 싶은데, Command쪽하곤 생긴 모양도 다르고... 이렇게저렇게 바꿔봐도 오류만 뜰 뿐이고...... 끝에 1 붙였더니, 저모양으로 뜨고......
이런 커스텀윈도우에서도, 가운데정렬을 하고 싶어요... (메시지창의 경우, 사용중인 메시지스크립트에서 지원해줘서 괜찮지만 이건...)
문제3) #3
$game_switches[27] = false # [관리화면_Food]OFF
$game_switches[51] = false # [책상위_Stuff]OFF
$scene = Scene_Map.new
이 부분 말인데요. (아이템선택시 / 창 취소시, 특정스위치 끄는 것)
첫 행의 스위치는 잘 꺼지는데, 둘째 행의 스위치는 안 꺼집니다.;;
원래 이런가요? 스위치는 한 번에 1개밖에 조작 못하나요??? (어찌 그런...)
2개 다 끄려면 뭐라고 써야 할까요.
(저 스위치들은 guide_window / s1,s2에 문구를 달리하기 위해, Scene호출 전 상황별로 ON하는 것들입니다)
질문이 너무 많아 죄송합니다. ㅠㅠ
하지만, 가능한 만큼만이라도 답을 얻어갈 수 있었으면 좋겠습니다.