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...

terça-feira, 9 de agosto de 2011

Magias de DotA

 Spellpack de magias do DotA. Ainda está em contrução, aos poucos estou adicionando mais magias.


Lista de magias que já tem:
- Torrent (Kunkka)
- Avalanche (Tiny)
- Ravege (Tidehunter)
Lista de Magias que estão por vim:
- Meat Hook (Pudge)
- Chronosphere (Void)
- Fissure (Earthshaker)
Changelogs: 
v1.1b
- 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.
v1.1
- 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".
v1.0
- Criação do spellpack.

Leia Mais...

quinta-feira, 28 de julho de 2011

MUI: Indexagem em GUI

Eai garotada, venho aqui ensinar como fazer, de um jeito super simples, magias MUI. No final do tutorial tem um mapa demo. Mas deixe para baixa-lo apenas depois do tutorial, tente fazer nossa magia MUI apenas lendo o tutorial. Nesse tutorial você terá que saber sobre variáveis array e sobre memory leaks, coisas importantes para quem quer aprender MUI.

Mas tio Bills o que é MUI?

MUI na teoria significa Multi-Unit Instanceability. Na prática significa qualquer coisa (não apenas magias) que possa ser usada por vários jogadores e unidades, diferentes ou iguais, ao mesmo tempo sem bugar.


     



    E como eu faço isso?
    É muito simples, jovem gafanhoto. Vou te ensinar pelo jeito mais fácil em GUI, a indexagem. Para quem não sabe o que é indexagem, é um jeito organizar dados de forma que você possa recupera-los através de seu index (um numero de referencia). É como se você fizesse uma “matriz” de dados ou uma lista.

    Vendo essa tabela imaginem uma trigger que roda a cada 1 segundo. Toda vez que ela roda ela busca todos os index, do primeiro (1) ao ultimo (3), Fazendo o CASTER[index] causar o DAMAGE_PER_SECOND[index] ao TARGET[index]. Assim quando o index ser 1, o CASTER[1] (Paladin) vai causar DAMAGE_PER_SECOND[1] (30) ao TARGET[1] (Death Knight), quando ser 2 seria... ah, só olhar na tabela.
    E como faríamos para saber qual é o primeiro index, o ultimo e como faríamos a trigger procurar por todos. Para isso usaremos o comando “For”.







      Mais para frente explicarei o "For", caso voce tenha alguma duvida.

      Vamos começar então?
      Para ensinar MUI vou dar um exemplo bem fácil, vamos criar uma shockwave MUI \o/. Eu sei que a shockwave do warcraft já é MUI, mas quero apenas usa-la como exemplo. Para criar uma shockwave totalmente triggered precisaríamos de uma dummy (que seria a wave/efeito), um trigger para inicia-la e também um trigger periodic (que ocorra a cada “0.03” segundos). Sem MUI, precisaríamos apenas de criar algumas variáveis, armazenar alguns dados nas variáveis quando a magia fosse usada, criar a dummy e armazena-la, mandar ativar a periodic, depois a periodic faria a dummy mover. E todos seriamos felizes, mas queremos mais, queremos MUI!


      Tá, e como vai ser em MUI ?
      Seria quase a mesma coisa, apenas teríamos que criar um novo index e armazenar os dados daquela execução da magia em variáveis “array” usando esse novo index.
      Obs: Para o tutorial usarei a sigla SW para referir a shockwave.

      Vamos lá, crie essas variáveis:

      SW_indexCount (Integer – Default Value: 0)
      SW_newIndex (Integer – Default Value: 0)
      SW_MUI_indexExists (Boolean – array – Size: 1)
      SW_MUI_waveCount (Integer – Default Value: 0)
      SW_MUI_Dummy (Unit – array – Size: 1)
      SW_MUI_Distance (Real – array – Size: 1)
      SW_Loop (Integer)
      Obs: outras variáveis vão aparecer no tutorial, tipo TempUnit. Com essas você pode usar alguma que já tenha ou crie elas se precisar.

      Nossa magia vai começar sempre que uma unidade usar a SW. Ops, já ia me esquecendo, crie uma dummy com locust e mude o modelo dela para o míssil da Shockwave, que vou chamar de SW Dummy, e crie também uma magia shockwave (retire todos efeitos e damage). Vamos lá, quando alguém usar a nossa shockwave custom, o trigger criará um novo index e assim armazenaremos todas as informações em nossas variáveis array usando nosso novo index.

         








        Toda vez que a magia for usada, a SW_indexCount vai ganhar +1 e a SW_newIndex guardará esse novo valor de SW_indexCount. Assim, toda que a magia for usada SW_indexCount vai aumentar seu valor, ficando toda vez diferente. Usaremos SW_MUI_indexExists para saber se a index existe (usaremos ela parar fazer a magia acontecer), se ela for true é porque o index existe e está sendo usado. A SW_MUI_waveCount vai contar quantas waves (dummy) estão se movendo ainda, ou seja, quatas SW ainda estão em andamento.
        Continuando nossa trigger, agora armazenaremos nossas informações e criaremos a dummy. Nessa parte uso algumas variáveis extras para adquirir valores e também para pegar um ângulo.














          Como viu usei algumas variaveis extras. É sempre bom que você armazene valores que serão usados mais de uma vez em variaveis temporárias. Pois o computador busca bem mais rápido uma variável do que uma função (Triggering Unit é uma function, por exemplo). Voltando... O “if” no final da trigger serve para ativar a periodic, caso ela esteja off.
          Obs: essa “Shockwave MUI movement” é nossa próxima trigger, crie ela antes de fazer essa parte.


          Criando uma Periodic com Indexagem
          Agora temos que fazer que todas as magias registradas no index de SW_indexCount seja movidas e causem dano nas unidades inimigas. Não vou explicar como se move uma dummy, não estou fazendo tutorial disso.
          Vamos lá, faça uma trigger chamada “Shockwave MUI movement” e desmarque a opção “Initally On”.
          No evento use “Time – Periodic Event”, coloque 0.03. Nenhuma condição.





            Agora faça o resto da trigger:














              Primeiro vou explicar o “for”, talvez tenha gente lendo isso que não entende ainda. O “for” no GUI pode usar Integer A, Integer B ou uma Integer a sua escolha (como no nosso caso). “For each” significa “Para cada”, Para cada inteiro (integer) de 1 até SW_indexCount (numero de index já usados) ele executará as functions no “Loop – Actions”. Ou seja, se a gente já tiver usado 3 indexs, ele executará ... ? 1 vez, 2 vezes, 3 vezes. 1 vez para cada index. A variável SW_Loop que foi nosso integer escolhido irá ter o valor 1 na 1ª execução, 2 na 2ª , 3 na 3ª e etc. Assim podemos buscar todos as informações guardadas nas nossas variáveis array.
              O primeiro “if”, SW_MUI_indexExists[SW_Loop] Equal to True (verdadeiro), serve para saber se o index existe e está sendo usado. Se der false (falso) é porque o index já foi usado, mas não está mais.
              O próximo if é “SW_MUI_Distance[SW_Loop] less than 1500”, se a distancia percorrida pela wave daquele index ainda é menor que 1500 (nossa distancia máxima), o trigger executa o que está dentro de “Then - Actions”. Ou Se a distancia for “maior ou igual” a 1500 executa o que está dentro do “Else - Actions”. Um if sempre executa apenas um bloco (Then ou Else), nunca os dois.
              Se a distancia for menor que 1500 a dummy irá mover mais 50 de distancia, até chegar no máximo (1500). Senão (else) o index dela será marcado que não existe (não está mais em uso), a dummy será destruída e SW_waveCount será subtraído 1. Lembrando que SW_MUI_waveCount conta quantas waves estão ativas no mapa.
              Lá no final temos um “if”, reparem que ele está fora do “for”, ou seja, ele só será executado quando o for (daquela execução do trigger) terminar. Esse for determina, se a SW_MUI_waveCount for igual a 0 (zero), desativa esse trigger (o periodic), pois não tem nenhuma wave ativa. Só precisamos que ela fique “ligada” quando tiver waves. Lembra que quando uma unidade usar nossa SW, se a periodic estiver “off” ela é ligada, lembrou? E pra finalizar SW_indexCount volta pra 0 (zero), pois nenhum index está sendo utilizado, então ele terá novamente o valor inicial.


              Nesse tutorial eu quis explicar apenas o básico de como fazer uma habilidade MUI, vocês podem se esforçar e ainda aprender sobre reciclagem de index. Procurem baixar mapas de magias no Hive WorkShop, geralmente as magias são todas MUI. Aé, caso você ficou com alguma duvida em alguma parte, baixe o Mapa de demonstração e veja nele. Nesse mapa coloquei duas shockwaves, uma MUI e uma não-MUI, para você verem o que pode acontecer quando uma magia não é MUI e ela é executada varias vezes ao mesmo tempo. No mapa as magias não tem cooldown nem mana cost, então usem varias vezes de uma vez cada shockwave e verá o que é ser MUI.


              Espero ajudar alguns com esse tutorial, beijos e abraços do Mano Bills!


              Leia Mais...

              Comentem!

              Caso voce esteja lendo meu blog e tenha gostado ou não gostado do post, poderia comentar algo? Não custa nada e só vai gastar um pouquinho seu teclado. Isso me ajuda à ajudar vocês.

              Grato desde já, volte sempre.

              Leia Mais...

              2ª Aula de vJass - Primeiras Noções

              Bom essa será nossa segunda aula, sugiro que leiam ela como muita atenção.
              Antes de tudo voce deve saber que vJass é "case sensitive", ou seja, letras maiusculas e minusculas fazem diferença. Unit, é diferente de UnIt ou uNiT ou unit ou uniT e etc. Desta maneira os comandos if e loop, por exemplo, só podem ser escritos em letras minusculas senão o compilador irá interpretá-los como variaveis.

              Primeiro Código

              Vejamos esse código escrito em vJass:
              library Exemplo1
               struct MyStruct
                   // Meu primeiro código
                   static method onInit takes nothing returns nothing
                       call BJDebugMsg("Hello World!")
                   endmethod
                endstruct
              endlibrary

              Este codigo exibirá a messagem Hello World! na tela quando seu mapa iniciar.

              Vamos entender o codigo

                  A linha library Exemplo1 cria uma library nomeada Exemplo1. Uma library é como se fosse um bloco de notas com codigos. Por enquanto é apenas isso que voce precisa saber. Caso queira saber mais leia este tutorial que eu fiz. Quando voce quiser terminar sua library, voce deve apenas escrever a linha (vista no final do código) endlibrary. Esta linha é obrigatória, nunca se pode deixar uma library aberta (sem o seu endlibrary).
                  Quando fazemos um código, uma boa idéia é usar comentarios que ajudem a explicar partes dele. No nosso código temos o comentario // Meu primeiro código, viu né? O compilador desconsidera qualquer coisa que esteja escrito depois do // naquela linha.
                  A linha struct MyStruct cria uma struct e nomeia ela de MyStruct. Uma struct é um objeto e como um objeto, ela pode ter varias caracteristicas. Nas proximas aulas voces entenderam melhor. Assim como na library, o compilador precisa saber onde termina sua struct, para isso apenas escreva endstruct depois de escrever os códigos da sua struct.
                  O static method onInit takes nothing returns nothing é nosso method que sempre vai iniciar junto com o mapa. O method onInit (escrito desse jeito, lembre-se do case sensitive) de uma struct sempre será executado quando seu mapa iniciar, sempre deve ser static e takes nothing returns nothing. O termo static vocês entederam mais tarde. A parte takes nothing diz que o method não precisa de nenhuma variavel para ser executado. Quando voce quiser que um method use alguma variável você pode passar o valor dela pra essa function. E returns nothing significa que esse method não retorna nenhum valor. Um method pode retornar um valor (move speed de uma unit, por exemplo) e você pode preferir guardar esse valor em uma variável. O onInit é o nome do method, esse nome pode ser qualquer um. Contando que não se repita ou comece com números. Aé, methods também precisam ser encerrados. Apenas coloque endmethod no final dele.
                  Única coisa que esse código faz é exibir a messagem Hello World!. 
              function BJDebugMsg takes string msg returns nothing
                  Olha ai, essa function (que é quase a mesma coisa que um method) requer uma string: takes string msg. Uma string é um conjunto de caracteres, quem conhece de trigger editor sabe disso. O comando BJDebugMsg exibe a string msg na tela por um minuto. Só!
                  Antes do comando pode ver que tem a palavra call, que significa chamar. Ele que chama/executa o comando. Uma string sempre deve ser escrita entre aspas (" "), sempre. Um exemplo:
              Faz de conta que voce quer mostrar mostrar a messagem Game Over. Então ficaria assim:

              call BJDebugMsg("Game Over")
                  As coisas escritas dentro dos parenteses são os parametros do comando, o takes dela. Quando um comando tem takes nothing você precisa apenas deixar os parenteses vazios.
              Exemplo:

              call CreateTimer() // um comando que cria um countdown timer.
              call CreateTimer // assim daria erro, faltou os parenteses.
              Quando um comando tem algum returns, voce pode preferir guarda o valor do retorno dela. O comando CreateTimer, por exemplo, é takes nothing returns timer. Ou seja ele retorna um timer, um timer que acabou de ser criado. Faz de conta que voce tem uma variável chamada TempTimer e você quer guarda um novo timer nela:

              set TempTimer = CreateTimer()
              // O comando CreateTimer foi chamado e seu valor de retorno
              // foi guardado na variavel TempTimer


              Primeiramente, desculpe pelas aulas serem semanais. Tentarei faze-las em um periodo mais curto. Espero que tenham entendido sobre esse inicio, voce ainda estará confuso, mas é assim mesmo. Logo logo voce estará entendendo a sintexe do vJass.

              Abraços.

              Leia Mais...

              quinta-feira, 21 de julho de 2011

              1º Aula de vJass - INTRODUÇÃO

                  Vamos, nestas lições, aprender os conceitos básicos da linguagem de programação vJass a qual é muito famosa entre os editores experientes de warcraft, devido ao seu poder.

              Leia Mais...

              quarta-feira, 20 de julho de 2011

              Novo Visual

              Modifiquei um pouco o blog, espero que tenham gostado.
              Em breve falarei de um projeto em que estou trabalhando e tambem iniciarei umas lições de vJass.

              Abraços, até a proxima.

              Leia Mais...

              domingo, 12 de junho de 2011

              Atualizações no Buff Generator

              Buff Generator atualizado pra 1.4b. Apenas poucas mudanças no codigo. E o BGType foi para a versão 1.01, agora ele tambem expecifica o buff por magico (magical) ou fisico (physical).

              Abraços

              Leia Mais...

              segunda-feira, 6 de junho de 2011

              Buff Generator

              Atualizei meu system para a versão 1.4. E agora ele chama Buff Generator.

              Siga o link: http://blizzeditors.com.br/topic/17-buff-generator/

              Leia Mais...

              sexta-feira, 3 de junho de 2011

              Aprenda a Fazer Recipes

              O que você vai precisar:
              • 3 itens (no minimo)
              • Noção básica sobre Triggers (para fazer uma trigger simples)
              • Criatividade para criar seus próprios recipes (Opcional)
              Vamos iniciar pelo início:
              Um recipe, no contexto popular, é o que podemos chamar de fusão de itens: "Quando um herói pegar tais itens, eles se juntam e formam apenas um (mais poderoso geralmente)", por exemplo. Você com certeza já viu isso em algum mapa, aposto que foi no DotA.
              Pois bem, se você está lendo esse tutorial, tem uma grande chance de você está querendo aprender a fazer isso. Você irá se surpreender como é facil.

              Vamos fazer nossos itens:
              Vamos começar fazendo apenas um teste, uma demonstração. Depois de aprender a fazer um recipe, você estará pronto para fazer seus recipes como você quiser.
              • Crie 3 novos itens.
              • Nomeie um de Item 1, outro de Item 2 e o ultimo de Item 3.

              Pronto, já temos nossos itens. Vamos trabalhar agora com a trigger, que irá fazer o Item 1 e Item 2 se jutarem e formar o Item 3.

              Evento:
              Precisamos de um evento que verifique quando uma unidade pegar um item. Usaremos esse:

              Events
                  Unit - A unit Acquires an item

              Assim, esse evento ativa a trigger quando uma unidade (qualquer uma) pegar um item.

              Condições:
              Para que o trigger não ative toda hora que uma unidade qualquer pegue um item, colocaremos a seguintes condições:

              Conditions
                  Or - Any (Conditions) are true
                      Conditions
                          (Item-type of (Item being manipulated)) Equal to Item 1
                          (Item-type of (Item being manipulated)) Equal to Item 2

              Essas condições irão verificar se o item que foi adiquirido é o Item 1 ou Item 2. Se não for um desses dois, não irá acontecer nada.

              Ações:
              É aqui que a mágica acontece. Iremos agora fazer com que a trigger verifique se a unidade tem os itens certos. Caso ela tenha, esses itens irão desaparece (fundir) e ela ganhará o Item 3 (a fusão dos Item 1 e Item 2). Essas são as ações:


              Actions
                  -------- Primeiro confira se a unidade tem os itens que precisa --------
                  If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                      If - Conditions
                          ((Triggering unit) has an item of type Item 1) Equal to True
                          ((Triggering unit) has an item of type Item 2) Equal to True
                      Then - Actions
                          -------- Se ela tiver, remova os itens de requerimento --------
                          Item - Remove (Item carried by (Triggering unit) of type Item 1)
                          Item - Remove (Item carried by (Triggering unit) of type Item 2)
                          -------- Adicione o item novo --------
                          Hero - Create Item 3 and give it to (Triggering unit)
                      Else - Actions
              Efeitos:
              Bem, a sua trigger já está completa. Mas caso você queira que algum efeito aconteça quando ela juntar os itens, é só por essas actions no final da trigger:

              -------- Cria um efeito na unidade --------
              Special Effect - Create a special effect attached to the origin of (Triggering unit) using Abilities\Spells\Items\AIam\AIamTarget.mdl
              -------- Destrua o efeito, para não causar lag --------
              Special Effect - Destroy (Last created special effect)

              O efeito que usei foi o "Abilities\Item Agility Gain". Depois dele coloquei uma ação que destroi um efeito especial depois que ele termina, não ligue para ela caso você não tenha entendido. Futuramente você entenderá.

              Resultado Final:
              Nossa trigger finalizada ficou assim:

              Trigger Pronta
                  Events
                      Unit - A unit Acquires an item
                  Conditions
                      Or - Any (Conditions) are true
                          Conditions
                              (Item-type of (Item being manipulated)) Equal to Item 1
                              (Item-type of (Item being manipulated)) Equal to Item 2
                  Actions
                      -------- Primeiro confira se a unidade tem os itens que precisa --------
                      If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                          If - Conditions
                              ((Triggering unit) has an item of type Item 1) Equal to True
                              ((Triggering unit) has an item of type Item 2) Equal to True
                          Then - Actions
                              -------- Se ela tiver, remova os itens de requerimento --------
                              Item - Remove (Item carried by (Triggering unit) of type Item 1)
                              Item - Remove (Item carried by (Triggering unit) of type Item 2)
                              -------- Adicione o item novo --------
                              Hero - Create Item 3 and give it to (Triggering unit)
                              -------- Cria um efeito especial na unidade (isso é opcional) --------
                              Special Effect - Create a special effect attached to the origin of (Triggering unit) using Abilities\Spells\Items\AIam\AIamTarget.mdl
                              Special Effect - Destroy (Last created special effect)
                          Else - Actions
              Espero do fundo do coração que você tenha entendido tudinho. Caso não tenha encontrado alguma ação ou condição, poste que eu te ajudo.



              Obrigado por ler.

              Leia Mais...

              quarta-feira, 30 de março de 2011

              O que faz um jogo ser um sucesso ou leva-lo ao fracasso?

              Esta é realmente um pergunta difícil de responder, pois envolve muitos aspectos diferentes. Neste tutorial, vamos ver alguns desses aspectos, na esperança de que vai ajudar você a criar jogos melhores. Este tutorial é um resumo do tutorial escrito por Mark Overmars.

              O que é um jogo?
              Antes de falar sobre bons jogos você deve saber o que um jogo é em primeiro lugar. Há uma quantidade surpreendente de discussões sobre esta questão e há muitas definições diferentes. É mais fácil dizer o que um jogo não é.

              Um jogo não é um filme (OH RLY?)
              Isto é bastante óbvio, mas por quê? Que elementos dos jogos estão faltando nos filmes? A principal diferença é que não há participação ativa do espectador em um filme. O espectador não tem controle sobre o filme e não pode tomar decisões que influenciam o resultado do filme. Além disso, o resultado final do filme é fixo (embora o espectador não pôde sabê-lo). Este é um aspecto crucial de filmes e peças teatrais. Nos jogos, o oposto é verdadeiro. As pessoas não gostam quando o resultado de um jogo é fixo. Elas querem influenciar o resultado. Elas querem estar no controle.

              Um brinquedo não é um jogo
              Você brinca com um brinquedo, mas não brinca com um jogo. Você joga o jogo. Alguns jogos chegam bem perto de serem um brinquedo. Um briquedo não tem objetivos predefinidos, você tem que cria-los por conta própria. Por exemplo, em The Sims não há objetivos claramente definidos. Você pode ter sua própria família e criar seus próprios objetivos (como criar a família mais bonitinha), mas não há realmente uma noção de ganhar o jogo. Você pode adicionar essa noção por si só (criando uma meta pra você), mas isso não será um fim natural. Mas claro, não há nada de errado em criar brinquedos interativos de computador.

              Um quebra-cabeça não é um jogo
              Este é mais difícil. É evidente que muitos jogos contêm elementos de quebra-cabeça. Mas um quebra-cabeça é estático, enquanto que um jogo é dinâmico e mudanças irão ocorrer enquanto jogá-lo. Um jogo pode ser jogado uma e outras vezes e há diferentes estratégias que levam ao sucesso.

              Então, o que é um jogo? Aqui está uma definição possível:
              Um jogo é uma atividade (vamos dizer assim) em que um ou mais jogadores tomam decisões através do controle de objetos do jogo e de recursos, em busca de um objetivo.
              Note que a definição não fala sobre gráficos ou efeitos sonoros (no caso de jogos de computador). Tais aspectos, obviamente, desempenham um papel importante para torna-los jogos atraentes, mas não são os aspectos essenciais dos jogos. Vejamos os ingredientes diferentes da definição em alguns detalhes. Focando sempre nos jogos de video game e computador.

              Um jogo de computador é um software
              Esta situação torna bastante diferente de outros jogos . Por exemplo, jogos de tabuleiro ou esportes. Ela tira um pouco da diversão dos jogos. Não há peças para se movimentar e não há satisfação física (Embora o Nitendo Wii e o Kinect estão mostrando o contrário). Também os aspectos sociais são menos importantes, embora os MMOs criaram uma nova forma de interação social. Mas nós ficamos um pouco em troca. Um software pode se adaptar muito melhor aos jogadores. A maioria dos jogos de computador têm um elemento em tempo real que não está presente em jogos de tabuleiro. O jogo continua mesmo quando os jogadores não fazem nada. Isso pode levar a emoção maior e uma melhor sensação de presença no mundo do jogo. Jogos de computador também podem se adaptar aos jogadores tornando-o satisfatório para jogadores muito diferentes, tanto para iniciantes ou veterandos. A possibilidade de ter adversários controlados pelo computador adiciona muitos novos desafios. Os jogos de computador também podem ser mais complexos, porque o próprio jogo pode ajudar os jogadores a entender os diferentes aspectos e ensinar o jogador a jogar. Finalmente, os jogos de computador podem criar um ambiente mais envolvente, adicionando gráficos maravilhosos, músicas e cenas cortadas.

              Um jogo de computador tem jogadores
              Isto é bastante óbvio. Um jogo não é algo para assistir. Você deve estar envolvido em um jogo. Não subestime a importância do jogador. Game designers iniciantes geralmente se esquece que você faz não o jogo para si, mas para as pessoas que estão indo jogar. Assim, você sempre tem que pensar em quem eles são. Um jogo para crianças deve ser bastante diferente de um jogo para adultos. Você precisa escolher o público correto. Jogos ruins são frequentemente escritos para o público errado. Por exemplo, alguns simuladores tentam reproduzir todos os controles possivel, tornando o jogo mais realista. Mas para jogadores que só querem se divertir, isso se torna irritante.

              Jogar um jogo é tomar decisões
              O jogador toma decisões que influenciam no resto do jogo. Em jogos de ação geralmente tal decisão envolve em que direção ir e qual a arma de escolher. Em complicados jogos de estratégia as decisões envolvem construir seu reinado, quais unidades treinar, quando e onde atacar, etc. É claro que suas decisões devem ter algum efeito no jogo. Surpreendentemente, em muitos jogos o efeito das decisões é apenas ilusório. Por exemplo, em alguns jogos não vai importar a arma que você escolher. Isso muitas vezes leva à frustração. É importante que você saiba euilibrar todas as dicisões para o jogo se torne satisfatório.

              Jogar um jogo é controlar
              O jogador deve se sentir no controle do jogo. E não o contrário. Seqüências ininterruptas em que o controle é tirado das mãos do jogador, que ainda ocorre em muitos jogos, levam à frustração. Quanto mais liberdade existir para o jogador, o melhor será o jogabilidade. Há no entanto uma pegadinha aqui. Um jogo também tem surpresas e efeitos dramáticos. Tais efeitos podem ser criados muito melhor se o jogador não está no controle. Por exemplo, em um filme, quando o personagem principal se aproxima de uma porta e começa a tocar uma música. O espectador sabe que algo está para acontecer. Juntamente com zoom na porta, isso pode criar um grande efeito dramático. Mas se o mesmo acontecer em um jogo e no último instante, o jogador decide não abrir a porta, a maioria dos efeitos desaparece e até torna o momento sem noção. Saber até que ponto oferecer liberdade ao jogador é meio dificil, pois muita liberadade torna até o jogo mais díficil. Sempre que você precisar restringir o jogador, tente fazer isso de uma maneira natural. Por exemplo, usar uma cinematic, como fazemos no warcraft.

              Objetos e recursos do jogo
              Em alguns jogos o jogador controla várias unidades, contruções, veiculos, etc. Enquanto em outros o jogador controla apenas uma unidade, como jogos em primeira pessoa. Além dos objetos do jogo que o jogador controla, normalmente há muitos outros objetos que são controlados pelo computador. Porém os objetos do jogador desempenham um papel muito importante, não se esqueça. Além de controlar objetos o jogador muitas vezes tem que controlar recursos. Isso é comum em jogos de estrategia, quando o jogador tem que controalr comida, ouro, madeira. Mas também em muitos outros jogos que exista recursos para gerir, como munição para suas armas, um escudo que só pode ser usado por um tempo limitado, etc. Deve ser planejar muito bem os recursos do jogo, pois eles são um papel interessante na jogabilidade. E claro, o jogador deve balancear a disponibilidade dos recursos de acordo com a necessidade, tentando assim alcançar um nível de jogo interessante.
              É importante lembrar que o jogador deve alcançar esses objetivo pelo esforço dele, pela pratica que adquiriu ao longo do jogo e não pela sorte.

              Um jogo precisa de um objetivo
              Este é um elemento crucial do jogo. As pessoas querem ganhar o jogo, portanto, deve haver um objetivo a cumprir. Para jogos longos, deve haver também uns sub-objetivos, como passar uma fase, adiquirir um item, etc. Quando o jogador antingir um objetivo ou sub-objetivo ele deve ganhar recompensas. As melhores recompensas são geralmente são objetos do jogo (como armas), novos poderes e até informações úteis.

              Então, por que um jogo é bom?
                  Você já sabe o que é um jogo, pelo menos um de computador. No entanto lá não fala quando um jogo é bom. Tudo citado acima são elementos que um jogo bom de ter, porém faltou dizer que a criatividade e a inovação são igualmente importantes.
                  Como eu disse, este tutorial deve ter-lhe dado uma idéia das coisas que importam ao tentar criar um bom jogo de computador. Mas no final a melhor maneira de aprender é você fazer um jogo e criticar seus próprios resultados.
                  Outro conselho é aprender com os erros de outras pessoas. Sempre que você planejar fazer um determinado tipo de jogo, olhe para os jogos similares. Tente jogá-los e ver o que eles fizeram certo e o que eles fizeram de errado. É muito comum ainda ver alguns jogos repitindo os erros de outros jogos.

              Créditos ao Mark Overmars que escreveu o tutorial original (em inglês). E também ao gostoso do Bills por ter resumido, quase nada, e ter traduzido.

              Leia Mais...