¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.
Conectarse

Recuperar mi contraseña

Temas importantes
----------------------------------------
Páginas con recursos RPG Maker
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
----------------------------------------
Afiliados
Estadísticas
Tenemos 3396 miembros registrados.
El último usuario registrado es Discorded.

Nuestros miembros han publicado un total de 79808 mensajes en 11257 argumentos.
Navega con Google Chrome
[DESCARGA]

Optimizando tus scripts

 :: RPG Maker :: Scripts

Ver el tema anterior Ver el tema siguiente Ir abajo

Optimizando tus scripts

Mensaje por newold el 2013-01-09, 10:40

Hoy os traigo unos tips para optimizar los scripts que hagais

1) Usar tablas siempre que sea posible (Table). Las tablas solo pueden contener números hasta un valor de 32.767 y solo enteros, nada de decimales. Las tablas son más rápidas que los arrays y hashes

2) Usar arrays siempre que sea posible (Array). Los arrays son más rápidos que los hashes.

3) loops a través de tablas, arrays, hashes

Para arrays el loop más rápido es éste:

array.each {|value| # hacer lo que quieras}

Para hashes el loop más rápido es éste:

hash.each {|key,value| # hacer lo que quieras}

Para tablas el loop más rápido es éste:

for z in 0...table.zsize
for y in 0...table.ysize
for x in 0...table.xsize
# hacer lo que quieras
end
end
end

4) Cuando se tiene un array para comprobar si incluye una serie de valores (por ejemplo un array que contenga muchas ids y se quiere comprobar si el array incluye una id dada mediante include?) Es mucho más rápido tener para eso una variable de texto que almacene todas las IDs (o lo que sea) en una sola cadena de texto y mediante la propiedad index verificar si existe una ID (o lo que sea en la cadena)

Ejemplo:

Esto..........

Array = [10,20,30,40,50,1,8,95]
Array.include?(96) # false (no incluye la id)
Array.include?(95) # true (incluye la id)

Sería más lento que esto..........

IDS = "<10><20><30><40><50><1><8><95>"
IDS.index("<96>").nil? # true (no incluye la id)
IDS.index("<95>").nil? # false (incluye la id)

5) Loops en general

un loop de esta forma:

while true
# hacer lo que quieras
end

es más rápido que un loop de esta otra forma:

loop do
# hacer lo que quieras
end

Por último dejo un pequeño script para testear errores. Ponerlo arriba del todo.

Código:
class Kernel
  #--------------------------------------------------------------------------
  def err
    e1 = $@ # El lugar de el último error
    e2 = $. # La última línea leída por el interprete
    e3 = $0 # El nombre de el script de Ruby que se está ejecutando
    e4 = $* # Los argumentos de la línea de comandos usados para invocar el script
    e5 = $!.backtrace
    e6 = $!
    p "* Se ha producido el siguiente error:\n\n" + "#{e6}" + "\n\n" +
      "* Backtrace:\n\n" + "#{e5}" + "\n\n" +
      "* Último script leido: #{e3}" + "\n\n" +
      "* Última línea: #{e2}" + "\n\n" +
      "* Argumentos usados para invocar al script: #{e4}"
  end
  #--------------------------------------------------------------------------
end

Para usarlo debéis meter el código que queráis entre etiquetas begin rescue de esta forma:

begin
# código a analizar
rescue err; end; # Si se produce un error salta un cuadro de mensaje con información detallada del error.


PD: Testeado en RGSS 1 y 3

newold
Principiante
Principiante

0/3

Créditos 1060

Gracias : 59

Volver arriba Ir abajo

Re: Optimizando tus scripts

Mensaje por Wecoc el 2013-01-09, 16:05

Esto es muy chachi, y de hecho ya sigo los puntos 1,2,5 (y el 3 más o menos) xDD
Pero el punto 4 no lo conocía, no lo usaré y tampoco lo recomiendo.

Cabe señalar que cuando creas un código, a parte de que funcione, tienes dos objetivos a tener en cuenta. El primero es que sea lo más rápido posible (optimizado), y el segundo, que sea lo más entendible posible para otros scripters o para tú mismo en un futuro. El 4o punto plantea un método más rápido pero bastante más difícil de entender a simple vista.
-------
Fíjate en este caso, escribiré lo mismo de 3 maneras distintas; tabla, hash (1) y hash (2):

Código:
def trigger_skill(id)
 case id
 when 1 then return 12
 when 4 then return 31
 when 7 then return 9
 when 12 then return 4
 when 81 then return 27
 end
 return 0
end

Código:
TRIGGER_SKILL = {}
TRIGGER_SKILL[1] = 12
TRIGGER_SKILL[4] = 31
TRIGGER_SKILL[7] = 9
TRIGGER_SKILL[12] = 4
TRIGGER_SKILL[81] = 27

Código:
TRIGGER_SKILL = {1 => 12, 4 => 31, 7 => 9, 12 => 4, 81 => 27}

El último caso es muy difícil de ver y entender, sobretodo para alguien que no es un programador y solo quiere modificar las skills que convenga para su proyecto.
El segundo caso puede pasar, pero es mucho más facil de entender el primer caso, sabiendo inglés casi puedes leerlo textualmente como una frase.

Cuando hagas scripts tienes que tener en cuenta ese factor.

Wecoc
Administrador
Administrador



Créditos 8272

Gracias : 372

Volver arriba Ir abajo

Re: Optimizando tus scripts

Mensaje por orochii el 2013-01-09, 17:00

Hay cosas que sabía, hay cosas que no 8D. El 1 y el 2 ya los aplicaba creo. Los loops en arrays llevo toda mi vida usando for x'D...
El 4 no lo sabía, porque no había considerado la velocidad del include contra la búsqueda en un string (un string es un array, aunque el string guarda 8bits por elemento, el array no). ...bueno eso creo que me da una idea del porqué xD.
El 5, creo que nunca uso esos loops xD. En C++ sí, uso while, para el loop principal.
Lo malo es que Enterbrain nos enseñó a usar loop do para el loop de las escenas xD.

Aaah, qué suerte que no soy scripter 8D!,
Orochii Zouveleki

orochii
Caballero Shiro
Caballero Shiro

0/3

Créditos 6045

Gracias : 266

http://drekirokr.weebly.com/

Volver arriba Ir abajo

Re: Optimizando tus scripts

Mensaje por newold el 2013-01-09, 18:25

añado otro consejo más:

6)A la hora de dibujar contenido en una imagen/ventana y borrarle contenido, es más eficiente dibujar solo lo que sea visible en pantalla y borrar solo lo que sea necesario. Por ejemplo en los menús que dibujan listas de objetos, skills etc... se puede hacer lo siguiente (voy a tomar de ejemplo el script Window_Item):

pongo el script Window_item modificado para que sea mucho más eficiente, ahora puede dibujar listas más grandes de objetos sin lag

Código:
#==============================================================================
# ** Window_Item
#------------------------------------------------------------------------------
#  This window displays items in possession on the item and battle screens.
#==============================================================================

class Window_Item < Window_Selectable
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize
    super(0, 64, 640, 416)
    ##### AÑADIDO #####
    @checks_id = "" # las ids contenidas aquí no se dibujarán
    @last_oy = nil # variable para evitar loops innecesarios
    ###################
    @column_max = 2
    refresh
    self.index = 0
    # If in battle, move window to center of screen
    # and make it semi-transparent
    if $game_temp.in_battle
      self.y = 64
      self.height = 256
      self.back_opacity = 160
    end
  end
  #--------------------------------------------------------------------------
  # * Get Item
  #--------------------------------------------------------------------------
  def item
    return @data[self.index]
  end
  ##### AÑADIDO #############################################################
  #--------------------------------------------------------------------------
  # * update
  #--------------------------------------------------------------------------
  def update
    refresh_items
    super
  end
  #--------------------------------------------------------------------------
  def refresh_items
    if @item_max > 0 and @last_oy != self.oy
      height_line = 32.0
      @last_oy = self.oy
      from = self.oy / height_line
      to =  (self.oy + self.height) / height_line * @column_max
      for i in from.floor...to.floor
        next if @data[i].nil?
        if @checks_id.index("<#{i}>").nil?
          draw_item(i)
          @checks_id << "<#{i}>"
        end
      end
    end
  end
  #--------------------------------------------------------------------------
  ###########################################################################
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    @data = []
    # Add item
    for i in 1...$data_items.size
      if $game_party.item_number(i) > 0
        @data.push($data_items[i])
      end
    end
    # Also add weapons and items if outside of battle
    unless $game_temp.in_battle
      for i in 1...$data_weapons.size
        if $game_party.weapon_number(i) > 0
          @data.push($data_weapons[i])
        end
      end
      for i in 1...$data_armors.size
        if $game_party.armor_number(i) > 0
          @data.push($data_armors[i])
        end
      end
    end
    # If item count is not 0, make a bit map and draw all items
    @item_max = @data.size
    ##### AÑADIDO #####
    if @item_max > 0
      self.contents = Bitmap.new(width - 32, row_max * 32)
      refresh_items
    end
    ###################
    #**#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
  #--------------------------------------------------------------------------
  # * Draw Item
  #    index : item number
  #--------------------------------------------------------------------------
  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
    if item.is_a?(RPG::Item) and
      $game_party.item_can_use?(item.id)
      self.contents.font.color = normal_color
    else
      self.contents.font.color = disabled_color
    end
    x = 4 + index % 2 * (288 + 32)
    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 + 28, y, 212, 32, item.name, 0)
    self.contents.draw_text(x + 240, y, 16, 32, ":", 1)
    self.contents.draw_text(x + 256, y, 24, 32, number.to_s, 2)
  end
  #--------------------------------------------------------------------------
  # * Help Text Update
  #--------------------------------------------------------------------------
  def update_help
    @help_window.set_text(self.item == nil ? "" : self.item.description)
  end
end

las partes que tienen un comentario así: #**# son partes originales del script que ya no son necesarias.

y las partes que están marcadas como

##### AÑADIDO #####
contenido añadido extra
###################

son las partes añadidas (muy pocas pero hacen al script mucho más eficiente). Haciendo los mismos cambios en otros scripts se logra la misma eficiencia. (Este script probado con los items default, 32 objetos, 32 armas y 32 protectores, se tarda en dibujarlo entre 0.034 y 0.043 segundos. Sin embargo con el script sin optimizar entre 0.08 y 0.1 segundos, más de un 130% más)

newold
Principiante
Principiante

0/3

Créditos 1060

Gracias : 59

Volver arriba Ir abajo

Re: Optimizando tus scripts

Mensaje por orochii el 2013-01-09, 18:48

Ese último sí lo he visto C:. Es una de las cosas que me gustan de los scripts de Blizzard, que siempre actualiza el espacio justo donde está cada cosa.
Creo que lo mejor es guardar cada rect de cada elemento, o tener algo para determinarlos a mano (preferiría guardarlos, para evitar rehacerlos, aunque gaste un poco más de recurso, por ahí escuché que las divisiones son lentas por ejemplo, y que es mejor guardar una constante que estar haciendo la división por decir algo).

O no sé xD,
OZ

orochii
Caballero Shiro
Caballero Shiro

0/3

Créditos 6045

Gracias : 266

http://drekirokr.weebly.com/

Volver arriba Ir abajo

Re: Optimizando tus scripts

Mensaje por Contenido patrocinado Hoy a las 06:57


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


 :: RPG Maker :: Scripts

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