Os modos antigos de se adicionar eventos aos objetos, como on(Release), foram abandonados. O ActionScript 3 usa Event Listeners (ouvintes de eventos). São gerenciadores de eventos, que podem ser de vários tipos, desde uso de mouse e teclado até carregamento de dados externos (para criação dos famosos preloaders) e uso do objeto Timer.

A biblioteca usada nos eventos deste artigo são:

  • flash.events.Event - eventos em geral;
  • flash.events.KeyboardEvent - eventos de teclado;
  • flash.events.MouseEvent - eventos de mouse;
  • flash.events.TimerEvent - eventos de Timer;

Adicionando eventos

editar

Eventos de mouse

editar

Para adicionar um evento clique do botão do mouse ao Sprite desenho, basta fazer isto:

var desenho:Sprite = new Sprite();

desenho.addEventListener(MouseEvent.CLICK, girarDesenho);

function girarDesenho(evt:MouseEvent):void {
    desenho.rotation += 20;
}

Foi criado o objeto desenho, e através de addEventListener foi adicionado o evento de mouse MouseEvent.CLICK com a funçãogirarDesenhocomo administradora de ações referentes a cliques. Em outras palavras, quando se clicar em desenho serão acrescentados mais 20 graus de rotação. Esta função também poderia ser transcrita desta maneira:

var desenho1:Sprite = new Sprite();
var desenho2:Sprite = new Sprite();

desenho1.addEventListener(MouseEvent.CLICK, girarDesenho);
desenho2.addEventListener(MouseEvent.CLICK, girarDesenho);

function girarDesenho(evt:MouseEvent):void {
    evt.target.rotation += 20;
}

Neste caso, a função girarDesenho irá trabalhar para desenho1 e desenho2. Eles sofrerão rotações específicas se um deles for clicado, ou alvo do evento (representado porevt.target). Quando desenho1 for clicado, ele girará 20 graus, mas desenho2 não, pois não é o alvo (target) do clique. Repare que evt não é uma palavra reservada (pode ser qualquer nome de variável válida), mas deve ser discriminada nos parâmetros por ser um listener.

A função listener sempre retorna valor vazio (void).

Além de MouseEvent.CLICK, você também pode usarMouseEvent.MOUSE_DOWN (instante em que o botão é pressionado) e MouseEvent.MOUSE_UP(momento em que o botão deixa de ser pressionado). Há também MouseEvent.MOUSE_OVER (cursor sobre objeto), MouseEvent.MOUSE_OUT (objeto perde foco do mouse) eMouseEvent.MOUSE_WHEEL (a roda de rolagem do mouse), entre outros.

Eventos de teclado

editar

Para reconhecer eventos de teclado, é necessário utilizar o objeto da classeKeyboardEvent. Você pode usarKeyboardEvent.KEY_DOWN (instante em que a tecla é pressionada) como KeyboardEvent.KEY_UP (tecla solta).

A função de evento tem que ter como parâmetro evt:KeyboardEvent.

// Independentemente de outros, o palco receberá o foco sobre as ações do teclado
stage.addEventListener(KeyboardEvent.KEY_DOWN, teclaPressionada);

function teclaPressionada(evt:KeyboardEvent):void 
{
    if (evt.keyCode > 0)
    {
        trace('Tecla: ', String.fromCharCode(evt.charCode), '. Em código: ', evt.charCode);
    }
}

Caso a tecla a (minúscula) seja pressionada, será exibido "Tecla: a. Em código: 97". O 97 é valor de a minúsculo na tabela w:ASCII.

Eventos de tempo (Timer)

editar

Para utilizar tempo, é preciso criar um objeto Timer com dois parâmetros: 1 O intervalo que o Timer irá cobrir (em milissegundos) e 2) Quantas vezes será repetido (se posto 0, será infinito).

Podemos criar dois eventos, um para o evento do Timer (TimerEvent.TIMER) contando tempo e um para quando o trabalho dele se completar (TimerEvent.TIMER_COMPLETE).

O parâmetro da função deve ser um evt:Event. O objeto de Timer deve ser acionado com o método start() (tempo.start()). Para parar o relógio, acione o método tempo.stop().

// Criando o objeto...
var tempo:Timer = new Timer(1000, 3);

tempo.addEventListener(TimerEvent.TIMER, movendo);
tempo.addEventListener(TimerEvent.TIMER_COMPLETE, acabou);

// Necessário para o evento começar
tempo.start();

// A cada segundo esta função será executada...
function movendo(evt:Event):void 
{
    mc.x += 10;
}

// Quando o terceiro segundo chegar, irá realizar esta tarefa...
function acabou(evt:Event):void
{
    trace("Trabalho finalizado");
}

Eventos de frame

editar

Utilizando o Event.ENTER_FRAME, você pode adicionar um evento que será realizada a cada passagem de um novo frame. A frequência da ação será repetida de acordo com o FPS (frames por segundo) do documento.

O parâmetro da função deve ser um evt:Event.

// mc é um MovieClip qualquer...
mc.addEventListener(Event.ENTER_FRAME, movendo);

public function movendo(evt:Event):void 
{
    evt.target.x += 10;    
}

O alvo da ação, mc, será movido mais 10 a cada entrada de frame.

Removendo eventos

editar

A remoção de eventos se dá pela função removeEventListener(). Remover um listener pode ser necessário quando não queremos que um objeto tenha um evento, ou então quando isso não é necessário mais o coletor de lixo os remove, a fim de melhorar o gerenciamento da mesma.

var sp:Sprite = new Sprite();

sp.addEventListener(MouseEvent.CLICK, girarDesenho);

function girarDesenho(evt:MouseEvent):void {
    evt.target.rotation += 20;
    evt.target.removeEventListener(MouseEvent.CLICK, girarDesenho);
}

Da próxima vez que sp for clicado, ele não irá mais girar 20 graus, pois a linhaevt.target.removeEventListener(MouseEvent.CLICK, girarDesenho) fez com que ele perdesse a possibilidade de receber eventos referentes ao clique do mouse.

Usando listeners fracos, fase de captura e determinando a prioridade

editar
  • Para processar um evento antes que chegue ao seu alvo é necessário determinar o parâmetrouseCapture para true (o padrão é falso), terceiro do método addEventListener().
  • Supondo que um objeto recebe mais de um evento MouseEvent.CLICK, você pode determinar qual será executado primeiro com o penúltimo parâmetro priority. Se não determinado, nenhuma ordem será considerada. O prioritário deve receber o valor 1, o segundo 2 e assim por diante.
  • Para usar referências fracas nos eventos e assim facilitar a remoção de eventos não mais utilizados basta colocar true no último parâmetro, o useWeakReference. O padrão é false, uma conexão de listener forte. Isso deixa o Flash ajudar um pouco o desenvolvedor, em caso de projetos complexos. A ideia é que, caso o listener e a sua referência não sejam mais utilizados, ele não atrapalha o trabalho do coletor de lixo do Flash, procurando trabalhar melhor com o gerenciamento de memória.

Esses parâmetros adicionais não precisam ser configurados quando evocamos umremoveEventListener();

var sp:Sprite = new Sprite();

// Quando sp for clicado, ele executará primeiro exibeMsg (prioridade 1)
sp.addEventListener(MouseEvent.CLICK, exibeMsg, true, 1, true);
sp.addEventListener(MouseEvent.CLICK, exibeOutraMsg, false, 2, true);

function exibeMsg(evt:MouseEvent):void {
    trace("Clicado primeiro");
}

function exibeOutraMsg(evt:MouseEvent):void {
    trace("Clicado segundo");
    sp.removeEventListener(MouseEvent.CLICK, exibeMsg);
}

Estes parâmetros são poucos usados, apenas em casos muito específicos.

Criando seus próprios eventos

editar

Basta chamar o nome da função de listener e o seu respectivo tipo de evento. No caso do exemplo abaixo, logo que o programa for executado ele irá exibir "OK", porque a última linha dispara artificialmente um clique.

stage.addEventListener(MouseEvent.CLICK, noClique);

function noClique(evt:Event):void {
    trace("OK");
}

// Dispara um clique mesmo sem o palco ter sido clicado
noClique(new MouseEvent(MouseEvent.CLICK));

Disparando eventos

editar

Toda vez que o palco (stage) for clicado, ele irá disparar, através da linhadispatchEvent(), um evento "meu novo evento". Esse evento foi adicionado ao palco, com o função listener dispara.

stage.addEventListener(MouseEvent.CLICK, novoEvento);

function novoEvento(evt:Event):void {
    dispatchEvent(new Event("meu novo evento"));
}

stage.addEventListener("meu novo evento", dispara,false,0,true);
function dispara(evt:Event):void {
    trace("Seu evento personalizado!");
}

Todo clique no palco irá exibir "Seu evento personalizado!".

Diferenças: target e currentTarget

editar

A diferença entre currentTarget etarget é que o primeiro lida com o abrangente e o segundo é mais específico.

var mc:MovieClip = new MovieClip();
mc.name = "Container mc";

var sp1:Sprite = new Sprite();
var sp2:Sprite = new Sprite();

sp1.name = "Azul";
sp2.name = "Verde";
sp1.graphics.beginFill(0x0000FF,1);
sp1.graphics.drawRect(10,10,100,100);
sp1.graphics.endFill();

sp2.graphics.beginFill(0x00FF00,1);
sp2.graphics.drawRect(10,120,100,100);
sp2.graphics.endFill();

mc.addEventListener(MouseEvent.CLICK, exibeInfo);

mc.addChild(sp1);
mc.addChild(sp2);

addChild(mc);

function exibeInfo(evento:MouseEvent):void {
    evento.target.startDrag();
    trace(evento.target.name);
}

Se clicar em um dos quadrados, ele irá exibir seu nome e arrastará o quadrado que for clicado. Isso se dá porque target procura dentro de mc o alvo da ação. Agora alteraremos a função exibeInfo:

function exibeInfo(evento:MouseEvent):void {
    evento.currentTarget.startDrag();
    trace(evento.currentTarget.name);
}

O método currentTarget especifica o alvo relativo ao contâiner de objetos. Se clicado, ele irá permitir o arrastamento do mc (os dois quadrados juntos) e exibe o nome dele (no caso, "Container mc").