Joselitos of the World

Hi guys.

After my last post i had some comments from some idiots telling me that i should be ashamed of my self by talking neave’s project, decompiling it and have the balls to post it on my site. Well, the neave light experiment is OPEN SOURCE. You can download it and modify and even use on commercial projects. i didn’t aprove the comments from these 2 guys becouse i don’t want to use my blog as a place for this kind of discussion. 

Still on that topic, everybody that join foruns and another comunities, have found themselfs at least once, added on someone’s IM list. When you chat with this person, is usualy someone that gives you a lot of compliments at first, but what they really want is you to help them in some way, or even make something for them.

In brazil there is a term called “sem noção” that suits this kind of person. Sem noção stands for people with no common sense. In fact, the sem noção indiom is so used here, that we have a show based on a life of a senseless character, joselito. Check some joselito’s videos on youtube.

So, the other day i was quiet at my msn when this guy adds me (click to see it bigger):

Let me give you guys a quick translation for you to realize what’s going on:

Joselito: hello man, what’s up?

me: hi. who is this?

Joselito: so man, my name is Joselito and i found your msn at a flash forum. Did you make that site from a maternity hospital that has a bird?

me: i just did the flash part, but the concept is from the company i work for

Joselito: I see. Man, that site is fucking great! Did you make the bird flying around the mouse?

me: yes i did

Joselito: Man, listen up. i have decompiled the swf, i have found the code that make that animation, but i can’t understand it. i have post this help at a flash forum, but they banned me. can you help me? i want to adapt it for a site i’m making

me: ok… i’ll have to block you now. but be sure you made me laught

 

And you thinking that you were crazy…

Monday, November 24th, 2008 Uncategorized 1 Comment

Updating…

Yes. From there to eternity, all my blog posts will be in English? Well, brazilian audience sucks. People are not really interested in good Flash Development here. Looking on my google analytics statistics, i noticed that this blog recieves visits from Zimbabue (?) but the visits from Brazil are very tiny, so there’s no point on keeping writing for people that won’t read. So that’s about it.

For now, i have been working on sound stuff on Flash. I have found a very nice experiment by neave called neave light that detects the activation level of the microphone and generate colored ovals with some blending modes. The experiment is very nice and i had an idea of using it as a sound spectrum experiment. So i took a look on neave’s code and made some performance modifications (my goal was to look great fullscreen) and changed the generation code that worked based on the microphone to work based on the ByteArray object. The result is very smooth and you can see it below:

Speaking of experiments. Check out my Flash Den account. Flash Den is a marketplace where you can buy royality-free Flash files ready for you to customize. Need a gallery or a video player? There are tons of it and for a very good price. 

If you are wondering what is the name of the music playing on the file, it’s called Dreamhunt, by Rubies, remixed by Shinichi Osawa. Very good music!

That’s all folks

Saturday, November 22nd, 2008 Flash, Projetos 1 Comment

Super Site Me!

Eu não sou de andar em shopping. Geralmente quando quero comprar uma coisa, compro pela internet, mas se tiver com pressa pra receber, entro no shopping, compro e vou pra casa. O último notebook que comprei não demorou nem 5 minutos para ser comprado (imagina a cara de alegria do vendedor em vender algo caro tão rápido). E isso tem um motivo: você ve cada coisa bizarra no shopping!

Sexta-feira eu precisei ir até um shopping daqui de Recife para instalar os touchscreens da nova campanha da Claro. Cansado, após lutar com a 3G, estou a caminho do applebees para tomar meu merecido Cosmopolitan, quando me deparo com isso:

Seu site em 48 horas? Só pode ser zoação né? Cheguei em casa, fui checar meus e-mails e resolvi dar uma olhada no site da empresa, vejam só que pérola da redação publicitária:

Quicksite funciona como um fast-food, onde o cliente escolhe os ingredientes e recebe seu prato personalizado em instantes. Durante o atendimento do consultor, o cliente, dentro do cardápio apresentado, solicita o pacote e os opcionais de acordo com a sua necessidade, entrega o conteúdo que será veiculado (textos e imagens) e pronto, o site é colocado no ar em48 horas! Detalhe, já com domínio e hospedagem, estes não são itens opcionais.

O Quicksite funciona como um fast-food? Que tipo de metáfora é essa? Será que esse redator não assistiu super-size-me? O cliente solicita o pacote e os opcionais de acordo com a sua necessidade? Ou seja, ele vai, escolhe o que ele quer e o carinha da empresa não tem nada a mais de diferente a oferecer? E se eles quiserem algo mais elaborado do que um site feito em 48 horas? O consultor vai dispensar o cliente dizendo que eles não tem esse ítem no menu?

Brincadeiras à parte, eu até achei bem interessante a proposta da empresa. To precisando dum site, tem um stand ali no shopping, eu nao preciso ligar pra milhares de pessoas atrás de um contato numa agência ou studio de web, rapidinho meu site tá pronto e beleza. Uma coisa que eu achei interessante foi o sistema de administração que eles tem, que promete mundos e fundos, mas infelizmente não tem nenhuma demonstração do sitema online, então pode muito bem ser um wordpress da vida.

Tudo estava indo muito bem, até eu chegar no portifólio. Fazer seu site em 48 horas com certeza lhe proporciona tantas vantagens quanto comer no mcdonalds: sua comida sai rápido, mas pode ter certeza que no fundo no fundo todo mundo naquela lanchonete está comendo a mesma coisa. Num mundo onde se paga milhares de reais por uma bolsa, ou milhões por um carro só pela exclusividade, oferecer sites a atacado é uma idéia no mínimo ultrapassada.

Impressionante a semelhança não? Parecem irmãos gêmeos. Aqui em Pernambuco é bem comum uma agência copiar o projeto da outra (umas mais que as outras), mas eu nunca vi a agência se auto-copiar. Antes de ver como os layouts eram parecidos, eu iria comentar sobre a falta de finalização dos projetos, mas acho que nem precisa mais né? Vejam as pérolas aqui: #1, #2, #3, #4, #5, #6.

Como sempre eu guardei o melhor para o final.

Fazer um site em 48 horas não é lá um bicho de sete cabeças, mas fazer um site ruim, independente do prazo, isso sim é um problema. Eu já fiz projetos em um fim de semana, todos 100% em flash, acessíveis, com CMS, google analytics e finalização delicada. (pagando, rs…)

Vender sites baseados em templates também não é nenhum crime, eu inclusive apóio. Falando nisso, se vocês catarem por template monster no meu delicious, vão achar projetos deles que eu utilizo como referência de animação (os caras se garantem sim). O diferencial do Template Monster é que além de oferecer uma alto grau de parametrização (como o quicksite), ele oferece um alto grau de customização, lhe enviando os arquivos .psd, .fla, .html e etc. O que eles ganham com isso? Eu em toda minha experiência de internet nunca vi dois sites vindo de templates do TM iguais como esses que eu mostrei acima.

O que esperar da galera do QuickSite? Bem, que eles cresçam no mercado e eventualmente amadureçam os seus conceitos a ponto de perceber que dos menores frascos vêm os melhores perfumes e que os melhores vinhos passam anos no carvalho e principalmente ninguém fica satisfeito com um BigMac. Pode até encher a barriga, mas não deixa de ser um lanche!

Tuesday, October 21st, 2008 Uncategorized 1 Comment

[AS3] BOX2DFlash - Primeiros Passos

Olá. Se você vive no planeta Terra e está antenado nas últimas notícias relevantes no mundo, você deve ter visto uma coisa surpreendente por esses dias. Não, eu não estou falando da crise econômica, eu to falando da ação interativa que a Nintendo promoveu no Youtube para o jogo Warioland: Shake it. (se você ainda não viu, clique aqui e espere seu queixo cair [literalmente]). O joguinho é muito bacana. A Nintendo mais uma vez inova nos conceitos de interatividade do Wii, que nesse game permite que você chacoalhe o controle para movimentar o personagem. O site do game (que é muito legal) e a ação do Youtube foram feitos pela premiadíssima Fantasy Interactive. No Youtube, os caras usaram a tecnologia dos cuepoints para em que determinados momentos do vídeo, coisas acontecessem com a página do Youtube. Então eles recriaram toda a página num flash e montaram a catástrofe utilizando uma biblioteca de física chamada box2D, originalmente de C++ e agora portada para AS3.

destruindo o Youtube

A box2D é uma biblioteca fantástica que simula o mundo da física numa forma bem realista e lógica. Tudo pode ser controlado, gravidade vertical, horizontal, fricções, pesos, massas, densidades e todas a grandes variáveis da física.

Para você começar no box2d, faça o download lá no site deles, descompacte o zip e comece a brincar. Num projeto de box2d, primeiramente você vai especificar os limites do seu mundo, para isso, você vai usar um objeto da classe b2AABB. Essa classe de nome maluco é que vai verificar os limites do funcionamento da engine dentro do seu mundo.

Depois disso, você vai precisar criar um mundo. Nesse mundo, você deve especificar os limites (que é o objeto b2AABB), a gravidade e se os objetos devem ficar imóveis quando inativos (o que é altamente recomendável para economizar performance e evitar loucuras imprevistas).

Uma curiosidade é que a gravidade no box2D é tratada como vertical e horizontal, portanto deve ser um objeto da classe b2Vec2, que trata pontos X e Y. Outra coisa importante a se falar é que no box2d, todas as medidas são em metros, então sempre que usar no Flash, você vai precisar fazer a conversão de pixes para metros que é de 30 para 1. Portanto, sempre quando for criar um projeto com box2d, é interessante criar uma variável para armazenar o número 30 e facilitar as conversões. Veja abaixo um exemplo de um sketch para box2d:

package
{
 
	import flash.display.Sprite;
	import flash.events.Event;
 
	import Box2D.Dynamics.*;
	import Box2D.Collision.*;
	import Box2D.Collision.Shapes.*;
	import Box2D.Dynamics.Joints.*;
	import Box2D.Dynamics.Contacts.*;
	import Box2D.Common.*;
	import Box2D.Common.Math.*;
 
	import General.Input;
 
	public class Gallery extends Sprite
	{
 
		public var mundo	       :b2World;
 
		public function Gallery()
		{
 
			var limites:b2AABB 	= new b2AABB();
			limites.lowerBound.Set(-100.0, -100.0);
			limites.upperBound.Set(100.0, 100.0);
 
			var gravidade:b2Vec2 	= new b2Vec2(0.0, 9.5);
			var dormem:Boolean 	= true;
			mundo 			= new b2World(limites, gravidade, dormem);
 
		}
	}
}

Se você pulicar isso no Flash, não vai ver nada na tela, mas tenha certeza que seu mundo box2d estará criado. Agora vamos para a parte legal do bagulho: os objetos e a colisão. O box2d vem com muitas classes padrão de objetos de colisão, mas os mais comuns são Polygon (para quadrados, retangulos) e Circle (para círculos e elipses). Todos os objetos são formados por basicamente duas classes, a classe de Body e a classe de Def.

As classes Def (de definition) possui os dados abstratos do objeto (massa, posicionamento, angulos, e userData). A propriedade userData talvez seja a mais útil, pois permite que o objeto fique com a “cara” de qualquer classe que você tenha feito, ou que esteja na biblioteca. Para definir as dimensões de uma def, utiliza-se o método SetAsBox (geralmente) e para definir a posição, utiliza-se o position.Set (lembrando do pixels/metros).

As classes Body (de corpo mesmo) criam o objeto propriamente dito baseada numa classe mais simples, a b2Shape. Para criação de um novo body, você tem que passar sempre a definição para esse corpo. Isso pode parecer um processo trabalhoso, mas a vantagem é que você não precisa criar várias instâncias de defs e bodys para utilizar em vários objetos, basta você reiniciar as mesmas instâncias usando o new. Para iniciar um sistema de colisão, a primeira coisa que você precisa fazer é criar as paredes. No exemplo abaixo eu vou demonstrar a criação de uma parede do tamanho do stage utilizando as definições de def e body acima:

//paredes
 
var paredeDef:b2PolygonDef	= new b2PolygonDef();
var paredeBodyDef:b2BodyDef	= new b2BodyDef();
var parede			:b2Body;
 
paredeDef.SetAsBox(100/pixelParaMetro, (stageHeight+40)/pixelParaMetro / 2);
 
// esquerda
paredeBodyDef.position.Set(-100 / pixelParaMetro, stageHeight/pixelParaMetro/2);
parede 				= mundo.CreateBody(paredeBodyDef);
parede.CreateShape(paredeDef);
 
// direita
paredeBodyDef.position.Set((stageWidth+100) / pixelParaMetro, stageHeight/pixelParaMetro/2);
parede 				= mundo.CreateBody(paredeBodyDef);
parede.CreateShape(paredeDef);
 
// Definitions do topo e do chão
paredeDef.SetAsBox((stageWidth + 40)/pixelParaMetro/2, 100 / pixelParaMetro);
 
// Topo
paredeBodyDef.position.Set(stageWidth/pixelParaMetro/2, -100/pixelParaMetro);
parede 				= mundo.CreateBody(paredeBodyDef);
parede.CreateShape(paredeDef);
 
// Chão
paredeBodyDef.position.Set(stageWidth/pixelParaMetro/2, (stageHeight+100)/pixelParaMetro);
parede 				= mundo.CreateBody(paredeBodyDef);
parede.CreateShape(paredeDef);
 
parede.SetMassFromShapes();

Parece dar trabalho né? Pois dá sim viu! Você pode notar que eu re-utilizei todos as instâncias de bodyDef e body. Depois da definition e body criados, para adicionar esse objeto ao seu mundo, utilize o método CreateBody. É importante lembrar que se esse objeto não estiver associado a nenhuma Sprite (através do userData) ou não houver nenhum debugDraw (agente vai falar disso ainda), o objeto será criado apenas numa forma abstrata e vc não vai ver nada. Por fim, o método setMassFromShapes() computa a quantidade de massa dos objetos e adiciona no sistema.

No parágrafo anterior eu falei de DebugDraw, agora deixa eu explicar. DebugDraw é um conjunto de classes que permite que você visualize seus objetos sem associar a nenhuma sprite ou classe. Dessa forma, o debugdraw cria um objeto com simples linhas e fills para visualização rápida. Se você foi à pagina do box2d e viu aqueles exemplos, pode ver o que eu estou falando. Para criar um debugdraw, você cria um objeto da classe DebugDraw, seta as cores de linhas, fills e especifica quais detalhes do objeto você quer que sejam desenhados no stage (através da propriedade m_drawFlags). Uma vez criado seu DebugDraw, todos os objetos criados no seu sistema box2d serão interpretados e mostrados na tela. Veja um exemplo de criação de um DebugDraw:

var dbgDraw:b2DebugDraw = new b2DebugDraw(); // novo objeto criado
dbgDraw.m_sprite = minhaSprite; // associamos isso a um sprite (depois dar addChid)
dbgDraw.m_drawScale = 30.0; // associamos a escala  de pixels (por padrão, 30 pra 1)
dbgDraw.m_fillAlpha = 0.3; // associamos o alpha dos preenchimentos
dbgDraw.m_lineThickness = 1.0; // a grossura da linha
dbgDraw.m_drawFlags = b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit | b2DebugDraw.e_centerOfMassBit; // aqui especificamos o que queremos que a engine desenhe, separando sempre por barras bitwise (|). Nesse casso, eu quero o contorno, as juntas e o centro de massa
mundo.SetDebugDraw(dbgDraw); // mandamos o DebugDraw para o nosso mundo

A próxima coisa a fazer num sistema box2d é criar os seus objetos de colisão. O jeito mais fácil de fazer isso é colocar num for (ou outro loop) quantos objetos quer criar e gerenciar suas propriedades dentro dele. Aqui nós vamos aplicar todos os conceitos que vimos até agora e também o conceito de userData.

No exemplo abaixo, eu estou criando 20 objetos do tipo Polygon, associando-os à minha classe ImageBox (que carrega fotos), sorteando suas posições e seu tamanho e aplicando esse tamanho sorteado à minha classe userData (fazendo a conversão pixels/metros). Veja o exemplo:

for (var i:int = 1; i < 20; i++)
{
 
    bodyDef             = new b2BodyDef(); // crio uma nova definição para o corpo
    bodyDef.position.x  = Math.random() * 15 + 5; // sorteio a posição X
    bodyDef.position.y  = Math.random() * 10; // sorteio a posição Y
 
    var rX:Number       = Math.random() + 0.8; // sorteio a largura
    var rY:Number       = rX; // como estamos falando de quadrados, a altura é a mesma da largura
 
    boxDef              = new b2PolygonDef(); //crio uma definição para o polígono
    boxDef.SetAsBox(rX, rY); // seto como as dimensões que eu sorteei
    boxDef.density      = 1.0; // densidade de 1
    boxDef.friction     = 0.5; // fricção ou atrito, ou easing
    boxDef.restitution  = 0.2; // restituição é a elasticidade do objeto
 
    bodyDef.userData    = new ImageBox(i); // aqui eu associo o shape com uma classe própria
    bodyDef.userData.width  = rX * 2 * 30; // deixo a largura igual fazendo a conversão
    bodyDef.userData.height = rY * 2 * 30; // deixo a altura igual fazendo a conversão
    body                = mundo.CreateBody(bodyDef); // adiciono esse objeto ao meu mundo
    body.CreateShape(boxDef); // crio o objeto baseado na definição acima
 
    body.SetMassFromShapes(); // calculo o peso
    addChild(bodyDef.userData); // adiciono para o displayList
 
}

A última coisa (ufa!) a se fazer num sistema box2d é criar o loop que atualizará a posição dos objetos no stage. Antes disso, nós devemos atualizar a engine através do método Step (que é como se fosse um ENTER_FRAME). O método Step pede 2 parâmetros, o timeStep (que é o tempo do mundo, geralmente a divisão de 1 para o framerate do swf. no caso de um swf com FPS de 30, o timeStep deve ser sempre 1.0/30.0) e as interations (que é basicamente a constante nos cálculos de colisão, o número padrão para isso é 10).

Eu deixei para fazer a observação mais importante do box2d aqui no final, que é onde nós mais vamos usar e entender melhor: tudo criado no box2d é abstrato e funciona numa espécie de backend do FlashPlayer. Tendo dito isso, num loop as posições, os ângulos, etc dos objetos são atualizadas, mas tudo fica armazenado internamente nos objetos b2Body.

Para você ver alguma mudança no stage você precisa associar essas mudanças às propriedades do userData desse b2BodyDef (x, y, width, height, rotation, etc). Agora eu entreguei o ouro pra vocês (podem me chamar de burro, mas demorou bastante pra eu entender que as é assim que as coisas funcionam por aqui). Veja no exemplo abaixo como criar um evento ENTER_FRAME que atualiza as posições e ângulos das sprites baseadas nos valores dos corpos:

// nosso evento ENTER_FRAME
public function redraw(e:Event):void
{
 
    // atualizamos a engine com o nosso timeStep e as interations
    mundo.Step(m_timeStep, m_iterations); 
 
     // criamos um for para atualizar todas os objetos do mundo;
    // essa sintaxe de for é bem diferente das usadas no flash e não utiliza um int,
    //mas sim o próprio body atual da lista e no final sempre passa para o próximo da lista.
 
    for (var bb:b2Body = mundo.m_bodyList; bb; bb = bb.m_next)
    {
 
	// verificamos se o userData é Sprite para podermos modificar as propriedades
	   if (bb.m_userData is Sprite)
	{
 
		// associamos o x com a posição X do objeto convertendo de metros para pixels
		bb.m_userData.x = bb.GetPosition().x * 30;
		// o mesmo para o Y
		bb.m_userData.y = bb.GetPosition().y * 30;
		// convertemos o angulo do objeto para rotation. lembrando que um está como graus e o outro como radianos, por isso a multiplicação por PI/180
		bb.m_userData.rotation  = bb.GetAngle() * (180 / Math.PI);
 
	}
 
    }
 
}

A primeira vista um desenvolvedor que nunca trabalhou com games e/ou simulações (como eu) pode achar a sintaxe muito diferente do costume, mas uma vez que você pega o jeito, tudo vai ficando mais simples. Nesse sentido, o problema é que o maluco que fez o port para AS3 deixou tudo muito parecido com a classe C++ e ignorou o fato que os desenvolvedores de Flash são bem diferentes dos de C++. Mas como nem tudo são lágrimas, teve um outro maluco que, como eu, estava insatisfeito com o port para AS3 e resolveu fazer o dele. Veja aqui a diferença na sintaxe e como está mais fácil de entender. Vamos esperar que o cara termine para poder usar.

Para finalizar esse post (enorme) vou mostrar pra vocês um pouco do que se pode fazer com box2d. Essa é uma galeria de fotos (só os thumbnails na verdade) onde os thumbs são objetos polygon e circle onde seus userData carregam fotos do meu flickr (clique e arraste as fotos).

Bom, é isso ai. Espero que eu tenha entusiasmado a todos em estudarem essa biblioteca fantástica que leva a animação no Flash para um próximo nível. Em breve mais novidades aqui no blog

Tags: ,

Saturday, October 11th, 2008 Artigos, Flash 1 Comment

[AS3] Criando Eventos PARTE 1

Olá,

Vamos continuar falando de eventos em AS3, pois como eu falei no post passado, me parece ser o assunto mais complicado de se entender entre os iniciantes.

Antigamente, nos tempos de AS2, para despachar um evento, simplesmente nós chamaríamos uma variável onEvento e associariamos uma função a ela. Essa era a forma mais primitiva de passar qualquer evento em AS2. Desenvolvedores mais experientes também conhecem outra forma, o ASBroadcaster que utilizava já da técnica dos listeners e tudo, mas a arquitetura do AS2 não permitia uma orientação a objetos fiel o suficiente para o uso correto de eventos. Por exemplo, o ASBroadcaster sempre estava relacionado a uma classe nativa do Flash, o que dificultava qualquer tipo de abstração.

Para o AS3, o time da Adobe resolveu tornar o despachamento de eventos mais fiel às regras do OOP e isso trouxe muitas melhorias em desempenho, coesão do código, reaproveitamento, etc. Mas antes de aprendermos como despachar e escutar nossos próprios eventos no Flash, vamos entender por que utilizar as técnicas de onEvento não é nada recomendável.

Digamos que nós estamos fazendo um sistema de colisão. Como todo sistema de colisão, existem duas possibilidades: dentro e fora do objeto. Veja o código abaixo e copie para o Flash e teste.

var onDentro:Function;
var onFora:Function;
 
var quadrado:Sprite = new Sprite();
addChild(quadrado);
 
quadrado.x 			= 225;
quadrado.y			= 150
 
quadrado.graphics.beginFill(0xFF0000);
quadrado.graphics.drawRect(0,0,100,100);
quadrado.graphics.endFill();
 
this.addEventListener(Event.ENTER_FRAME, moveMouse);
 
function moveMouse(e:Event):void
{
 
	if(quadrado.hitTestPoint(this.mouseX,this.mouseY,true))
	{
 
		onDentro();
 
	} else
	{
 
		onFora();
 
	}
 
}
 
function vaiTraceDentro():void
{
 
	trace("dentro");
 
}
 
function vaiTraceFora():void
{
 
	trace("fora");
 
}
 
onDentro = vaiTraceDentro;
onFora = vaiTraceFora;

Viu que a sintaxe é BEEEEM AS2? Pois é. O grande problema desse código é que se você não associar essas variáveis a alguma função, o Flash Player irá gerar um erro de runtime, pois não conseguiu encontrar uma função correspondente. Para contornar isso, muitos desenvolvedores mais inexperientes têm utilizado a técnica do try//catch que permite que o código funcione mesmo sem uma função relacionada, veja o exemplo:

var onDentro:Function;
var onFora:Function;
 
var quadrado:Sprite = new Sprite();
addChild(quadrado);
 
quadrado.x 			= 225;
quadrado.y			= 150
 
quadrado.graphics.beginFill(0xFF0000);
quadrado.graphics.drawRect(0,0,100,100);
quadrado.graphics.endFill();
 
this.addEventListener(Event.ENTER_FRAME, moveMouse);
 
function moveMouse(e:Event):void
{
 
	if(quadrado.hitTestPoint(this.mouseX,this.mouseY,true))
	{
 
		try
		{
 
			onDentro();
 
		} catch(e:Error)
		{
 
			trace(e)
 
		}
 
	} else
	{
 
		try
		{
 
			onFora();
 
		} catch(e:Error)
		{
 
			trace(e)
 
		}
 
	}
 
}
 
function vaiTraceDentro():void
{
 
	trace("dentro");
 
}
 
function vaiTraceFora():void
{
 
	trace("fora");
 
}
 
//onDentro = vaiTraceDentro; // Comentando essa parte e nao utilizando o try/catch geraria um erro
//onFora = vaiTraceFora; // Comentando essa parte e nao utilizando o try/catch geraria um erro

O problema é que a estrutura try//catch//finally é uma estrutura usada em debugging ou em circunstâncias onde existem exceções a serem lidadas. No nosso caso, não há exceção alguma, pois a sempre que o usuário movimentar o objeto, um dos dois eventos deve ser chamado. [NOTA: Já estou preparando um post sobre try//catch//finally, aguardem]

Todas as BaseClass (SimpleButton, Sprite, MovieClip, etc) no AS3 obedecem a seguinte herança: DisplayObjectContainer » InteractiveObject » DisplayObject » EventDispatcher » Object. Dessa forma, é possível concluir que a própria estrutura inerente do AS3 permite uma fácil manipulação de eventos de uma maneira mais coerente com o OOP, uma vez que a classe EventDispacher está presente no âmago da linguagem.

Então vamos deixar de enrolação e mostrar um exemplo. Eu refiz nosso código de colisão e transformei para uma classe. Observe:

package
{
 
	import flash.display.*;
	import flash.events.*;
 
	public class Colision extends Sprite
	{
 
		public static const DENTRO:String = "dentro";
		public static const FORA:String = "fora";
 
		private var quadrado:Sprite = new Sprite();
 
		public function Colision()
		{
 
			quadrado.x 	= 225;
			quadrado.y	= 150;
 
			quadrado.graphics.beginFill(0xFF0000);
			quadrado.graphics.drawRect(0,0,100,100);
			quadrado.graphics.endFill();
			addChild(quadrado);
 
			this.addEventListener(Event.ENTER_FRAME, moveMouse);
 
		}
 
		private function moveMouse(e:Event):void
		{
 
			if(quadrado.hitTestPoint(this.mouseX,this.mouseY,true))
			{
 
				this.dispatchEvent(new Event(Colision.DENTRO));
 
			} else
			{
 
				this.dispatchEvent(new Event(Colision.FORA));
 
			}
 
		}
 
	}
 
}

Implementação:

import Colision;
 
var teste:Colision = new Colision();
addChild(teste)
 
teste.addEventListener(Colision.DENTRO, traceDentro);
teste.addEventListener(Colision.FORA, traceFora);
 
function traceDentro(e:Event):void
{
 
	trace("dentro");
 
}
 
function traceFora(e:Event):void
{
 
	trace("fora");
 
}

Veja que nós criamos duas constantes estáticas, DENTRO e FORA do tipo String. Cada vez que o objeto está dentro o dispatchEvent é chamado para informar a mudança, para isso ele despacha a constante DENTRO como novo evento e vice-versa.

Agora como fazer para verificar essas mudanças e ativar as suas próprias funções? Para isso, nós utilizamos o método addEventListener que está disponível em todas as classes que herdam a EventDispatcher. Veja o exemplo abaixo:

Veja algumas vantagens de se utilizar addEventListener ao invés de onIsso onAquilo:

  • Seu código fica mais OOP-friendly ou seja, mais fiel às regras de orientação a objeto, o que facilita a manutenção e a adaptação por outros usuários;
  • Você não precisa se peocupar se os eventos despachados estão sendo escutados, uma vez que o próprio Flash se encarrega disso, ou seja: bye bye para try//catch//finally;
  • Você pode adicionar quantos addEventListener precisar para o mesmo objeto ou para objetos diferentes e associar a quantas funções quiser (veja o post sobre event.target e event.currentTarget para mais informações nisso);
  • O mais importante: você leva seus projetos a um maior nível de profissionalismo.

Bem, isso é o básico que você precisa saber para criar seus próprios eventos. Além disso, é possível criar classes de eventos que dê um melhor suporte à parametrização. Mas isso é assunto para outro post.

Até a próxima

Tags:

Saturday, September 27th, 2008 Artigos, Flash No Comments

Claro Foto-Print

Olá,

Há mais ou menos 1 ano atrás agente fez uma ação para a Claro de PE e uma loja de roupas de Recife. A Ação consistia em um monitor touchscreen, webcam e uma mini impressora de vouchers para descontos. A ação ficou bem conhecida e muito elogiada pela Claro nacional e esse mês surgiu a oportunidade para refazê-la durante a Casa Cor de Brasília!

Nós da Cappen ficamos muito lisongeados com o convite. Nessa nova ação, decidimos refazer todo o sistema, portá-lo para AS3 com Zinc para gerenciar a impressão.

Bem, deixa eu falar um pouco da ação: o usuário chega até o stand e insere seu nome. Depois ele escolhe dentre 4 estilos o que ele mais se identifica. Baseado no estilo escolhido, um celular é apresentado para o usuário. Nessa tela, ele pode ver as especificações do celular e no lado direito da tela existe um botão “clique aqui para ter uma surpresa”. Ao clicar nesse botão, o visor do celular mostra o rosto do usuário através de uma webcam escondida. Então, o botão de surpresa vira o botão “clique aqui para tirar uma foto”, que quando clicado imprime (numa impressora também escondida) um voucher que dá direito a desconto na compra daquele ou de outro aparelho dentro das lojas Claro na Casa Cor.

Esse tipo de ação é bem legal porque o usuário vai até o stand despretensioso e nunca espera o resultado final. Durante a ação aqui em Recife, as vendas aumentaram muito, tanto que eles quiseram outra ação para o Dia dos Namorados e outra para o Dia das Mães.

Dados do projeto:

Nome: Claro Foto-Print

Tipo: Ação digital com touchscreen, webcam e mini impressora de fotos

Agência: Cappen

Cliente: Claro para Casa Cor Brasília

Equipe: João Guilherme (desenvolvimento Flash/Zinc), Mauricio Nunes (Criação e Finalização)

Vejam as Fotos:

Tags:

Wednesday, September 24th, 2008 Flash, Projetos, Zinc 1 Comment

[AS3] Diferença entre event.target e event.currentTarget

Olá,

Tratamento de eventos em AS3 parece ser uma das maiores dificuldades encontradas quando migramos do AS2. Como a estrutura do AS3 é mais fiel ao OOP, isso resulta em uma maior organização dos projetos, mas a um alto custo de adaptação, códigos maiores e em muitos casos, confusão dos usuários.

Outro dia, um amigo estava com uma dúvida e veio conversar comigo. Qual é a real diferença entre event.target e event.currentTarget? Na hora, eu não soube explicar, sabe aquele tipo de coisa que agente sabe o que é, mas nao consegue explicar? Pois foi. Ai eu tive que dar um exemplo a ele, que eu lhes mostro abaixo:

stage.addEventListener(Event.ADDED, verifica);
 
function verifica(e:Event):void
{
 
          trace(e.target);
          trace(e.currentTarget);
 
}
 
var sprite:Sprite = new Sprite();
addChild(sprite);

Experimentem testar o código acima no Flash. Os resultados do output mostrarão [objet Sprite] e [object Stage]. Então o que podemos concluir disso?

Quando utilizamos eventos, a propriedade target é sempre uma referencia ao objeto que despachou o evento e a propriedade currentTarget é sempre uma referência ao objeto ouvinte do evento. Essa diferença na maioria dos casos não é percebida porque o objeto que despacha o evento geralmente é o que estamos escutando. Mas observem o exemplo abaixo:

stage.addEventListener(Event.ADDED, verifica);
 
function verifica(e:Event):void
{
 
          trace(e.target);
          trace(e.currentTarget);
 
}
 
function verificaClique(e:MouseEvent):void
{
 
          trace(e.target.name);
          trace(e.currentTarget.name);
 
}
 
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(0xFFCC00);
sprite.graphics.drawCircle(100, 100, 100);
sprite.name = "amarelo";
sprite.addEventListener(MouseEvent.CLICK, verificaClique);
addChild(sprite);
 
var sprite2:Sprite = new Sprite();
sprite2.graphics.beginFill(0xFF0000);
sprite2.graphics.drawCircle(50, 50, 50);
sprite2.x = sprite2.y = 50;
sprite2.name = "vermelho";
sprite.addChild(sprite2);

O que agente fez foi criar uma sprite dentro da outra, uma sendo amarela e outra vermelha. Quando clicamos na parte amarela da sprite, tanto o target quanto o currentTarget apontam para o mesmo objeto, a sprite amarela. Mas quando clicamos na parte vermelha, o target referencia à sprite vermelha (que foi onde clicamos) e o currentTarget à sprite amarela (que está ouvindo o evento). Bem, é isso. Espero que eu tenha esclarecido essa dúvida comum entre tantos desenvolvedores.

Eu continuarei a explicar mais coisas com relação a AS3, mas eu quero focar mais na parte lógica da coisa, como este tutorial. Bem. é isso, até a próxima

Tags:

Friday, September 19th, 2008 Artigos, Flash 1 Comment

Coca Cola Zero Mixer!

Olá,

Recentemente eu participei do desenvolvimento de uma ação digital que foi utilizada no camarote VIP do Coca Cola Zero Festival no Recife Indoor. O objetivo da ação era aprofundar o conceito de mistura de músicas que a Coca Cola está fazendo e torná-lo mais interativo.

Nós fizemos um software baseado em Flash AS3 e portado com o Zinc, onde o usuário poderia escolher uma música e misturá-la com uma batida. Depois ele poderia ver o resultado numa animação baseada no som que ele estava fazendo.

Para simplificar o processo, nós sincronizamos todas as musicas e as batidas num mesmo BPM, assim independente da escolha do usuário, elas sempre estariam sincronizadas. Ai faltou só colocar um controle de volume para definir a altura de cada musica em determinado trecho.

Além de escutar a sua mistura, os usuários eram presenteados com uma pulseira exclusiva que também era um pendrive, assim eles poderiam gravar as suas misturas na pulseira e colocar no seu mp3 player ou setar como ringtone do celular.

Pra mim a ação foi bastante satisfatória, os usuários ficaram muito satisfeitos e impressionados em poder com poucos toques misturar suas músicas favoritas. Um update para a proxima ação desse tipo seria enviar a musica via bluetooth para o celular do usuário, mas como agente não teve muito tempo pra fazer deixa pra proxima mesmo.

Dados projeto:

Nome: Coca Cola Zero Mixer

Tipo: Ação Digital com TouchScreen (4 monitores simultâneos)

Agência: Cappen

Cliente: Dot Assessoria para Coca Cola Festival

Equipe: Mauricio Nunes (Criação e Infra-Estrutura) // João Guilherme (Desenvolvimento Flash/Zinc)

Exemplos de telas:

Além desse software nós desenvolvemos um outro para pintar com tablet e tal, mas eu deixo esse para outro dia. Até mais

Tags: , ,

Tuesday, September 16th, 2008 Flash, Projetos, Zinc No Comments

I’m Back!

OIá pessoas.

Depois de mais de 1 ano sem postar nada, eu estou de volta. Muita coisa mudou, para começar o blog mudou muito. Passei do Blogger para o wordpress, algo bem mais profissional e chique! Por enquanto o blog está hospedado no wordpress.com mesmo, se essa onda de blogueiro pegar mesmo eu boto no servidor.

O que mais há de novo?

Bem, recentemente eu assumi o comando no desenvolvimento Flash na agência onde eu trabalho, a premiada Cappen. O desafio é grande, mas sempre é bom. Meu último trabalho lá foi o desenvolvimento de um software para o Festival da Coca Cola Zero, um projeto que envolveu Flash, Zinc e Clipper! (por que não né?). Os resultados foram muito satisfatórios e em breve eu postarei algumas screenshots e mais especificações do projeto.

painel flash setup jsfl

Simultaneamente eu também estou trabalhando na criação de um painel utilizando JSFL para facilitar o set-up do workspace na IDE do Flash e melhorar a produtividade da equipe, o que vocês podem ver ao lado.

A idéia é fazer algo parecido com o scaffolding do fantástico Gaia Framework, mas eu chegarei lá.

Além disso, estou trabalhando muito com o FIVe3D, os 2 primeiros projetos lançados utilizando-o foram o splash temporário da Cappen e a nova versão do meu site. Outra novidade é que eu comecei a usar o Flash Media Server 3.0 para fazer streaming de video live e aplicativos como batepapo. Eu tentei o red5, mas achei muito inconstante para o tipo de aplicativos e a audiencia que temos. No momento estou em dúvida entre dois servidores, o Influxis e o Server Room. Infelizmente ambos são caros, mas quem vai pagar mesmo é o cliente, so who cares!

Bem, por hoje é só. Esperem por mais notícias

Tags: , , ,

Monday, September 15th, 2008 Flash, Pessoal, Projetos No Comments