질문과 답변

Extra Form
엊그제 습작님께서 알려주신 '아이템선택창'을 써보다가, 몇 가지 벽에 부딪쳐서 관련 질문을 드리려고 합니다.
좀 여러 개라서 보다가 질리실지도... 모르겠지만...... 가능한 한 해결방안을 찾고 싶어서, 들고 왔습니다.

짜주신 스크립트를 커스텀하다가 부딪친 소소한 문제가 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
[질문]custom_window_align.png
이 부분은 제가 필요한 대로 만들어 넣어본 윈도우인데요(밝은부분).
아이템선택창에서 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하는 것들입니다)



질문이 너무 많아 죄송합니다. ㅠㅠ
하지만, 가능한 만큼만이라도 답을 얻어갈 수 있었으면 좋겠습니다.
Comment '2'
  • profile
    습작 2012.09.03 12:45

    0.

     

      조금 길긴 기네요.^^;;


      문 1 > 화면이 얼어버린 것이 아니라 생성한 배경 이미지가 해방되지 않았기 때문에 그런 것입니다. 배경 화면을 종료시 해방해 주시면 됩니다. 윈도우 쪽에서 해주어도 상관없지만, 윈도우와는 별개의 것인 만큼 이런건 씬처리 쪽에서 해주는 것이 좋습니다.


      문 2 > 헬프 윈도우를 변경하여 윈도우를 하나 제작하였는데 정렬문제로 고민하신다는 내용이군요.


      def set_text(text, align = 0)


      내용중 위와 같은 함수를 아래와 같이 수정하시면 됩니다.


      def set_text(text, align = 1)


      문 3 > 스위치는 둘다 잘 꺼지는 것이 정상입니다. 올려주신 스크립트를 돌려보았습니다만, 둘다 잘 꺼집니다.


      문 4 > 픽쳐를 표시하는 뷰포트의 z 값이 200입니다. 표시되는 윈도우들의 z값을 이보다 높게 설정하신다면 픽쳐보다 상위에 표시됩니다.



  • ?
    하진 2012.09.03 22:23
    !!!!
    알려주신 대로 봐서, 해결됐습니다.
    머리위에 느낌표가 마구 뜨는 기분이네요...

    문1> 맵배경은, back = dispose를 Scene쪽에 제자리 찾아 넣어주니까 딱 되네요.
    이걸 Window_쪽의 어디에 껴넣어야될지 몰라서 헤맸었는데... Scene에다 맞춰 넣는 거였군요.

    문2> align이 안 맞아보였던 이유는, 이제보니 창 위치를 너무 임의대로 바꿨기 때문이었던 것 같습니다. 원래 어디를 기준으로 중앙이 되는 건진 잘 모르겠지만 여튼... 앞쪽의 x,y값을 조금 조절하니까, 예쁘게 맞출 수 있었습니다.

    문3> 스위치가 안 꺼진다는 문제는.....ㅋㅋ 저 얼어버리는 문제때문에 디버그창을 볼 수가 없어서, 임시로 스위치에 따라 이벤트가 나타나게/사라지게 해놓고 그걸로 판별했었거든요. 근데 실제론 스위치가 OFF되어도 이벤트그래픽은 남아있었던 거더라고요.(F9해서 OFF된거 보고 오니까 사라져있었어요 ㅋㅋㅋ) 참.. 실없는 문제였네요...

    문4> 픽쳐는...ㅠㅠㅠㅠㅠㅠ 감격이빈다 이렇게나 간단한 문제였다니
    z란 게 대체 뭔가 했더니... 겹? 우선순위? 같은 거였군요. 이 부분은 뭔가 엄청난 수정이라도 필요할 줄 알았는데, z값 조정해주는 걸로 끝ㅋㅋ이라니ㅋㅋㅋㅋ 뭔가 횡재한 느낌이네요......ㅋㅋㅋㅋ 다행이에요 더 복잡해지지 않아도 되니까요ㅠㅠㅠㅠㅠ 고맙습니다 ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ

    덕분에 말끔하게 해결됐습니다.
    시스템구현의 짐 하나를 덜었네요. 이 긴 글을 다 읽고 답변해 주셨으니......ㅠㅠ
    시간이 되면 & 레핀님 허락까지 있으면 언제한번 커스텀된 걸 정리해서, 스크립트게시판에 올리든가 할게요. 물론 습작님이 괜찮으시다면요. ㅋㅋ
    스크립트 짜 주신 것도 감사한데 이 많은 질문에 답해주시고... 다시한번 감사드립니다. 스크립트 포함, 수정하면서 배운 부분들까지, 아주 유용하게 쓰일 것 같아요.

List of Articles
종류 분류 제목 글쓴이 날짜 조회 수
공지 묻고 답하기 가이드 습작 2014.06.14 12451
RMXP 타이틀 배경 노래바꾸는법 1 김빅밤 2010.09.19 1124
RMXP 캐릭터의 주위가 흰색이예요;; 4 file 흰고양이 2014.01.08 1124
RMXP 변수질문 1 Snow클라우드 2011.05.16 1123
RMXP XP 얼굴 상반신 그리는 프로그램좀 알려주세요 4 펀코우뤼 2014.01.03 1123
RMXP rmxp에서 직접 제작한 그림을 캐릭터&배틀러 그래픽으로 사용하고 싶은데 하는 방법좀 자세히 가르쳐 주세요. 8 창구 2014.01.05 1123
RMXP 자작 BGM은 못쓰나요? 1 잉재 2012.08.26 1119
RMXP 번역 에러인것 같은데 1 담먹캐 2011.02.18 1118
RMXP 쉐로오니칩,바퀴오니,오니 칩 1 사람맨의구원 2011.02.06 1115
RMXP 시간안에 하는 퀘스트! 1 ☆제나★ 2011.05.09 1114
RMXP 위력과 공격력은 뭐가 다른 건가요? 2 아미상 2012.07.03 1113
RMXP 메이플같이 퀘스트가 있으면 머리 위에 아이콘이 뜨는 스크립트를 구합니다. 3 ssbest1015 2010.12.11 1112
RMXP 그림의 표시를 처음 해봤더니 도저히 모르겠네요 3 네네네duyd 2012.09.03 1112
RMXP 배틀종류후 화면멈춤현상 2 캬아악 2012.09.14 1112
RMXP 캐릭터칩사이트 2 밀키웨이 2014.03.02 1110
RMXP 흐아아.. 맵칩 관련 질문 입니다. 4 미니쿠키 2011.01.22 1107
RMXP vx 맵 칩셋 4 박세한 2011.01.19 1104
RMXP xp시스템 데이터 읽기 실패 4 file 린네 2013.12.10 1104
RMXP 습작님의 Scene_Item_Select 관련질문 (픽쳐, 커스텀윈도우, 스위치, 정렬) 2 file 하진 2012.09.03 1103
RMXP 겹쳤을때 이벤트 발생하기 / 이벤트변수 참조법 질문입니다. 1 한우형 2012.11.01 1102
RMXP 이벤트로 아이템 획득후 시간이 지난후 다시 획득 가능하게 하는법... 5 도페로 2013.10.17 1102
Board Pagination Prev 1 ... 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 ... 90 Next
/ 90