underpop

http://underpop.online.fr 2009-08-22  

Video - Produtos - edi 02

edi_02




Marcadores: ,



2009-08-21  

Video - Produtos - eda 01

eda_01




Marcadores: ,



2009-08-20  

Video - Produtos - depressao

depressao




Marcadores: ,



 

Lua e Jogos

A linguagem Lua e suas aplicações em jogos

A Linguagem Lua e suas Aplicacoes em Jogos ¸˜ Waldemar Celes, Luiz Henrique de Figueiredo, Roberto Ierusalimschy 1 Introducao ¸˜ Uma pesquisa realizada em setembro de 2003 pela gamedev.net — um importante site para progra´ madores de jogos — revelou que a grande maioria dos jogos (72%) e desenvolvida com o aux´lio de ı uma linguagem de script. Embora as linguagens de script n˜ o sejam definidas muito precisamente, elas apresentam um a conjunto de caracter´sticas comuns t´picas. Em geral, as linguagens de script s˜ o linguagens inı ı a terpretadas, tˆ m tipagem dinˆ mica e gerˆ ncia autom´ tica de mem´ ria, e fornecem facilidades para e a e a o construcao de estruturas de dados dinˆ micas e manipulacao de cadeias de caracteres. Tipicamente, ¸˜ a ¸˜ essas linguagens funcionam acopladas a programas hospedeiros implementados em linguagens compiladas tradicionais como C e C++. Uma outra caracter´stica importante de linguagens de ı ´ script e que elas devem ser seguras, n˜ o sendo poss´vel acessar servicos n˜ o autorizados do proa ı ¸ a grama hospedeiro. A combinacao dessas caracter´sticas resulta numa excelente ferramenta para o ¸˜ ı desenvolvimento de jogos. Acoplar uma linguagem de script em um jogo traz v´ rios benef´cios. A linguagem de script pode a ı ser usada para efetivamente implementar o script do jogo, para definir objetos e seus comportamentos, para gerenciar os algoritmos de inteligˆ ncia artificial e controlar os personagens, e ainda e para tratar os eventos de entrada e descrever a interface com o usu´ rio. Uma linguagem de script a tamb´ m desempenha um papel importante nas etapas de prototipacao, teste, depuracao e an´ lise e ¸˜ ¸˜ a de adequacao do jogo. A escolha de uma linguagem de script simples permite ainda que seja dado a ¸˜ roteiristas e artistas acesso program´ vel ao jogo, a fim de que eles que possam experimentar novas a id´ ias e variacoes. Esses profissionais conduzem a maior parte do desenvolvimento real do jogo e ¸˜ mas n˜ o s˜ o em geral programadores profissionais e n˜ o est˜ o familiarizados com t´ cnicas sofistia a a a e cadas de programacao. ¸˜ ´ A mesma pesquisa mencionada acima revelou que Lua e atualmente a linguagem de script mais utilizada no desenvolvimento de jogos (20% dos jogos s˜ o desenvolvidos com Lua, enquanto soa mente 7% usam Python, a segunda linguagem de script mais citada na pesquisa). De fato, devido ao seu pequeno tamanho, bom desempenho, portabilidade e facilidade de integracao, Lua tem sido ¸˜ ´ amplamente utilizada na industria de jogos. Empresas com LucasArts, BioWare, Microsoft, Relic Entertainment, Absolute Studios e Monkeystone Games desenvolvem jogos usando Lua. ´ Lua e uma linguagem de script extens´vel, projetada para oferecer meta-mecanismos que possiı ´ a ` bilitam a construcao de mecanismos mais espec´ficos. Com isso, e f´ cil adequar Lua as necessida¸˜ ı des da aplicacao, sem comprometer as suas caracter´sticas b´ sicas, mantidas desde a sua criacao, ¸˜ ı a ¸˜ tais como portabilidade, pequeno tamanho e simplicidade. Em particular, os programadores dos jogos podem fornecer abstracoes adequadas para roteiristas e artistas, simplificando as tarefas des¸˜ ses. Neste tutorial, discutiremos o uso da linguagem Lua no desenvolvimento de jogos. Vamos apresentar os principais mecanismos de programacao oferecidos pela linguagem e a interface para a ¸˜ integracao com programas hospedeiros escrito em C ou C++. Discutiremos ainda como estes me¸˜ canismos podem ser usados para a construcao de jogos mais flex´veis, que fornecem acesso pro¸˜ ı gram´ vel aos servicos implementados pelo programa hospedeiro. a ¸ 1 2 Linguagens de extens˜ o a Vamos classificar as linguagens de extens˜ o ou de script segundo a sua complexidade: a • Linguagens de configuracao servem para selecionar preferˆ ncias e s˜ o tipicamente uma lista ¸˜ e a de valores associados a vari´ veis. Um exemplo t´pico s˜ o os arquivos .ini do Windows. a ı a • Linguagens de macros servem para automacao de tarefas e s˜ o tipicamente uma lista de acoes ¸˜ a ¸˜ primitivas, com muito pouco ou nenhum controle de fluxo. Um exemplo t´pico s˜ o os arquiı a vos de automacao de conex˜ es internet via modem. ¸˜ o • Linguagens embutidas permitem acesso program´ vel aos servicos da aplicacao, com fluxo de a ¸ ¸˜ controle completo e funcoes definidas pelo usu´ rio a partir de primitivas exportadas pela ¸˜ a aplicacao. Essas linguagens s˜ o linguagens completas, muitas vezes variantes simplificadas ¸˜ a de linguagens tradicionais como Lisp ou C. Independente da complexidade da linguagem, a adocao de uma linguagem de extens˜ o e uma ¸˜ a ´ t´ cnica poderosa de desenvolvimento de software, pois permite que muitos aspectos da aplicacao e ¸˜ sejam controlados externamente, a partir de arquivos textos facilmente editados pelo programador ou pelo usu´ rio, sem necessidade de recompilar a aplicacao. Isso torna o desenvolvimento mais a ¸˜ ´ agil, pois permite que partes importantes da aplicacao sejam desenvolvidas por outros membros ¸˜ da equipe que n˜ o s˜ o programadores profissionais (no caso de jogos, animadores e artistas). a a Al´ m disso, a adocao de uma mesma linguagem para v´ rias tarefas na aplicacao permite um e ¸˜ a ¸˜ aumento importante de produtividade global, pois n˜ o e necess´ rio definir, documentar e manter a ´ a v´ rios formatos diferentes. Para o usu´ rio da aplicacao, isso se traduz no re-aproveitamento aua a ¸˜ tom´ tico (e inconsciente) dos conceitos aprendidos para realizar as v´ rias tarefas, encorajando a a a exploracao. ¸˜ 3 A linguagem Lua ´ A linguagem Lua e uma linguagem de programacao poderosa e leve, projetada para estender aplica¸˜ coes. Isso quer dizer que ela foi projetada para ser acoplada a programas maiores que precisem ler ¸˜ ´ e executar programas escritos pelos usu´ rios. Na classificacao da Secao 2, Lua e uma linguagem a ¸˜ ¸˜ ` embutida, com sintaxe semelhante a de Pascal mas com construcoes modernas, como funcoes ¸˜ ¸˜ anˆ nimas, inspiradas no paradigma funcional, e poderosos construtores de dados. Isso faz com o que Lua seja uma linguagem de grande express˜ o com uma sintaxe familiar. a 3.1 Hist´ ria o Lua foi projetada e implementada no Tecgraf, o Grupo de Computacao Gr´ fica da PUC-Rio. A pri¸˜ a ´ ´ ´ meira vers˜ o de Lua (1.0) e de julho de 1993. A primeira vers˜ o publica (1.1) e de julho de 1994. a a ´ A vers˜ o atual e a 5.0.2, lancada em marco de 2004 para corrigir pequenas falhas na vers˜ o 5.0, de a ¸ ¸ a abril de 2003. A vers˜ o 5.1 est´ em desenvolvimento no momento. Este texto trata da vers˜ o oficial a a a atual (5.0.2). A motivacao para a criacao de Lua no Tecgraf foi a necessidade crescente das suas aplicacoes ¸˜ ¸˜ ¸˜ serem configur´ veis externamente pelos usu´ rios. Isso quer dizer que diversos aspectos essenciais a a das aplicacoes podem ser modificados sem recompilar a aplicacao. Desde o in´cio, nas aplicacoes ¸˜ ¸˜ ı ¸˜ criadas no Tecgraf, esse tipo de configuracao era muito mais do que simplesmente poder esco¸˜ lher a cor da janela ou o tipo de fonte de texto: era necess´ rio poder tomar decis˜ es em tempo de a o execucao que somente os usu´ rios sabiam quais eram. Sendo assim, era necess´ rio fornecer al¸˜ a a gum tipo de programacao para os usu´ rios finais. Um outro tipo de configuracao era a descricao de ¸˜ a ¸˜ ¸˜ 2 complexos relat´ rios e an´ lises feitas pela Petrobras por encomenda ao Tecgraf. Mais uma vez, essa o a descricao n˜ o podia estar congelada dentro da aplicacao pois cada usu´ rio tinha uma necessidade ¸˜ a ¸˜ a diferente e que mudava a cada tarefa. O Tecgraf tinha portanto (e ainda tem) forte demanda para aplicacoes que fossem configur´ veis externamente, tanto descrevendo que decis˜ es deveriam ser ¸˜ a o tomadas quanto descrevendo quais dados seriam usados e como eles seriam usados. Ap´ s projetar e usar com sucesso duas pequenas linguagens espec´ficas para cada uma dessas o ı ´ tarefas, o Tecgraf decidiu investir na criacao de uma linguagem unica que pudesse atender a todas ¸˜ as necessidades de configuracao das suas aplicacoes. Assim nasceu Lua: uma linguagem procedu¸˜ ¸˜ ral simples com poderosas construcoes para descricao de dados. Desde ent˜ o Lua tem sido usada ¸˜ ¸˜ a ´ em inumeros projetos no Tecgraf. A vers˜ o seguinte de Lua (2.1) foi lancada em fevereiro de 1995 e trouxe maior poder de exa ¸ press˜ o, introduzindo a nocao de semˆ ntica extens´vel: passou a ser poss´vel programar o que fazer a ¸˜ a ı ı em casos excepcionais, como quando um campo n˜ o existe numa tabela. Ter uma semˆ ntica exa a ´ tens´vel e desde ent˜ o uma caracter´stica marcante de Lua. ı a ı A vers˜ o 2.1 tamb´ m foi a primeira a ser completamente livre; as vers˜ es anteriores eram livres a e o ` ` somente para aplicacoes acadˆ micas. Aliada a portabilidade e a eficiˆ ncia da implementacao, a ¸˜ e e ¸˜ ´ falta de restricoes de uso foi um dos fatores importantes na adocao de Lua em inumeros projetos ¸˜ ¸˜ no mundo todo. A primeira not´cia que tivemos do uso de Lua em jogos foi em 1997 quando a LucasArts adotou ı Lua como a sua linguagem de script no lugar de SCUMM no jogo “Grim Fandango”. A adocao de ¸˜ Lua nesse jogo foi uma consequˆ ncia direta da publicacao de um artigo de divulgacao sobre Lua na e ¸˜ ¸˜ revista Dr. Dobb’s Journal, em junho de 1996. Desde ent˜ o, Lua tem sido cada vez mais usada em a ´ ´ jogos, uma area longe das areas que motivaram a sua criacao! ¸˜ Atualmente, Lua tem uma comunidade ativa de programadores. A lista de discuss˜ o tem mais a de 750 assinantes do mundo todo. Al´ m do site oficial de Lua (lua.org), h´ tamb´ m um ativo site e a e mantido por usu´ rios (lua-users.org), uma sala de bate-papo, um web forum e um reposit´ rio (luaa o forge.net). 3.2 Caracter´sticas b´ sicas ı a ´ ` Lua e uma linguagem de extens˜ o projetada para dar suporte a programacao procedural, oferea ¸˜ cendo facilidades para descricao de dados. No contexto da programacao de jogos, isso significa que ¸˜ ¸˜ Lua possibilita combinar a descricao de objetos e a programacao de seus comportamentos num ¸˜ ¸˜ ´ mesmo contexto. Lua e uma biblioteca implementada em C, podendo ser compilada em qualquer plataforma que tenha um compilador C padr˜ o. Lua tamb´ m pode ser compilada sem alteracoes a e ¸˜ como uma biblioteca C++. No que se segue, toda referˆ ncia a C deve ser entendida como uma e referˆ ncia a C++ tamb´ m. Em alguns poucos lugares trataremos exclusivamente de C++. e e Por ser uma linguagem de extens˜ o, Lua trabalha acoplada a uma aplicacao hospedeira (host). a ¸˜ Essa aplicacao pode criar e ler valores armazenados em Lua, executar funcoes de Lua e registrar ¸˜ ¸˜ funcoes C no ambiente de Lua. As funcoes C registradas em Lua, por sua vez, podem ser invocadas ¸˜ ¸˜ de programas Lua. Dessa forma, podemos conciliar as facilidades de uma linguagem de script oferecidas por Lua com a eficiˆ ncia das linguagens C e C++. A distribuicao da linguagem Lua inclui um e ¸˜ programa hospedeiro, lua.c, que pode ser usado para executar scripts Lua interativamente ou em batch. Neste tutorial, no entanto, focaremos no uso de Lua acoplada a programas de jogos. Para que uma aplicacao tenha acesso a Lua, precisamos abrir a biblioteca conforme ser´ discu¸˜ a ˜ o 3.9. Ao final, a aplicacao deve fechar a biblioteca. Ap´ s a abertura da biblioteca, a ˜ tido na Seca ¸ ¸ o aplicacao pode usar os recursos oferecidos por Lua, como por exemplo, executar scripts Lua e aces¸˜ sar dados armazenados em Lua. Antes de detalharmos como isso pode ser feito dentro do c´ digo da o aplicacao, temos que aprender como escrever scripts em Lua. Programas ou scripts Lua s˜ o arma¸˜ a zenados em arquivos (usualmente com extens˜ o .lua) ou em strings da aplicacao. Um arquivo ou a ¸˜ 3 ´ ¨e string com c´ digo Lua caracteriza o que chamamos de chunk, que e simplesmente uma sequˆ ncia o de comandos Lua. Daremos a seguir uma breve introducao as principais caracter´sticas da lingua¸˜ ` ı gem Lua. 3.3 Vari´ veis e tipos a Em Lua, as vari´ veis n˜ o tˆ m tipos associados a elas: os tipos est˜ o associados aos valores armazea a e a nados nas vari´ veis. Dessa forma, uma mesma vari´ vel pode num momento armazenar um valor de a a um tipo e depois passar a armazenar o valor de outro tipo (naturalmente, a vari´ vel deixa de armaa zenar o valor inicial). O trecho de c´ digo abaixo ilustra o uso de vari´ veis armazenando diferentes o a valores: a = b = ... b = a = "Exemplo" 1.23 nil 3 -- a armazena string -- b armazena n´mero u -- b armazena nil -- a armazena n´mero u (Note a forma dos coment´ rios em Lua: comecam com -- e v˜ o at´ o final da linha.) a ¸ a e ` O fato de o tipo estar associado ao valor, e n˜ o a vari´ vel, d´ grande flexibilidade a linguaa ` a a gem. Podemos, por exemplo, criar conjuntos de valores heterogˆ neos naturalmente, pois o polie ´ ` formismo e intr´nseco a linguagem. Por outro lado, a verificacao de tipo s´ pode ser feita em tempo ı ¸˜ o ´ de execucao. Assim, se tentarmos somar duas vari´ veis cujos valores n˜ o s˜ o numericos, um erro ¸˜ a a a ser´ reportado, mas somente quando a soma for executada. Como pretendemos, ao acoplar Lua a ao jogo, exportar servicos da aplicacao, devemos prever um tratamento adequado desses erros de ¸ ¸˜ execucao. Um usu´ rio de um jogo pode codificar uma configuracao inv´ lida e isso deve ser tratado ¸˜ a ¸˜ a de maneira adequada, sem necessariamente abortar o jogo. Em Lua, vari´ veis globais n˜ o precisam ser declaradas. Quando escrevemos a = 3, a vari´ vel a a a a ´ e, por default, uma vari´ vel global. Se desejarmos que uma vari´ vel tenha escopo local (a um bloco a a ou chunk), devemos declar´ -la previamente usando a palavra local. Por exemplo: a local a ... a = 3 Os valores em Lua podem ser de oito tipos: • nil: o valor nil indica ausˆ ncia de valor. Vari´ veis n˜ o inicializadas contˆ m o valor nil. O valor e a a e nil tamb´ m e interpretado como falso numa express˜ o booleana. e ´ a • boolean: valor booleano, podendo ser falso (false) ou verdadeiro (true); • number: valor num´ rico. Lua n˜ o diferencia valor inteiro de valor real; s´ existe um tipo para e a o ´ representar numeros; • string : valor cadeia de caracteres. Uma constante string pode ser delimitada por aspas duplas ("..."), aspas simples (’...’), ou duplo colchetes ([[...]]). • table: vetor associativo (a ser detalhado na Secao 3.6); ¸˜ • function: funcao escrita em Lua ou escrita em C e registrada em Lua; ¸˜ • userdata: dado do host, representado por um ponteiro void*; • thread: linha de execucao, que ser´ apresentado na Secao 3.8, quando descrevermos o uso de ¸˜ a ¸˜ co-rotinas em Lua. 4 3.4 Operadores e controladores de fluxo A linguagem Lua oferece os operadores comumente encontrados em linguagens de programacao. ¸˜ Os operadores aritm´ ticos s˜ o os usuais: + (adicao), - (subtracao), * (multiplicacao), / (divis˜ o), e a ¸˜ ¸˜ ¸˜ a ^ (exponenciacao) e - un´ rio (negacao). Os operadores relacionais resultam num valor booleano ¸˜ a ¸˜ e incluem: < (menor que), > (maior que), <= (menor ou igual que), >= (maior ou igual que), == (igualdade), ~= (diferenca). Os operadores l´ gicos servem para combinar valores booleanos e s˜ o ¸ o a dados por: and (e), or (ou), not (negacao). Existe ainda o operador .. para concatenacao de strings. ¸˜ ¸˜ Os operadores l´ gicos and e or s˜ o uteis tamb´ m na avaliacao de express˜ es. Esses operadores o a ´ e ¸˜ o combinam duas express˜ es e fazem a avaliacao da segunda express˜ o apenas quando necess´ rio. o ¸˜ a a ´ ´ ´ Al´ m disso, o resultado de um and ou or e ultimo valor usado na sua avaliacao. Dessa forma, e e ¸˜ ´ v´ lido e muito util usar construcoes como as seguintes: a ¸˜ x = v or w y = a and b or c Na primeira atribuicao acima, x passa a armazenar o valor de v, se esse for diferente de falso (false ¸˜ ou nil); caso contr´ rio, passa a armazenar o valor de w. A segunda atribuicao, que deve ser lida a ¸˜ ´ ` como (a and b) or c, e equivalente a express˜ o y = a ? b : c em C, desde que b n˜ o resulte a a em falso. ` A linguagem Lua oferece os controladores de fluxo comuns as linguagens procedurais. As construcoes para tomada de decis˜ o s˜ o as variantes usuais de if ... then ... else: ¸˜ a a if expr then ... end if expr then ... else ... end if expr1 then ... elseif expr2 then ... else ... end As construcoes para execucao iterativa podem ter o seu teste no in´cio (while) ou no fim (repeat): ¸˜ ¸˜ ı while expr do ... end repeat ... until expr Lua oferece ainda a construcao de lacos com for. O for num´ rico tem a seguinte forma: ¸˜ ¸ e for var = expr_inicial, expr_final, expr_incremento do ... end ´ ´ a Nessa construcao, a vari´ vel var e autom´ tica e local ao laco, isto e, n˜ o precisa ser explicitamente ¸˜ a a ¸ declarada e s´ existe dentro do laco. As express˜ es inicial, final e de incremento s˜ o avaliadas uma o ¸ o a ´ unica vez, antes do in´cio da execucao do bloco de comandos do laco. A express˜ o de incremento, ı ¸˜ ¸ a se omitida, vale 1. Um laco de for pode ainda aparecer na sua forma gen´ rica, que permite a construcao de diver¸ e ¸˜ sos tipos de iteradores especializados. O trecho de c´ digo abaixo, por exemplo, usa um for gen´ rico o e para ler e imprimir cada linha do arquivo de entrada corrente, usando funcoes pr´ -definidas na bi¸˜ e blioteca de entrada e sa´da (uma discuss˜ o de como se constr´ i iteradores foge do escopo desse ı a o tutorial). 5 for line in io.lines() do io.write(line,"\n") end A execucao de lacos while, repeat e for pode ser interrompida usando o comando break. ¸˜ ¸ 3.5 Funcoes ¸˜ Funcoes em Lua s˜ o valores de primeira classe. Isso significa que, como qualquer outro valor, uma ¸˜ a funcao pode ser criada, armazenada em uma vari´ vel (local ou global) ou campo de tabela e pas¸˜ a sada adiante como parˆ metro ou valor de retorno de uma outra funcao. Uma funcao pode receber a ¸˜ ¸˜ ´ zero ou mais valores. A lista de parˆ metros e especificada da maneira usual: entre os parˆ nteses a e ´ que seguem o nome da funcao. Como exemplo simples (tradicional, mas util somente para fins ¸˜ did´ ticos), consideremos a definicao da funcao recursiva abaixo para o c´ lculo do fatorial de um a ¸˜ ¸˜ a ´ numero inteiro: function fat (n) if n==0 then return 1 else return n*fat(n-1) end end ´ As funcoes em Lua n˜ o tˆ m nome; elas s˜ o sempre anˆ nimas. O c´ digo acima e apenas uma ¸˜ a e a o o ´ maneira conveniente de definir uma funcao e atribu´-la a uma vari´ vel global, e e equivalente a ¸˜ ı a fat = function (n) ... end -- fun¸~o an^nima atribu´da ` vari´vel fat ca o ı a a Para testar essa funcao, podemos usar a funcao print da biblioteca padr˜ o de Lua que imprime ¸˜ ¸˜ a um valor na tela (nesse caso, 120): local a = 5 print(fat(a)) ´ a ´ Lua permite atribuicoes multiplas. E v´ lido, por exemplo, escrever x,y = y,x, que troca os va¸˜ ´ a lores de x e y sem a necessidade de usar uma vari´ vel tempor´ ria, da mesma forma que e v´ lido a a ´ a escrever a,b = 1,2. Ainda de forma an´ loga, e v´ lido escrever a,b = f() — os valores retornados a ` ´ por f ser˜ o atribu´dos as vari´ veis a e b. (Sim, Lua permite que uma funcao retorne multiplos valoa ı a ¸˜ res, escrevendo return expr1, expr2, ... . Isso evita em grande parte a necessidade de passagem de parˆ metros por referˆ ncia; em Lua todos os parˆ metros s˜ o passados por valor.) a e a a ´ ´ ´ Se o numero de vari´ veis numa atribuicao multipla for maior que o numero de valores resula ¸˜ ` ´ tantes a direita do sinal de igualdade, as vari´ veis excedentes recebem o valor nil. Se o numero a de valores for maior, os valores excedentes s˜ o descartados. Esse mesmo ajuste ocorre ao se chaa mar funcoes: argumentos ausentes recebem o valor nil; argumentos extras s˜ o ignorados (exceto ¸˜ a ´ quando a funcao aceita um numero vari´ vel de argumentos). ¸˜ a Funcoes podem ser criadas localmente dentro de outras funcoes, e depois retornadas ou arma¸˜ ¸˜ zenadas em uma tabela. Uma funcao pode ainda acessar vari´ veis locais do escopo acima. Consi¸˜ a dere por exemplo o trecho de c´ digo abaixo: o 6 function counter () local i = 0 return function () i = i+1 return i end end local c = counter() print(c()) print(c()) A vari´ vel c armazena uma instˆ ncia da funcao anˆ nima criada (e retornada) em counter. Essa a a ¸˜ o funcao usa a vari´ vel local i declarada em counter. Assim, cada vez que executamos a funcao ¸˜ a ¸˜ armazenada em c, recebemos o valor da vari´ vel i incrementado de uma unidade. Se fizermos um a paralelo com C, a vari´ vel da funcao counter funciona como uma vari´ vel est´ tica para a funcao a ¸˜ a a ¸˜ c. Se executarmos a funcao counter novamente, teremos como retorno uma outra funcao que, se ¸˜ ¸˜ chamada, retornar´ da primeira vez o valor 1, depois 2, e assim por diante. Essa segunda funcao e a ¸˜ ´ diferente da primeira: embora ambas facam a mesma coisa, elas o fazem de maneira independente. ¸ ´ ´´ ´ ´ E importante observar que a funcao anˆ nima e unica e seu c´ digo e gerado uma unica vez. A funcao ¸˜ o o ¸˜ counter retorna o que chamamos de closure, que guarda uma referˆ ncia para a funcao anˆ nima e e ¸˜ o uma lista com os valores das vari´ veis do escopo superior usadas, entre outras coisas. A existˆ ncia a e de closures com escopo l´ xico (acesso a vari´ veis do escopo superior) permite que Lua seja usada e a como linguagem funcional, o que d´ grande flexibilidade de programacao. a ¸˜ Por fim, considere o trecho de c´ digo abaixo: o a = 2 function f ( ) ... end local b = 3 function g ( ) local x = b ... end ´ ´ Todo chunk representa o corpo de uma funcao anˆ nima que e retornada quando o chunk e carre¸˜ o gado. No exemplo acima, atribui-se trˆ s vari´ veis globais (a, f e g) e declara-se uma vari´ vel local b. e a a Fazendo uma analogia com programacao em C, temos que a vari´ vel b funciona como uma vari´ vel ¸˜ a a ´ est´ tica do m´ dulo. Na verdade, em Lua, b e uma vari´ vel local da funcao anˆ nima caracterizada a o a ¸˜ o pelo chunk, acessada de dentro da funcao que foi armazenada na vari´ vel global g. ¸˜ a 3.6 Tabelas e objetos O tipo table representa um vetor associativo, implementado internamente com o uso de uma efici´ ente combinacao de array e hash (tabela de dispers˜ o). As tabelas s˜ o a unica forma de estruturacao ¸˜ a a ¸˜ de dados em Lua. Todas as estruturas de dados comumente encontradas em programacao (tais ¸˜ 7 como vetores, listas, filas, conjuntos e hash) podem ser eficientemente (e facilmente) implementa´ das com o uso de tabelas. Uma tabela em Lua e criada pela express˜ o { }. Se uma vari´ vel armazena a a um valor do tipo tabela, essa vari´ vel pode ser indexada por qualquer outro valor (exceto nil ). O a valor armazenado em cada ´ndice da tabela tamb´ m pode ser de qualquer tipo (incluindo nil ). O ı e valor associado a um ´ndice da tabela n˜ o inicializado tem o valor nil. O trecho de c´ digo abaixo ı a o ilustra a criacao de uma tabela e a atribuicao de alguns campos: ¸˜ ¸˜ local t = {} t[1] = 4 t[2] = "alo" t["alo"] = 5 t[t[2]] = 0 -----cria nova tabela armazena 4 no ´ndice 1 ı armazena "alo" no ´ndice 2 ı armazena 5 no ´ndice "alo" ı armazena 0 no ´ndice "alo" (sobrescrevendo) ı ´ Lua oferece uma sintaxe simplificada quando o ´ndice e uma string simples (desde que a string ı n˜ o seja uma palavra reservada na sintaxe de Lua). Assim, a atribuicao acima t["alo"] = 5 pode a ¸˜ ser escrita simplesmente por t.alo = 5. Lua permite ainda que campos da tabela sejam inicializados na criacao. Dessa forma, as trˆ s primeiras linhas do c´ digo acima podem ser substitu´das ¸˜ e o ı por: local t = {4,"alo"; alo=5} A biblioteca padr˜ o de Lua oferece duas funcoes que permitem iterar sobre os elementos armaa ¸˜ zenados na tabela. A funcao ipairs itera sobre todos os ´ndices num´ ricos armazenados na tabela. ¸˜ ı e Assim, for i,v in ipairs(t) do ... end itera sobre os pares (1,t[1]), (2,t[2]), . . . , at´ que o primeiro ´ndice com valor associado igual a e ı nil seja encontrado. A funcao pairs permite iterar sobre todos os pares armazenados na tabela, independente do ¸˜ ` tipo associado a chave: for k,v in pairs(t) do ... end ´ Nesse caso, a ordem em que os pares k,v s˜ o reportados e indefinida. a Como ´ndices (chaves) e valores de uma tabela podem ser valores quaisquer, podemos natuı ralmente usar tabelas como ´ndices e valores. Com isso, podemos ter tabelas aninhadas (inclusive ı com ciclos). Considere a tabela abaixo, que especifica os parˆ metros para a criacao de uma janela a ¸˜ de di´ logo numa aplicacao gr´ fica. Observe que funcoes podem tamb´ m ser armazenadas em taa ¸˜ a ¸˜ e belas. local w = { width = 640, height = 480, menu = { {label="Load",action=function () ... end}, {label="Save",action=function () ... end}, }, ... } Lua permite ainda a especificacao de um “construtor” na criacao da tabela. Consideremos, por ¸˜ ¸˜ exemplo, a especificacao de um ponto em 3D, dado pelas suas coordenadas. Em Lua, podemos ¸˜ escrever: 8 local p = Point{x=3.0,y=1.3,z=3.2} ´ O c´ digo acima e equivalente a o local p = Point({x=3.0,y=1.3,z=3.2}) ´ ´ isto e, uma tabela e criada e chama-se a funcao Point passando a nova tabela como parˆ metro. ¸˜ a Essa funcao pode ser o construtor do objeto sendo criado. Por exemplo, podemos usar a funcao ¸˜ ¸˜ para validar e inicializar campos do objeto. function Point (self) self.x = tonumber(self.x) or 0.0 self.x = tonumber(self.y) or 0.0 self.x = tonumber(self.z) or 0.0 return self end Assim, se na criacao do objeto n˜ o forem especificados valores das coordenadas (ou se forem espe¸˜ a cificados valores n˜ o num´ ricos), a funcao inicializa esses valores com zero. a e ¸˜ Lua oferece ainda um eficiente mecanismo para estendermos a sua semˆ ntica atrav´ s do uso a e de eventos. Esse mecanismo permite, por exemplo, adotarmos uma programacao orientada a ob¸˜ jetos. Para estender a semˆ ntica de um objeto (tabela), devemos associar a ele uma outra tabela, a chamada de metatable. Na metatable, podemos programar a acao que deve ser tomada quando ¸˜ ocorre um determinado evento. Por exemplo, a operacao de soma n˜ o e especificada para tabelas; ¸˜ a ´ no entanto, podemos fazer com que dois objetos do nosso tipo Point acima possam ser somados, gerando um terceiro novo objeto do tipo Point. Para isso, devemos primeiro criar uma metatable com o comportamento da operacao de soma definido: ¸˜ local Point_metatable = { __add = function (p1,p2) return Point(p1.x+p2.x,p1.y+p2.y,p1.z+p2.z} end } Devemos reescrever o construtor de Point para definir a metatable de cada objeto criado: function Point (self) self.x = tonumber(self.x) or 0.0 self.x = tonumber(self.y) or 0.0 self.x = tonumber(self.z) or 0.0 setmetatable(self,Point_metatable) return self end Assim, definimos um objeto Point e podemos us´ -lo de maneira transparente: a local p = Point{x=3.0,y=1.3,z=3.2} local q = Point{x=4.2,y=1.0} local r = p+q -- r.x=7.2, r.y=2.3, r.z=3.2 Al´ m de add, podemos (re-)definir o comportamento quando da ocorrˆ ncia dos seguintes evene e tos de operacao aritm´ tica: sub (subtracao), mul (multiplicacao), div (divis˜ o), pow (exponeciacao), ¸˜ e ¸˜ ¸˜ a ¸˜ unm (negacao), concat (concatenacao), eq (igualdade), lt (menor que), le (menor ou igual que). ¸˜ ¸˜ 9 ´ Basta criar o campo adequado na metatable. (O nome do campo e o nome do evento precedido de __.) Existem ainda dois eventos especiais cujos comportamentos podem ser programados: index, gerado quando tentamos acessar um ´ndice n˜ o existente na tabela, e newindex, gerado quando ı a tentamos atribuir um valor a um ´ndice ainda n˜ o existente na tabela. Esses eventos podem ser ı a usados para programar diferentes comportamentos. Por exemplo, podemos usar o evento index para delegar a uma outra tabela a busca do valor associado ao ´ndice. Dessa forma, podemos proı gramar nosso pr´ prio mecanismo de heranca. Se o objeto n˜ o tem o campo, retornamos o campo o ¸ a ` associado a sua “classe”: local Point_methods = { Print = function (self) print(self.x, self.y, self.z) end, ... } Na metatable, associamos a tabela acima ao campo __index: local Point_metatable = { __index = Point_methods, __add = function (p1,p2) return Point(p1.x+p2.x,p1.y+p2.y,p1.z+p2.z} end } Podemos ent˜ o acessar o “m´ todo” Print de nosso tipo: a e local p = Point{x=3.0,y=1.3,z=3.2} local q = Point{x=4.2,y=1.0} local r = p+q r.Print(r) ´ Para facilitar o uso e dar clareza ao c´ digo, a ultima linha do c´ digo acima pode ser escrita o o r:Print(), como se espera de uma chamada de m´ todo em C++ ou Java. Em Lua, a chamada de e ´ funcao da forma t:meth(...) e equivalente a t.meth(t,...). ¸˜ Se a delegacao n˜ o for direta, podemos atribuir ao campo __index da metatable uma funcao que ¸˜ a ¸˜ deve ser executada quando o evento ocorrer. Isto nos d´ flexibilidade para, por exemplo, buscarmos a o valor do campo num objeto em C ! 3.7 Biblioteca padr˜ o a A distribuicao oficial de Lua inclui um conjunto de bibliotecas que implementam diversas funcoes ¸˜ ¸˜ importantes para a construcao de programas. Com excecao das funcoes que pertencem ao que ¸˜ ¸˜ ¸˜ chamamos de biblioteca b´ sica, as funcoes de cada biblioteca s˜ o agrupadas em tabelas. Assim, a ¸˜ a a tabela string agrupa as funcoes para manipulacao de strings, a tabela table agrupa as funcoes ¸˜ ¸˜ ¸˜ para manipulacao de tabelas e assim por diante. Listamos abaixo as bibliotecas padr˜ o inclu´das ¸˜ a ı na distribuicao. O manual de referˆ ncia cont´ m uma descricao detalhada das funcoes oferecidas. ¸˜ e e ¸˜ ¸˜ Al´ m da biblioteca b´ sica, que oferece funcoes b´ sicas para a programacao em Lua (como print, e a ¸˜ a ¸˜ setmetatable, pairs, que usamos acima), a distribuicao inclui as seguintes bibliotecas: ¸˜ • string: oferece funcoes para manipulacao de strings. Destacamos o poderoso mecanismo ¸˜ ¸˜ de casamento de padr˜ es (pattern matching ) oferecido atrav´ s das funcoes string.find, que o e ¸˜ 10 permite buscar a ocorrˆ ncia de um padr˜ o numa string, e string.gsub, que permite substie a tuirmos ocorrˆ ncia de um padr˜ o por uma sequˆ ncia de caracteres dentro de uma string. e a e • table: oferece funcoes para manipulacao de tabelas, tais como funcoes para inserir um novo ¸˜ ¸˜ ¸˜ elemento (associado a um ´ndice num´ rico) na tabela (table.insert), remover um elemento ı e da tabela (table.remove) e ordenar os elementos armazenados em ´ncides num´ ricos de uma ı e tabela (table.sort). ` • math: oferece funcoes semelhantes as funcoes oferecidas pela biblioteca matem´ tica de C, tais ¸˜ ¸˜ a como math.sqrt, math.sin, math.log, etc. • io: oferece funcoes para operacoes de entrada e sa´da, tais como abertura (io.open), fecha¸˜ ¸˜ ı mento de arquivos (io.close), leitura (io.read) e escrita (io.write). A biblioteca de io tra´ balha com o conceito de objeto. Um arquivo aberto e um objeto ao qual temos associado m´ todos. Assim, ap´ s o comando f = io.open("entrada.txt","r"), a vari´ vel f cont´ m e o a e um objeto do tipo arquivo. De posse do objeto, podemos usar funcoes (io.read(f,...)) ou ¸˜ m´ todos (f:read(...)) para manipularmos o arquivo. e ` • os: oferece funcoes relacionadas ao sistema operacional, tamb´ m an´ logas as funcoes ofere¸˜ e a ¸˜ cidas pela biblioteca C, tais como os.clock, os.date, os.execute (an´ loga a system de C). a • debug: oferece funcoes para depuracao de c´ digos Lua. As funcoes oferecidas permitem, por ¸˜ ¸˜ o ¸˜ exemplo, consultar o estado corrente da pilha de execucao de Lua e os valores de vari´ veis ¸˜ a locais em todos os n´veis da pilha. Essa biblioteca oferece ainda mecanismos para cadastrar ı acoes a serem tomadas a cada execucao de uma linha de c´ digo, a cada chamada de funcao, ¸˜ ¸˜ o ¸˜ etc., viabilizando a construcao de interfaces de depuracao. Assim, em vez de oferecer uma fer¸˜ ¸˜ ramenta de depuracao, Lua oferece mecanismos para que tais ferramentas sejam facilmente ¸˜ constru´das, direcionadas para o dom´nio da aplicacao em quest˜ o. ı ı ¸˜ a Lua oferece ainda a biblioteca de co-rotinas, que discutiremos na pr´ xima secao, dada a sua o ¸˜ especial importˆ ncia para a programacao de jogos. a ¸˜ 3.8 Co-rotinas ´ Co-rotinas s˜ o um poderoso mecanismo de programacao para jogos. Uma co-rotina e semelhante a ¸˜ a um thread num sistema de multithreading, no sentido de que temos uma linha de execucao com ¸˜ seu pr´ prio ambiente local (pilha de execucao) compartilhando o ambiente global com outras coo ¸˜ rotinas. A grande diferenca entre uma co-rotina e uma funcao e que a execucao de uma co-rotina ¸ ¸˜ ´ ¸˜ pode ser suspensa e retomada posteriormente (no ponto em que foi suspensa). A diferenca en¸ ´ tre co-rotinas e threads e que, conceitualmente, diferentes threads executam simulataneamente, enquanto que num sistema com co-rotinas, apenas uma co-rotina executa por vez. As funcoes que manipulam co-rotinas est˜ o agrupadas na tabela coroutine. Criamos uma co¸˜ a rotina passando uma funcao (em geral, anˆ mina) para a funcao de criacao, que retorna um valor ¸˜ o ¸˜ ¸˜ do tipo thread: local c = coroutine.create(function () ... end) print(type(c)) --> "thread" Uma co-rotina pode estar em trˆ s diferentes estados: suspensa, executando e inativa. Imediae tamente ap´ s a sua criacao, uma co-rotina est´ no estado “suspensa”. Para executar uma co-rotina, o ¸˜ a invocamos a funcao coroutine.resume. A execucao de uma co-rotina comeca pela execucao da ¸˜ ¸˜ ¸ ¸˜ funcao passada como parˆ metro na sua criacao. Dentro do c´ digo da co-rotina, podemos suspen¸˜ a ¸˜ o der sua execucao invocando a funcao coroutine.yield. Ao executar essa funcao, o controle volta ¸˜ ¸˜ ¸˜ 11 para o c´ digo que tinha dado coroutine.resume na co-rotina, restaurando todo o ambiente local. A o co-rotina pode voltar a ser executada com uma outra chamada de coroutine.resume, e a execucao ¸˜ ´ ´ e retomada logo ap´ s o ultimo comando coroutine.yield executado. Do ponto de vista da coo ´ rotina, uma chamada a coroutine.yield retorna quando a execucao da co-rotina e retomada (via ¸˜ coroutine.resume). Lua oferece um mecanismo simples e vers´ til para troca de dados (mensagens) a entre co-rotinas. Os argumentos de uma chamada a coroutine.yield s˜ o passados como valores a de retorno da chamada a coroutine.resume. Simetricamente, os argumentos de coroutine.resume s˜ o passados como valores de retorno da funcao coroutine.yield. a ¸˜ ´ Co-rotinas s˜ o muito uteis quando queremos implementar um procedimento de maneira increa mental. Em jogos, onde temos um tempo limitado para executarmos nossas simulacoes, podemos ¸˜ implementar as simulacoes de forma incremental, executando os passos que s˜ o poss´veis entre ¸˜ a ı quadros da animacao. Para ilustrar, vamos considerar um exemplo hipot´ tico: um jogo tem que ¸˜ e fazer a simulacao do comportamento de diversos personagens. Para n˜ o favorecer um personagem ¸˜ a em relacao aos outros, podemos pensar em implementar a simulacao de forma incremental, cri¸˜ ¸˜ ando co-rotinas e suspendendo sua execucao ap´ s um passo da simulacao. Podemos prever ent˜ o ¸˜ o ¸˜ a uma funcao que gerencia a execucao das diversas simulacoes, executando cada uma passo a passo. ¸˜ ¸˜ ¸˜ ´ Note que o uso de co-rotinas aqui e muito apropriado, pois cada simulacao pode ser retomada a ¸˜ qualquer instante — a linguagem garante a restauracao do seu ambiente local. ¸˜ Comecamos pela programacao da simulacao de cada personagem (ou grupo de personagens) ¸ ¸˜ ¸˜ encapsulada por co-rotina. Agrupamos as co-rotinas numa tabela e passamos essa tabela para um gerenciador das simulacoes. O gerenciador chama uma co-rotina por vez. Conforme ilustrado ¸˜ abaixo, o gerenciador pode, por sua vez, ser uma co-rotina gerenciada por um controle externo. local simulators = { coroutine.create(function () coroutine.create(function () coroutine.create(function () ... } ... end), ... end), ... end), -- simula¸~o 1 ca -- simula¸~o 2 ca -- simula¸~o 3 ca function manager () while true do for i,v in pairs(simulators) do coroutine.resume(v) end coroutine.yield() -- repassa para controlador externo end end 3.9 Interface com C ´ Como Lua e uma linguagem para estender aplicacoes, ela n˜ o tem somente uma sintaxe e uma ¸˜ a semˆ ntica: ela tem tamb´ m uma API para comunicacao com a aplicacao. Essa API est´ descrita em a e ¸˜ ¸˜ a ´ ´ ´ lua.h e e formada por aproximadamente 80 funcoes C. (N˜ o se assuste com esse numero! A API e ¸˜ a razoavelmente simples.) ´ O primeiro conceito na API e o estado Lua: a execucao de um programa Lua e a comunicacao ¸˜ ¸˜ de C com Lua se d˜ o atrav´ s de um estado Lua, que cont´ m todas as vari´ veis e seus valores correna e e a tes. A aplicacao pode criar mais de um estado Lua. Eles s˜ o todos completamente independentes ¸˜ a uns dos outros. Por isso, cada funcao da API recebe como primeiro parˆ metro o estado Lua sobre ¸˜ a ´ ´ o qual ela deve operar. A unica excecao a essa regra e a funcao lua_open, que cria um estado novo. ¸˜ ` ¸˜ 12 Um estado Lua existe at´ que ele seja fechado, com lua_close. Nesse momento, toda a mem´ ria e o ´ usada pelo estado e liberada, e suas vari´ veis e valores desaparecem. a ´ O principal mecanismo de comunicacao entre Lua e C e uma pilha virtual. Nela, C p˜ e valores ¸˜ o a serem usados por Lua e vice-versa. A pilha pode armazenar valores Lua de qualquer tipo (nil, ´ booleano, numero, string, tabela, funcao, userdata e thread). H´ portanto funcoes da API para por ¸˜ a ¸˜ na pilha valores de cada um desses tipos. H´ tamb´ m funcoes da API para consultar o tipo de um a e ¸˜ valor que est´ na pilha e para convertˆ -lo para um valor C, quando isso faz sentido. (N˜ o faz sentido a e a ´ converter uma tabela Lua para C porque C n˜ o tem tabelas. Mas faz sentido converter um numero a ou string para C.) ´ Como Lua tem coleta autom´ tica de lixo, e necess´ rio estar atento para n˜ o usar valores obtidos a a a ´ de uma pilha inativa. O erro mais comum e guardar um string Lua em C como simplesmente o ponteiro que Lua retorna via lua_tostring: quando a pilha ficar inv´ lida, esse ponteiro pode n˜ o mais a a ´ apontar para o string correspondente (nem para nenhum outro string ou qualquer area v´ lida). A a ´ pilha fica inv´ lida quando a funcao C retorna ou quando o estado e fechado. a ¸˜ 4 Uso de Lua em jogos Nesta secao, discutiremos o uso de Lua em jogos, desde um n´vel mais simples at´ um n´vel sofisti¸˜ ı e ı cado. 4.1 Lua como linguagem de configuracao ¸˜ Como discutimos na Secao 2, no n´vel mais simples uma linguagem de configuracao e uma ma¸˜ ı ¸˜ ´ neira de associar valores a vari´ veis. N˜ o h´ controle de fluxo nem funcoes definidas pelo usu´ rio, a a a ¸˜ a ´ somente uma sequˆ ncia de atribuicoes. Um exemplo t´pico e: e ¸˜ ı -- come¸ar no meio do jogo, usando Mickey... c LEVEL = 13 HERO = "Mickey" ` Mesmo uma linguagem simples como essa j´ d´ uma grande flexibilidade a aplicacao, pois permite a a ¸˜ ao usu´ rio controlar a aplicacao externamente, bastando editar um arquivo texto. a ¸˜ Vejamos como usar Lua nessa situacao do ponto de vista do programador da aplicacao. Estamos ¸˜ ¸˜ portanto agora falando de c´ digo C. (Do ponto de vista do usu´ rio da aplicacao, para usar a linguao a ¸˜ gem de configuracao basta ler a documentacao da aplicacao para saber que vari´ veis existem, quais ¸˜ ¸˜ ¸˜ a os seus poss´veis valores e o que eles significam para a aplicacao. O usu´ rio nem precisa saber que ı ¸˜ a est´ escrevendo na verdade um programa Lua.) a ´ ´ A primeira coisa e carregar essa configuracao de dentro da aplicacao. Antes disso, e preciso ¸˜ ¸˜ inicializar Lua, criando um estado, que vai existir at´ ser fechado: e #include "lua.h" #include "lauxlib.h" ... lua_State *L=lua_open(); ... lua_close(L); Uma vez criado um estado Lua, podemos carregar um arquivo de configuracao, digamos init.lua: ¸˜ luaL_loadfile(L,"init.lua"); lua_pcall(L,0,0,0); 13 Note que a carga da configuracao e feita em dois passos: leitura com luaL_loadfile e execucao com ¸˜ ´ ¸˜ lua_pcall. Isso permite o tratamento separado de erros de sintaxe e erros de execucao. Entretanto, ¸˜ o c´ digo acima n˜ o trata erros. Na pr´ tica, usa-se o c´ digo abaixo ou algo parecido: o a a o if (luaL_loadfile(L,"init.lua") || lua_pcall(L,0,0,0)) error(lua_tostring(L,-1)); ´ onde error e uma funcao que trata erro. A mensagem de erro vinda de Lua est´ no topo da pilha e ¸˜ a ´ portanto e obtida com lua_tostring(L,-1). Assumindo que n˜ o houve erros na carga da configuracao, a execucao de init.lua criou no a ¸˜ ¸˜ ´ estado L as vari´ veis com seus valores dados em init.lua. E hora portanto da aplicacao usar esses a ¸˜ ´ valores. Note que os valores est˜ o em Lua, mas ainda n˜ o em C; e necess´ rio lˆ -los de Lua para C. a a a e Tipicamente, a aplicacao est´ interessada nos valores de algumas vari´ veis espec´ficas, como LEVEL ¸˜ a a ı no exemplo inicial. Podemos ler o valor de LEVEL com lua_getglobal(L,"LEVEL"); ´ Isso lˆ o valor da vari´ vel LEVEL de Lua e deixa esse valor na pilha, que e o mecanismo de comunicacao e a ¸˜ entre Lua e C e vice-versa. Basta agora copiar essa valor para uma vari´ vel C: a level=lua_tonumber(L,-1); assumindo claro que level esteja declarada corretamente em C. Note que n˜ o h´ nenhuma relacao a a ¸˜ entre a vari´ vel C e a vari´ vel Lua. Nesse exemplo, elas nem tˆ m o mesmo nome, somente um nome a a e parecido. Mas mesmo que tivessem o mesmo nome, seriam vari´ veis em mundos separados, sem a ´ nenhuma relacao autom´ tica entre elas. (E poss´vel programar uma tal relacao autom´ tica entre os ¸˜ a ı ¸˜ a mundos C e Lua usando mecanismos avancados de Lua.) ¸ A mesma coisa se aplica para HERO, exceto que agora queremos um string : lua_getglobal(L,"HERO"); hero=lua_tostring(L,-1); ´ E isso e tudo. A aplicacao n˜ o precisa mais de Lua e pode agora fazer o que ela tem que fazer, ¸˜ a usando os valores de level e hero fornecidos pelo usu´ rio. Um c´ digo completo seria ent˜ o algo a o a como: #include "lua.h" #include "lauxlib.h" static int level=0; const char* hero="Minnie"; ... int main(void) { lua_State *L=lua_open(); luaL_loadfile(L,"init.lua"); lua_pcall(L,0,0,0); lua_getglobal(L,"LEVEL"); level=lua_tonumber(L,-1); lua_getglobal(L,"HERO"); hero=lua_tostring(L,-1); play(level,hero); lua_close(L); return 0; } 14 ´ Note que n˜ o podemos fechar o estado Lua antes de chamar play, pois play usa hero, que e a um string obtido de Lua. Para poder fechar o estado Lua antes de chamar play, seria necess´ rio a duplicar o valor de hero antes. ´ Mais uma vez, o c´ digo acima n˜ o trata erros. Isso e feito somente para simplificar a exposicao. o a ¸˜ ´ Na pr´ tica, o tratamento de erros e obrigat´ rio (como em toda aplicacao de qualidade), principala o ¸˜ mente quando se carrega arquivos escritos por usu´ rios: n˜ o se pode exigir que os usu´ rios n˜ o a a a a cometam enganos! (A aplicacao tamb´ m precisa se proteger contra usu´ rios mal intencionados. . . ) ¸˜ e a ´ o O uso de Lua nessa situacao simples pode parecer um exagero. E c´ digo demais para ler dois ¸˜ valores fornecidos pelo usu´ rio. Seria bem mais simples lˆ -los da linha de comando ou mesmo a e de um arquivo, mas sem a necessidade de nomes de vari´ veis. Na pr´ tica, s˜ o necess´ rios muito a a a a mais do que somente dois valores. De qualquer modo, note como usar uma linguagem tem grandes vantagens: coment´ rios, linhas em branco, indentacao, aspas e espacos dentro de aspas s˜ o todos a ¸˜ ¸ a tratados automaticamente e funcionam da maneira como o usu´ rio espera inconscientemente que a eles funcionem. Fazer isso manualmente na aplicacao seria sim uma grande complicacao! ¸˜ ¸˜ Esse n´vel simples de configuracao tamb´ m permite coisas mais complicadas, como definir ı ¸˜ e vari´ veis em funcao de outras: a ¸˜ -- come¸ar no meio do jogo, usando Mickey... c LEVEL = 13 HERO = "Mickey" GREET = "Bom dia " .. HERO .. "! Como vai" SCORE = 1.2 * LEVEL ´ Embora o arquivo continue sendo uma lista de atribuicoes de valores a vari´ veis, e poss´vel ¸˜ a ı usar express˜ es do lado direito das atribuicoes. Entender e executar express˜ es e uma das tarefas o ¸˜ o ´ principais de uma linguagem de programacao. Note aqui a vantagem de termos uma linguagem ¸˜ embutida completa! ´ O usu´ rio pode n˜ o saber que e poss´vel fazer isso, mas assim que ele souber ou descobrir, vai a a ı provavelmente usar atribuicoes complicadas sem ter que pensar muito na sua forma, pois a sintaxe ¸˜ ´ das express˜ es em Lua e a mesma da maioria das linguagens (com a poss´vel excecao do operador o ı ¸˜ de combinacao de strings). ¸˜ 4.2 Lua como linguagem de extens˜ o a ´ O uso de Lua como linguagem de configuracao mostrado na secao anterior ainda e muito simples. ¸˜ ¸˜ Lua oferece facilidades para estruturacao de dados que podemos explorar quando descrevemos os ¸˜ objetos de um jogo. Para ilustrar a discuss˜ o, vamos considerar que precisamos descrever diferentes a armas que podem ser usadas por nossos personagens. Para cada arma, devemos informar seu “fator de agressividade”, “alcance de ataque” e “precis˜ o”. O conjunto de armas pode ser agrupado numa a tabela, onde os elementos especificam as caracter´sticas de cada arma: ı weapons = { knife = { aggression = 0.3, attackrange = 0.5, accuracy = 1.0, }, sword = { aggression = 0.5, attackrange = 1.5, accuracy = 0.8, 15 }, ... } ´ a Com os dados estruturados, e f´ cil estender o jogo, incluindo, por exemplo, um novo tipo de arma. ´ Dessa forma, a “precis˜ o” de uma espada e obtida consultando o valor de weapons.sword.accuracy. a ´ De C, assumindo que weapons e uma vari´ vel global de Lua, esse valor seria obtido pelo seguinte a trecho de c´ digo: o double accuracy; lua_getglobal(L,’weapons’); lua_pushstring(L,’sword’); lua_gettable(L,-2); lua_pushstring(L,’accuracy’); lua_gettable(L,-2); accuracy = lua_tonumber(L,-1); lua_pop(L,2); /* /* /* /* /* /* /* push weapons on stack */ push string ’sword’ */ get weapons.sword */ push string ’accuracy’ */ get weapons.sword.accuracy */ convert value to C */ restore Lua stack */ ´ Conforme mencionado na secao anterior, e fundamental que tenhamos verificacao de erros. ¸˜ ¸˜ A verificacao de erros em C seria tediosa. Fica bem mais simples escrever c´ digo Lua que faca a ¸˜ o ¸ verificacao de erros nos scripts escritos pelos usu´ rios (roteiristas, artistas, programadores, ou os ¸˜ a ´ pr´ prios usu´ rios finais dos jogos). Uma maneira simples de fazer a verificacao de erro e incluir o a ¸˜ construtores de tabelas. No exemplo acima, podemos incluir o construtor Weapon para cada arma descrita: weapons = { knife = Weapon{ aggression = 0.3, attackrange = 0.5, accuracy = 1.0, }, sword = Weapon{ aggression = 0.5, attackrange = 1.5, accuracy = 0.8, }, ... } O construtor Weapon pode ent˜ o verificar erros e preencher valores defaults: a funciton Weapon (self) if not self.aggression then self.aggression = 0.5 -- default aggression value elseif self.aggression <> 1.0 then ReportError("Invalid aggression value") ... return self end Podemos ir mais longe, por exemplo, especificando o comportamento dos personagens. Em Lua, como funcoes s˜ o tratadas como valores de primeira classe, esses comportamentos e acoes ¸˜ a ¸˜ 16 podem ser facilmente integrados na descricao de tabelas. Como exemplo, vamos imaginar o mo¸˜ mento em que o personagem encontra uma nova arma. As caracter´sticas da arma encontrada ı podem enriquecer o di´ logo: a weapons = { knife = Weapon{ aggression = 0.3, attackrange = 0.5, accuracy = 1.0, getit = function (person) if person:HasEnoughWeapon() then person:Speak("N~o preciso dessa faca") a return false else person:Speak("Essa faca me ser´ muito ´til") a u return true end end, }, ... } 4.3 Lua como linguagem de controle Nesse terceiro n´vel de utilizacao da linguagem Lua em jogos, invertemos os pap´ is: Lua passa a ı ¸˜ e ser o controlador do jogo, o cliente, e o c´ digo C funciona apenas como servidor, implementando o de forma eficiente os servicos demandados por Lua. Nesse caso, ganhamos uma grande flexibi¸ lidade com o uso de uma linguagem de script. Os programadores C ficam respons´ veis por ima plementar algoritmos eficientes e os “programadores” Lua ficam respons´ veis por criar o roteiro, a a hist´ ria, o comportamento dos personagens, etc. Dessa forma, em C codificamos as engines do o jogo (estruturacao e rendering de cenas, simulacao f´sica, algoritmos de inteligˆ ncia artificial, ge¸˜ ¸˜ ı e renciamento de sons, etc.) e, em Lua, escrevemos o script, decidindo que arma usar, que som tocar, ´ que algortimo de inteligˆ ncia artificial usar, etc. Essa e uma divis˜ o natural para o desenvolvimento e a ´ dos jogos. A vantagem de se usar uma linguagem como Lua e que os profissionais envolvidos com a programacao do roteiro n˜ o s˜ o, em geral, profissionais com experiˆ ncia em programacao. No ¸˜ a a e ¸˜ ´ entanto, aprender a programar um ambiente Lua onde os erros s˜ o automaticamente verificados e a muito simples. Al´ m disso, como n˜ o h´ necessidade de compilacao da aplicacao — que pode ser e a a ¸˜ ¸˜ demorada — o desenvolvimento do jogo fica muito mais r´ pido. a Para que de Lua tenhamos acesso aos servicos oferecidos por C temos que exportar as funcio¸ nalidades de C para Lua. Isso pode ser feito utilizando a API de Lua diretamente ou atrav´ s de ferrae mentas que fazem o mapeamento de forma autom´ tica. No site de Lua, encontram-se dispon´veis a ı algumas dessas ferramentas. A disponibilizacao dos servicos implementados em C para “programadores” Lua pode ser feita ¸˜ ¸ em duas etapas: mapeamento direto das funcoes e classes, e c´ digo de interface em Lua. ¸˜ o Na primeira etapa, usando a API ou uma ferramenta de mapeamento, obtemos um c´ digo C que o ´ exporta as funcoes e m´ todos para Lua. Em geral, isso e feito escrevendo-se funcoes C que, usando ¸˜ e ¸˜ a API de Lua, recebem os parˆ metros de Lua, chamam as funcoes e m´ todos de C e mapeiam os a ¸˜ e valores retornados para Lua. Na segunda etapa, podemos encapsular as chamadas das funcoes e m´ todos de C atrav´ s de ¸˜ e e construtores e funcoes escritos em Lua, elevando o n´vel de abstracao para acesso aos servicos das ¸˜ ı ¸˜ ¸ 17 engines. Dessa forma, fazemos com que a programacao em Lua seja feita de forma simples, facili¸˜ tando o acesso program´ vel a artistas, roteiristas, etc. a Para exemplificar, vamos considerar a implementacao em C++ da classe ‘CPerson’ que estrutura ¸˜ as caracter´sticas de uma personagem do jogo. A cada personagem associamos uma s´ rie de atriı e butos: nome, energia inicial, listas das armas que sabe manusear, etc. Em C++, esses atributos s˜ o a definidos atrav´ s de chamadas de m´ todos. Podemos tamb´ m prever a implementacao de acoes e e e ¸˜ ¸˜ simples como andar, correr, pular, atacar. A interface da classe em C++ poderia ser dada ent˜ o por: a class CPerson { ... public: CPerson (char* model_file); void SetName (char* name); void SetEnergy (double value); AddSkill (Weapon* w); double GetEnergy (); Walk (); Run (); Jump (); Attack (); ... }; Com o uso de uma ferramenta (ou fazendo o mapeamento diretamente via API), podemos ter acessos a esses m´ todos em Lua. No entanto, n˜ o queremos que o roteirista do jogo tenha que fazer e a chamadas de m´ todos de C++. O quanto poss´vel, devemos dar preferˆ ncias a interfaces descritivas, e ı e como j´ vinhamos fazendo nas secoes anteriores. Um roteirista poderia, por exemplo, instanciar a ¸˜ um novo personagem de forma descritiva: Hero = Person { name = "Tarzan", model = "models/tarzan.mdl", energy = 1.0, skills = {knife, axe} } O construtor, previamente codificado em Lua, seria respons´ vel por instanciar o objeto em C++ a e definir seus atributos iniciais (al´ m de fazer verificacao de erros, que ser´ omitida aqui): e ¸˜ a function Person (self) local cobj = CPerson:new(self.model) cobj:SetName(self.name) cobj:SetEnergy(self.energy) for i,v = ipairs(self.skills) do cobj:AddSkill(v) end return cobj end -- create instance Numa segunda etapa, o roteirista pode programar as acoes associadas ao personagem: ¸˜ 18 ... if Hero:GetEnergy() > 0.5 then Hero:Attack() else Hero:Run() end ... 5 Conclus˜ o a A linguagem Lua tem sido amplamente utilizada no desenvolvimento de jogos. A Lucasarts, por exemplo, usou a vers˜ o 3.1 de Lua para desenvolver os t´tulos “Grim Fandango” e “Scape from Mona ı key Island”. A vers˜ o 3.1 de Lua foi por eles modificada para tratar co-rotinas. Hoje, como vimos, a suporte para co-rotinas est´ presenta na vers˜ o 5.0. a a Double Fine utilizou Lua em “Psychonauts” para controlar toda a l´ gica do jogo. Basicamente, o a engine carrega um mundo est´ tico e os scripts em Lua tomam o controle, dando vida e interatia ` vidade as cenas. Em ”Baldur’s Gate”, Bioware usou Lua para prover uma ferramenta de depuracao ¸˜ em tempo-real. Relic utilizou Lua em “Impossible Creatures” para controlar a IA, as aparˆ ncias dos e objetos e personagens, para definir as regras do jogo e tamb´ m como ferramenta de depuracao em e ¸˜ tempo-real. Em “FarCry”, Crytek tamb´ m utilizou Lua para controlar diversos aspectos do jogo e e para permitir a criacao de modificadores atrav´ s da codificacao de scripts Lua. ¸˜ e ¸˜ 6 Agradecimentos Os usos de Lua em jogos listados na conclus˜ o foram levantados por Marcio Pereira de Araujo como a parte do trabalho da disciplina “Linguagem Lua”, ministrada por Roberto Ierusalimschy, oferecida nos programas de graduacao e p´ s-graduacao do Departamento de Inform´ tica da PUC-Rio. ¸˜ o ¸˜ a 7 Referˆ ncias e Para saber mais sobre Lua, leia o livro “Programming in Lua”, o manual de referˆ ncia e os artie gos abaixo. Todos esses documentos e muitas outras informacoes est˜ o dispon´veis no site de Lua ¸˜ a ı (lua.org). • R. Ierusalimschy, Programming in Lua. Lua.org, December 2003. ISBN 85-903798-1-7. • R. Ierusalimschy, L. H. de Figueiredo, W. Celes. “Lua 5.0 Reference Manual”. Technical Report MCC-14/03, PUC-Rio, 2003. • R. Ierusalimschy, L. H. de Figueiredo, W. Celes. The evolution of an extension language: a history of Lua, Proceedings of V Brazilian Symposium on Programming Languages (2001) B14–B-28. • R. Ierusalimschy, L. H. de Figueiredo, W. Celes. Lua—an extensible extension language. Software: Practice & Experience 26 #6 (1996) 635–652. • L. H. de Figueiredo, R. Ierusalimschy, W. Celes. Lua: an extensible embedded language. Dr. Dobb’s Journal 21 #12 (Dec 1996) 26–33. • L. H. de Figueiredo, R. Ierusalimschy, W. Celes. The design and implementation of a language for extending applications. Proceedings of XXI Brazilian Seminar on Software and Hardware (1994) 273–83. 19

Marcadores: , , ,



2009-08-19  

Video - Produtos - corinthians

corinthians




Marcadores: ,



2009-08-18  

Conceito de "raças" foi criado para justificar dominação



Marcadores: , , , , , , , , , , ,



 

Video - Produtos - bp 148

bp_148




Marcadores: ,



2009-08-17  

Dr Pepper

Dr. Pepper

Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper
Dr. Pepper

Marcadores:



 

Video - Produtos - bal 180

bal_180




Marcadores: ,



2009-08-16  

Video - Produtos - bal 150pa

bal_150pa




Marcadores: ,



 

Lua Frequently Asked Questions ( FAQ )

Programming in LuaImage by Metaphox via Flickr

Lua Frequently Asked Questions (FAQ)


Marcadores: , , , , , , , , , ,



 

arquivo morto

A gente não deseja o mal a ninguém, mas você já parou pra pensar no que vai acontecer com seu MSN quando você morrer? O que vão fazer com seu perfil no Orkut ou no Facebook? E seus e-mails importantes, o que será deles? Dá pra recuperar suas fotos no Flickr e deixá-las para alguém?

Bom, temos uma notícia boa e outra ruim. A boa é que a maioria dos seus pertences cibernéticos podem ser recuperados e, se você não quer receber homenagens digitais depois que partir dessa pra melhor, é possível deletar seus perfis no Orkut ou no Facebook. Mas aí é que entra a má notícia: eliminar rastros na internet dá um trabalho gigante.

O Superblog oferece duas opções. Na primeira, mostramos os caminhos que seus amigos e parentes devem seguir para apagar o que sobrou de você na internet. Já a segunda tem uma função mais preventiva: apresentamos serviços de “testamento virtual”, que distribuem seu legado cibernético entre os mais chegados. O que você prefere? Prevenir ou remediar? Dê uma olhada no post e decida.

O QUE SEUS AMIGOS PODEM RESOLVER POR VOCÊ

Hotmail

Não adianta insistir: a política de privacidade do Windows é muito restrita e não manda senhas para ninguém. Contudo, a empresa pode enviar os contatos e e-mails arquivados em um CD para um parente ou amigo. É preciso redigir uma solicitação contendo seu e-mail pessoal, endereço, um comprovante de que você é o responsável legal pelos pertences do falecido, uma cópia da sua carteira de motorista (!), cópia de certidão de óbito e as seguintes informações sobre a conta de e-mail:

- Endereço da conta

- Primeiro e ultimo nome do dono do e-mail

- Data de nascimento

- Cidade, estado e código postal

- Data aproximada de criação da conta

- Data aproximada do último login

Depois disso, é preciso juntar todos esses documentos e enviá-los por fax para o Custodian of Records, no número 00(XX)1 (425) 708-0096, ou por correio, aos cuidados do Windows Live/MSN Compliance, no endereço: 1065 La Avenida, Building 4, Mountain View, CA 94043, USA. Você deve escrever por fora do envelope que o conteúdo é destinado à seção Custodian of Records. Cinco dias úteis depois, o Windows Live vai procurar o encarregado pelo requerimento e conferir os dados. Tudo certo? Você irá receber todas as informações do seu chegado em casa, pelo correio.

Facebook

É preciso enviar um e-mail para a divisão de privacidade do Facebook, em inglês, com uma cópia do atestado de óbito do morto. Também é necessário comprovar parentesco com o falecido, ou a equipe do Facebook pode se negar a deletar o perfil. Se você desejar retirar apenas algumas informações mais importantes, mas manter o perfil, é possível “memorizá-lo”, ou seja, mantê-lo visível apenas para amigos adicionados. Neste caso, basta preencher este formulário, comprovando seu relacionamento com o morto, onde o conheceu, entre outros. O Facebook não fornece nenhuma senha.

Gmail/Google Account

O jeito mais fácil de cancelar uma conta de e-mail no Google é esquecer dela. Ao completar seis meses de inatividade, a conta fica “dormente” e é necessário reativá-la para recuperar seus e-mails e arquivos. Se ela permanecer inalterada por mais três meses – ou seja, nove meses consecutivos –, ela é totalmente cancelada.

Há outro jeito de obter as informações da conta, mas para isso é preciso preparar a papelada, o inglês e a boa vontade. Para ter acesso total ao e-mail de um ente querido no Gmail, é preciso mandar um fax ou e-mail diretamente para o Google com as seguintes informações:

- Seu nome completo e informações de contato, inclusive seu e-mail;

- O endereço de e-mail do falecido;

- Um cabeçalho completo de uma mensagem de e-mail que você tenha recebido do falecido e todo o conteúdo da mensagem enviada. (Para obter o cabeçalho completo no Gmail: abra a mensagem, clique em “More Options” > “Show Original”. Copie tudo que aparecer depois de “Delivered-To”, na linha de “References”. Se você não tem e-mail no Gmail, pode conferir as exigências do cabeçalho completo neste link )

- Comprovante de óbito

- Se o conhecido tinha 18 anos ou mais, providencie um atestado que você é o representante legal dessa pessoa ou de suas posses. Se era um menor de idade e você for pai dessa pessoa, faça uma cópia da certidão de nascimento dela.

Você deve enviar todo esse material para o Google e escrever no envelope “Attention: Gmail User Support”. O endereço é 1600 Amphitheatre Parkway, Mountain View, CA 94043. Também pode enviar por fax, pelo número 00(XX)1-650-644-0358.

Depois de receber as informações, o Gmail vai precisar de 30 dias para processar e validar os documentos enviados. Se você achar que vale a pena, pode recorrer ao tribunal para tentar diminuir esse prazo. No fim das contas, até ajustar os trâmites legais brasileiros com os americanos, o processo de validação do material é bem mais rápido.

Orkut

Se você seguir os procedimentos do Gmail, pode acessar o Orkut e cancelar a conta facilmente, basta ter o acesso à conta. Outra maneira de eliminar o perfil do conhecido é clicar em “Denunciar Abuso”, selecionar a opção “Atividade Ilegal” e fornecer o maior número possível de informações, como data e causa da morte, nome completo, a relação que vocês tinham... quanto mais pessoas denunciarem o perfil da mesma maneira, maior é a chance do Orkut retirar o perfil do ar mais rapidamente.

Twitter

Uma conta inativa no Twitter é desativada seis meses depois do último login. Então, se ninguém souber sua senha, seu perfil vai desaparecer em questão de tempo. Entramos em contato com a equipe de privacidade do Twitter para descobrir se há uma medida mais específica nesse caso, mas não houve retorno.

O QUE VOCÊ PODE FAZER PARA FACILITAR

Se você acha que prevenir é melhor do que remediar, prepare-se para mexer no bolso e desenferrujar o inglês. A maioria dos sites que oferecem testamentos virtuais são gringos, pagos e cobram pagamento anual, em dólares, naturalmente. Acha que compensa? Você sempre pode compartilhar suas senhas com um amigo confiável e vice-versa. Mas se mesmo assim você deseja passar seu legado virtual para a frente, confira as opções:

YouDeparted

O YouDeparted oferece o serviço completo. Além de armazenar suas senhas, logins e informações confidenciais, você pode guardar cópias de documentos e fotos, mandar uma mensagem de despedida para seus conhecidos e planejar seu funeral. Você deve indicar até 99 “beneficiários” para o serviço, que devem notificar o site quando você morrer. Quando isso acontecer, o YouDeparted distribui as informações fornecidas por você aos respectivos amigos e parentes. O site é um dos mais completos do ramo, por assim dizer, e também um dos mais baratos: enquanto você não morre, tem que pagar anualmente entre 10 e 80 dólares, dependendo do plano que você escolher, com mais ou menos memória de armazenamento.

Legacy Locker

O serviço é mais simples: você cadastra os serviços que possui e escolhe um “herdeiro” pra cada um deles, que receberá as informações por e-mail. De resto, é igualzinho ao YouDeparted – seus amigos precisam confirmar o óbito antes de receber as informações e você pode armazenar o que quiser. A diferença é o preço: você pode desembolsar US$300 de uma vez e ter o serviço até sua morte, ou optar pelo plano anual e pagar US$30 por mês.

Slightly Morbid

Na verdade, o Slightly Morbid não guarda seus pertences, mas é uma forma de avisar que algo aconteceu com você. O usuário cadastra seus contatos, recebe um certificado e repassa instruções para uma única pessoa. Se você morrer, essa pessoa envia uma mensagem a todos os contatos cadastrados explicando o que houve. O serviço também pode ser usado da maneira contrária: se houve um acidente, por exemplo, é fácil avisar a todo mundo que você está bem. Os preços variam entre US$10 e US$50, de acordo com o número de contatos que você deseja informar.

Marcadores: , , , , , , , , , ,