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

Você não está conectado. Conecte-se ou registre-se

Ver o tópico anterior Ver o tópico seguinte Ir para baixo  Mensagem [Página 1 de 1]

Fetelk13

Fetelk13
Membro Honorário I
Membro Honorário I
Quero iniciar esta aula agradecendo a todos pela paciência. Tenho estado com tantos projetos ao mesmo tempo que meu tempo livre acabou. Ser Torneiro Mecânico (minha profissão), Baixista (1º Hobby), Programador (2º,3º e 4º Hobbys) e Marido (Obrigação ;D) não é nada fácil...

Na aula anterior eu prometi que ia mostrar algo que muitos esperam, a muito tempo, que é a animação do heroi numa janela. Já vou adiantando que eu não sei se funciona com 4 ao mesmo tempo, eu sei como fazer de apenas um. Fizemos algumas alterações nas janelas do menu, hoje vamos construir uma janela que irá substituir a janela de Status. Vamos lá.

Criando uma janela com Barras de HP/SP e Animação

As barras não vamos criar, há vários códigos prontos para isso e eu não vejo necessidade de "recriarmos a roda". Para tanto, insira no projeto este código:

Código:
class Window_Base
  def draw_actor_name2(actor, x, y,align=0)
    self.contents.font.color = normal_color
    self.contents.draw_text(x, y, 64, 32, actor.name ,align)
  end
  def draw_actor_parameter2(actor, x, y, type)
    case type
    when 0
      parameter_name = $data_system.words.atk
      parameter_value = actor.atk
    when 1
      parameter_name = $data_system.words.pdef
      parameter_value = actor.pdef
    when 2
      parameter_name = $data_system.words.mdef
      parameter_value = actor.mdef
    when 3
      parameter_name = $data_system.words.str
      parameter_value = actor.str
    when 4
      parameter_name = $data_system.words.dex
      parameter_value = actor.dex
    when 5
      parameter_name = $data_system.words.agi
      parameter_value = actor.agi
    when 6
      parameter_name = $data_system.words.int
      parameter_value = actor.int
    end
    self.contents.font.color = system_color
    self.contents.draw_text(x, y, 120, 32, parameter_name)
    self.contents.font.color = normal_color
    self.contents.draw_text(x + 164, y, 36, 32, parameter_value.to_s, 2)
  end
  alias cbs_draw_actor_hp draw_actor_hp
  def draw_actor_hp(actor, x, y, width = 146, height = 15)
    bg = Color.new(  0,  0,  0, 160)
    c1 = Color.new(255,  0,  0, 0)
    c2 = Color.new(255, 255,  0, 160)
    self.contents.fill_rect(x, y, width, height, bg)
    width2 = width * actor.hp / actor.maxhp
    gradient(x + 1, y + 1, width2 - 2, height - 2, c1, c2)
    cbs_draw_actor_hp(actor, x, y, width)
  end
  alias cbs_draw_actor_sp draw_actor_sp
  def draw_actor_sp(actor, x, y, width = 146, height = 15)
    bg = Color.new(  0,  0,  0, 160)
    c1 = Color.new(  0,  0, 255, 0)
    c2 = Color.new(  0, 255, 255, 160)
    self.contents.fill_rect(x, y, width, height, bg)
    if actor.maxsp != 0
      width2 = width * actor.sp / actor.maxsp
    else
      width2 = width * actor.sp / 1
    end
    gradient(x + 1, y + 1, width2 - 2, height - 2, c1, c2)
    cbs_draw_actor_sp(actor, x, y, width)
  end
  def gradient(x, y, width, height, c1, c2)
    for i in 1..width
      x2 = x + i - 1
      r = c1.red * (width - i) / width + c2.red * i / width
      g = c1.green * (width - i) / width + c2.green * i / width
      b = c1.blue * (width - i) / width + c2.blue * i / width
      a = c1.alpha * (width - i) / width + c2.alpha * i / width
      self.contents.fill_rect(x2, y, 1, height, Color.new(r, g, b, a))
    end
  end
end

Neste código já há alguns complementos que usaremos depois. Inicie o código da janela, chamando-a de Window_Hero_Status. Ela terá uma clausula no procedimento initialize, o herói em questão. Como vamos fazer um menu para um único herói, vamos usar muito daqui para a frente a var $game_party.actors[0], que indica o primeiro herói da equipe. Sempre que for desenhar qualquer classe ou módulo, lembre-se de ir colocando os end, para evitar erros futuros. Inicie o código da janela assim:

Código:
class Window_Hero_Status < Window_Base
  def initialize(actor)

  end
end

No initialize, você com certeza já sabe o que é necessário para o funcionamento da janela. Crie uma janela com 320 X 192, e declare as seguintes vars:

@actor = actor -> O Herói em questão
@frame = 0 -> Var necessária para a animação
@pose = 0 -> Var necessária para a animação


E crie já um procedimento refresh. Se você já prestou bastante atenção nas outras aulas, já sabe que são os procedimentos necessários de uma janela. Até aqui, seu código deve estar assim:

Código:
class Window_Hero_Status < Window_Base
  def initialize(actor)
    super(0, 0, 320, 192)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.contents.font.name = $fontface
    self.contents.font.size = $fontsize
    @actor = actor
    @frame = 0
    @pose = 0
    refresh
  end
  def refresh
 
  end
end

Na sessão refresh, vamos desenhar o herói, nome, level, Status, Exp, HP e SP. Para isso, usaremos alguns dos procedimentos declarados como complementos da classe Window_Base. Vamos lá. Inicie o Procedimento refresh com um self.contents.clear, necessário, pois é ele quem permite a aualização da janela sem erros. Agora, usaremos alguns procedimentos usados na Window_MenuStatus. Dê uma boa olhada na imagem do menu anterior e, imagine quais procedimentos serão usados. Os nomes são óbvios, como draw_actor_hp sabendo que draw é desenhar, bem... ;D Para que você não se complique muito, aqui está o código:

Código:
draw_actor_name2(@actor, 8, 0, 1)
    draw_actor_class(@actor, 96, 0)
    draw_actor_level(@actor, 96, 24)
    draw_actor_state(@actor, 96, 48)
    self.contents.font.color = system_color
    self.contents.draw_text(96, 72, 80, 32, "EXP:")
    self.contents.font.color = normal_color
    self.contents.draw_text(96, 72, 160, 32, @actor.exp_s + "/" + @actor.next_exp_s , 2)
    draw_actor_hp(@actor, 96, 100, 172)
    draw_actor_sp(@actor, 96, 124, 172)

O código de sua janela já deve estar assim:

Código:
class Window_Hero_Status < Window_Base
  def initialize(actor)
    super(0, 0, 320, 192)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.contents.font.name = $fontface
    self.contents.font.size = $fontsize
    @actor = actor
    @frame = 0
    @pose = 0
    refresh
  end
  def refresh
    self.contents.clear
    draw_actor_name2(@actor, 8, 0, 1)
    draw_actor_class(@actor, 96, 0)
    draw_actor_level(@actor, 96, 24)
    draw_actor_state(@actor, 96, 48)
    self.contents.font.color = system_color
    self.contents.draw_text(96, 72, 80, 32, "EXP:")
    self.contents.font.color = normal_color
    self.contents.draw_text(96, 72, 160, 32, @actor.exp_s + "/" + @actor.next_exp_s , 2)
    draw_actor_hp(@actor, 96, 100, 172)
    draw_actor_sp(@actor, 96, 124, 172)
  end
end

Acho que não há nada pior que escrever muito e não testar... Vamos testar nossa janela substituindo-a pela Window_MenuStatus do menu. procure a seguinte linha no Scene_Menu:

@status_window = Window_MenuStatus.new

Aqui, declare assim:

@status_window = Window_Hero_Status.new($game_party.actors[0])

repare que já enviamos para a janela o parametro do herói. Execute o game e abra o menu, ele deve estar assim:

Lição 8.2 - Scenes - Nosso Primeiro Menu - 2º Parte Image041

Ele ainda não tem o herói em movimento, por enquanto... Gerar uma animação, desde que você já tenha os quadros, é simples. No caso do Herói, é uma animação padrão, que o RMXP usa. Só vamos reproduzí-la. Lembra da aula passada quando falamos de Indexação?? Bem, se você pretende ser um bom programador, você verá essa palavra para o resto da sua vida... É ela que torna simples as tarefas que seriam complicadíssimas na linguagem. Vamos ver porque.

Declaramos duas vars no início do código, a @frame e a @pose. baseado na @frame, vamos "mover" o herói, e na pose vamos mudar sua direção. Observe a imagem abaixo:

Lição 8.2 - Scenes - Nosso Primeiro Menu - 2º Parte Image042

Na horizontal, temos nossos frames, na vertical nossas poses. Levando em conta a indexação(que sempre começa no zero) vamos apenas "Substituir" o quadro do herói que será desenhado. Para isso, acrescente este procedimento na sua janela:

Código:
def draw_actor_sprite
    #Limpa a área onde o heroi será desenhado
    self.contents.fill_rect(0, 32, 80, 120, Color.new(0, 0, 0, 0))
    #Carrega a imagem do herói numa var
    bitmap = RPG::Cache.character(@actor.character_name, @actor.character_hue)
    #desenha o herói, aumentado de tamanho e no frame correnspondente
    self.contents.stretch_blt(Rect.new(0, 32, 80, 120), bitmap,
    Rect.new(bitmap.width / 4 * @frame,  bitmap.height / 4 * @pose , bitmap.width / 4 , bitmap.height / 4))
  end

Se você observou bem esta matemática acima, já entendeu como funciona a "Animação". Mas eu vou explicar.
Quando usando a função Stretch_blt, explicada na apêndice sobre a classe Bitmap, ela desenha o bitmap no tamanho predefinido no rect, distorcendo se for mal calculada claro. Neste caso, eu fiz uma apliação mediana, pois as dimensões originais do char são de 32/48, aqui ele está sendo desenhado em 80/120. Agora a mágica vem aqui. Determinamos a área que será desenhada da imagem no Rect.new, usando uma fórmula bem simples:

bitmap.width / 4 * @frame

Aqui, eu digo ao Rect que eu quero que ele desenhe a imagem na posição X, usando a medida do bitmap dividida por 4 e multiplicada por @frame. Se você lembrar que qualquer valor multiplicado por 0 é 0, por 1 é ele mesmo, e assim vai, o rect muda de frame na direção Horizontal de acordo com a variação da var @frame. A mesma coisa acontece com a posição Y, e altura e largura não tem alterações. No procedimento refresh, adicione esta linha logo abaixo de self.contents.clear:

draw_actor_sprite

Experimente rodar seu projeto agora. O menu estará assim:

Lição 8.2 - Scenes - Nosso Primeiro Menu - 2º Parte Image043

O herói ainda está estático. bem, a solução já vem. Você se lembra que na Scene há um loop infinito que mantém tudo atualizado no procedimento update? que todos os objetos declarados na Scene possuem um objeto.update dentro do procedimento? É aqui que faremos nossa animação funcionar. Dentro da janela, insira um procedimento update, assim:

Código:
def update
    super
  end

O super significa que vamos apenas complementar o procedimento, o restante fica por conta da superclasse. Lembra das condições rápidas? aqui vamos usar a contagem de frames para, a cada determinado tempo, ele atualizar a imagem. assim:

Código:
if Graphics.frame_count % 10 == 0
@frame == 3 ? @frame = 0 : @frame += 1
draw_actor_sprite
end

MAS O QUE FIZEMOS AQUI ??
Toda vez que a contagem de frames radiciada por 10 retornar 0, a ação ocorrerá. Sim, é uma radiciação, é uma "Raiz". Porque isso? bem, se eu for explicar temos que abrir um tópico de aulas de matemática ... ;D O mais importante é que, toda vez que, na contagem de frames, existir o valor, ele efetue nossa condição. Se @frame for 3, ele a torna zero, se não, ele adiciona 1, e executa o draw_actor_sprite.

Depois de feito isso, rode seu game. MARAVILHOSO !!

Simples demais fazer uma animação. ( Meu pai sempre diz que depois que a onça tá morta qualquer um quer pegar no rabo dela ) ;D
Se quiser mudar a direção do herói, basta mudar o valor de @pose, entre 0 e 3.

UFA !! que dureza. Bem, esse foi mais um complemento do nosso menu. Ainda faltam 4 janelas, concertar funções, inserir o ABS... Bem, como eu sei que você se deu bem com este, o mais complexo, vou passar uma lição de casa... Observe a imagem abaixo, veja o que as outras janelas tem, as duas abaixo do herói. Uma delas mostra as armas, a outra os parâmetros. Todos estas funções você as encontra na Window_Status.

Lição 8.2 - Scenes - Nosso Primeiro Menu - 2º Parte Image046

Sua lição será criar estas duas janelas, e inserí-las no menu.

Mudar a posição das janelas é fácil, já falamos sobre x e y e tenho certeza que pra você será simples. As outras( Nome do Mapa e Armas do SBAS) faremos na próxima aula.

Por enquanto é só.

Obrigado.

http://elementosrpgmakerbr.forumeiros.com/forum

BrunoFox

BrunoFox
Administrador
Administrador
Nossa muito boa essa lição vou usar! +rep

https://templorpgmakerbr.forumeiros.com

Fetelk13

Fetelk13
Membro Honorário I
Membro Honorário I
BrunoFox escreveu:Nossa muito boa essa lição vou usar! +rep

Ainda bem que gostou :^^:

http://elementosrpgmakerbr.forumeiros.com/forum

Conteúdo patrocinado


Ver o tópico anterior Ver o tópico seguinte Ir para o topo  Mensagem [Página 1 de 1]

Permissões neste sub-fórum
Não podes responder a tópicos