질문과 답변

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 12456
RMXP 맵을 넘어가도 따라오는 npc 질문 알피지가좋아요 2013.08.16 927
RMXP 맵을 만들엇는데 이동할수있는 공간이 못갈떄 해결방법;; 2 조규상 2011.05.29 1015
RMXP 맵을 복제해서 해당맵으로 이동하게하는법좀요 2 식빵족추장 2012.09.23 1212
RMXP 맵의 모든 이벤트를 조사 2 말짱꽝이지롱 2012.08.19 1290
RMXP 맵의 몬스터를 모두 해치우면 특정 이벤트 자동실행 4 라랍두 2013.01.29 1069
RMXP 맵이동 1 아저씨앙아앙라 2010.09.25 821
RMXP 맵이동 1 김윤아 2010.11.12 801
RMXP 맵이동시 맵 색조변경해제 방법 어떻게하나요? 4 소울상 2013.10.12 1008
RMXP 맵이름 스크립트의 표시를 사진표시보다 위로 하려면 어떻게 해야 하나요? 2 file 팥떡 2012.11.26 1000
RMXP 맵이름 표시 스크립트/맵이름을 사진표시보다 위로 설정하는법좀.. 1 소 울 2011.04.10 1426
RMXP 맵칩 2 크루즈 2011.02.08 579
맵배치 RMXP 맵칩 버그 ssplokks 2023.10.20 19
RMXP 맵칩 설정관련 백개의검 2011.02.13 731
RMXP 맵칩 수정하는 방법 좀 알려주세요. 1 배고픈 2011.12.17 1985
RMXP 맵칩 오류 떄문에요....... 꼭 부탁드립니다. 1 NightWolf 2010.12.30 451
RMXP 맵칩 우선순위 질문 4 file 삼팸스튜디오 2013.06.01 831
맵배치 RMXP 맵칩 이거저거 쓰고 싶어서 다른 타일셋의 칩을 합성하고 싶어요 1 아스리테 2022.03.04 227
RMXP 맵칩 적용법 2 폭풍강타 2013.08.17 1760
RMXP 맵칩과 기타 공백이 전부 검은색으로 변했어요 2 file 공개아이디 2011.07.02 2027
RMXP 맵칩셋 사용 방법좀 알려주세요. 1 file 곧이 2011.01.04 751
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