Archive for the ‘AS 3.0’ Category

De Monster Debugger – como utilizar

0saves

Faz tempo que eu não posto nada, devido a falta de tempo , e de ideias sobre o que postar.
Hoje, resolvi postar sobre como utilizar o MonsterDebugger, o melhor debugger que eu ja vi para actionscript.

Primeiro, o que é esse MonsterDebugger ?
O MonsterDebugger ( http://demonsterdebugger.com/ ) é um debugger Open Source feito em AIR, que permite debugar aplicaçoes Actionscript (flash, flex, air …), não só dando trace, mas podendo editar as propriedades dos objetos em tempo real, e podendo executar os metodos dos objetos quando quiser. Alem de claro, dar trace nas coisas (se for algum array, xml, objeto … ele apresenta o conteudo em arvore, assim fica mais facil de debuggar).

Agora sim, vou mostrar como se usa ele.

1 – Instale o client:
Va em http://demonsterdebugger.com/ , pegue a versão mais recente do MonsterDebugger e instale ele no seu computador.

2 – Gere as classes necessarias:
Abra o client (instalado anteriormente) e va em File -> Export Client Class
Exportar Classe Cliente - MonsterDebugger

3 – Se quiser pode gerar um exemplo (File -> Export example), ou pode tentar usar direto sem o exemplo.

Como dar um simples Trace:

1
MonsterDebugger.trace(this, o_que_é_para_ir_no_trace)

Como ativar o live application:

1
2
var _debugger:MonsterDebugger;
_debugger = new MonsterDebugger(this);

A parte de utilizar o Client é bem intuitiva, caso alguem tenha duvidas de como utilizar, favor me avisar que eu coloco aqui detalhadamente como utilizar.

Lembrando que aceito sugestoes de posts, é só entrar em contato.

Conexão AS3 com python via socket (simplificado)

0saves

Algumas vezes me perguntei como fazer algumas coisas mais complexas em AIR de uma maneira rapida e segura, como por exemplo pegar informaçoes do usuario, conectar com um banco de dados (sem ser o nativo do AIR) como oracle,mssql… executar linha de comando, e outras coisas que só seriam possiveis utilizando alguma outra linguagem mais poderosa. Levando em conta que isto realmente era necessario para aumentar o “poder” do AIR e que o AMF fazia algo parecido, só que para a internet, resolvi criar uma classe em AS e uma função em Python que facilita a comunicação entre os dois (deixe o servidor python rodando de fundo e chame as funçoes dele :D )

Primeiro a classe Python.as que pode ser baixada aqui :

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
package
{
    import com.adobe.serialization.json.JSON;
    import flash.net.Socket;
   /**
     * Classe para conexao com python utilizando socket
     * @author    Armando Leopoldo Keller - (http://alkeller.wordpress.com) - alkeller@live.de
     */
    public class Python extends Socket
    {
        // TODO: Implementar um metodo de retorno, verificando o tipo do retorno, e passando como parametro na funcao associada
        /**
         * Cria um novo Socket
         * @param host    Host onde esta o socket
         * @param port    Porta que esta o socket
         * @see flash.net.Socket
         * @usage    var p:Python = new Python("10.1.1.23",2727);
         */
        public function Python(host:String=null, port:uint=0)        {
            super(host, port);
            host = null;
            port = 0;
        }
        /**
         * Chama uma funcao do python se o socket estiver conectado 
         * @param func    Nome da funcao a ser chamada no python
         * @param args    Argumentos a serem chamados no python
         * @usage p.call("teste",{um:1,dois:2,tres:3});
         * @usage p.call("teste");
         */
        public function call(func:String,args:Object=null):void
        {
            if(this.connected)
            {
                this.flush();
                var obj:Object = new Object();
                obj["funcao"] = func;
                for(var i:* in args)
                {
                    if(args[i] is String) args[i] = "'"+args[i]+"'";
                    obj[i]=args[i];
                }
                this.writeUTFBytes(JSON.encode(obj));
                obj = null;
            }
            else
                throw new Error("Voce deve estar conectado ao socket.")
            this.flush();
        }
    }
}

Depois é necessario a função em python que vai reconhecer o que está sendo chamado pelo flash, o arquivo pode ser baixado aqui :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import json;
def executar(objeto):
    __arr__ = [];
    __str__ = "";
    obj = json.loads(objeto);
    __str__ = str(obj["funcao"])+"(";
    obj.pop("funcao");
    if len(obj.keys()) >;= 1:
        for k in obj:
            __arr__.append(str(k)+"="+str(obj[k]));
        for x in xrange(len(__arr__)-1):
            __str__ = __str__+__arr__[x]+",";
        __str__ = __str__ +__arr__[len(__arr__)-1]+")";
    else:
        __str__ = __str__+")";
    return __str__;

Agora precisamos de um “servidor socket” rodando de fundo com as funçoes a serem chamadas, que pode ser baixado aqui :

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
import socket
import threading
import json
from JMF import executar
class ClientThread ( threading.Thread ):
    def __init__ ( self, channel, details ):
        self.channel = channel
        self.details = details
        threading.Thread.__init__ ( self );
    def run ( self ):
        print 'Conexao recebida: ', self.details [ 0 ]
        self.channel.send ( "resposta vinda do python" )
        for x in xrange ( 10 ):
            string = self.channel.recv ( 1024 )
            self.interpretaComando(string)
        self.channel.close();
        print 'Conexao fechada: ', self.details [ 0 ]
    def interpretaComando(self,string):
        eval("self."+executar(str(string)));
    def testar(self,arg1,arg2):
        print "Chamou testar: "+str(arg1)+","+str(arg2);
        self.channel.send("Chamou testar: "+str(arg1)+","+str(arg2));
    def pegaVariaveis(self):
        print "chamou pegaVariaveis"
        self.channel.send("chamou pegaVariaveis");
    def pegarArray(self):
        print "Chamou pegar Array";
        arr = ['a','b','c',1,2,3];
        txt = json.dumps(arr);
        self.channel.send(txt);
    def pegarObj(self):
        print "Chamou pegar Objeto";
        teste = {}
        teste["item1"]   =   "Primeiro item";
        teste["item2"]   =   "Segundo item";
        teste["numero"]  =   2;
        self.channel.send(json.dumps(teste));
# Inicia o servidor
server = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
server.bind ( ( socket.gethostbyname(socket.gethostname()), 2727 ) )
server.listen ( 5 )
print "Iniciando servidor..."
while True:
    channel, details = server.accept()
    ClientThread ( channel, details).start()

Pronto, agora só falta uma aplicação de exemplo chamando estas funçoes, que pode ser baixada aqui :

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
76
<?xml version="1.0" encoding="utf-8"?>;
<mx:WindowedApplication applicationComplete="iniciar()" xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Script>
        <![CDATA[
            import com.adobe.serialization.json.JSON;
            private var py:Python
            [Bindable]
            public var texto:String = ""
            public function iniciar():void
            {
                py = new Python();
                py.addEventListener(ProgressEvent.SOCKET_DATA,onRecebe);
                py.addEventListener(Event.CONNECT,onConecta);
                py.addEventListener(IOErrorEvent.IO_ERROR,onErroIO);
                py.connect("10.1.1.3",2727);
            }
            public function onRecebe(e:ProgressEvent):void
            {
                var str:String = py.readUTFBytes(py.bytesAvailable);
                texto = str;
                py.flush();
            }
            public function onConecta(e:Event):void
            {
                trace("Conectou")
            }
            private function chamarTeste():void
            {
                if(py.connected)
                    py.call("testar",{arg1:"Argumento 1",arg2:"Argumento 2"})
                else
                    texto = "O socket esta desconectado";
            }
            private function chamarPegaVariaveis():void
            {
                if(py.connected)
                    py.call("pegaVariaveis")
                else
                    texto = "O socket esta desconectado"
            }
            private function pegarArray():void
            {
                if(py.connected)
                    py.call("pegarArray");
                else
                    texto = "O socket esta desconectado";
            }
            private function pegarObj():void
            {
                if(py.connected)
                    py.call("pegarObj");
                else
                    texto = "O socket esta desconectado";
            }
            private function matarServer():void
            {
                py.close();
                texto = "Desconectado"
            }
            public function onErroIO(e:IOErrorEvent):void
            {
                trace("Erro ao conectar com o socket");
            }
        ]]>
    </mx:Script>
    <mx:VBox>
        <mx:HBox>
            <mx:Button label = "Testar"         click = "chamarTeste()"         />
            <mx:Button label = "PegaVar"        click = "chamarPegaVariaveis()" />
            <mx:Button label = "pegarArray"     click = "pegarArray()"          />
            <mx:Button label = "pegarObj"       click = "pegarObj()"            />
            <mx:Button label = "Kill Server"    click = "matarServer()"         />
        </mx:HBox>
        <mx:Text text="{texto}" width="100%" height="115"/>
    </mx:VBox>
</mx:WindowedApplication>

Claro que esta aplicação ainda está bastante simples, mas o objetivo é demonstrar como pode ser facil conectar o AS3 com Python utilizando socket, para quem não conhece python, vale a pena dar uma estudada, é uma linguagem muito util, poderosa, e simples, que é utilizada em diversos lugares, alguns exemplos bons são nasa e google (precisa mais ? ), agora mistura isso com AS3 (tem algo MUITO funcional e bonito).

Explicação rapida

A sintaxe é muito parecida com a Tweener (classe de tween) que ja é bastante conhecida, então creio que não deve ter muita dificuldade para utilizar esta classe. Sendo que para chamar uma função do python é só chamar instancia.call(“nome_da_funcao”,{nome_do_argumento:valor_do_argumento…….});

Se alguem tiver alguma duvida, ou sugestão para esta classe ou para futuras classes, deixe um comentario ou envie por email mesmo.

A formatação dos codigos ainda não está boa, mas esta melhorando (plugin do Windows Live Writer) se alguem conhecer algum plugin para formatar codigos que tenha suporte a AS, Python, PHP,e C me avisa.

JSFL para ajustar posiçoes dos itens como campos de texto com pixelFonts(pixel Snapping)

0saves

Olá, primeiramente quero dizer que não tenho postado muita coisa no blog devido a falta de tempo, e tambem de conteudo(até se alguem tiver alguma sugestão manda por email ou coloca aqui como comentario que eu farei o possivel para falar sobre o assunto).

Hoje a tarde depois de arrumar as posiçoes dezenas de movieClips para que não distorcessem eu pensei “por que eu estou fazendo isso? o flash poderia fazer sozinho”, então criei este JSFL que faz exatamente isto (link)

OBS: se o link não funcionar copie ele e cole no navegador;

Como utilizar: é só executar.

ele pega todos os itens(movieClip,Button,Graphic,TextField..) da timeline atual e ajusta as posiçoes dos mesmos.

para aplicar isto dentro de um movieClip , abra-o e execute o comando dentro do movie;

pra quem não conseguiu abrir o link aqui vai o codigo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// Pixel Snapping [alk].jsfl
 
/*
Script criado por Armando Leopoldo Keller(http://alkeller.wordpress.com)
para instalar: só colar este arquivo em C:\Users\nome_do_usuario\AppData\Local\Adobe\Flash CS3\en\Configuration\Commands
obs: este é o caminho no windows vista
*/
for( var i = 0; i < fl.getDocumentDOM().getTimeline().layers.length; i++)
{
var layerAtual = fl.getDocumentDOM().getTimeline().layers[i];
for(var j = 0 ; j < layerAtual.frames.length ; j++)
{
var frameAtual = layerAtual.frames[j];
for(var k = 0 ; k < frameAtual.elements.length ; k++)
{
var elementoAtual = frameAtual.elements[k];
elementoAtual.x = parseInt(elementoAtual.x);
elementoAtual.y = parseInt(elementoAtual.y);
}
}
}

Qualquer coisa é só comentar, ou mandar email que eu respondo.

Classe para utilização de SQL em AIR (Flash, Flex)

0saves

Neste tutorial mostrarei como utilizar uma classe que eu criei para facilitar o uso de SQL em AIR (tanto para flash quanto para flex)
A classe é esta:

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
76
77
78
79
80
81
82
83
84
/*
################################################
#                                              #
#   Classe  : DB (com.alkeller.air.DB)         #
#   Autor   : Armando Leopoldo Keller          #
#   Versão  : 1.0                              #
#   Contato : alksk8@hotmail.com               #
#   Blog    : http://alkeller.wordpress.com    #
#   Documentaçao em breve no blog              #
#                                              #
################################################
------- Deixe os creditos na classe ----------
*/
package com.alkeller.air
{
	// Imports
	import flash.data.SQLResult;
	import flash.filesystem.File;
	import flash.data.SQLStatement;
	import flash.data.SQLConnection;
	import flash.events.SQLEvent;
	import flash.events.SQLErrorEvent;
	import flash.errors.SQLError;
 
	// Classe;
	public class DB
	{
		// Variaveis utilizadas;
		private static var conectado:Boolean = false;
		private static var dbFile:File
		private static var conn:SQLConnection
		private static var _sqlStatement:SQLStatement;
		private static var resultado:SQLResult;
		private static var retornoString:String;
		private static var retornoObjeto:Object;
 
		// Funçao Inicia :utilizada para conectar com o banco de dados;
		public static function Inicia(_nome:String):String
		{
			conn = new SQLConnection();
			dbFile = File.applicationStorageDirectory.resolvePath(String(_nome+".db"));
			try
			{
				conn.open(dbFile);
				conectado = true;
				trace("Conectado com "+_nome+".db");
				retornoString = "Conectado com "+_nome+".db";
			}
			catch (error:SQLError) 
			{
				conectado = false;
				retornoString = "Falha ao conectar: "+error.message+"\nDetalhes: "+error.details;
			}
			return retornoString;
		}
		// Funçao executeQuery: Utilizada para executar um comando SQL(verificar quais são aceitos pelo AIR);
		// Retorno: SQLResult --> http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/data/SQLResult.html
		// ou  String de erro;
		public static function executeQuery(_sql:String):Object
		{
			if(conectado == true)
			{
				_sqlStatement = new SQLStatement();
				_sqlStatement.sqlConnection = conn;
				_sqlStatement.text = _sql;
				try
				{
					_sqlStatement.execute();
					resultado = _sqlStatement.getResult();
					retornoObjeto = resultado;
				}
				catch (error:SQLError)
				{
					retornoString = "Falha ao executar("+_sql+"): "+error.message+"\nDetalhes: "+error.details;
				}
				return retornoObjeto?retornoObjeto:retornoString;
			}
			else
			{
				return "Não conectado!";
			}
		}
	}
}

Classe para download: http://paginas.terra.com.br/lazer/alksk8/DB.as

Como utilizar:
1 – Importe a classe:

1
2
3
4
// OBS: Aqui é bom verificar se a classe esta no local certo com/alkeller/air/
import com.alkeller.air.*;
// ou
import com.alkeller.air.DB;

2 – Inicie o banco:

1
DB.Inicia("teste"); // sendo que teste é o nome do banco

3 – Se as tabelas não existirem, crie elas:

1
DB.executeQuery("CREATE TABLE IF NOT EXISTS testando (id INTEGER PRIMARY KEY AUTOINCREMENT,nome TEXT,sobrenome TEXT)");

4.1 – Execute as Querys que desejar, por exemplo inserir alguns dados:

1
DB.executeQuery("INSERT INTO testando (id,nome,sobrenome) VALUES (null,'ARMANDO LEOPOLDO','KELLER')");

4.2 – Exemplo de como buscar dados:

1
2
3
4
5
6
7
8
9
var obj:Object = DB.executeQuery("SELECT * FROM testando").data;
for(var i:uint=0; i < obj.length; i++)
{
	trace("linha: "+i);
	for(var j:Object in obj[i])
	{
		trace(j+": "+obj[i][j])
	}
}

Aproveitem a classe :D

Em breve colocarei aqui este tutorial em video.

NativeMenu em AIR (flash)

0saves

Olá, segue abaixo um exemplo comentado de como utilizar menus(como os da maioria dos softwares) em AIR, é um exemplo básico baseado em tutoriais da Adobe.

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
/*
Primeiro crie um arquivo novo(air)
crie um campo de texto com o tamanho que desejar
instancie o campo de texto como "texto" (sem as aspas)
cole o codigo a seguir no primeiro frame
*/
 
// importa	as classes necessarias
import flash.display.NativeMenu;
import flash.display.NativeMenuItem;
import flash.display.NativeWindow;
import flash.desktop.NativeApplication;
 
//declara os 2 items do menu
var Menu01:NativeMenuItem;
var Menu02:NativeMenuItem;
 
if (NativeWindow.supportsMenu)// Se o sistema operacional for windows
{
	stage.nativeWindow.menu = new NativeMenu(); //cria o menu
	stage.nativeWindow.menu.addEventListener(Event.SELECT, selecionouUmItem);//adiciona um evento de seleção no menu
	Menu01 = stage.nativeWindow.menu.addItem(new NativeMenuItem("Primeiro item"));//adiciona o primeiro item no menu
	Menu01.submenu = criaSubMenu(); // adiciona o submenu(que vai ser criado logo abaixo) ao primeiro item
	Menu02 = stage.nativeWindow.menu.addItem(new NativeMenuItem("Segundo item"));//adiciona o segundo item no menu
}
 
if (NativeApplication.supportsMenu)// se o sistema operacionall for mac
{
	Menu01 = NativeApplication.nativeApplication.menu.addItem(new NativeMenuItem("Primeiro item"));//adiciona o primeiro item no menu
	NativeApplication.nativeApplication.menu.addEventListener(Event.SELECT, selecionouUmItem);//adiciona um evento de seleção no menu
	Menu01.submenu = criaSubMenu(); // adiciona o submenu(que vai ser criado logo abaixo) ao primeiro item
	Menu02 = NativeApplication.nativeApplication.menu.addItem(new NativeMenuItem("Segundo item"));//adiciona o segundo item no menu
}
 
function criaSubMenu():NativeMenu
{
	var tmpMenu:NativeMenu = new NativeMenu(); // cria o submenu do primeiro item
	var MenuNovo:NativeMenuItem = tmpMenu.addItem(new NativeMenuItem("Novo"));//adiciona o item "Novo" ao submenu
	var MenuSalva:NativeMenuItem = tmpMenu.addItem(new NativeMenuItem("Salva"));//adiciona o item "Salva" ao submenu
	var MenuSair:NativeMenuItem = tmpMenu.addItem(new NativeMenuItem("Sair"));//adiciona o item "Sair" ao submenu
	return tmpMenu;
}
 
function selecionouUmItem(e:Event)
{
	texto.text = e.target.label // escreve o nome do item selecionado no campo de texto
}

Qualquer duvida é só postar que eu respondo.

Assim que sobrar algum tempo por aqui eu postarei um tutorial (bem detalhado) e com os exemplos, de como utilizar um banco de dados local com o AIR.

Adobe AIR é lançado

0saves

Olá, fiquei um tempo sem postar devido a falta de tempo , mas estou devolta, para quem ainda não sabe o Adobe AIR não é mais beta, ele ja foi lançado.

player : http://get.adobe.com/air/

Como instalar e começar com AIR + Flash : http://www.adobe.com/devnet/air/flash/getting_started.html

Se alguém tiver duvidas de como instalar ou algo do genero, fala ai que eu vou procurar sanar as duvidas.

Classe de validação de formularios

0saves

Oi, eu fiquei um tempo sem postar devido a falta de tempo ( muito trabalho) .

Mas ai vai uma classe que poupa muito tempo na validação de formularios

// Teste.as

package alkeller
{
public class Teste
{
private var campos:Array
 
public function Teste()
{
this.campos = new Array();
}
public function adiciona(Campo, Nome)
{
this.campos.push( { campo:Campo, nome:Nome } );
}
public function Verifica()
{
for (var i:int = 0 ; i &lt; this.campos.length; i++)
{
if (
(this.campos[i].campo.text == undefined) ||
(this.campos[i].campo.text == "undefined") ||
(this.campos[i].campo.text == "") ||
(this.campos[i].campo.text == null) ||
(this.campos[i].campo.text == " ")
)
{
return "Preencha o campo " + this.campos[i].nome;
}
}
return true;
}
}
}

E para utilizar é simples:
1º – Crie um movieClip e instancie ele como “bt”(sem as aspas).
2º – Crie 5 campos de texto tipo input e instancie eles como(“cp1″,”cp2″ ……) obs: isso é só um exemplo, pode ser quantos campos você quiser e com o nome que você quiser.
3º – Crie um campo de texto dinamico e instancie ele de resultado
4º – Cole o codigo abaixo no frame
5º – Teste
// Teste.fla 1º frame

 import alkeller.Teste
var ve:Teste = new Teste();
ve.adiciona(cp1,"Campo 1");
ve.adiciona(cp2,"Campo 2");
ve.adiciona(cp3,"Campo 3");
ve.adiciona(cp4,"Campo 4");
ve.adiciona(cp5,"Campo 5");
 
bt.addEventListener(MouseEvent.CLICK,clicou);
function clicou(e:MouseEvent):void
{
if(ve.Verifica() != true)
{
resultado.text = ve.Verifica();
}
else
{
resultado.text = "Tudo preenchido"
}
}

Qualquer duvida é só falar.

Eventos em objetos com Papervision 2.0 (Great White)

0saves

Bom, aqui vai um exemplo simples de como pegar eventos em objetos 3D (papervision), por exemplo clicar num cubo…

1º crie um AS chamado testando_papervision.as, e cole o seguinte codigo:

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
package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.materials.BitmapFileMaterial;
	import org.papervision3d.objects.Cube;
	import org.papervision3d.scenes.MovieScene3D;
 
	public class testando_papervision extends Sprite
	{
		public function testando_papervision()
		{
 
			var rodando = false;
			var cont:Sprite = new Sprite();
			cont.x = stage.stageWidth * 0.5;
			cont.y = stage.stageHeight * 0.5;
			addChild(cont);
 
			var cena:MovieScene3D = new MovieScene3D(cont);
 
			var cam:Camera3D = new Camera3D();
			cam.z = -500;
			cam.zoom = 5;
 
			var mat:BitmapFileMaterial = new BitmapFileMaterial("porquinho1.jpg");
			mat.doubleSided = true;
			mat.smooth = true;
			var cubo:Cube = new Cube(mat,128,128,128);
			cena.addChild(cubo);
			cubo.container.addEventListener(MouseEvent.CLICK,roda);
 
			function roda(e:MouseEvent):void
			{
				if(rodando == false)
				{
					rodando = true
				}
				else
				{
					rodando = false
				}
			}
 
			this.addEventListener(Event.ENTER_FRAME,renderiza)
 
			function renderiza(e:Event):void
			{
				if(rodando == true)
				{
					cubo.rotationY +=5
				}
				cena.renderCamera(cam);
			}
		}
	}
}

Depois crie um Fla vazio e em propriedades , Document Class, escreva: testando_papervision

coloque uma imagem com o nome de porquinho1.jpg com 128px por 128px na mesma pasta

salve tudo e compile o flash.

Quando você clicar no cubo, se ele estiver parado ele vai começar a rodar, e se ele estiver rodando vai parar.

Até a próxima, qualquer duvida comentem.

Como controlar as janelas do AIR

0saves

Controlar as janelas transparentes do AIR é mais fácil do que parece, aqui vão alguns exemplos de como fazer isso:

Fechar

//tendo um movieClip com instanciado de bt_fechar
bt_fechar.addEventListener(MouseEvent.CLICK,sair);
function sair(e:MouseEvent):void{

    stage.nativeWindow.close();

}

Minimizar

//tendo um movieClip com instanciado de bt_minimizar
bt_minimizar.addEventListener(MouseEvent.CLICK,minimizar);
function minimizar(e:MouseEvent):void{

    stage.nativeWindow.minimize();

}

Maximizar

//tendo um movieClip com instanciado de bt_maximizar
bt_maximizar.addEventListener(MouseEvent.CLICK,maximizar);
function minimizar(e:MouseEvent):void{

    stage.nativeWindow.maximize();

}

Restaurar

//tendo um movieClip com instanciado de bt_restaurar
bt_restaurar.addEventListener(MouseEvent.CLICK,restaurar);
function restaurar(e:MouseEvent):void{

    stage.nativeWindow.restore();

}

Mover

//Crie um movieClip com a area para ser usada para arrasta, instancie ele como bt_arrastar
bt_arrastar.addEventListener(MouseEvent.MOUSE_DOWN,arrastar);
function arrastar(e:MouseEvent):void{

    stage.nativeWindow.startMove();

}

Dimensionar

//Crie um movieClip com a area para ser usada para dimensionar, instancie ele como bt_dimensionar
bt_dimensionar.addEventListener(MouseEvent.MOUSE_DOWN,dimensionar);
function dimensionar(e:MouseEvent):void{

    stage.nativeWindow.startResize(NativeWindowResize.BOTTOM_RIGHT);

}

A formatação do código não está das melhores( tudo feito a mão :-P ), com o tempo quero ver se consigo colocar o plugin de formatação de código aqui, ou encontrar algum que formate sozinho e gere o html com as cores e espaços tudo certos, caso alguém tenha uma sugestão ou duvida, comenta ai.