Wybór Postaci / Character Select [XP]

 

screen character select

 

Autor: Ayene [ Ten adres pocztowy jest chroniony przed spamowaniem. Aby go zobaczyć, konieczne jest włączenie obsługi JavaScript. ]

Kompatybilność: RPG Maker XP

Krótki opis:

Skrypt pozwala na wybór postaci na początku gry. Może mieć również zastosowanie przy wyborze więcej niż jednego bohatera (maksymalnie tyle, ile może liczyć drużyna).

Instrukcja:

Wystarczy na początku gry wywołać za pomocą polecenia "Script" w zdarzeniu:

$scene = Scene_Character_Select.new

Jeśli chcesz, aby okno wyboru pojawiło się od razu po wyborze nowej gry:

Wejdź w klasę 'Scene_Title' i znajdź:

$scene = Scene_Map.new

zamień na:

$scene = Scene_Character_Select.new

Pamiętaj, aby w konfiguracji skryptu ustawić:

NEXT_SCENE = Scene_Map          # kolejna scena

Skrypt:

#==============================================================================
# Wybór postaci [XP]
# by Ayene
# 15.07.2011 ver 2.0
# www.ultimateam.pl
#==============================================================================
# Opis:
# Skrypt pozwala na wybór postaci na początku gry. Może mieć również
# zastosowanie przy wyborze więcej niż jednego bohatera (maksymalnie tyle,
# ile może liczyć drużyna).
#==============================================================================
# Instrukcja:
#==============================================================================
# Na początku gry wywołaj za pomocą polecenia "Script" w zdarzeniu:
# $scene = Scene_Character_Select.new
#
#==============================================================================
# Konfiguracja:
#==============================================================================

module AYENE
  module Character_Select
   
    # Ustawienia czcionki
    FONT_NAME = 'Comic Sans MS'    # nazwa czcionki (folder Fonts)
    FONT_SIZE = 26                 # rozmiar czcionki
    FONT_BOLD = false              # pogrubienie
    FONT_ITALIC = false            # kursywa   
    FONT_COLOR = Color.new(255, 255, 255, 255)   # kolor tekstu
    FONT_OUTLINE = true                          # obwódka? (true/false)   
    FONT_OUTLINE_COLOR = Color.new(0, 0, 0, 255) # kolor obwódki tekstu     
    FONT_SHADOW = true                          # cień? (true/false)
    FONT_SHADOW_COLOR = Color.new(0, 0, 0, 100)  # kolor cienia
     
    WLH = 32                        # interlinia
   
    # Ustawienia tła obrazkowego (folder Graphics/Pitures)   
    BACKGROUND_IMAGE = ''           # nazwa tła; '' wyłącza tło
    BACKGROUND_OPACTIY = 255    # przezroczystość tła
   
    # Ustawienia okna (folder Graphics/Windowskins)
    WINDOW = ''                              # nazwa pliku; '' domyślne okno
    WINDOW_OPACTIY = 255           # przezroczystość okna
    WINDOW_HELP_TEXT = 'Wybierz bohatera'
   
    # Ustawienia muzyki w tle
    STAGE_BGM = ''                  # nazwa pliku z muzyką (folder Audio/BGM)
    STAGE_BGM_VOLUME = 100          # głośność
       
    # Ustawienia postaci
    CHAR_IDS = [1, 5, 4, 2, 3, 6, 7, 8]  # ID postaci do wyboru
   
    # Obrazek bohatera. By go wyświetlić należy w folderze Graphics/Pictures
    # umieścić plik o nazwie "Face_ID", gdzie zamiast ID należy podać id postaci,
    # np. "Face_2" to obrazek bohatera o ID 2.
    CHAR_FACE = true                     # obrazek bohatera? (true/false)   
       
    # Ustawienia statystyk i ich pasków
    # Maksymalna wartość pasków wynosi tyle, ile największa wartość danej
    # statystyki u wszystkich postaci do wyboru. Innymi słowy, skrypt porównuje
    # wielkość danej statystyki u postaci, następnie wyłania najwyższą.
   
    CHAR_PARAMS = [ :hp, :sp, :str, :dex, :agi, :int ]  # nazwy statystyk po przecinku
   
    CHAR_PARAMS_BAR = { # :par => "nazwa", color1, color2
    :hp  => ["Życie", Color.new(0, 100, 17, 255), Color.new(0, 223, 37, 255)],
    :sp  => ["Mana", Color.new(0, 60, 95, 255), Color.new(0, 142, 223, 255)],
    :str => ["Siła", Color.new(140, 20, 20, 255), Color.new(230, 34, 34, 255)],
    :dex => ["Celność", Color.new(124, 38, 132, 255), Color.new(209, 62, 222, 255)],
    :agi => ["Szybkość", Color.new(142, 134, 12, 255), Color.new(228, 219, 71, 255)],
    :int => ["Inteligencja", Color.new(33, 143, 136, 255), Color.new(68,224, 215, 255)],
    }
   
    BAR_WIDTH = 150                 # Szerokość pasków   
    COLMUNS = 3                     # Liczba kolumn
   
    NEXT_SCENE = Scene_Map          # kolejna scena   
    PREVIOUS_SCENE = Scene_Title    # poprzednia scena
   
    MAX_MEMBER = 3        # maksymalna liczba bohaterów w drużynie
    DELCHAR_SWITCH = 4    # przełącznik włączający usuwanie bohaterów z drużyny
  end   
end

#==============================================================================
# ** Game_Party
#==============================================================================

class Game_Party
  attr_accessor   :actors                   # actors
end

#==============================================================================
# ** Scene_Character_Select
#==============================================================================

class Scene_Character_Select
  include AYENE::Character_Select
  #--------------------------------------------------------------------------
  # * Main Processing
  #--------------------------------------------------------------------------
  def main
    start
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    end
    Graphics.freeze
    terminate
  end
  #--------------------------------------------------------------------------
  # * Start processing
  #--------------------------------------------------------------------------
  def start
    @actor_id = 0
    if STAGE_BGM != ''
      Audio.bgm_play("Audio/BGM/" + STAGE_BGM, STAGE_BGM_VOLUME, 100)
    end
    if BACKGROUND_IMAGE != ''
      @background = Sprite.new
      @background.bitmap = RPG::Cache.picture(BACKGROUND_IMAGE)
      @background.opacity = BACKGROUND_OPACTIY
    end     
    @window_command = Window_Command_Select.new
    @window_help = Window_Char_Select_Help.new
  end
  #--------------------------------------------------------------------------
  # * Termination Processing
  #--------------------------------------------------------------------------
  def terminate
    @window_command.dispose
    @window_help.dispose
    unless @background.nil?
      @background.bitmap.dispose
      @background.dispose
    end   
    Audio.bgm_fade(1500) if STAGE_BGM != ''
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update   
    @window_command.update
    @window_help.update
    if Input.trigger?(Input::C)
      determine_character     
      $game_party.actors = [] if $game_switches[DELCHAR_SWITCH]
      if $game_party.actors.size < MAX_MEMBER   
        $game_party.add_actor(@actor_id)
        $game_system.se_play($data_system.decision_se)
        $scene = eval("#{NEXT_SCENE}.new")       
      else
        $game_system.se_play($data_system.buzzer_se)
      end
      return
    elsif Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      $scene = eval("#{PREVIOUS_SCENE}.new")
      return
    end   
  end
  #--------------------------------------------------------------------------
  # * Determine Character
  #--------------------------------------------------------------------------
  def determine_character
    actor_index = @window_command.index
    data = []     
    CHAR_IDS.each {|i| data.push(i) if !$game_party.actors.include?($game_actors[i])}   
    @actor_id = data[actor_index]
  end
end

#==============================================================================
# ** Window_Command_Select
#==============================================================================

class Window_Command_Select < Window_Selectable
  include AYENE::Character_Select
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize   
    super(0, 65, 640, 415)
    data = []
    CHAR_IDS.each {|i| data.push(i) if !$game_party.actors.include?($game_actors[i])}   
    @commands = data
    @_blink_count = 0
    @item_max = @commands.size
    @cursor_width = ((width-32) / COLMUNS)     
    self.windowskin = RPG::Cache.windowskin(WINDOW) if WINDOW != ''
    self.opacity = WINDOW_OPACTIY
    self.contents = Bitmap.new(@cursor_width+@item_max * @cursor_width-32, height-32)
    refresh
    self.index = 0
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear   
    @commands.each_index { |i| draw_item(i)}   
  end
  #--------------------------------------------------------------------------
  # * Draw Item
  #--------------------------------------------------------------------------
  def draw_item(index)
    x = 4 + @cursor_width * index
    y = 4     
    actor = $game_actors[@commands[index]]     
    draw_actor_status(actor, x, y)
    x = (@cursor_width-BAR_WIDTH)/2 + @cursor_width * index
    CHAR_PARAMS.each_index { |i|
      draw_actor_params(actor, x, y + @bit_height + WLH * (i+2), CHAR_PARAMS[i])
    }
  end
  #--------------------------------------------------------------------------
  # * Draw Actor Status
  #--------------------------------------------------------------------------
  def draw_actor_status(actor, x, y)   
    self.contents.font.size = FONT_SIZE
    self.contents.draw_char_status(x, y, @cursor_width - 8, WLH, "#{actor.name}", FONT_COLOR, 1)           
    if CHAR_FACE
      bitmap = RPG::Cache.picture("Face_#{actor.id}")   
      rect = Rect.new(0, 0, bitmap.width, bitmap.height)
      self.contents.blt(x + (@cursor_width-bitmap.width)/2, y + WLH * 1, bitmap, rect)   
      @bit_height = bitmap.height
      bitmap.dispose
    else
      @bit_height = 0
    end   
    self.contents.font.size = FONT_SIZE-2
    class_name = $data_classes[actor.class_id].name
    text = sprintf("Klasa: %s", class_name)   
    self.contents.draw_char_status(x, y + @bit_height + WLH, @cursor_width - 8, WLH, text, FONT_COLOR, 1)   
  end
  #--------------------------------------------------------------------------
  # * Draw Actor Parameters
  #--------------------------------------------------------------------------
  def draw_actor_params(actor, x, y, type)
    members = []
    @commands.each {|i| members.push($game_actors[i])}   
    case type
    when :hp   
      members.sort!   { |a, b| a.maxhp <=> b.maxhp }     
      gw = BAR_WIDTH * actor.hp / members.pop.maxhp
      text = "#{actor.maxhp}"
    when :sp
      members.sort!   { |a, b| a.maxsp <=> b.maxsp }     
      gw = BAR_WIDTH * actor.sp / members.pop.maxsp
      text = "#{actor.maxsp}"
    when :str
      members.sort!   { |a, b| a.str <=> b.str }
      gw = BAR_WIDTH * actor.str / members.pop.str
      text = "#{actor.str}"   
    when :dex
      members.sort!   { |a, b| a.dex <=> b.dex }
      gw = BAR_WIDTH * actor.dex / members.pop.dex
      text = "#{actor.dex}"
    when :agi
      members.sort!   { |a, b| a.agi <=> b.agi }
      gw = BAR_WIDTH * actor.agi / members.pop.agi
      text = "#{actor.agi}"   
    when :int
      members.sort!   { |a, b| a.int <=> b.int }
      gw = BAR_WIDTH * actor.int / members.pop.int
      text = "#{actor.int}"   
    end
    self.contents.fill_rect(x, y+WLH-8, BAR_WIDTH+2, 8, Color.new(0, 0, 0, 255))
    self.contents.gradient_fill_rect(x+1, y+WLH-7, gw, 6, CHAR_PARAMS_BAR[type][1], CHAR_PARAMS_BAR[type][2])     
    self.contents.draw_char_status(x, y, 100, WLH, CHAR_PARAMS_BAR[type][0], system_color, 0)
    self.contents.draw_char_status(x + BAR_WIDTH - 42, y, 44, WLH, text, FONT_COLOR, 2)
  end   
  #--------------------------------------------------------------------------
  # * Get Top Row
  #--------------------------------------------------------------------------
  def top_row   
    return self.ox / @cursor_width
  end
  #--------------------------------------------------------------------------
  # * Set Top Row
  #--------------------------------------------------------------------------
  def top_row=(row)   
    row = 0 if row < 0
    row = @item_max - 1 if row > @item_max - 1     
    self.ox = row * @cursor_width
  end
  #--------------------------------------------------------------------------
  # * Update Cursor Rectangle
  #--------------------------------------------------------------------------
  def update_cursor_rect     
    if @index < 0
      self.cursor_rect.empty
      return
    end   
    row = @index     
    self.top_row = row if row < self.top_row
    self.top_row = row - (COLMUNS - 1) if row > self.top_row + (COLMUNS - 1)
    x = @index * @cursor_width - self.ox
    y = 0         
    self.cursor_rect.set(x, y, @cursor_width, height-32)   
  end
  #--------------------------------------------------------------------------
  # * Frame Update
  #--------------------------------------------------------------------------
  def update
    super
    if self.active and @item_max > 0 and @index >= 0
      if Input.repeat?(Input::RIGHT)
        $game_system.se_play($data_system.cursor_se)       
        @index += 1
        @index %= @item_max
      end
      if Input.repeat?(Input::LEFT)
        $game_system.se_play($data_system.cursor_se)
        @index += @item_max - 1
        @index %= @item_max       
      end
    end   
    update_cursor_rect
  end   
end

#==============================================================================
# ** Window_Char_Select_Help
#==============================================================================

class Window_Char_Select_Help < Window_Base
  include AYENE::Character_Select
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    super(0, 0, 640, 64)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.windowskin = RPG::Cache.windowskin(WINDOW) if WINDOW != ''
    self.opacity = WINDOW_OPACTIY
    refresh
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear   
    self.contents.font.size = FONT_SIZE
    self.contents.draw_char_status(4, 0, width-32, WLH, WINDOW_HELP_TEXT, FONT_COLOR, 1)
  end
end

#==============================================================================
# ** Bitmap
#==============================================================================

class Bitmap
  include AYENE::Character_Select
  #--------------------------------------------------------------------------
  # * Draw Text Outline
  #--------------------------------------------------------------------------
  def draw_char_status(x, y, width, height, text, color, align = 1)
    font.name = FONT_NAME   
    font.bold = FONT_BOLD
    font.italic = FONT_ITALIC
    if FONT_OUTLINE
      font.color = FONT_OUTLINE_COLOR
      draw_text(x + 1, y, width, height, text, align)
      draw_text(x - 1, y, width, height, text, align)
      draw_text(x, y + 1, width, height, text, align)
      draw_text(x, y - 1, width, height, text, align)
    end   
    if FONT_SHADOW
      font.color = FONT_SHADOW_COLOR   
      draw_text(x + 1, y + 4, width, height, text, align)
    end
    font.color = color
    draw_text(x, y, width, height, text, align)
  end
  #--------------------------------------------------------------------------
  # * Draw Gradient Fill Rectangle
  #--------------------------------------------------------------------------
  def gradient_fill_rect(x, y, width, height, c1, c2)
    (x...x + width).each { |i|
      r = c1.red + (c2.red - c1.red) * (i - x) / (width - 1)
      g = c1.green + (c2.green - c1.green) * (i - x) / (width - 1)
      b = c1.blue + (c2.blue - c1.blue) * (i - x) / (width - 1)
      color = Color.new(r, g, b)
      fill_rect(i, y, 1, height, color)
      }   
  end
end

Dodatkowe informacje:

1. Wklej skrypt nad "Main" w Edytorze Skryptu.
2. Reszta instrukcji znajduje się w treści skryptu.