Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.

[XP] Message Font Fix (espacio entre letras)

Ver el tema anterior Ver el tema siguiente Ir abajo

RPG Maker XP [XP] Message Font Fix (espacio entre letras)

Mensaje por Wecoc el 2016-11-28, 22:07

Ledai y yo hemos estado hablando de un problema recurrente del RPG maker XP/VX/Ace. No sé si me explicaré muy bien, pero en resumen digamos que a veces cuando insertas una fuente para usarla en el RPG maker la separación entre algunas letras no se corresponde a como se ve en un editor de texto.

Imagen:

Las fuentes que quedarían superpuestas porque tienen esos trazos quedan totalmente separadas.

Es problema del maker, del modo como lee las fuentes para los mensajes.
El modo en el que se muestran los textos en las ventanas y en la ventana de mensaje de evento son distintos. En las ventanas normales el texto se muestra todo a la vez, con un único "draw_text" para todo ese texto, por lo que ahí no debería haber ese problema. En los mensajes de evento en cambio las letras se muestran una a una y a la "x" se le va sumando el tamaño de la letra anterior, por eso pasa eso. Está hecho así para leer bien los carácteres especiales \c[n] y todo eso, no hay otro modo mejor de hacerlo.

La forma de arreglar ese problema es definir en una global las alteraciones de la x personalizadas que quieras hacer en algunas letras.

Las instrucciones que daré a continuación sirven para XP, VX y Ace, y sirven además para insertar el fix en scripts de mensajes personalizados. Explico los pasos porque no es complicado hacerse el script uno mismo, y como hay tantos scripts que modifican el refresh de Window_Message no hay más remedio.

Instrucciones:
Se define en una global dentro de Window_Message para cada letra la diferencia que quieres aplicarle en la x antes de dibujar ésta y después (de cara a dibujar la siguiente).
Así: Nombre fuente => [[letra, x (antes), x (después)], ...]
De ese modo configuras todas las fonts que uses en el juego y tengan ese problema. La x (después) suele valer 0, solo la puse por si acaso.

Ejemplo:
Código:
 CONF_FONTS = { "Arial" => [ ["f", -8, 0], ["g", -8, 0] ] }

Luego solo hay que buscar en el refresh dónde se añade el tamaño de la letra actual a la x (siempre ocurre justo después del draw_text de esa letra, y se mide con un self.contents.text_size)

Luego solo hay que añadir ésto justo antes del draw_text:

Código:
       # New X feature (Before)
        if !CONF_FONTS[self.contents.font.name].nil?
          array = CONF_FONTS[self.contents.font.name].select{|a| a[0] == c}[0]
          x += array[1] if !array.nil?
        end

Y ésto después del text_size que comenté antes:

Código:
       # New X feature (After)
        if !CONF_FONTS[self.contents.font.name].nil?
          array = CONF_FONTS[self.contents.font.name].select{|a| a[0] == c}[0]
          x += array[2] if !array.nil?
        end

Para quien use el XP sin scripts de mensajes costumizados, os pongo el script ya hecho, pegadlo encima de main:

Código:
#==============================================================================
# ** Message Font Fix
#------------------------------------------------------------------------------
#  Autor: Wecoc (no requiere créditos)
#==============================================================================

class Window_Message < Window_Selectable

  # Nombre fuente => [[letra, x (antes), x (después)], ...]
  CONF_FONTS = { "Arial" => [ ["f", -8, 0], ["g", -8, 0] ] }
  
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    self.contents.font.color = normal_color
    x = y = 0
    @cursor_width = 0
    # Indent if choice
    if $game_temp.choice_start == 0
      x = 8
    end
    # If waiting for a message to be displayed
    if $game_temp.message_text != nil
      text = $game_temp.message_text
      # Control text processing
      begin
        last_text = text.clone
        text.gsub!(/\\[Vv]\[([0-9]+)\]/) { $game_variables[$1.to_i] }
      end until text == last_text
      text.gsub!(/\\[Nn]\[([0-9]+)\]/) do
        $game_actors[$1.to_i] != nil ? $game_actors[$1.to_i].name : ""
      end
      # Change "\\\\" to "\000" for convenience
      text.gsub!(/\\\\/) { "\000" }
      # Change "\\C" to "\001" and "\\G" to "\002"
      text.gsub!(/\\[Cc]\[([0-9]+)\]/) { "\001[#{$1}]" }
      text.gsub!(/\\[Gg]/) { "\002" }
      # Get 1 text character in c (loop until unable to get text)
      while ((c = text.slice!(/./m)) != nil)
        # If \\
        if c == "\000"
          # Return to original text
          c = "\\"
        end
        # If \C[n]
        if c == "\001"
          # Change text color
          text.sub!(/\[([0-9]+)\]/, "")
          color = $1.to_i
          if color >= 0 and color <= 7
            self.contents.font.color = text_color(color)
          end
          # go to next text
          next
        end
        # If \G
        if c == "\002"
          # Make gold window
          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 new line text
        if c == "\n"
          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
        # New X feature (Before)
        if !CONF_FONTS[self.contents.font.name].nil?
          array = CONF_FONTS[self.contents.font.name].select{|a| a[0] == c}[0]
          x += array[1] if !array.nil?
        end
        # Draw text
        self.contents.draw_text(4 + x, 32 * y, 40, 32, c)
        x += self.contents.text_size(c).width
        # New X feature (After)
        if !CONF_FONTS[self.contents.font.name].nil?
          array = CONF_FONTS[self.contents.font.name].select{|a| a[0] == c}[0]
          x += array[2] if !array.nil?
        end
      end
    end
    # If choice
    if $game_temp.choice_max > 0
      @item_max = $game_temp.choice_max
      self.active = true
      self.index = 0
    end
    # If number input
    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  
end
avatar
Wecoc
Administrador
Administrador



Créditos 12193

Gracias : 546

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Message Font Fix (espacio entre letras)

Mensaje por Ledai el 2016-11-29, 17:51

Pues es un aporte, nuevamente; único. 
No conocía la diferencia de actuación a la hora de dibujar el texto en un menú y en el cuadro de evento, pero ahora tiene sentido el problema y la solución.

Acabo de adaptar el Script que uso en el proyecto siguiendo tus instrucciones y siguiendo paso a paso el script original y...

¡¡En serio, si lo he logrado hacer yo con un script en japones lo puede hacer cualquiera XD!!

Buen aporte y buena explicación, ahora este tipo de  fuente no parecerá partida.
avatar
Ledai
Aventurero
Aventurero

0/3

Créditos 4001

Gracias : 185

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Message Font Fix (espacio entre letras)

Mensaje por kyonides-arkanthos el 2016-12-01, 03:46

Código:
CONF_FONTS = { "Arial" => [ ["f", -8, 0], ["g", -8, 0] ] }

Creo que sería más efectivo hacerlo así:

CONF_FONTS = { "Arial" => { "f" => [-8, 0], "g" => [-8, 0] } }

Entonces más adelante solo habría que llamarlo así:

x1, x2 = CONF_FONTS[contents.font.name][c] || [0, 0]
x += x1

y luego...

x+= x2

Es solo una sugerencia para minimizar la cantidad de código que se leerá desde la ventana de mensajes.
avatar
kyonides-arkanthos
Principiante
Principiante

0/3

Créditos 507

Gracias : 78

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Message Font Fix (espacio entre letras)

Mensaje por Wecoc el 2018-01-08, 23:46

Anotación:
Debo decir que en mi juego arreglo el problema que se plantea en este topic de un modo bastante más elegante, convirtiendo el letter-by-letter default del maker (aunque se muestran a la vez) en un format-by-format (color de letra) haciendo como resultado que la ventana de mensajes funcione mucho más como las demás. Tal como está montado solo sirve en ese juego pero lo dejo como propuesta si tuvierais problemas.

Me avisaron de que este script no sirve si estás definiendo la fuente del juego mediante una array en vez de mediante un único nombre, lo que se suele hacer para asignar una fuente alternativa en caso que falle la primera. No es el único script que puede dar problemas por ese motivo así que decidí hacer otro script añadido que arregla eso.

Current Font Name Bugfix v1.1:
Código:
#=============================================================================
# ** [XP] Current Font Name Bugfix v1.1
#------------------------------------------------------------------------------
# Si defines la fuente del juego como una array, por defecto no hay modo de
# saber cual está usando el juego realmente. Con este fix al usar font.name
# no obtiene la array entera sino solo la que haya detectado.
#------------------------------------------------------------------------------
# Créditos: Wecoc (No requiere créditos)
#=============================================================================

class Font
  alias get_current_names name unless $@
  def name
    result = get_current_names
    return result if result.is_a?(String)
    for r in result
      return r if Font.exist?(r)
    end
    return ""
  end
end

Current Font Name Bugfix v1.0:
Código:
#=============================================================================
# ** [XP] Current Font Name Bugfix v1.0
#------------------------------------------------------------------------------
# Si defines la fuente del juego como una array, por defecto no hay modo de
# saber cual está usando el juego realmente. Con este fix al usar font.name
# no obtiene la array entera sino solo la que haya detectado.
#------------------------------------------------------------------------------
# Créditos: AWorks & Wecoc
#=============================================================================

module AWorks
  module_function
  module API
    RegCloseKey = Win32API.new('advapi32', 'RegCloseKey', 'L', 'L')
    RegEnumKeyExA = Win32API.new('advapi32', 'RegEnumKeyExA', 'LLPPLLLP', 'L')
    RegEnumValueA = Win32API.new('advapi32', 'RegEnumValueA', 'LLPPPPPP', 'L')
    RegOpenKeyExA = Win32API.new('advapi32', 'RegOpenKeyExA', 'LPLLP', 'L')
    RegQueryValueEx = Win32API.new('advapi32', 'RegQueryValueExA','LPLPPP', 'L')
    RegDeleteValue = Win32API.new('advapi32', 'RegDeleteValue','LP', 'L')
    RegDeleteKey = Win32API.new('advapi32', 'RegDeleteKey','LP', 'L')
  end
  
  module Registry
    module_function
    
    HKEYS = {'HKEY_CLASSES_ROOT' => 0x80000000,'HKEY_CURRENT_USER' =>0x80000001,
      'HKEY_LOCAL_MACHINE' => 0x80000002, 'HKEY_USERS' => 0x80000003,
      'HKEY_CURRENT_CONFIG' => 0x80000005}

    def enum_keys(key)
      key.sub!(/(.*?)\\/, '')
      return nil if HKEYS[$1].nil?
      hkey = HKEYS[$1]
      index, keys, opened = 0, [], [0].pack('V')
      API::RegOpenKeyExA.call(hkey, key, 0, 131097, opened)
      opened = (opened + [0].pack('V')).unpack('V')[0]
      loop do
        name = ' ' * 514
        size = [514].pack('V')
        result = API::RegEnumKeyExA.call(opened, index, name, size, 0, 0, 0, 0)
        if result == 0
          keys.push(name[0, (size += [0].pack('V')).unpack('V')[0]])
          index += 1
        else
          break
        end
      end
      API::RegCloseKey.call(opened)
      keys
    end

    def enum_values(key)
      key.sub!(/(.*?)\\/, '')
      return nil if HKEYS[$1].nil?
      hkey = HKEYS[$1]
      index, entries, opened = 0, [], [0].pack('V')
      API::RegOpenKeyExA.call(hkey, key, 0, 131097, opened)
      opened = (opened + [0].pack('V')).unpack('V')[0]
      loop do
        name = ' ' * 514
        size = [514].pack('V')
        result = API::RegEnumValueA.call(opened, index, name, size, 0, 0, 0, 0)
        if result == 0
          entries.push(name[0, (size += [0].pack('V')).unpack('V')[0]])
          index += 1
        else
          break
        end
      end
      API::RegCloseKey.call(opened)
      entries
    end
  end
  
  def get_fonts_names
    key = "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\#{ENV['OS'].sub(/_/,' ')}\\"
    fonts = Registry.enum_values(key + 'CurrentVersion\\Fonts')
    fonts.each_index {|f|
      fonts[f].sub!(' (TrueType)', '')
      fonts[f] = nil if !Font.exist?(fonts[f])
    }.delete(nil)
    fonts
  end
end

class Font
  alias get_default_fonts_ini initialize unless $@
  def initialize
    get_default_fonts_ini
    @default_fonts = AWorks.get_fonts_names
  end
  
  alias get_current_names name unless $@
  def name
    result = get_current_names
    return result if result.is_a?(String)
    for r in result
      return r if @default_fonts.include?(r)
    end
    return ""
  end
end

Debería ser compatible con todo, y no tenéis que editarle nada, solo insertarlo encima de los demás scripts custom (y debajo del script Fonts si existe).


Última edición por Wecoc el 2018-01-18, 18:01, editado 1 vez
avatar
Wecoc
Administrador
Administrador



Créditos 12193

Gracias : 546

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Message Font Fix (espacio entre letras)

Mensaje por xXIsrael0499Xx el 2018-01-09, 19:14

Ah que chido, siempre con el problema con las fuentes, ¿por que darán tantos problemas?, en fin muy buen script.

+1 :v
avatar
xXIsrael0499Xx
Veterano
Veterano

0/3

Créditos 973

Gracias : 73

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Message Font Fix (espacio entre letras)

Mensaje por Wecoc el 2018-01-18, 18:02

UPDATE: Disponible nueva versión 1.1 de Current Font Name Bugfix, mucho más corta y compatible que la anterior.
Me había sobrecomplicado la vida al ignorar un método ya existente por defecto.
avatar
Wecoc
Administrador
Administrador



Créditos 12193

Gracias : 546

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Message Font Fix (espacio entre letras)

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.