Quero iniciar esta aula agradecendo a todos pela paciência.
Tenho estado com tantos projetos ao mesmo tempo que meu tempo livre acabou. Ser Baixista(1º Hobby), Arquiteto de Soluções(Emprego) e Marido(Obrigação Feliz) 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. é possível fazer para quantos chars quiser.
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:
classWindow_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 when0 parameter_name = $data_system.words.atk parameter_value = actor.atk when1 parameter_name = $data_system.words.pdef parameter_value = actor.pdef when2 parameter_name = $data_system.words.mdef parameter_value = actor.mdef when3 parameter_name = $data_system.words.str parameter_value = actor.str when4 parameter_name = $data_system.words.dex parameter_value = actor.dex when5 parameter_name = $data_system.words.agi parameter_value = actor.agi when6 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 in1..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 endend
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:
classWindow_Hero_Status<Window_Base def initialize(actor) endend
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:
classWindow_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 endend
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... Feliz Para que você não se complique muito, aqui está o 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:
classWindow_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) endend
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:
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:
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:
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:
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:
def update superend
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:
ifGraphics.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 ... Feliz 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 ) Feliz
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.
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.
Obrigado.
Welkom bij de ultieme gids voor webdesigners die de kunst van websiteoptimalisatie onder de knie willen krijgen. In het huidige digitale tijdperk, waarin elke seconde telt en de aandachtsspanne korter is dan ooit, is het van cruciaal belang dat websites bliksemsnel, visueel verbluffend en zeer interactief zijn. Als experts op dit gebied begrijpen we hoe belangrijk het is om een naadloze gebruikerservaring te creëren die niet alleen bezoekers boeit, maar ook conversies maximaliseert en tastbare resultaten oplevert. In deze uitgebreide blogpost gaan we dieper in op de basisprincipes van websiteoptimalisatie, waaronder best practices, inzichten uit de branche en bruikbare tips waarmee u uw webdesignvaardigheden naar een hoger niveau kunt tillen. Maak je dus maar vast, want deze reis brengt je diep in het hart van websiteoptimalisatie en rust je uit met de tools die je nodig hebt om impactvolle online ervaringen te creëren die een blijvende indruk achterlaten bij je gebruikers. De basisprincipes van Website optimalisatie