Aldeia RPG

Gostaria de reagir a esta mensagem? Crie uma conta em poucos cliques ou inicie sessão para continuar.

Suporte ao desenvolvimento de jogos


2 participantes

    Evitando lag

    Valentine
    Valentine
    Administrador
    Administrador


    Medalhas : Evitando lag ZgLkiRU
    Mensagens : 5336
    Créditos : 1163

    Evitando lag Empty Evitando lag

    Mensagem por Valentine Qui Out 06, 2016 6:30 pm

    O lag deve ser evitado a todo custo. Um jogo perfeito em conteúdo, cheio de beleza, cheio de opções, com animações maravilhosas, não será nada divertido se tiver lag. Pode ser o projeto que use os melhores sistemas do mundo, mas, se for lento, ninguém joga.

    É para evitar problemas com o lag que irei dar dicas e macetes para você se livrar deste terrível vilão.

    Inicilaize as variáveis

    Sempre inicialize as suas variáveis. Exemplo:
    Código:
    #Ao invés disso:
    y = x + 1 # Retorno: 1

    #Use isso:
    x = 0
    y = 0
    y = x + 1 # Retorno: 1

    Motivo: performance. O ganho pode ser verificado com o seguinte código Ruby:
    Código:
    require "benchmark"
    include Benchmark

    n = 1000000
    bm(12) do |test|

      test.report("Normal:") do
        n.times do |x|
          y = x + 1
        end
      end

      test.report("Inicializando:") do
        x = y = 0
        n.times do |x|
          y = x + 1
        end
      end

    end

    O retorno deste teste (do código acima) é o seguinte:
    Código:
                      user     system      total        real
    Normal:        0.920000   0.000000   0.920000 (  0.978238)
    Inicializando: 0.720000   0.000000   0.720000 (  0.761112)

    Ou seja... Inicializando é mais rápido.

    Complexidade do código nas repetições

    Como determinar a complexidade de uma rotina? Antes de responder esta pergunta vamos ver alguns exemplos:

    Exemplo 1:
    Código:
    p s

    if s = nil
      s = Sprite.new
    end

    c = d + 1

    s.x = c

    Achou complexo? Vamos ver outro exemplo.

    Exemplo 2:
    Código:
    n = 100
    for i in 0...n
      f + = self.uma_string_qualquer(i)
    end

    Pareceu ser menos complexo? Ou ficou mais complexo? Antes da resposta vamos ver outro exemplo.

    Exemplo 3:
    Código:
    n = 100

    for i in 0...n

      for j in 0...n

        for k in 0...n
          self.faz_alguma_coisa(i,j,k)
        end

      end

    end

    E agora? Mais ou menos complexo?

    Se considerarmos que a complexidade depende do número de repetições executadas, então o mais complexo é o exemplo 3. Observe que se n for igual a 2, serão executadas 8 repetições. Se n=3 , serão 27 repetições. Com n=4 serão 64 repetições. Com n=100 será um milhão de repetições.

    Ao criar qualquer rotina é necessário lembrar deste detalhe para evitar repetições desnecessárias.

    Mais um exemplo:
    Código:
    nIdSkill = 1

    #Lento
    for actor in $game_party.actors
      actor.hp -= calcular_dano_da_habilidade(nIdSkill)
    end

    #Rápido
    nDano = calcular_dano_da_habilidade(nIdSkill)
    for actor in $game_party.actors
      actor.hp -= nDano
    end

    Gráficos e imagens

    Se tem alguma coisa que pode causar lag são as imagens. A chamada de um simples método como o set_pixel gera uma reação em cadeia. O módulo Graphics gerencia a tela no RGSS. Alterar um pixel usando o método set_pixel irá alterar dados da classe instanciada (window/sprite), que, por sua vez, irá manipular o bitmap contents. Este, por sua vez, avisa ao Graphics que a janela/sprite precisa de um update para redesenhar as alterações. Por isso, o Graphics.update é chamado. Por isso, cada janela aberta causa lag. O Graphics.update irá tentar atualizar todas elas.

    Sabendo o que causa o lag, podemos evitá-lo. No RGSS, o lag é causado por janelas abertas/invisíveis ou muitos eventos no mapa. Cada evento possui um sprite associado. Cada sprite cria lag através do procedimento acima.

    É por isso que a maioria dos scripts anti-lag são, na verdade, scripts Event-Anti-Lag. Eles simplesmente evitam a atualização dos sprites dos eventos que não estão na tela.

    É possível ir além do que procurar um script anti-lag para usar em nossos projetos. Lembre-se de usar o dispose em todas as janelas e sprites que não estão sendo usadas. Se depois precisar da janela/sprite, é melhor recriar ele. O código pode ficar um pouco maior ou complexo, mas o lag será reduzido.

    set_pixel    VS    fill_rect

    Agora que têmos uma idéia do lag que o set_pixel pode causar, vamos evitá-lo na prática. Observe os dois exemplos de barras gradientes a seguir:
    Código:
    class bitmap
      def gradient_bar_1(x, y, w, h, fill_rate, c1, c2)
        fill_rect(x, y, , w, h, Color.new(0, 0, 0))
        for i in 0...(w * fill_rate).to_i
          r = c1.red + (c2.red - c1.red) * i / w
          g = c1.green + (c2.green - c1.green) * i / w
          b = c1.blue + (c2.blue - c1.blue) * i / w
          fill_rect( x+i, y, 1, h, Color.new( r, g, b ) )
        end
      end

      def gradient_bar_2(x, y, w, h, fill_rate, c1, c2)
        fill_rect(x, y, , w, h, Color.new(0, 0, 0))
        for i in 0...(w * fill_rate).to_i
          for j in 0...h
            r = (c1.red + (c2.red - c1.red) * i / w) * j  / h
            g = (c1.green + (c2.green - c1.green) * i / w) * j  / h
            b = (c1.blue + (c2.blue - c1.blue) * i / w) * j  / h
            set_pixel( x+i, y+j, Color.new( r, g, b ) )
          end
        end
      end
    end

    Agora observe o resultado das duas barras, nas imagens abaixo:
    Evitando lag Bar1
    Barra 1
    Evitando lag Bar2
    Barra 2

    Qual seria a melhor? A primeira ou a segunda? Muitos podem achar o efeito da segunda barra visualmente melhor. Afinal, é um efeito mais bonito, mas o lag da segunda barra é muito maior que da primeira. A diferença de tempo de execução chega a superar 40%.

    A beleza é realmente necessária? Se não for, é melhor usar a barra 1 (ao invés da barra 2), pois assim evita-se bastante lag.

    Aspas simples ou aspas duplas?

    No RGSS, existem comandos lentos e comandos rápidos. De posse desta informação, podemos deixar nosso código mais rápido e com menos lag. A primeira coisa a se ter em mente é o uso das aspas. Observe o exemplo abaixo:
    Código:
    bitmap.draw_text(0, 0, 600, 32,
                     'Esta primeira string é processada mais rapidamente' +
                     " do que esta segunda string.\n")

    Mais exemplos:
    Código:
    #Lento
    bitmap.draw_text(0, 0, 100, 32, "#{$game_party.gold}" )
    bitmap.draw_text(0, 0, 100, 32, "#{$game_party.gold}".to_s )

    #Rápido
    bitmap.draw_text(0, 0, 100, 32, $game_party.gold.to_s )

    Evite usar as aspas duplas. Em grande parte do código podemos usar somente as simples, mas às vezes esquecemos isso. Outras vezes fazemos o famoso CTRL+C CTRL+V e lá vem as aspas duplas. Troque sempre que puder para as asplas simples.

    Mas antes de sair mudando todo o código vamos ver mais um exemplo:
    Código:
    #Exemplo 1
    nums = [0, 1, 2, 3]
    cTexto = "#{nums[0]} #{nums[1]} #{nums[2]} #{nums[3]}"

    #Exemplo 2
    nums = [0, 1, 2, 3]
    cTexto = nums[0].to_s + nums[1].to_s + nums[2].to_s + nums[3].to_s

    E agora? No exemplo anterior, o mais rápido é o exemplo 1 ou o exemplo 2?

    Inicialmente, parece ser o exemplo 2, mas a chamada de to_s 4 vezes e a concatenação destes 4 valores com o operador + também irá gastar tempo. Nessa situação, pode-se usar qualquer um dos dois. O maior problema é quando se usa os dois ao mesmo tempo. Sempre evite usar os dois ao mesmo tempo.

    Créditos:
    Marcelo Cavaco

    Tópico original:
    http://www.rgss.com.br/dicas_lag.html


    Última edição por Valentine em Sex Dez 17, 2021 8:08 am, editado 1 vez(es)
    Komuro Takashi
    Komuro Takashi
    Colaborador
    Colaborador


    Mensagens : 1047
    Créditos : 130

    Evitando lag Empty Re: Evitando lag

    Mensagem por Komuro Takashi Qui Out 06, 2016 7:45 pm

    Ótimas dicas valeu pela contribuição.


    _________________
    Evitando lag Takashi_komuro_by_minato8-d51g9o4

    Paga um café? Patreon

      Data/hora atual: Qui Mar 28, 2024 10:28 am