setMask para multiplos movieClips (#%@#!)
março 4, 2008
Mais uma maravilhosa vez, o flash me surpreende com sua incapacidade de fazer as coisas.
Pois veja bem, se você está criando movieClips dinamicamente (ou atachando) e pretendia utilizar o setMask com um mesmo movieClip de máscara para todos eles, desista. Ele não funciona.
Como proceder?
existem duas opções viáveis para solucionar o problema:
1) você pode duplicar a mascara junto com os movieClips, dar uma nova instancia e mascarar cada movieClip com uma máscara diferente.
2) você coloca todos movieClips duplicados dentro de um content e mascara o content.
Veja só, mais uma daquelas coisas da macromedia/adobe que não dá para acreditar quando se vê. Embora funcione perfeitamente na timeline, por action não é possível.
Em tempo, você não precisa alterar o depth dos movieClips quando usa o .setMask, o método já faz isto sozinho.
Encapsulamento
fevereiro 4, 2008
Encapsulamento é uma das bases da Orientação a Objetos onde a idéia principal é tornar cada objeto auto-suficiente (na medida do possível). Com isso podemos gerar código com um grande índice de reuso, além de facilitar a manutenção.
Vamos tomar como exemplo um ComboBox: Você adiciona o componente no Stage e insere os dados no mesmo (label, data, etc), certo? O componente é responsável por exibí-los. Assim, podemos dizer que você usa um ComboBox e tem acesso às propriedades necessárias para personalizá-lo ao seu modo (Talvez o combo do flash não seja o melhor exemplo de personalização, mas essa é outra história, rss). Já pensou se você precisasse programar um código para que depois de um numero x de elementos fosse inserida uma rolagem no combo? Felizmente, neste conceito (e no do flash, graças a Deus!), você não precisa. O combo é responsável pelos seus estados (lembre dessa palavra! Vamos lá, repita comigo:estado, estado, estado…), e é ele quem deve cuidar da sua rolagem independente do número de itens que possua.
Vamos supor que o nosso combo possua uma variável estática (que consequentemente tem o mesmo valor para todos os combos – ou em se tratando de OO propriamente dita, para todas as instâncias do objeto) chamada MIN_ELEMENTS, que é responsável por armazenar o número mínimo de elementos visíveis, cuja declaração seria a seguinte:
public static var MIM_ELEMENTS:Number = 1;
Então, por descuido ou qualquer outro motivo alguém resolve escrever o código:
ComboBox.MIM_ELEMENTS = -10;
A variável é publica e pode ser acessada de qualquer lugar. Mas me diga, é possível renderizar -10 itens? Você acha possível que a alteração de um atributo como este poderia afetar o funcionamento do combo? É provável que sim. Não precisamos ter acesso a atributos deste gênero para utilizar o nosso objeto combo, mas é um dado importante dentro do mesmo. Assim a declaração correta seria:
private static var MIM_ELEMENTS:Number = 1;
Agora esse atributo só é visível dentro da classe e só pode ser alterado internamente.
Vamos a outro exemplo. Temos uma classe Pessoa e um de seus atributos é sexo e seu conteúdo pode ser feminino ou masculino.
class Pessoa{
public var sexo:String;
// continua o codigo
// ...
}
var p:Pessoa = new Pessoa();
p.sexo = "Maria";
A variável sexo é pública e do tipo String portanto poderia aceitar tranquilamente a String “Maria”, entretanto, isso pode – e provavelmente irá – comprometer o funcionamento do nosso objeto, tendo em vista que o sexo “Maria” definitivamente não existe. Assim, utilizamos recursos de encapsulamento de OO para proteger o nosso objeto. Os getters e os setters.
class Pessoa{
private var _sexo: String;
public function get sexo():String{
return _sexo;
}
public function ser sexo(sexo:String){
sexo = sexo.toLowerCase();
if (sexo == "feminino" or sexo="masculino")
_sexo = sexo;
// caso nao fosse atribuido poderia ser disparado um evento,
// ser gerada uma excessao,
// exibir uma mensagem de erro e por ai vai.
}
}
No exemplo acima, garantimos que será inserido apenas um dado válido. E o getter? Bom, se você restringe o acesso a um dado e ele precise ser visto fora do objeto, é necessário disponibilizá-lo (se e somente se ele realmente precisa ser visto de fora). Mas não confunda! O getter pode conter outras coisas além do retorno do atributo.
Geralmente quando se começa a aprender POO (seja para criar o hábito, começar a identificar necessidades, ou qualquer outra coisa que se possa querer com isso) se indica utilizar atributos privados para tudo (ou quase) e a criação de getters/setters de todos eles. Isso porque quando se vem de uma linguagem procedural se pode fazer tudo com todos os atributos, não existe encapsulamento e literalmente “todo mundo é de todo mundo“. Então tenta-se a criar (ou modificar) uma cultura. Se isso é certo ou não… é um jeito (e a maioria dos programadores em algum momento passam por essa fase, depois passamos a fase de nos livrar do hábito do excesso).
A identificação das necessidade da utilização desses metodozinhos vem com a experiência em POO. É preciso saber identificar quando o usuário pode inserir um dado diretamente, quando ele pode ver um dado, quando ele pode inserir algum dado mas com restrições, quando você precisa saber se um dado é inserido, etc… Uma forma de saber isso antes de colocar a mão na massa é a modelagem. O código abaixo por exemplo é uma maneira mais burocrática de “gerar uma variável pública“.
private var _sexo: String;
public function get sexo():String{
return _sexo;
}
public function set sexo(sexo:String){
_sexo = sexo;
}
Então… Vamos modelar, modelar e modelar? Ok! Você “não tem tempo pra isso” ou “não gosta de fazer isso” ou qualquer outro “ou“. Neste caso, eu simplesmente aconselho que comece com todas os atributos privados e vá filtrando conforme desenvolve a classe (dentre os males, penso que este é o menor), mas acredite: modelar é mais rápido.
Verdadeiro ou falso: tipos
janeiro 25, 2008
Se considerarmos,
var a:String = new String(“string”);
var b:String = new String(“string”);
var c:String = “string”;
var d:String = “string”;
Então:
1) a == b ?
2) a === b?
3) c == a?
4) c === a?
5) c == d?
6) c === d?
Respostas (publicado em 03/02/08):
Começando pela diferença entre os operadores de igualdade.
O operador de igualdade estrita (===) é como o operador de igualdade, com uma diferença importante: o operador de igualdade estrita não executa a conversão de tipo. Se os dois operandos forem de tipos diferentes, o operador de igualdade estrita retornará false (MACROMEDIA, Guia de Referência do ActionScript Flash MX 2004, pag. 44).
A variável a, assim como a variável b são objetos do tipo String. Ao serem comparadas com operador estrito ou não, sempre retornarão false.
1) a == b // false
2) a === b // false
Isso porque a e b são objetos diferentes. Mesmo sendo instâncias da mesma classe e contendo atributos iguais, eles possuem identidade diferentes, são armazenados em lugares diferentes da memória, assim as variáveis a e b são referências a objetos String e contém o endereço de memória de cada um dos objetos criados. Dessa forma podemos concluir que, quando comparamos a e b, sempre será false, pois em seu conteúdo não constam valores literais, mas distintos endereços de memória.
Então, como comparar os seus conteúdos?
a.valueOf() === b.valueOf() ou a.valueOf() == b.valueOf()
Mais uma consulta ao help do flash e temos, valueOf - Método; retorna o valor primitivo do objeto especificado. Se o objeto não tiver um valor primitivo, o objeto é retornado.
Já as variáveis c e d são tipos primitivos e possuem em seu conteúdo um valor literal que lhes foi atribuído. Veja mais um trecho do Guia de Referência AS:
Os tipos de dados descrevem que tipos de informações um elemento do ActionScript ou variável pode conter. Existem dois tipos de dados internos no Flash: primitivo e referência. Os dados do tipo primitivo — String, Number e Boolean — têm um valor constante e, portanto, podem manter o valor real do elemento que representam. Os de referência— MovieClip e Object — têm valores que podem ser alterados e, portanto, contêm referências ao valor real do elemento.
Assim, considerando que c e d armazenam um conteúdo e não uma referência a uma posição de memória, podemos afirmar que:
5) c == d // true
6) c === d //true
Com base em tudo isso, podemos concluir também que:
4) c === a // false
Considerando que estamos comparando uma referência de memória com um tipo primitivo.
Já no caso:
3) c== a // true
É verdadeiro porque o operador de igualdade (==) analisa conteúdos e faz a conversão de tipo. Como o conteúdo é idêntico, o resultado é verdadeiro, independente de serem valores literais, variáveis ou referências. Então você me pergunta, porque a== b não é verdadeiro então? E a resposta é… Como o operador de igualdade considera que c == a e String(a) == b são verdadeiros?
Objetos: Instâncias e referências
janeiro 24, 2008
Objetos são instâncias de classes, que determinam qual informação um objeto contém e como ele pode manipulá-la. É através de objetos que (praticamente) todo o processamento ocorre em aplicações desenvolvidas com linguagens de POO.
Manipulando objetos
Quando declara-se uma variável cujo tipo é o nome de uma classe, como em:
var nome:String;
não está se criando um objeto dessa classe, mas simplesmente uma referência para um objeto da classe String, a qual inicialmente não faz referência a nenhum objeto válido:

Quando um objeto dessa classe é criado, obtém-se uma referência válida, que é armazenada na variável. Por exemplo:
Nome = new String(“Nova instância”);
Nome é uma variável que armazena uma referência para um objeto específico da classe String, cujo conteúdo é “Nova instância”:

A variável nome mantém apenas a referência para o objeto e não o objeto em si. Assim, uma atribuição como
var Nome2:String = Nome;
não cria outro objeto, mas simplesmente uma outra referência para o mesmo objeto

Referência:
http://www.dca.fee.unicamp.br/cursos/PooJava/objetos/manipul.html
O link acima está com explicações e exemplo de codigos para Java.
o maldito do espaço .
janeiro 17, 2008
Lá vamos nós… decompila o fla e ahn, o evento cadê? não funciona. verifica daqui, verifica dali, vai, volta, nada. chama o adriano, senta olha olha olha… nada tudo ok, listener ok, sintaxe ok, object ok, diabos o que seria? nome de evento errado, copia e cola, copia e cola, copia e cola… nada… vem o fernando, testa tuuuudo de novo, desde o início: agora vai! Não, não foi. nada. Verifica, denovo, mais uma vez, cada detalhe… ai céus, não é nada!
[ pausa para xingamentos, raivas, promessas de nunca mais usar o flash... ]
and theeen…
Fernando: “LUCIANA MARIA! e esse espaço?”
por deus, no final do nome correto de cada evento, antes de finalizar a string com aspas, tinha um espaço…
ai ai, quem sabe se na proxima vida eu não nascer astigmata hipermétrope (depois de uma longa consulta ao google para saber como poderia me denominar – obrigada dani), eu encontro os espaços sem problemas!
Cache de Classes no Flash
janeiro 17, 2008
Para não cometer o erro, ou a falha de alterar uma classe e o flash pegar a classe do cache, pode ser associada as teclas atalho do Control > Delete ASO Files and Test Movie ao CTRL + Enter.
Para isso, o Control > Test Movie tem que ter outro atalho ou nenhum. Caso queiram associar um atalho, sugiro o CTRL+M, pois não tem nenhum comando do programa associado.
Alteração fantasma
janeiro 16, 2008
Fazia umas duas horas que eu estava alterando uma classe, compilando o fla e a alteração não aparecia.
Comecei a testar colocando (“) no código, forçando um erro na classe. Compilava novamente o fla e dava erro. Ou seja, funciona o erro e não funciona a alteração. ãh?
Chamei a Dani!!!
Expliquei e ela me falou que não tinha como ser a classe correta. Enfim, não era mesmo.
Ok, achei a classe certa.
Alterei a classe e compilei. Nada! #$%@#$%@@#$@%#$
Mais uns 30 min e percebi que o fla também estava errado. O Fla 1 carregava o 2, por isso, não percebi o erro e compilava o 1 ao invés do 2, que deveria receber a alteração, mais necessitava de um simples CTRL+Enter.
Tsc .. tsc .. tsc!!
fmw.Debugger(“Olá mundo”); // Ops, faltou o …
janeiro 16, 2008
E lá vem uma história de sintaxe.
Era uma vez um evento que não funcionava. Mexi aqui e ali… E não funcionava… Não funcionava… Até que pedi água: “Lú, olha esse listener. Eu esqueci alguma coisa. Acho q é coisa boba, mas não estou enxergando.”
E a Lú mudou aqui e ali e continuava não funcionando. O Fernando (nosso dicionário de ActionScript ambulante) se juntou e nada! Eu até que estava desconfiada do trace dentro do listener (era a única coisa que tinha lá), mas quem decora sintaxe é o Fernado, que a essas alturas já estava olhando o código junto… Eu pensei: se eles que decoram sintaxe não falaram nada do trace, se eu falar levo uma xícara na cabeça. Então continuamos olhando o evento. E dispara evento e escuta evento… E nada. Então o Fernando teve a brilhante idéia: “Cria um outro evento“. A Lu criou, o evento funcionou e eu criei coragem: “Acho q é o trace“. E não é que era ele mesmo. Não levei a xícara na cabeça, mas esse trace vai me acompanhar por um bom tempo. É só eles verem um tarce que lembram de mim… E olha, que trace não se usa pouco…
Tudo isso porque resolvi usar o tal do trace do framework de flash daqui da empresa, cuja sintaxe é fmw.Debugger.trace(mensagem) e eu coloquei apenas fmw.Debugger(mensagem)… O Flash bem que podia ter avisado né, mas o bendito não deu nenhum errinho… só não acontecia nada.
Lição do dia: Os erros podem estar nas coisas mais simples. Que mania de achar que tudo é complicado, rssss…
1ª falha
janeiro 16, 2008
A gente não sabe criar usuários para esse blog sem ter que criar um outro blog.
Resultado:
5 usuários do blog, 5 blogs … grgrgr
Bom, esse espaço é reservado aos flashers (expert mode ou topeira mode) que de vez em quando, ou melhor, sempre cometem alguma mancada como por ex:
- editar uma classe de um arquivo e testar no outro;
- escrever (tracee(“Olá mundo”)) e esperar que o flash entenda isso;
Enfim, assim poderemos aprender muito com os nossos erros e mancadas.