segunda-feira, 3 de agosto de 2009

Seguindo o Mouse com Trigonometria

Olá, esse poste de hoje foi baseado na dúvida do leitor Jefferson A. Pereira. Espero que gostem...

Se não leu meu post sobre Trigonometria em Actionscript, leia-o antes clicando aqui.

Vou ensinar hoje como usar a trigonometria em actionscript para fazer o olhos seguirem o ponteiro do mouse. Assim...


No método construtor, vamos adicionar o listener MouseEvent.MOUSE_MOVE no STAGE:

public function Main() 
{
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveHandler);
}

No método listener, vamos limpar os riscos antigos dos triângulos que usamos para testar e executar a função que rotaciona o olho. Também forço o updateAfterEvent para que fique mais suave.

private function onMouseMoveHandler($event:MouseEvent):void 
{
graphics.clear();

rotateEye(eye1);
rotateEye(eye2);

$event.updateAfterEvent();
}

No método rotateEye é onde faço os cálculos para que o olho seja rotacionado de forma que "siga" o mouse do usuário. Primeiro eu encontro os catetos adjacente e oposto para que possa encontrar a hipotenusa:

var catAdj:Number = mouseX - $eye.x;
var catOp:Number = mouseY - $eye.y;
var hipot:Number = Math.sqrt((catAdj * catAdj) + (catOp * catOp));

Com isso posso calcular o ângulo de abertura do triângulo em radianos:

var radians:Number = Math.asin(catOp / hipot);

E transformar em graus:

var degree:Number = radians * (180 / Math.PI);

Ok, até essa parte tudo bem. Mas como o actionscript trabalha com graus de forma diferente, temos que verificar se o mouse está a direita ou esquerda do nosso olho. Fazemos isso comparando se o cateto adjacente está positivo ou negativo:

if (catAdj >= 0)
{
$eye.rotation = degree;
}
else
{
$eye.rotation = 180 - degree;
}

Se for negativo, subtraimos o valor de 180º. Por exemplo: 180º - (-90º) = 180º + 90º = 270º. Ou seja, está apontando na direção norte.

E depois adicionamos as linhas de teste e o log:

log.text = 'catAdj: ' + catAdj;
log.appendText('\ncatOp: ' + catOp);
log.appendText('\nhipot: ' + hipot);
log.appendText('\nradians: ' + radians);
log.appendText('\ndegree: ' + degree);

graphics.lineStyle(1, 0xff0000);
graphics.moveTo($eye.x, $eye.y);
graphics.lineTo(mouseX, mouseY);
graphics.lineStyle(1, 0xcccccc);
graphics.lineTo(mouseX, $eye.y);
graphics.lineTo($eye.x, $eye.y);

O método rotateEye ficou assim:

private function rotateEye($eye:MovieClip):void
{
var catAdj:Number = mouseX - $eye.x;
var catOp:Number = mouseY - $eye.y;
var hipot:Number = Math.sqrt((catAdj * catAdj) + (catOp * catOp));

var radians:Number = Math.asin(catOp / hipot);
var degree:Number = radians * (180 / Math.PI);

if (catAdj >= 0)
{
$eye.rotation = degree;
}
else
{
$eye.rotation = 180 - degree;
}

log.text = 'catAdj: ' + catAdj;
log.appendText('\ncatOp: ' + catOp);
log.appendText('\nhipot: ' + hipot);
log.appendText('\nradians: ' + radians);
log.appendText('\ndegree: ' + degree);

graphics.lineStyle(1, 0xff0000);
graphics.moveTo($eye.x, $eye.y);
graphics.lineTo(mouseX, mouseY);
graphics.lineStyle(1, 0xcccccc);
graphics.lineTo(mouseX, $eye.y);
graphics.lineTo($eye.x, $eye.y);
}

Pronto!!!

Abaixo a classe Main inteira:

package  
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.text.TextField;

/**
* ...
* @author www.idemax.net
*/
public class Main extends MovieClip
{
public var eye1:MovieClip;
public var eye2:MovieClip;
public var log:TextField;

public function Main()
{
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveHandler);
}

private function onMouseMoveHandler($event:MouseEvent):void
{
graphics.clear();

rotateEye(eye1);
rotateEye(eye2);

$event.updateAfterEvent();
}

private function rotateEye($eye:MovieClip):void
{
var catAdj:Number = mouseX - $eye.x;
var catOp:Number = mouseY - $eye.y;
var hipot:Number = Math.sqrt((catAdj * catAdj) + (catOp * catOp));

var radians:Number = Math.asin(catOp / hipot);
var degree:Number = radians * (180 / Math.PI);

if (catAdj >= 0)
{
$eye.rotation = degree;
}
else
{
$eye.rotation = 180 - degree;
}

log.text = 'catAdj: ' + catAdj;
log.appendText('\ncatOp: ' + catOp);
log.appendText('\nhipot: ' + hipot);
log.appendText('\nradians: ' + radians);
log.appendText('\ndegree: ' + degree);

graphics.lineStyle(1, 0xff0000);
graphics.moveTo($eye.x, $eye.y);
graphics.lineTo(mouseX, mouseY);
graphics.lineStyle(1, 0xcccccc);
graphics.lineTo(mouseX, $eye.y);
graphics.lineTo($eye.x, $eye.y);
}

}

}

Clique abaixo para fazer o download dos arquivos:

Nenhum comentário:

Postar um comentário