XP 스크립트

출처는 상입 오두막입니다. (http://aea.to/hako/)
사용법은 댓글로

#===============================================================================
# ■ Free_Window (ver.3.01)
# ------------------------------------------------------------------------------
# 메세지 윈도우·커멘드 윈도우를 표시
# ------------------------------------------------------------------------------
# 2005/07/29 by 상입 오두막 http://aea.to/hako/
#===============================================================================
class Free_Window < Window_Selectable
  #-----------------------------------------------------------------------------
  # 정수(값은 자유롭게 설정할 수 있습니다)
  #-----------------------------------------------------------------------------
  # 행간(pixel)
  LINE_SPACE = 10
  # 윈도우의 불투명도(0..255)
  OPACITY = 255
  # 윈도우 배경의 불투명도(0..255)
  BACK_OPACITY = 160
  # 폰트(Font)
  FONT = Font.new("MS P고딕", 22) # 폰트명, 사이즈    (★폰트명이 고딕과 다른경우 고치도록.)
  FONT.bold = false                      # 볼드(굵은 글씨) 플래그
  FONT.italic = false                    # 이탤릭(이탤릭) 플래그
  # 선택사항의 결과(항목 번호)를 대입하는 변수 ID($game_variables)
  RESULT = 1
  # 그래픽 참조 폴더
  GRA_DIR = "Graphics/"
  #-----------------------------------------------------------------------------
  # ● 오브젝트 초기화
  #-----------------------------------------------------------------------------
  def initialize(text, wx = 80, wy = 304, ww = 480, wh = 160)
    @command = text.is_a?(Array) ? true : false # 커멘드 플래그
    @text = text.dup
    # 커멘드
    if @command
      # 말미 요소가 "!cancel" 였던 경우
      if @text[-1] == "!cancel"
        @text.pop    # 말미 요소를 없앤다
        @cancel = true  # 캔슬 유효 플래그
      else
        @cancel = false
      end
      # 렬수를 설정
      if @text[0].is_a?(Integer) and @text[0] > 0
        col = @text[0]
        @text.shift  # 선두 요소를 삭제
      else
        col = 1
      end
      # 렬수의 조정
      col = @text.size if col > @text.size
      @cw = ww
      super(wx, wy, @cw, wh)
      @column_max = col # 렬수
      @disable = Array.new(@text.size) # 선택 불가 플래그의 배열
      @text.each_index {|i| @disable[i] = @text[i].gsub!(/^\[xX]|\[xX]$/, "") != nil}
      refresh_command(wh)
      self.index = 0
      @pause_show = false  # 포즈 싸인 표시 플래그
      self.visible = true
      @contents_showing = true  # 메세지 표시중 플래그
    # 메세지
    else
      super(wx, wy, ww, wh)
      self.contents = Bitmap.new(ww - 32, wh - 32)
      # "<NP>"(이)가 있으면 포즈 싸인을 비표시
      @pause_show = @text.gsub!(/<NP>/) { "" } == nil
      # "<IN>"(이)가 있으면 메세지를 순간 표시·순간 소거
      @fade_speed = @text.gsub!(/<IN>/) { "" } != nil ? 255 : 48
      # "<+>"(이)가 있으면, 직후의 개행을 무시한다
      @text.gsub!(/<+>n/) { "" }
      # "\mini[캐릭터 라인 or 엑터 번호]"가 있으면, 미니 윈도우를 표시
      @text.gsub!(/\mini[(.+)]/) { "" }
      mini_c = $1
      if mini_c != nil
        if mini_c.to_i > 0
        mini_c = $game_actors[mini_c.to_i].name
        end
        mini_window(mini_c, wx, wy)
      end
      # "\gra[파일명, 파일 번호]"가 있으면 그래픽을 표시
      @text.gsub!(/\gra[(.+),s*(d+)]/) { "" }
      if $1 != nil and $2 != nil
        window_graphic(GRA_DIR + $1, $2.to_i, wx, wy)
      else
        @graphic = false # 그래픽 표시 플래그
        @gw = 0
      end
      self.index = -1
      self.visible = false
      @contents_showing = false
    end
    self.z = 1000
    self.opacity = OPACITY
    self.back_opacity = BACK_OPACITY
    @fade_in = false
    @fade_out = false
    @next_page = false  # 개페이지 플래그
    @ww = ww
    @wh = wh
    update
  end
  #-----------------------------------------------------------------------------
  # ● 해방
  #-----------------------------------------------------------------------------
  def dispose
    return if self.disposed?
    self.pause = false
    # 윈두우와 메세지를 페이드아웃
    while(not @command and self.opacity > 0)
      Graphics.update
      self.contents_opacity -= 64
      self.opacity -= @fade_speed
      if @mini_win
        @mini_txt.opacity -= 64
        @mini_win.opacity -= @fade_speed
      end
      if @graphic
        @gr.opacity -= @fade_speed
      end
      self.opacity
    end
    @fade_out = false
    @contents_showing = false
    @next_page = false
    super()
    if @mini_win
      @mini_win.dispose
      @mini_txt.dispose
    end
    if @graphic
      @gr.dispose
      @grahic = false
    end
    if @command
      @command = false
      @cancel = false
    end
    $game_temp.message_window_showing = false
  end
  #-----------------------------------------------------------------------------
  # ● 리프레쉬 : 메세지 묘화 처리
  #-----------------------------------------------------------------------------
  def refresh
    self.contents.clear
    if Font.exist?(FONT.name)
      self.contents.font = FONT
    end
    self.contents.font.color = normal_color
    @graphic ? x = @gw : x = 0
    y = 0
    @text.gsub!(/\[Cc][([0-9]+)]/) { "01[#{$1}]" } # "\C[n]" => "01"
    @text.gsub!(/\[Ff]n/) { "02" }  # "\Fn" => "02"
    @text.gsub!(/\[Ff]/) { "02" }    # "\F" => "02"
    @text.gsub!(/\[Vv][(d+)]/){ ($game_variables[$1.to_i]).to_s }
    while ((c = @text.slice!(/./m)) != nil)
      if c == "01"
        @text.sub!(/[([0-9]+)]/, "")
        color = $1.to_i
        if color >= 0 and color <= 7
          self.contents.font.color = text_color(color)
        end
        next
      end
      # n 의 경우 : 개행 처리
      if c == "n"
        @graphic ? x = @gw : x = 0
        y += FONT.size + LINE_SPACE
        next
      end
      w = self.contents.text_size(c).width
      h = self.contents.text_size(c).height
      # \F or 문장이 하단까지 왔을 경우 : 개페이지
      if c == "02" or y >= @wh - ( FONT.size + 32)
        x = y = 0
        text = c == "02" ? "" : c
        while ((c = @text.slice!(/./m)) != nil)
          text += c # 개페이지 후의 캐릭터 라인
        end
        @text = text
        @next_page = true # 개페이지 플래그
        break
      else
        self.contents.draw_text(4 + x, y , w, h, c)
      end
      x += w
      # 문장이 우단까지 오면(자) 강제적으로 개행
      if x >= @ww - (FONT.size + 28)
        y += FONT.size + LINE_SPACE
        x = @graphic ? @gw : 0
      end
    end    # while [END]
  end
  #-----------------------------------------------------------------------------
  # ● 프레임 갱신
  #-----------------------------------------------------------------------------
  def update
    loop do
      Graphics.update
      Input.update
      super
      # 용명
      if @fade_in
        self.contents_opacity += @fade_speed
        if @graphic
          @gr.opacity += @fade_speed
        end
        if @mini_win
          @mini_txt.opacity += @fade_speed
        end
        if self.contents_opacity == 255
          @fade_in = false
        end
        next
      end
      if @contents_showing    # 메세지 표시중의 경우
        if @pause_show == true
          self.pause = true    # 포즈 싸인을 표시
        end
        # B (캔슬)
        if Input.trigger?(Input::B)
          if @command    # 커멘드
            $game_system.se_play($data_system.cancel_se)
            if @cancel  # 캔슬의 경우 한층 더 분기
              $game_variables[RESULT] = @text.nitems  # 요소수+1을 대입
              break
            end
            next
          end
          break
        end
        # C (결정)
        if Input.trigger?(Input::C)
          if @command    # 커멘드
            # 선택 불가
            if @disable[self.index]
              $game_system.se_play($data_system.buzzer_se)
            else
              $game_system.se_play($data_system.decision_se)
              $game_variables[RESULT] = self.index  # 항목 번호를 대입[0~n]
              break
            end
          else
            break
          end
        end
        next
      end    # if @contents_showing [END]
      # 페이드아웃중이 아니고, 표시 대기 메세지가 있다
      if @fade_out == false and @text != nil and not @command
        @contents_showing = true    # 메세지 표시중
        $game_temp.message_window_showing = true
        refresh
        Graphics.frame_reset
        self.visible = true
        self.contents_opacity = 0
        @fade_in = true
        next
      end
      # 표시해야 할 메세지가 없고, 윈도우가 가시 상태의 경우
      if self.visible
        @fade_out = true
        self.opacity -= 48
        if self.opacity == 0
          self.visible = false
          @fade_out = false
          $game_temp.message_window_showing = false
        end
        next
      end
    end    # loop do [END]
    # 개페이지
    if @next_page
      # 메세지만 페이드아웃
      while(self.contents_opacity > 0)
        Graphics.update
        self.contents_opacity -= @fade_speed
      end
      @fade_out = false
      @contents_showing = false
      @next_page = false  # 개페이지
      update
    end
    if @command    # 커멘드의 경우는 선택 후, 해방
      dispose
    end
  end
  #--------------------------------------------------------------------------
  # ● 커멘드 리프레쉬
  #--------------------------------------------------------------------------
  def refresh_command(ch)
    @item_max = @text.size
    self.contents = Bitmap.new(width - 32, height - 32)
    if Font.exist?(FONT.name)
      self.contents.font = FONT
    end
    for i in 0...@item_max
      self.contents.font.color = @disable[i] ? disabled_color : normal_color
      c = @text[i].dup
      c.gsub!(/\[Vv][(d+)]/){ ($game_variables[$1.to_i]).to_s }
      w = @cw / @column_max
      @ch = self.contents.text_size(c).height
      x = (i % @column_max) * w
      y = (i / @column_max) * (@ch + LINE_SPACE) + LINE_SPACE / 2
      self.contents.draw_text(x + 4, y, w, @ch, c, 0)
    end
  end
  #--------------------------------------------------------------------------
  # ● 커서의 구형 갱신
  #--------------------------------------------------------------------------
  def update_cursor_rect
    # 커서 위치가 0 미만의 경우
    if @index < 0
      self.cursor_rect.empty
      return
    end
    # 현재의 행을 취득
    row = @index / @column_max
    # 현재의 행이, 표시되고 있는 선두의 행보다 전의 경우
    if row < self.top_row
      # 현재의 행이 선두가 되도록(되듯이) 스크롤
      self.top_row = row
    end
    # 현재의 행이, 표시되고 있는 최후미의 행부터 뒤의 경우
    if row > self.top_row + (self.page_row_max - 1)
      # 현재의 행이 최후미가 되도록(되듯이) 스크롤
      self.top_row = row - (self.page_row_max - 1)
    end
    h = FONT.size + LINE_SPACE
    # 커서의 폭을 계산
    w = self.width / @column_max - h
    # 커서의 좌표를 계산
    x = @index % @column_max * (w + h)
    y = @index / @column_max * h - self.oy
    # 커서의 구형을 갱신
    self.cursor_rect.set(x, y, w, h)
  end
  #--------------------------------------------------------------------------
  # ● 미니 윈도우
  #--------------------------------------------------------------------------
  def mini_window(text, wx, wy)
    @text_mn = text
    @mini_txt = Sprite.new
    @mini_txt.z = 5000
    @mini_txt.bitmap = Bitmap.new(640, 480)
    b = @mini_txt.bitmap
    if Font.exist?(FONT.name)
      b.font = FONT
    end
    @cw = b.text_size(@text_mn).width
    @ch = b.text_size(@text_mn).height
    @cx = wx + 12
    @cy = wy - (@ch + 24) + 12
    b.clear
    b.draw_text(@cx, @cy, @cw, @ch, @text_mn, 0)
    @mini_txt.opacity = 0
    @mini_win = Window_Base.new(wx, wy, @cw + 24, @ch + 24)
    @mini_win.x = wx
    @mini_win.y = wy - (@ch + 24)
    @mini_win.z = 2000
    @mini_win.opacity = OPACITY
    @mini_win.back_opacity = BACK_OPACITY
  end
  #--------------------------------------------------------------------------
  # ● 그래픽
  #--------------------------------------------------------------------------
  def window_graphic(filename, number, wx, wy)
    @gr = Sprite.new
    @gr.bitmap = Bitmap.new(filename)
    @gw = @gr.bitmap.width
    gh = @gr.bitmap.height
    @gr.ox = 0
    @gr.oy = 0
    if (gnum = number - 1) >= 0  # 그래픽 번호(0-16)
      gx = (@gw / 4) * (gnum % 4)
      gy = (gh / 4) * (gnum / 4)
      @gw = @gw / 4
      gh = gh / 4
      @gr.src_rect.set(gx, gy, @gw, gh)  # 파일을 16 분할(4*4)해 표시
    else
      @gr.src_rect.set(0, 0, @gw, gh)  # 파일을 그대로 표시
    end
    @gr.x = wx + 16
    @gr.y = wy + 16
    @gr.z = 3000
    @gr.opacity = 0
    @graphic = true # 그래픽 표시 플래그
  end
end


스크립트가 표시되면(자),[Ctrl]+A,[Ctrl]+C로 전체를 카피합니다.
트크르 XP의 스크립트 편집자를 열어, 「Window_Selectable」보다 아래에서 오른쪽 클릭 메뉴 「삽입」,
새롭게 할 수 있던 섹션에 본체를 붙여 주세요.


사용예
────────────────────────────────────────────────
실행은 이벤트 커멘드 「스크립트」로 실시합니다.
이벤트가 정상적으로 실행되도록, 「스크립트」의 전후에는 「웨이트」(1 프레임)을 두는 것을 추천합니다.


■ 메세지 윈도우를 표시
┌────────────────────────┐
│w = Free_Window.new("abcde...", 80, 50, 304, 100) │
│w.dispose                   │
└────────────────────────┘

인수는 왼쪽으로부터 표시하는 캐릭터 라인, 윈도우 위치 x, 윈도우 위치 y, 윈도우폭, 윈도우 높이입니다.


────────────────────────────────────────────────

■ 복수의 메세지 윈도우를 표시
┌─────────────────────┐
│s = "메세지n메세지"           │
│w1 = Free_Window.new(s, 80, 50, 304, 120)  │
│s =                     │
│"메세지                   │
│메세지"                   │
│w2 = Free_Window.new(s, 80, 250, 304, 120) │
│w1.dispose                 │
│w2.dispose                 │
└─────────────────────┘

이 예에서는 캐릭터 라인을 한 번 로컬 변수 s에 격납해, 그것을 참조시키고 있습니다.
n는 개행을 나타내기 때문에, 결과적으로 어느 쪽의 윈도우도 같은 내용이 표시됩니다.


────────────────────────────────────────────────

(이하, 오브젝트 생성 등 같은 기술은 생략 합니다)
■ 좌상에 작은 윈도우를 표시

┌───────────┐
│"\mini[아르시스]「?"│
└───────────┘

제어 문자 \mini[s]는 캐릭터 라인 s를 미니 윈도우에 표시합니다.

┌────────┐
│"\mini[1]「···."│
└────────┘

숫자로 지정하면(자) 그 번호의 엑터명을 표시합니다.



───────────────────────────────────────────────

■ 윈도우에 그래픽 표시
┌──────────────────┐
│"\gra[Battlers/001-Fighter01, 0]「!" │
└──────────────────┘

제어 문자 \gra[filename, number]는, 지정한 그래픽 파일(filename)을 표시합니다.
또, , (반각 칸마)그리고 단락지어 표시 방법을 번호로 지정할 수 있습니다.
0 때, 지정한 화상을 그대로 표시합니다.
1~16 때, 화상을 세로 4 분할, 옆 4 분할했을 때에 할당해지는 번호에 일치하는 그래픽을 표시합니다.



────────────────────────────────────────────────

■ 커멘드 윈도우를 표시
┌──────────────────┐
│s = ["선택 1", "선택 2", "선택 3"]    │
│Free_Window.new(s, 80, 50, 150, 200) │
└──────────────────┘

제일 인수를 배열로 하면(자), 커멘드 윈도우가 됩니다.
커멘드 윈도우는 dispose를 호출할 필요는 없습니다.
선택한 결과는 소스내에서 지정한 번호의 변수에 대입됩니다.
이 예에서는 「선택 1」 때 0, 「선택 2」 때 1, 「선택 3」 때 2가 변수에 대입됩니다.

┌──────────────────┐
│["선택 1", "선택 2", "선택 3", "!cancel"] │
└──────────────────┘

배열의 말미의 요소를"!cancel"로 하면(자), 캔슬 버튼을 눌렀을 때에, 지정한 변수에 요소의 수가 대입됩니다.(이 예에서는 변수에 3을 대입)

┌─────────────────┐
│[3, "A1", "A2", "A3", "B1", "B2", "B3"]  │
└─────────────────┘

배열의 최초의 요소를 정수로 하면(자), 열을 복수로 할 수 있습니다. 이 예의 경우, 다음과 같은 및 됩니다.

A1  A2  A3
B1  B2  B3

┌────────────────────────────────┐
│["\x아르시스", "그로리아 \x", "히르다"]  #=> 히르다만 선택 가능 │
└────────────────────────────────┘

항목이 되는 캐릭터 라인의 최초인가 마지막에 「\x」인가 「\X」를 넣으면(자), 그 항목은 선택 불가(회색 표시/버저 SE)가 됩니다. 다만, 모든 항목을 선택 불가로 하면(자) 게임이 진행되지 않게 될테니 주의해 주세요.
「\x」는 바트(×)이니까 선택할 수 없다, 라고 기억합시다.

Who's 백호

?

이상혁입니다.

http://elab.kr

Comment '6'

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
공지 스크립트 자료 게시물 작성시 주의사항 습작 2012.12.24 6153
701 기타 Sphere Grid System file 백호 2009.02.21 765
700 전투 전투 관련 횟수 취득 스크립트 백호 2009.02.21 783
699 기타 Materia System file 백호 2009.02.21 749
698 이동 및 탈것 8방향움직임과 8방향 캐릭터칩 호환 2 file 백호 2009.02.21 2274
697 스킬 [KGC] Skill Grouping 백호 2009.02.21 861
696 파티 Party & Class Changing script 1 file 백호 2009.02.21 962
695 맵/타일 World Map 스크립트 1 file 백호 2009.02.21 1983
694 기타 액터 선택 스크립트 2 백호 2009.02.21 1228
693 장비 Multi-equip script 2 file 백호 2009.02.21 1101
692 스킬 [KGC] 다단공격 (즉, 여러번 공격하는 스킬) 10 백호 2009.02.21 2817
691 기타 [KGC] 개요 스크립트 2 백호 2009.02.21 1049
690 장비 장비착용시 올스탯 표시 2 file 백호 2009.02.21 1664
689 스킬 스킬 도감 1 백호 2009.02.21 1138
» 기타 프리 윈도우 스크립트 (상입오두막 출처) 6 백호 2009.02.21 1449
687 기타 스크립트로 프리윈도우 예제 4 file 백호 2009.02.21 812
686 기타 killer님 요청하신 스크립트 두번째입니다. 나뚜루 2009.02.21 759
685 전투 SBABS게이지바 file 백호 2009.02.21 2285
684 기타 Anti Event Lag Script 3 백호 2009.02.21 1057
683 기타 시작하자 마자 풀 스크린 2 백호 2009.02.21 1082
682 기타 AMS-Advanced Message Script Edited by Dubleax 3 file 백호 2009.02.21 765
Board Pagination Prev 1 ... 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 ... 52 Next
/ 52