Hoje estão surgindo muitas interfaces utilizando dispositivos de manipulação diferentes de teclado e mouse. É possível e muito fácil utilizar o flash para acionar eventos utilizando uma webcam comum ou microfone. Explorei esta técnica em meu TCC e vou disponibilizar aqui umas instruções básicas desta captura de movimento para identificação do nível de intensidade da movimentação e posicionamento.
Conceito
Não é preciso ter uma webcam caríssima ou ser um ninja em AS para desenvolver um aplicativo simples. Imagine o que é possível fazer no flash com o evento do clique do mouse e entenda que a identificação de movimento em um determinado ponto da interface pode executar a mesma ação. O que temos que fazer é identificar este movimento. No caso de controle de interface utilzando o microfone também, basta identificar o nível de atividade do microfone e definir um evento condicionado a um nível de atividade.
O conceito básico é mapear em um segundo cada informação de pixel da tela e no próximo segundo mapear novamente e comparar com o anterior. Se no novo mapa de pixels algum deles estiver com uma cor diferente do anterior, identificamos um movimento naquele ponto.
É possível também definir uma tolerância de forma bem simples. Posso especificar à minha função que apenas deve-se entender a alteração como um movimento caso seja identificada a mudança de cor na matriz de pixels determinado número de vezes, por exemplo, se compar três vezes e sempre existir diferença, é um movimento. Caso contrário, nada a fazer.

Capturando a câmera
- Insira no palco um objeto de vídeo e instancie-o como quiser. No exemplo instanciei como “meu_video”.
- declare o objeto criado e uma variável para a câmera como no código abaixo.
- Vincule a câmera ao objeto usando o attachVideo.
1 2 3 | var meu_video:Video; var cam:Camera = Camera.get(); meu_video.attachVideo(cam); |
Teste e será possível visualizar a imagem da câmera no objeto.
Identificando a intensidade de movimento
Para o objeto câmera existe um evento nativo do flash chamada onActivity que serve justamente para a detecção de atividade (movimento) do objeto. Vou utilizar também o activityLevel, propriedade que retorna um valor numérico para a intensidade de movimentação identificada no objeto.
Crie uma caixa de texto e no atributo “var” insira um nome de variável. No exemplo inseri “nivelAtividade”:
1 2 3 4 5 6 7 8 | var meu_video:Video; var cam:Camera = Camera.get(); meu_video.attachVideo(cam); cam.onActivity = function(isActive:Boolean) { trace("algo se mexeu"); _root.nivelAtividade = cam.activityLevel; }; |
Teste e será possível visualizar o nível de intensidade do movimento inserido na caixa de texto. Podemos acionar um evento qualquer condicionado a estes valores dizendo, por exemplo, que caso a intensidade seja maior do que 50, deve-se avançar um frame ou acionar um evento qualquer. No caso do meu TCC na última fase era necessário que o usuário se movimentasse com nível 100 e utilizasse o mesmo nível de atividade no microfone, gritando, para avançar aos créditos finais.
Identificando o evento de movimentação
Então vamos ao que interessa… crie um movie clip, duplique-o em três e instancie-os como bolinha1, bolinha2 e bolinha3 respectivamente e faça uma animação qualquer dentro dos MC, com um stop(); no primeiro frame.
O que faremos então:
- Identificaremos as propriedades de todos os objetos e as guardaremos em variáveis;
- Encontraremos a proporção da imagem capturada VS recipiente de exibição;
- Executaremos o tempo todo uma função para compararmos um mapa inicial com um final;
- Criaremos condições para os eventos de comparação positivos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | var meu_video:Video; //declara o objeto video var cam:Camera = Camera.get(); //declara o obj camera meu_video.attachVideo(cam); //atribui a imagem da camera ao objeto cam.onActivity = function(isActive:Boolean) { //quando houver atividade, executar... trace("algo se mexeu"); //output _root.nivelAtividade = cam.activityLevel; //atualizar texto }; import flash.display.BitmapData; //importar a classe BitmapData var videoX:Number = meu_video._x; //identificacao das coordenadas var videoY:Number = meu_video._y; var videoW:Number = meu_video._width; var videoH:Number = meu_video._height; var proporcao:Number = videoW/cam.width; //encontra a proporcao var now = new BitmapData(cam.width, cam.height); //declara o mapa inicial var before = new BitmapData(cam.width, cam.height); //declara o mapa de comparacao function hitDetect() { //identifica as propriedades iniciais var bolinhaX:Number = (bolinha1._x-videoX)/proporcao var bolinhaY:Number = (bolinha1._y-videoY)/proporcao var bolinha2X:Number = (bolinha2._x-videoX)/proporcao var bolinha2Y:Number = (bolinha2._y-videoY)/proporcao var bolinha3X:Number = (bolinha3._x-videoX)/proporcao var bolinha3Y:Number = (bolinha3._y-videoY)/proporcao now.draw(meu_video) //renderiza o "agora" //inicial var valNowBall1:Number=(now.getPixel(bolinhaX, bolinhaY) >> 16 & 0xFF); //comparacao var valBeforeBall1:Number=(before.getPixel(bolinhaX, bolinhaY) >> 16 & 0xFF); //inicial var valNowBall2:Number=(now.getPixel(bolinha2X, bolinha2Y) >> 16 & 0xFF); //comparacao var valBeforeBall2:Number=(before.getPixel(bolinha2X, bolinha2Y) >> 16 & 0xFF); //inicial var valNowBall3:Number=(now.getPixel(bolinha3X, bolinha3Y) >> 16 & 0xFF); //comparacao var valBeforeBall3:Number=(before.getPixel(bolinha3X, bolinha3Y) >> 16 & 0xFF); //condicoes para eventos //o valor "30" é a intensidade que eu defini. //quanto menor este valor, maior a sensibilidade if (valNowBall1>valBeforeBall1+30 || valNowBall1<valBeforeBall1-30) { if (bolinha1._currentframe == 1) trace("bola 1"); bolinha1.gotoAndPlay(2) } if (valNowBall2>valBeforeBall2+30 || valNowBall2<valBeforeBall2-30) { if (bolinha2._currentframe == 1) trace("bola 2"); bolinha2.gotoAndPlay(2) } if (valNowBall3>valBeforeBall3+30 || valNowBall3<valBeforeBall3-30) { if (bolinha3._currentframe == 1) trace("bola 3"); bolinha3.gotoAndPlay(2) } before.draw(meu_video) //compara a renderizacao anterior } //intervalo de repeticao da funcao var intervalID:Number = setInterval(hitDetect, 20); |
Veja o resultado:
Vou mandar o link pra galera da facu, acho que alguns grupos pretendem usar isso no inter
conheço esses flas rsrs… bem legal heim boss
Muito legal essa matéria… esta me ajudando bastante… Obrigadão!!!!
Po bem legal o arquivo
É possível fazer efeito semelhante com um vídeo no lugar da webcam?
Sim, a detecção é baseada alteração da matriz de cores.
É possível aumentar a área do componente webcam sem distorcer a imagem?
Eu não to achando como aqui:(
Hmm sim, pelo que me lembro nem distorce. É só aumentar o componente pelo flash mesmo.
muito boa sua explicação. parabéns!
MUITO MASSA
Olá Junior…
Gostei bastante da interação pela webcam, mas a imagem está invertida !!! Minha mão esquerda aciona o botão da direita e vice-versa.
Você sabe como corrigir esse problema ?
Abraço !!!
Olá, Richard.
Esta configuração é no próprio aplicativo da WebCam. Dá para inverter no flash o MC horizontalmente multiplicando por -1 por exemplo mas o problema aconteceria nas máquinas de quem já ajustou isso na configuração da CAM.
Sugiro ajustar no aplicativo da webcam.
Vi seu e-mail só um dia desses, respondo ainda nesta semana rs.
Abs
Obrigado por seu código, como é que faço para as 3 bolas começarem paradas porque ele no trace detecta logo as 3 bolas e apenas depois fica parado.
Obrigado