ActionScript/Eventos
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 | editar código-fonte]Eventos de mouse
[editar | editar código-fonte]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çãogirarDesenho
como 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 | editar código-fonte]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 | editar código-fonte]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 | editar código-fonte]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 | editar código-fonte]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 | editar código-fonte]- Para processar um evento antes que chegue ao seu alvo é necessário determinar o parâmetro
useCapture
paratrue
(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âmetropriority
. 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 | editar código-fonte]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 | editar código-fonte]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 | editar código-fonte]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").