sexta-feira, 23 de novembro de 2012

Novo Projeto

Galera agora estou com um novo blog: Update and Draw
Nele estou atualmente ensinando como criar jogos para navegador (browser games).
Vou adorar ver vocês por lá!

Leia Mais...

domingo, 3 de junho de 2012

Tutorial básico sobre hashtable

Eai galera, há um tempo havia falado que iria fazer um tutorial sobre hashtables. Então chega de enrolação e vamos logo com isso.

Galera antes de ensinar sobre hashtable, vou dizer tudo que vocês precisam pra usar hashtable. Você terá que ter um conhecimento básico sobre variáveis array e precisará criar uma hashtable em uma trigger com evento "Map Initialization":


O que é uma Hashtable?


Hashtable é uma tabela na qual você pode guardar qualquer tipo de informação. Como se fosse uma variável array. Porém nas variáveis array só temos 1 indice, em hashtable temos 2.
Exemplo:
set variavel [1] = informação
set hashtable [1] [2] = informação
Veja o exemplo de hashtable, para absorver mais ainda:











Para salvar algo na hashtable você precisa fornecer dois índices (números) que serão como um código para achar a informação. Como no exemplo acima, eu quero guardar MinhaUnit dentro da MinhaHashtable no índice 0 (zero) e 0 (zero). Então para eu recuperar o que eu gravei na hashtable eu apenas tenho que usar o load (carregar/recuperar) nos índices 0 e 0 gravando direto na minha variável.

Mas qual a real vantagem da hashtable?


A vantagem é que cada coisa do mapa tem um id (código) chamado HandleId. Esse handle id é um número maior que o limite dos indices das variáveis array, que é 8191, mas não é maior que o limite para os indices da hashtable. E além disso, a hashtable possui dois indices, tornando o armazenamento de informações mais dinâmico ainda. Vou dar um exemplo. Vou ensinar a fazer um simples knockback (aquelas magias que empurram) usando hashtable. Usarei a magia Thunder Clap para ativar nosso knockback. veja:

Acima são as triggers do knockback com hashtable. Só quero explicar mesmo a linha que salvo o valor do Angulo no indice Key (Picked Unit), isso significa que usei o código daquela unidade para ser um índice. Assim quando eu for fazer o Pick Every Unit no grupo que está todos os alvos do knockback eu novamente usarei o Key (Picked Unit) para recuperar as informações que gravei. No outro índice ainda tenho que usar valores diferentes. Se a hashtable fosse mesmo uma variável com 2 índices, é como se eu tivesse fazendo isso:
set MinhaHashtable[0][PickedUnit] = Angulo
set MinhaHashtable[1][PickedUnit] = DistanciaRestante
Estou deixando no final do tutorial um mapa com esse knockback. Caso ainda tenha restado duvidas, eu aconselho tentar usar hashtables no world editor. Ver pessoalmente como elas funcionam. E mais outra coisa, se você sabe o que são leaks verá que nas triggers que postei está cheio deles. Se você não sabe o que são leaks, procure tutoriais na internet, para criadores de mapa esse é um assunto muito importante.

É isso ai galera, até a próxima!

Mapa de Demonstração


Leia Mais...

sexta-feira, 1 de junho de 2012

Atualização: Blog com syntax highlighter

Syntax highlighter para quem não conhece é uma maneira melhor de visualizar um código. Ele colore palavras importantes do código, facilitando assim a leitura. Sem falar que deixa o código bem mais bonito.

Então, existe um syntax highlighter na internet muito bom, porém como não tinha para "jass" eu improvisei uma.

Um exemplo de código com SH:

struct Bar
 method foo takes nothing returns boolean
  call KillUnit(GetTriggerUnit())
  return false
 endmethod
endstruct

Agora quando eu voltar a fazer as aulas de vjass os códigos estarão bonitinhos.

Até mais galera!

Leia Mais...

Como trabalhar com várias unidades de uma vez

De vez em quando precisamos fazer uma mesma coisa para várias unidades ao mesmo tempo. Por exemplo, eu tenho 10 footmans em um local do meu mapa, quando já tiver 2 segundos que o jogo começou todos os footmans vão morrer. Quando eu comecei a aprender sobre world editor eu pensaria em fazer uma trigger com 10 Kill Units, um para cada footman. Para nossa alegria, existe os Unit Groups (grupos de unidade), com eles trabalhar com várias unidades fica muito mais fácil.
Vamos denovo tentar matar nossos 10 footman, só que dessa vez de maneira mais fácil. Usaremos a action Pick Every Unit In Unit Group para agrupar todos os footmans e mata-los. Veja a trigger:

O evento ali faz a trigger executar automaticamente quando já estiver passado 2 segundos que o jogo começou (depois de terminar de carregar).
Nas actions, usamos o Pick Every Unit para agrupar todas "Units owned by Player 1 of type Footman", ou seja, todos os footmans que pertencem ao player 1. Em Loop - Actions, são as actions que acontece para cada unidade no grupo. O Picked unit referece à uma unidade do grupo de cada vez, ou seja, quando o Loop executar na primeira vez o Picked Unit será o primeiro footman do grupo, depois ele será o segundo, depois o terceiro e assim até o ultimo footman.

A linha acima do Pick Every Unit, aquele custom script, significa que queremos destruir o grupo depois que usa-lo. Por que se não destruirmos ele, ele vai ficará ocupando espaço na memória desnecessáriamente, o que conhecemos por Memory Leaks.

Bom galera é só isso, é bem simples assim mesmo. Voce não precisa necessáriamente usa-lo para matar unidades, pode usa-lo para teleporta muitas unidades de um lugar para outro, por exemplo.

Estou colocando um link para download de um mapa de exemplo, nele vocês podem notar que os footmans vão morrer todos ao mesmo tempo, isso por que o Pick Every Unit executa muito rápido.



Até a próxima galera!

Leia Mais...

domingo, 29 de abril de 2012

Como Renascer Árvores

Perguntaram ontem no Team Kings, um fórum que frequento, como que faz para renascer as árvores destruidas no mapa. É uma dúvida comum de muitos que estão começando no world editor e, por sinal, uma coisa muito útil para mapas que têm suas árvores constantemente destruidas. Assim vou ensinar como criar uma simples trigger que faça isso com eficácia.


A Trigger


Ontem quando ajudei aquele membro com essa dúvida, falei para ele usar duas triggers. Sendo que por ser em GUI, Uma causava um leak indestrutivel em GUI. Então resolvi reconsiderar e ver se existia uma maneira mais simples de renascer uma árvore. Então consegui chegar numa única trigger mais simples do que eu havia explicado para ele. Eis a seguinte trigger:


Explicando a Trigger


A trigger começa com um evento que detecta quando uma destructible morre. Nas condições você verifica se a destructible é uma árvore. Na trigger de exemplo, eu verifico com um "Or" se é uma das duas árvores de Ashenvale. Se a destructible for uma árvore então a trigger espera um certo tempo (no exemplo foi 10 segundos) e, logo após, renasce a árvore.
Para configurar a trigger é muito fácil. Se voce quiser que a trigger detecte outras arvores apenas adicione mais condições iguais aquelas modificando apenas o tipo da arvores que voce deseja. Se quiser que demore mais ou menos tempo para renascer, modifique o valor do wait.
Estou postando também um MAPA de exemplo. Mas acho que ele nem era preciso.


Até a próxima, meus camaradas.

Leia Mais...

sábado, 8 de outubro de 2011

Magia Simples em vJass

Fiz essa magia (um Blink) para tentar mostrar um pouco de jass para um padawan meu. Espero que ajude mais pessoas também.


Leia Mais...

segunda-feira, 19 de setembro de 2011

3ª Aula de vJass - Aprendo mais sobre struct

Primeiramente, desculpa pela demora da 3ª aula. Nem ia dar ela tão cedo, ando muito ocupado com java e faculdade, até esqueço do resto do mundo (nerdisse do caramba). Mas um colega meu (Victor) conseguiu arrumar o JNGP no computador dele. Então vou dar essa aula nova, que pretendo ensinar sobre structs, methods e variaveis. Vamos lá, né?

Quem leu a segunda aula viu que mostrei um exemplo de struct e expliquei sobre structs e o method onInit. Vamos relembra-lo:
library Exemplo1
 struct MyStruct
  // Meu primeiro código
  static method onInit takes nothing returns nothing
   call BJDebugMsg("Hello World!")
  endmethod
 endstruct
endlibrary
Então essa nossa struct apenas mostrava uma mensagem ("Hello World") quando o jogo começava. Vamos ir além dessa vez. Antes de prosserguimos gostaria que vocês entendessem que uma struct é um "objeto". Um objeto pode ter caracteristicas e comportamentos e além disso um objeto é um tipo de dado (assim como unit, effect, player, group, etc). O method onInit, por exemplo, é um "comportamento inicial" da nossa struct. Veja:

library Exemplo2
 struct Object
  // Agora nossa struct chama Object
  // nosso Object tem um comportamento (method) stop.
  method stop takes nothing returns nothing
   call BJDebugMsg("object paused")
   call TriggerSleepAction(10)
   call BJDebugMsg("object unpaused!")
  endmethod

  static method onInit takes nothing returns nothing
   local Object obj = Object.create() // cria um objeto do tipo Object
   call obj.stop()
   call obj.destroy() //destroi o objeto
  endmethod
 endstruct
endlibrary
No código acima a struct Object tem um method (comportamento) chamado stop. Esse method faz a mensagem object paused aparecer na tela e executa uma function chamada TriggerSleepAction, essa function é o famoso wait do GUI. O numero 10 indicado entre parenteses é o numero de segundos que pausará, no caso 10 segundos. Logo depois dos 10 segundos do wait, mostra a mensagem object unpaused. Percebeu que aquele method não tem static na declaração dele? Isso quer dizer que aquele method só pode ser executado de um Object "criado" ou como dizemos em programação instanciado.
No method onInit (o que sempre executa quando o jogo começa) nós criamos um Object:
local Object obj = Object.create()
O que fizemos ali foi criar uma variável para guardar o Object que criamos. O local significa que aquela variavel só vai existir dentro daquele method (no caso, o onInit). Object é o tipo da variável (lembra que as struct são tipos?) e por ultimo, obj é apenas o nome da nossa variável local. Agora sim, Object.create() isso é que cria um objeto (instancia uma struct). Voce poderia chamar isso sem colocar numa variavel:
call Object.create()
Mas voce não poderia acessar aquele objeto, pois ele não teria um registro (uma variável). Quando executamos obj.stop(), fizemos o objeto criado que estava guardado na variavel obj chamar o method stop dele. O ponto final entre o nome e o method é importante, nunca esqueçam dele. Logo em seguida, destruímos nosso objeto com o obj.destroy(). O comando destroy libera o espaço daquela instancia da struct. "Cada struct" só pode ter 8190 instancias, ou seja, só pode ser criada 8190 vezes de uma vez. Então Para completar a aula ensinarei a criar variáveis locais. É facil:
local tipo-da-variavel nome-da-variavel
Exemplos:
local unit caster
local effect efeito
local timer tempo
local player jogador1
local integer i
Voce pode "setar" o valor dela na criação ou durante o method, como qualquer variável:
set caster = GetTriggerUnit()
set i = 1348
Mas cuidado, as variáveis locais podem causar leak quando você não remover o conteúdo delas. Apenas as variaveis do tipo handle podem causar leak. Handle é tudo que não é integer, real, boolean e string. Ou seja, unit, effect, timer, group, force, etc. Dê uma olhada no documento Common.j dentro do MPQ do war3 para saber mais. E qualquer variável do tipo de uma struct também não causa leak, voce só precisa destruir aquela instancia quando não precisa mais dela. Mas como remove um conteudo de uma handle? Apenas no final seu method dê set para null. Veja:

method XXX takes nothing returns nothing
 local unit u = GetTriggerUnit()
 local integer i = 12 // integer não causa leaks
 // código restante do method
 // ...
 set u = null
endmethod
Espero que essa aula tenha sido muito esclarecedora. 
Então, até breve!

Leia Mais...

domingo, 18 de setembro de 2011

Download do JNGP

Jass New Gen Pack, JNGP, é um World Editor com ferramentas extras. Ele é muito usado por ter Jasshelper, um compilador de vJass. Porém, o jnpg causa um pouco de ódio à alguns, pois de vez em quando aqueles que tentam usa-lo, simplismente não conseguem. Vamos ver as possiveis falhas que não permitem que o jnpg teste seu mapa.


Jasshelper desativado: Talvez no seu mapa tenha algum código de vJass, ai você precisa do Jasshelper. Então vá no menu JassHelper e veja se Enable JassHelper está marcado, caso não esteja marque-o.
Reinventing the Craft: nunca deixe o Enable Reinventing the Craft marcado.
Testar mapa sem salvar: sempre quando for testar seu mapa, salve ele.
Desative o seu anti-virus/firewall: o jngp é confundido com virus por eles.
Use um Warcarft Register/Fixer: já me ajudou uma vez.


Pode haver outras coisas que influencie para que o JNPG não funcione, caso saiba de algum, comente por favor.



Leia Mais...

quarta-feira, 10 de agosto de 2011

Mais Atualização no Spellpack

Um colega meu tava testando as magias e acabou vendo 2 bugs no torrent, mas já corrigi. Atualizei o spellpack para 1.1b.

Mudanças:
- Consertado um bug no torrent que fazia ele não explodir.
- Consertado um bug no torrent que fazia ele abrir visão da área permanentemente.

Link do Dota Spellpack

Leia Mais...

Atualização: DotA Spellpack v1.1

Dota Spellpack foi atualizado para 1.1.

Mudanças:
- Guia de configuração para Ravege e Avalanche adicionado.
- Trigger de configuração do Torrent adicionado.
- Damage do Torrent agora pode ser dividido em duas partes.
- Torrent agora causa slow e libera visão da área da explosão (como no DotA).
- Adicionado Trigger de "Respawn de creeps" e "Remoção de dummies".


Leia Mais...