Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.
Conectarse

Recuperar mi contraseña

Últimos temas
» Gameplay - Mansión Rybi - RMVXA.
por Miky Joe 2018-12-10, 08:36

» The Town of The Lost Witch [Horror/Suspense] - Enero 2019
por rstudios 2018-12-10, 01:20

» muchas dudas
por DiegoArancibia 2018-12-09, 16:55

» Galería Miky Art [Bocetos y más]
por Miky Joe 2018-12-09, 09:16

» Hemos vuelto
por alex1633 2018-12-08, 23:17

» [MV] Precognition
por franciscojapones 2018-12-08, 07:06

» (AJUDA) Conpatibilidade de 2 scripts simples
por orochii 2018-12-08, 03:14

» ("TCG") Que RPG Maker es el recomendado?
por orochii 2018-12-08, 03:03

» BOAS VINDAS
por orochii 2018-12-08, 02:58

» Script de mensaje de Wecoc
por orochii 2018-12-07, 23:43

Afiliados

[XP] Wecoc's Letter by Letter

Ver el tema anterior Ver el tema siguiente Ir abajo

RPG Maker XP [XP] Wecoc's Letter by Letter

Mensaje por Wecoc el 2014-06-25, 01:17

Sí, he hecho un Letter by Letter, inspirado un poco en la idea que Pokepik dió hace tiempo en el topic de ideas.

Antes de nada, cuatro cosas:

1) Para quien no lo sepa, un Letter by Letter es una modificación del efecto del texto en la ventana de mensaje. Si Letter by Letter está activado el texto va apareciendo letra por letra, mientras que si no aparece de golpe.
2) Es imposible pasar ésto a VX o VX Ace sin hacer otro script completamente distinto, y no lo haré.
3) Hay muchos Letter by Letter 723.5 veces mejores que éste para XP. La diferencia es que yo lo hice de otra forma de modo que permite efectos que los demás no pueden tener.
4) Sí, pido créditos. Pero os dejo modificarlo como queráis, y os animo a publicar aquí vuestras mejoras al script, como nuevos tipos de efecto y cosas así. Si lo hacéis seréis añadidos en los agradecimientos del script.

Código:
#==============================================================================
# Wecoc's Letter by Letter 1.0
#==============================================================================
# Autor: Wecoc
#==============================================================================
# * Tipos de letter_mode:
#
# - Default
# - Letter by Letter
# - Word by Word
# - Scroll Right / Left
# - Scroll Right / Left [D]
# - Zig-Zag
#
#==============================================================================

# Nuevas variables en Game_System

class Game_System
 
  attr_accessor :letter_mode
  attr_accessor :letter_speed
  attr_accessor :letter_can_skip
 
  alias lbl_wecoc_ini initialize unless $@
  def initialize
    lbl_wecoc_ini
    @letter_mode = "Default"  # Los tipos se definen dentro de define_mode
    @letter_speed = 6        # Velocidad del texto; Máximo : 6
    @letter_can_skip = true  # Indica si el texto se puede saltar con Enter
  end
end

# Modificación de Window_Message

class Window_Message < Window_Selectable
 
  alias lbl_wecoc_ini initialize unless $@
  def initialize
    lbl_wecoc_ini
    @wait_count = 0  # Tiempo de espera del texto
    @text_array = []  # Texto a escribir con información por carácter
    @line_0 = []      # Primera línea de @text_array
    @line_1 = []      # Segunda línea de @text_array
    @line_2 = []      # Tercera línea de @text_array
    @line_3 = []      # Cuarta  línea de @text_array
  end

  def define_mode
    @auto = false              # El texto aparece directamente
    @timing = false            # Efecto por tiempo activado
    @scroll = "None"            # Tipo de scroll, por defecto "None"
    @no_spaceship = false      # No considera espacios al dibujar
    @by_words = false          # El texto se lee palabra por palabra
    @by_lines = false          # Va por líneas
    @line_0_scroll = "None"    # Tipo de scroll, por defecto "None"
    @line_1_scroll = "None"    # Tipo de scroll, por defecto "None"
    @line_2_scroll = "None"    # Tipo de scroll, por defecto "None"
    @line_3_scroll = "None"    # Tipo de scroll, por defecto "None"
    @line_0_delay = 0          # Tiempo de espera extra para iniciar efecto
    @line_1_delay = 0          # Tiempo de espera extra para iniciar efecto
    @line_2_delay = 0          # Tiempo de espera extra para iniciar efecto
    @line_3_delay = 0          # Tiempo de espera extra para iniciar efecto
    @wait_lines = false        # Dice si los efectos por línea son simultáneos
   
    # Activación de variables según tipo de efecto.
    # Puedes añadir los que quieras
   
    case $game_system.letter_mode
    # Aparece el texto de golpe como siempre
    when "Default"     
      @auto = true
   
   
    when "Letter by Letter"
    # Aparece el texto letra por letra en orden, como en los scripts de éste tipo
      @timing = true
      @scroll = "Right"
      @no_spaceship = true
     
    when "Word by Word"
    # Aparece el texto palabra por palabra en orden
      @timing = true
      @scroll = "Right"
      @by_words = true
     
    when "Scroll Right"
    # Es como el Letter by Letter pero todas las líneas a la vez
    # Se va rellenando de izquierda a derecha
      @timing = true
      @by_lines = true
      @line_0_scroll = "Right"
      @line_1_scroll = "Right"
      @line_2_scroll = "Right"
      @line_3_scroll = "Right"
     
    when "Scroll Left"
    # Es como el Letter by Letter pero todas las líneas a la vez
    # Se va rellenando de derecha a izquierda
      @timing = true
      @by_lines = true
      @line_0_scroll = "Left"
      @line_1_scroll = "Left"
      @line_2_scroll = "Left"
      @line_3_scroll = "Left"
           
    when "Scroll Right [D]"
    # Es como el Scroll Right pero permite hacer que no todas las líneas
    # empiecen justo al mismo tiempo
      @timing = true
      @by_lines = true
      @line_0_scroll = "Right"
      @line_1_scroll = "Right"
      @line_2_scroll = "Right"
      @line_3_scroll = "Right"
      @line_0_delay = 0
      @line_1_delay = 10
      @line_2_delay = 20
      @line_3_delay = 30
   
    when "Scroll Left [D]"
    # Es como el Scroll Left pero permite hacer que no todas las líneas
    # empiecen justo al mismo tiempo
      @timing = true
      @by_lines = true
      @line_0_scroll = "Left"
      @line_1_scroll = "Left"
      @line_2_scroll = "Left"
      @line_3_scroll = "Left"
      @line_0_delay = 0
      @line_1_delay = 10
      @line_2_delay = 20
      @line_3_delay = 30
   
    when "Zig-Zag"
    # Es como el Letter by Letter pero con un efecto de ida y vuelta
      @timing = true
      @by_lines = true
      @line_0_scroll = "Right"
      @line_1_scroll = "Left"
      @line_2_scroll = "Right"
      @line_3_scroll = "Left"
      @wait_lines = true

    # when ...
   
    end
  end

  def refresh
    # Definir las variables según el $game_system.letter_mode
    define_mode
    # Refresh por defecto
    self.contents.clear
    self.contents.font.color = normal_color
    x = y = 0
    @wait_count = 0
    @cursor_width = 0
    if $game_temp.choice_start == 0
      x = 8
    end
    if $game_temp.message_text != nil
      text = $game_temp.message_text
      # Sustituciones de los carácteres especiales de los textos (por defecto)
      begin
        last_text = text.clone
        text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] } # \v[id]
      end until text == last_text
      text.gsub!(/\\[Nn]\[([0-9]+)\]/) do # \n[id]
        $game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : ""
      end
      text.gsub!(/\\\\/) { "\000" } # \\
      text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" } # \c[id]
      text.gsub!(/\\[Gg]/) { "\002" } # \G
      while ((c = text.slice!(/./m)) != nil)
        if c == "\000"
          c = "\\"
        end
        if c == "\001" # Cambiar color
          text.sub!(/\[([0-9]+)\]/, "")
          color = $1.to_i
          if color >= 0 and color <= 7
            self.contents.font.color = text_color(color)
          end
          next
        end
        if c == "\002" # Mostrar ventana de dinero
          if @gold_window == nil
            @gold_window = Window_Gold.new
            @gold_window.x = 560 - @gold_window.width
            if $game_temp.in_battle
              @gold_window.y = 192
            else
              @gold_window.y = self.y >= 128 ? 32 : 384
            end
            @gold_window.opacity = self.opacity
            @gold_window.back_opacity = self.back_opacity
          end
          next
        end
        if c == "\n" # Salto de línea
          if y >= $game_temp.choice_start
            @cursor_width = [@cursor_width, x].max
          end
          y += 1
          x = 0
          if y >= $game_temp.choice_start
            x = 8
          end
          next
        end
        # Definir el texto en una nueva variable para poder escribirlo luego
        @text_array.push([c, x, y, self.contents.font.color.clone])
        x += self.contents.text_size(c).width
      end
    end
   
    # Si el texto tiene que mostrarse ya ("Default") se muestra
    if @auto
      skip
    end
   
    # Si no consideran los espacios, son eliminados
    if @no_spaceship
      @text_array.reject!{|array| array[0] == " "}
    end
   
    # Si el letter by letter va por palabras, se alteran los valores de la
    # array de modo que en vez de ser un carácter sean los de toda la palabra
    if @by_words
      @text_array = @text_array.letter_to_word
    end
   
    # Si el efecto va por líneas se definen según la y del texto
    if @by_lines
      @line_0 = @text_array.select{|array| array[2] == 0}
      @line_1 = @text_array.select{|array| array[2] == 1}
      @line_2 = @text_array.select{|array| array[2] == 2}
      @line_3 = @text_array.select{|array| array[2] == 3}
      # Excepto si no se consideran espacios, se llenan las líneas con espacios
      # de modo que todas tengan el mismo tamaño para poder cuadrar mejor los
      # efectos
      unless @no_spaceship
        max = [@line_0.size, @line_1.size, @line_2.size, @line_3.size, 1].max
        @line_0.fill_letters(max)
        @line_1.fill_letters(max)
        @line_2.fill_letters(max)
        @line_3.fill_letters(max)
      end
      # Para el efecto de delay se añaden espacios extra al principio o final
      # de esa línea según su dirección de scroll
      lines = [@line_0, @line_1, @line_2, @line_3]
      scrolls = [@line_0_scroll, @line_1_scroll,
                @line_2_scroll, @line_3_scroll]
      delays = [@line_0_delay, @line_1_delay,
                @line_2_delay, @line_3_delay]
      for i in 0...lines.size
        line = lines[i]
        scroll = scrolls[i]
        delay = delays[i]
        if line.size != 0 and delay >= 0
          case scroll
          when "Right"
            s = line[0]
            delay.times do
              line.unshift([" ", s[1], s[2], s[3]])
            end
          when "Left"
            s = line[-1]
            delay.times do
              line.push([" ", s[1], s[2], s[3]])
            end
          end
        end
      end
    end
   
    # Si el texto no es nulo, se empieza a escribir el texto
    @writing = (@text_array.size > 0)
   
    # Si hay elecciones se indica en Game_Temp
    if $game_temp.choice_max > 0
      @item_max = $game_temp.choice_max
      self.active = true
      self.index = 0
    end
   
    # Si hay un input number se crea su ventana
    if $game_temp.num_input_variable_id > 0
      digits_max = $game_temp.num_input_digits_max
      number = $game_variables[$game_temp.num_input_variable_id]
      @input_number_window = Window_InputNumber.new(digits_max)
      @input_number_window.number = number
      @input_number_window.x = self.x + 8
      @input_number_window.y = self.y + $game_temp.num_input_start * 32
    end
  end

  # Mostrar todo el texto de golpe
  def skip
    until @text_array.size == 0
      array = @text_array.shift
      self.contents.font.color = array[3]
      self.contents.draw_text(4 + array[1], 32 * array[2], 40, 32, array[0])
    end
  end
 
  def update
    super
    # No empezar a escribir hasta que no haya aparecido totalmente la ventana
    if @fade_in
      self.contents_opacity += 24
      if @input_number_window != nil
        @input_number_window.contents_opacity += 24
      end
      if self.contents_opacity == 255
        @fade_in = false
      end
      return
    end
    # Si no hay texto no escribe
    if @text_array.size == 0
      @writing = false
    end
    if @by_lines
      if @line_0.size == 0 and @line_1.size == 0 and
        @line_2.size == 0 and @line_3.size == 0
        @writing = false
      end
    end
    # Si el contador de tiempo no es 0 durante ese frame no escribe
    if @wait_count > 0
      @wait_count -= 1
      return
    end
    # Escribir el contenido
    if @writing
      # Efecto Letter By Letter
      if @timing
        # Si pulsas Enter
        if Input.press?(Input::C)
          # Si skip está activado
          if $game_system.letter_can_skip
            # Mostrar el texto de golpe
            skip
            return
          end
        end
        # No va por líneas sinó el texto en conjunto
        if @by_lines == false
          # Dirección del texto ( "Right" / "Left" )
          case @scroll
          when "Right"
            a = @text_array.shift
          when "Left"
            a = @text_array.pop
          end
          # Dibujar el texto según sus características guardadas
          self.contents.font.color = a[3]
          width = [40, self.contents.text_size(a[0]).width].max
          self.contents.draw_text(4 + a[1], 32 * a[2], width, 32, a[0])
        # Va por líneas independientes
        else
          lines = [@line_0, @line_1, @line_2, @line_3]
          scrolls = [@line_0_scroll, @line_1_scroll,
                    @line_2_scroll, @line_3_scroll]
          # Si la siguiente no se activa hasta haber terminado la anterior
          if @wait_lines
            # Obtener la línea
            wait_lines = lines.select{|l| l.size > 0}
            line = wait_lines[0]
            scroll = scrolls[lines.index(wait_lines[0])]
            # Obtener el siguiente carácter de la línea según su dirección
            case scroll
            when "Right"
              a = line.shift
            when "Left"
              a = line.pop
            end
            # Dibujar el texto según sus características guardadas
            self.contents.font.color = a[3]
            width = [40, self.contents.text_size(a[0]).width].max
            self.contents.draw_text(4 + a[1], 32 * a[2], width, 32, a[0])
          # Si las líneas tienen el efecto simultáneamente (con delay corregido)
          else
            # Obtener todas las líneas a la vez
            lines = lines.select{|l| l.size > 0}
            for i in 0...lines.size
              line = lines[i]
              scroll = scrolls[i]
              # Obtener el siguiente carácter de la línea según su dirección
              case scroll
              when "Right"
                a = line.shift
              when "Left"
                a = line.pop
              end
              # Dibujar el texto según sus características guardadas
              self.contents.font.color = a[3]
              width = [40, self.contents.text_size(a[0]).width].max
              self.contents.draw_text(4 + a[1], 32 * a[2], width, 32, a[0])
            end
          end
        end
        # Indicador de velocidad; de 1 para más lento a 6 para más rápido
        @wait_count += 6 - $game_system.letter_speed
        return
      end
    end
    # Redefinir variables para la siguiente ocasión
    define_mode
    @text_array = []
    @line_0 = []
    @line_1 = []
    @line_2 = []
    @line_3 = []
    # Si la ventana de Input está activada se updatea como siempre
    if @input_number_window != nil
      @input_number_window.update
      if Input.trigger?(Input::C)
        $game_system.se_play($data_system.decision_se)
        $game_variables[$game_temp.num_input_variable_id] =
          @input_number_window.number
        $game_map.need_refresh = true
        @input_number_window.dispose
        @input_number_window = nil
        terminate_message
      end
      return
    end
    # Si las elecciones estan activadas se updatean como siempre
    if @contents_showing
      if $game_temp.choice_max == 0
        self.pause = true
      end
      if Input.trigger?(Input::B)
        if $game_temp.choice_max > 0 and $game_temp.choice_cancel_type > 0
          $game_system.se_play($data_system.cancel_se)
          $game_temp.choice_proc.call($game_temp.choice_cancel_type - 1)
          terminate_message
        end
      end
      if Input.trigger?(Input::C)
        if $game_temp.choice_max > 0
          $game_system.se_play($data_system.decision_se)
          $game_temp.choice_proc.call(self.index)
        end
        terminate_message
      end
      return
    end
    # La ventana desaparece al finalizar los textos
    if @fade_out == false and $game_temp.message_text != nil
      @contents_showing = true
      $game_temp.message_window_showing = true
      reset_window
      refresh
      Graphics.frame_reset
      self.visible = true
      self.contents_opacity = 0
      if @input_number_window != nil
        @input_number_window.contents_opacity = 0
      end
      @fade_in = true
      return
    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
      return
    end
  end
end

# Métodos especiales de Array

class Array
  # Pasar de formato de letra a palabras (específico para @text_array)
  def letter_to_word
    x = self[0][1]
    y = self[0][2]
    color = self[0][3]
    array = [["", x, y, color]]
    array_index = 0
    for i in 0...(self.size - 1)
      letter = self[i][0]
      next_letter = self[i+1][0]
      if letter != " "
        array[array_index][0].concat(letter)
        if i == (self.size - 2)
          array[array_index][0].concat(next_letter)
        end
      end
      if next_letter == " "
        array_index += 1
        array.push([" ", self[i + 1][1], self[i + 1][2], self[i + 1][3]])
      elsif self[i+1][2] != self[i][2]
        array_index += 1
        array.push(["", self[i + 1][1], self[i + 1][2], self[i + 1][3]])
      end
    end
    return array
  end
 
  # Rellenar con espacios en blanco (específico para @text_array)
  def fill_letters(value)
    if self.size == 0
      return
    end
    until self.size == value
      s = self[-1]
      self.push([" ", s[1], s[2], s[3]])
    end
    return self
  end
end


Pegad encima de main.
Hay tres llamadas desde script que se pueden hacer para modificar ésto:

$game_system.letter_mode = "(Tipo)" * => Eso llama a un tipo concreto de letter mode, citados más abajo. Por ejemplo "Default", "Letter by Letter"... Se pueden añadir los tipos que quieras dentro del def define_mode al principio del script.

$game_system.letter_speed = (velocidad) => Define la velocidad a la que van las letras, de 1 (mínimo) a 6 (máximo)

$game_system.letter_can_skip = (true / false) => Indica si se puede saltar el efecto pulsando Espacio o no, si vale true es que sí.

====

* Tipos de efectos (letter_mode):

Para añadir tipos de efectos con opciones no disponibles hasta ahora (por ejemplo aparición de letras Random) evidentemente habrá que modificar el script y es bastante caótico, pero personalizar los efectos que ya hay es bastante sencillo.

- Default

Aparece el texto de golpe como siempre.

- Letter by Letter

Aparece el texto letra por letra en orden, como en los scripts de éste tipo.

- Word by Word

Aparece el texto palabra por palabra en orden.

- Scroll Right

Es como el Letter by Letter pero todas las líneas a la vez; se va rellenando de izquierda a derecha.

- Scroll Left

Es como el Letter by Letter pero todas las líneas a la vez; se va rellenando de derecha a izquierda.

- Scroll Right [D]

Es como el Scroll Right pero permite hacer que no todas las líneas empiecen justo al mismo tiempo.

- Scroll Left [D]

Es como el Scroll Left pero permite hacer que no todas las líneas empiecen justo al mismo tiempo.

- Zig-Zag"

Es como el letter by letter pero la primera línea va de izquierda a derecha, la segunda de derecha a izquierda, la tercera de izquierda a derecha otra vez y finalmente la cuarta de derecha a izquierda de nuevo (haciendo un efecto como de ida y vuelta)

Edito: Normalmente no lo hago pero como el script es bastante caótico he añadido comentarios sobre cada parte relevante del código.


Última edición por Wecoc el 2014-06-25, 05:24, editado 2 veces
avatar
Wecoc
Administrador
Administrador



Créditos 12314

Gracias : 655

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Wecoc's Letter by Letter

Mensaje por Faye Valentine el 2014-06-25, 02:50

Magnifico. ¿Es compatible con el UMS?

Faye Valentine
Soñador
Soñador

0/3

Créditos 287

Gracias : 35

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Wecoc's Letter by Letter

Mensaje por Wecoc el 2014-06-25, 03:42

Iba a decirte simplemente que no pero me duele no dar una explicación de por qué, así que aquí un va un tochazo explicativo.

No es compatible con prácticamente nada relacionado con sistemas de mensaje, porque es difícil hacer éstos scripts de modo que sean compatibles. Pero se puede adaptar a los demás scripts de mensaje, en la mayoría no hay demasiada complicación. Pero con UMS es prácticamente imposible.

Uno de los problemas es que UMS ya tiene letter by letter, adaptar éste script al UMS o a otros letter by letter, a parte de ser complicado por posibles variables repetidas implicaría tener dos letter by letter en uno mismo y eso es muy poco funcional. Y como dije el mío no está hecho exactamente de igual forma que los demás así que no se puede añadir lo que tenga de nuevo el mío "tal cual".

Otro problema del UMS es que es una modificación a grande escala, prácticamente una reescritura de todo lo relacionado con los mensajes, así que en realidad es el UMS la principal barrera de incompatibilidad entre ámbos.

¿Por qué es difícil hacer compatibles éste tipo de scripts?

Nuestro mejor aliado para evitar esas cosas aunque, se pierda performance, es el alias (aunque UMS está tan reescrito que ni eso nos salva), igualmente la mayoría de veces el alias sólo es útil para añadir nueva información a cosas ya descritas, no reescribirla, y eso para un mismo método se puede hacer tantas veces como se quiera con alias distintos. Resulta que por ese motivo en los dos platos fuertes de éste tipo de scripts, que son el refresh y el update de Window_Message, no se puede usar alias, porque se reescriben casi del todo esos métodos.

Hay otra forma de hacer compatible lo incompatible, que contemplaré pero con UMS sigue sin ser posible por ser tan distintos, y es añadir un module al principio del script con globales para indicar si se está usando algún script conocido que altere eso.

Un ejemplo cualquiera:

Código:
module Compat_Message
  AMS = false
  SDK = false
  PEPITO_SYSTEM = false
end


Luego según esas globales se plantean de forma distinta ciertas cosas dentro del script. Buscaré scripts usados sobre ésto y miraré qué puedo hacer, si os preocupa alguno en especial me lo decís.
avatar
Wecoc
Administrador
Administrador



Créditos 12314

Gracias : 655

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Wecoc's Letter by Letter

Mensaje por Faye Valentine el 2014-06-25, 04:51

Comprendo.

¿Por qué no haces tu propio sistema de mensajes? Eso sería algo... lunático. Yo lo usaría :p

Faye Valentine
Soñador
Soñador

0/3

Créditos 287

Gracias : 35

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Wecoc's Letter by Letter

Mensaje por Wecoc el 2014-06-25, 09:29

Mhm... Está bien, acepto el desafío, intentaré hacer un sistema de mensajes único y que incluya ésto. Pero no garantizo que sea de fácil uso xD

Ya hice algo, voy bien pero hay un error grave. El problema que tengo ahora mismo está con los códigos tipo \c[0] y similares cuando la línea va al revés de como debería (de derecha a izquierda). Si lo piensas es obvio, también los lee "al revés" puesto que esos códigos alteran lo siguiente y en ese caso lo siguiente es lo anterior. Arreglar eso es un auténtico, auténtico caos. Con el sistema por líneas también pasan algunas cosillas por el estilo aunque no tan graves. Así que lo que haré es dejar ese punto bastante al aire.

Si alguien quiere ayudar a arreglar cosas de éste estilo en el script que contacte conmigo. Es el primer script que hago de ese estilo, nunca hice nada parecido, así que un poco de ayuda no me vendría nada mal xD.
avatar
Wecoc
Administrador
Administrador



Créditos 12314

Gracias : 655

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Wecoc's Letter by Letter

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


Permisos de este foro:
No puedes responder a temas en este foro.