Archive for the ‘Programação’ Category

PAPERVISION Menu Over

agosto 31, 2009

ppvmenu

clique na imagem para poder visualizar

Olá Pessoal, Para nosso tutorial de hoje, preparei exemplo muito simples, utilização do mouse ma interação de um objeto primitivo do papervision, assim poderemos possamos montar um menu num futuro.

Ao se trabalhar com Orientação a Objetos devemos sempre estar atendendo a instância do objeto, ao utilizar o papervision, para alterar algumas propriedades de um simples material instanciado para um plane devemos alterar o movieclip no qual o nosso material recebe de instancia.

movie = new MovieClip();
material = new MovieMaterial(movie,true,true);

Seguindo a lógica, o nosso material armazena a instancia de “movie” ou seja, se alterarmos o alpha ou o posicionamento do frame de nosso movie o nosso material sofrerá a mesma alteração.

Em nosso exemplo teremos um movieclip aonde a propriedade linkage dele será “MovieButton”.

Iniciaremos nosso plane com as rotações em 25 e alpha 0.8, e em nosso enterframe colocaremos o nosso plane para ficar rotacionando para exemplificar melhor que aquele plane é um objeto do papervision. Ao passar o mouse em nosso plane, alteraremos o alpha para 1, reposicionaremos as rotações em 0 e bloquearemos o enterframe. Vamos para o código completo.

package
{
    import flash.display.MovieClip;
    import flash.events.Event;
    import org.papervision3d.materials.MovieMaterial;
    import org.papervision3d.objects.primitives.Plane;
    import org.papervision3d.events.InteractiveScene3DEvent;
    import org.papervision3d.view.BasicView;

    public class Menu extends BasicView
    {
        private var mov1:MovieClip;
        private var mat1:MovieMaterial;
        private var plane1:Plane;
        private var MOVE:Boolean = true;

        public function Menu()
        {
            viewport.buttonMode = true;
            viewport.interactive = true;

            camera.zoom = 5;
            camera.focus = 200;

            mov1 = new MovieButton();
            mat1 = new MovieMaterial(mov1, true, true)

            mat1.interactive = true;
            mat1.smooth = true;
            mat1.doubleSided = true;

            plane1 = new Plane(mat1, 130, 100)
            scene.addChild(plane1);
            plane1.rotationY = 25;
            plane1.rotationZ = 25;
            plane1.rotationX = 25;

            plane1.addEventListener(InteractiveScene3DEvent.OBJECT_OVER, _mouseOver);
            plane1.addEventListener(InteractiveScene3DEvent.OBJECT_OUT, _mouseOut);
            startRendering();
            mov1.alpha = 0.8;
            addEventListener(Event.ENTER_FRAME, _loop);

        }
        public function _loop(e:Event) {
            if (MOVE){
                plane1.yaw(3);
                plane1.roll(3);
                plane1.pitch(3);
            }
        }
        public function _mouseOver(e:InteractiveScene3DEvent):void
        {
            MOVE = false;
            mov1.alpha = 1;
            e.target.rotationY = 0;
            e.target.rotationZ = 0;
            e.target.rotationX = 0;

        }
        public function _mouseOut(e:InteractiveScene3DEvent):void
        {
            MOVE = true;
            mov1.alpha = 0.8;
        }

    }

}

Para dar um toque interessante ao seu menu aconselho a usar transições de tweeners, caurina, green sock ou ate mesmo o tweener do flash. Agora que eu já lhe mostrei a escada só falta vocês subirem ^^ até aproxima.

Papervision [ReflectionView]

julho 27, 2009

Imagem

Clique na imagem para testar

Olá pessoal , Hoje falarei sobre uma classe muito interessante e simples, ReflectionView. Uma classe que faz com que o viewport se transforme em um espelho tanto para cima do eixo y:0 quanto para baixo.

A classe ReflectionView é uma classe extendida da classe BasicView que por sua vez é extendido da classe AbstractView, o que eu quero dizer com tudo isso, que ao extender uma classe a RelectionView ele vai possuira atributos instanciados como:

AbstractView:
scene:Scene3D;
viewport:Viewport3D;
renderer:BasicRenderEngine;

startRendering();
stopRendering();
singleRender();

ReflectionView
viewportReflection : Viewport3D;
cameraReflection : CameraObject3D;
singleRender() (override - sobrescrevido)

Quando criávamos nosso BasicView ativávamos a função startRendering() para renderizar nossa aplicação, porem quando criamos um ReflectionView também podemos utilizar esta função para renderizar, porém não irá criar reflexo pois a função responsável pelo reflexo é a singleRender() que esta reescrita nesta classe para poder ativar o reflexo. Esta parecendo complicado mas as coisas são bem simples vamos analisar nosso código. Em resumo para funcionar precisamos apenas colocar dentro de um bloco ENTER_FRAME a função singleRender();

Como de custume trabalharemos com 2 arquivos. ppv_reflection.fla e ppv_reflection.as. Certifique de possuir 2 movieclip em sua biblioteca com os seguintes linkage: “smile” e “face”.

ppv_reflection.as

package
{
    import flash.display.Sprite;
    import flash.events.Event;
    import org.papervision3d.core.effects.view.ReflectionView;
    import org.papervision3d.materials.ColorMaterial;
    import org.papervision3d.materials.MovieAssetMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.primitives.Cube;

    public class ppv_reflection extends ReflectionView
    {
        public var matsmile:MovieAssetMaterial;
        public var matface:MovieAssetMaterial;
        public var cubo:Cube;
        public var lista:MaterialsList;

        public function ppv_reflection() {
            setChildIndex(viewportReflection, 1);
            viewportReflection.alpha = 0.8;
            matsmile  = new MovieAssetMaterial("smile");
            matface  = new MovieAssetMaterial("face");
            lista = new MaterialsList(
                {front: matface,
                  back: matsmile,
                  top: new ColorMaterial(0xF9EAAD),
                  bottom: new ColorMaterial(0x000000),
                  left: matface,
                  right: matface} );
            cubo  = new Cube(lista, 200, 200, 250);
            scene.addChild(cubo);

            cubo.y = 150;
            addEventListener(Event.ENTER_FRAME, onEnterFrame);

        }
        private function onEnterFrame(e:Event):void {
            cubo.rotationY = mouseX - stage.stageWidth / 2;
            cubo.rotationX = mouseY - stage.stageHeight / 2;
            singleRender();
        }

    }

}

Uma classe simples que possui uma imagem de fundo com um cubo personalizado, aonde este cubo se movimenta respondendo os comandos do mouse.Na primeira linha de nosso construtor utilizamos o seguinte código:

    setChildIndex(viewportReflection, 1);

Quando criamos nossa classe extendida de ReflectionView automaticamente nosso viewport refletor é criado no índex 0 porem se eu quiser deixar uma imagem de background desenhado em alguma layer da time line esse background entrará em um índex acima de nosso viewport fazendo com que o viewport refletor fique por trás do background, este é o motive desta linha de comando, estamos trocando o posicionamento índex de nosso viewport.

Nosso viewport refletor ele funciona da seguinte maneira, tudo que esta do eixo y:0 para cima será refletido para baixo o eixo y:0 e vice versa, a imagem a seguir ilustra um cubo desenhado abaixo do eixo y:0.

img_02

Espero que tenham gostado deste tutorial, não precisam se preocupar que teremos mais coisas interessantes no decorrer da semana, até a próxima.

Emulador de Game Boy Classic em Flash

julho 23, 2009

Olá pessoal, muitos de vocês adoram jogar jogos emulados, final fantasy, chrono trigger, Pokémon. Pois bem, aposto que vocês nunca imaginaram fazer um emulador em flash, eu pessoalmente nunca me imaginei, acontece que eu acabei esbarrando com um site muito interessante aonde possuía um código de um emulador de game boy classic feito em flash.

emuladorgb

Clique na imagem para visualizar o código

O site é uma espécie de compilador de flash online, aonde o usuário escreve seu código, compila e compartilha com outros usuários do site, encontrei uns códigos bem simples para usar como referencia em meus estudos da engine box2d, também encontrei bons exemplos de papervision, vale apena dar uma conferida no site. http://wonderfl.net/. Agora que vocês tem acesso ao código de um emulador de game boy classic desafio vocês a criar um emulador de game boy color. Heheh. Bem pessoal até o próximo post.

Papervision Math

julho 21, 2009

Olá pessoal, decidi que para este novo tutorial eu iria fazer alguma coisa simples mesclando matemática e papervision.

Papervision Math

Clique aqui na imagem para visualizar a aplicação

Para demonstrar o movimento de translação nada melhor que usar um exemplo já conhecido, o movimento da lua sobre a terra.

Criaremos 1 arquivo (.fla) e um arquivo (.as) rotulado como ppv_math, definimos no flash como document class nosso ppv_math. Nosso código não possui nenhum mistério para quem já vem acompanhando nossos tutoriais de papervision com exceção das seguintes linhas de código.

lua.z = Math.cos(teta) * 150;
lua.x = Math.sin(teta) * 150;
lua.y = Math.sin(teta) * 50;

Para fazer a translação padrão utilizamos como eixos base nosso “x” e “z” para interargimos lateralmente e com profundidade, para dar um efeito mais interessante na aplicação decidi colocar uma interação no eixo “y” para a lua percorrer em um sentido diagonal. Experimente comentar um dos eixos para ver o que acontece. Agora segue o código na integra.

ppv_math.as

package {
    //flash
    import flash.display.Sprite;
    import flash.events.Event;
    //papervision
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.render.BasicRenderEngine;
    //Material
    import org.papervision3d.materials.BitmapAssetMaterial;
    // objeto
    import org.papervision3d.objects.primitives.Sphere;

    public class ppv_math extends Sprite {

        public var cena:Scene3D;
        public var viewport:Viewport3D;
        public var camera:Camera3D;
        public var renderer:BasicRenderEngine;
        //objetos Primitivos
        public var terra:Sphere;
        public var lua:Sphere;
        //Matemática
        public var alfa:Number = Math.PI / 180;
        public var teta:Number = 0;

        public function ppv_math () {
            Set ();
            Objetos ();
        }
        public function Set ():void {

            viewport = new Viewport3D(400,400);
            addChild (viewport);
            cena = new Scene3D ;
            renderer = new BasicRenderEngine ;
            camera = new Camera3D ;
            camera.zoom = 5;
            camera.focus = 200;

        }
        public function Objetos ():void {
            terra = new Sphere(new BitmapAssetMaterial("Earth"), 100, 15,15);
            lua = new Sphere(new BitmapAssetMaterial("moon"), 30, 15,15);

            cena.addChild(terra);
            cena.addChild(lua);

            addEventListener (Event.ENTER_FRAME,Loop,false, 0, true);

        }
        public function Loop (e:Event):void {
            teta += alfa;
            renderer.renderScene (cena, camera, viewport);
            terra.yaw(1);
            lua.yaw(1);

            lua.z = Math.cos(teta) * 150;
            lua.x = Math.sin(teta) * 150;
            lua.y = Math.sin(teta) * 50;

        }
    }
}

Com conceitos básicos é possível criar diversas coisas interessantes com o papervision, tentarei criar mais tutoriais cultos envolvendo a matemática. Até a próxima!

Matemática no Flash

junho 25, 2009

math

Olá pessoal. Finalmente chegou a hora de vocês usarem seus conhecimentos do ginásio. Vocês sempre ouviram dizer que quem faz informática precisa saber matemática, bem se até hoje ainda não encontrou utilidade para ela, não se preocupe, hoje estarei estreando mais uma seqüência de tutoriais que mostrarão que a matemática é uma poderosa ferramenta para criação de jogos, menus interativos, aplicativos gráficos entre outra utilidade. O foco do nosso primeiro tutorial de matemática com actionscript será o movimento de translação.

01o_plano_cartesiano_img_5

Este é o plano cartesiano da matemática conceitual, no flash trabalhamos quase que exatamente igual com exceção que o eixo y é invertido, ao aumentarmos o valor de y a imagem segue para baixo.

Translação:

Para quem não se lembra, translação é o movimento que a terra faz em torno do sol. Resumindo , é quando um objeto circula um eixo sempre mantendo a mesma distância (raio).

translacao

Você com certeza já viram este recurso sendo usado em alguns jogos, assim como uma bola de fogo, bola de espinhos ou uma plataforma dinâmica. Para reproduzirmos este movimento precisamos relembrar alguns conceitos básicos de trigonometria.

math03

Como podemos ver no circulo trigonométrico a distancia oposta ao angulo é o Cosseno vezes o raio e a distancia adjacente é igual ao seno vezes o raio, Porem no actionscript o angulo deve ser escrito em Radianos vamos analisar a figura e ver como ficaria a posição dos objetos.

math04

Para efetuar o movimento de translação é necessário sempre estar incrementando o angulo por intermédio de enterframe ou timeout. Agora vamos seguir com o nosso exemplo pratico.

Iremos utilizar a linguagem estruturada em nosso exemplo, teremos apenas um arquivo .fla e já teremos um objeto que rotacionará o centro do palco, este objeto terá o nome de “ob”. No primeiro frame escreveremos o seguinte código.

No código a seguir utilizamos os seguintes métodos da classe Math:

Math.cos(n:Number): retorna o cosseno do ângulo.
Math.sin(n:Number): retorna o seno do ângulo.
Math.PI: constante que retorna o PI, PI é a representação gráfica de 180 em radianos.

Em nosso código o objeto ficará circulando o centro com um raio de 100px e a cada passada pelo loop de enterframe o angulo final receberá um ingremento de 2°.  O centro da circunferência será definido no final da equação. Adicionando o respectivo posicionamento do centro após a equação.

var angulo:Number = Math.PI/90;
var newAngulo:Number = 0;

addEventListener(Event.ENTER_FRAME,EnterFrame);

function EnterFrame(e:Event) {
	newAngulo += angulo;
	ob.x = Math.cos(newAngulo) * 100 + stage.stageWidth/2;
	ob.y = Math.sin(newAngulo) * 100 + stage.stageWidth/2;
}

Desculpe pela demora na postagem de um novo tutorial,  meu computador estava com problema e eu estava super atarefado no trabalho. Mas podem deixar que tentarei voltar a periodicidade^^ abraços.

Papervision BasicView

maio 28, 2009

Olá pessoal, finalmente consegui um tempinho para criar um novo post. Hoje falaremos sobre uma classe que foi criada no intuito de simplificar a nossa vida com o papervision a classe BasicView

BasicView é uma classe para aplicações simples, criando uma classe extendida de basicview você não precisa ficar instanciando cameras, viewports, renderes, pois a propria classe ja faz isso.

Veja como nosso código fica muito otimizado, Neste exemplo estamos criando apenas uma esfera, utilizando um MovieAssetMaterial para importar um movieclip com o id igual a “smile” de nossa biblioteca e rotacionando um pouco a esfera com o metodo yaw.

ppv

Arquivo: ppv_basic.as

package  {
	import org.papervision3d.objects.primitives.Sphere;
	import org.papervision3d.materials.MovieAssetMaterial;
	import org.papervision3d.view.BasicView;
	public class ppv_basic extends BasicView{
		public var sphere:Sphere =  new Sphere(
             new MovieAssetMaterial("smile"), 200,10,10);
		public function ppv_basic() {
			scene.addChild(sphere);
			sphere.yaw(-125);
			startRendering();
		}
	}
}
Lembrando que para este codigo funcionar precisamos criar um arquivo flash, adicionar o pacote de classes do papervision e ter algum movieclip na biblioteca com o linkage “smile”.

Apesar da simplicidade eu não recomendo usar basicview para projetos complexos, mas se você estiver interessado em algum projeto muito simples seu uso é indispensavel. Para complementar a classe BasicView possui os seguintes paramêtros opcionais, seguido de suas propriedades default:

BasicView (viewportWidth:Number = 640, viewportHeight:Number = 480,
 scaleToStage:Boolean = true, interactive:Boolean = false, cameraType:String = "Target")

Espero que tenham gostado deste post, ando meio ocupado estudando diversas coisas ao mesmo tempo, também comecei a estudar a engine Away3d muito utilizada também para construção de projetos 3d no flash, similar ao papervision, podes ter certeza que logo logo estarei compartilhando este novo conhecimento com vocês. Obrigado pela sua visita e até o proximo post

Papervision MouseClick

maio 7, 2009

mundi

Olá pessoal como havia prometido nosso mais novo tutorial papervision não estamos usando o Cubo, para diversificar um pouco decidi utilizar a Esfera.

Este tutorial é essencial para ter uma base de criação de site em papervion, neste tutorial vamos aprender a colocar nosso viewport para aceitar interação e definiremos nossa esfera para funcionar como botão simples, onde a única funcionalidade será pausar e retomar a rotação.

Depois de uma seqüência de tutoriais sobre papervision existe muitos pontos que não precisarei explicar de novo, como  por exemplo: inserir uma esfera e importar uma textura para ela. Hoje me focarei somente nos pontos chaves.

Viewport3D

O viewport é o nosso ambiente 3d, extremamente essencial para criar algo com o papervision, quando criamos nosso viewport3d podemos definir alguns parâmetros iniciais.

    new niewport3D(width, height, autoscale, interactive)
  • width (Number): Define a largura de nosso viewport3d;
  • height (Number): Define a altura de nosso viewport3d;
  • autoscale (Boolean): Determina se o viewport vai se escalar ao Stage.
  • Interactive (Boolean): Permite o uso de interações com o mouse, possibilitando o uso do evento InteractiveScene3DEvent.

Criando Interação

Em nosso código passaremos a definir o parâmetro interativo para true. Com o viewport definido para true poderemos definir agora nosso material para interative possibilitando ele ser clicado quando estiver em um objeto primitivo.Neste exemplo eu usarei o MovieMaterial, mas vocês poderiam utilizar qualquer outro tipo de material, lembrando que com o movie material eu importo um movieclip que esteja em minha biblioteca ou que já tenha sido instanciado.

     skin = new MovieMaterial(mov);
     skin.interactive = true;

Agora poderemos adicionar um listener em nossa esfera chamando o evento de interação especifico seguido de um método que será executado.

    esfera.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS,PRESS);

Código: main.as

package
{
    import flash.display.Sprite;
    import flash.display.MovieClip;
    import flash.events.Event;
    import org.papervision3d.materials.MovieMaterial;
    import org.papervision3d.objects.primitives.Sphere;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.events.InteractiveScene3DEvent;
    public class main extends Sprite
    {
        public var cena:Scene3D;
        public var viewport:Viewport3D;
        public var camera:Camera3D;
        public var renderer:BasicRenderEngine;
        public var esfera:Sphere;
        public var mov:MovieClip = new earth();
        public var skin:MovieMaterial;
        public var paused:Boolean = false;
        public function main ()
        {
            Set ();
            Objetos ();
        }
        public function Set ():void
        {
            viewport = new Viewport3D(300,300,false,true);
            addChild (viewport);
            cena = new Scene3D ;
            renderer = new BasicRenderEngine ;
            camera = new Camera3D ;
        }
        public function Objetos ():void
        {
            skin = new MovieMaterial(mov);
            skin.interactive = true;

esfera = new Sphere(skin,300,30);

            cena.addChild(esfera);

esfera.addEventListener(InteractiveScene3DEvent.OBJECT_PRESS,PRESS);

            addEventListener (Event.ENTER_FRAME,Loop,false, 0, true);
        }
        public function PRESS (e:InteractiveScene3DEvent ):void
        {
            paused = !paused;
        }
        public function Loop (e:Event):void
        {
            if (!paused)
            {
                esfera.roll(1)
                esfera.yaw(3)
                esfera.pitch(1)
            }
            renderer.renderScene (cena,camera,viewport);
        }
    }
}

Lembrando que para este tutorial funcionar devemos importer as classes do papervision e definir como classe padrão do fla a classe main,
Tentei fazer algo bem simples para demonstrar a interação do mouse com o papervision, com isso podemos criar diversas coisas seguindo a criatividade de cada um. Tentarei fazer algo mais elaborado para próximo tutorial. Espero que tenham gostado e que estes tutoriais sobre papervision estejam sendo úteis para vocês em seus estudos. Bem ate a próxima.


									

Papervision MovieMaterial

maio 4, 2009

moviematerial

Clique na imagem para testar

Olá pessoal , para dar continuidade ao nosso estudo sobre papervision, hoje vamos falar sobre mais um tipo de material que podemos utilizar nos nosso objetos primitivos a textura MovieMaterial. Antes de começamos a falar sobre esse material vamos falar sobre um problema que ocorria com a classe MovieAssetMaterial.

Quando aprendemos sobre MovieAssetMaterial, passávamos uma string como parâmetro e importávamos de nossa biblioteca um movieclip onde o valor da propriedade linkage era igual da string referida. Mas a classe MovieAssetMaterial não aceita importar um movieclip que tenha come base uma classe que necessite de um parâmetro.

A classe MovieMaterial utiliza como parâmetro a instanciação de um movielip ao invés de uma string referindo sua propriedade linkage, com isso seu movieclip padrão não necessariamente precisa estar na bibliote, você pode trabalhar com um movieclip já instanciado, assim você pode utilizar o método gotoAndStop para indicar outro frame antes de ter instanciado ele como material..Outra vantagem é a possibilidade de utilizar um movieclip da biblioteca que tenha como base uma classe que exija parâmetro.

Construtor

Para criarmos um MovieMaterial devemos instanciar um objeto do tipo MovieMaterial.
Nosso único parâmetro obrigatório é um do tipo DisplayObject que é a referencia de nossa textura.

var  material:MovieMaterial =  new MovieMaterial(movieAsset);

movieAsset (DisplayObject): Referencia de um movieclip existente carregado na memória ou no stage.
Transparent (Boolean): Define se a textura possuirá transparência. [opcional]
Animated (Boolean): Define se o movieclip sera animado [opcional]

Tutorial

Neste tutorial eu quis brincar um pouco e mais uma vez dou uma demonstração de tile system com papervison, mas desta vez vamos ter uma classe que se comportará como movieclip aonde receberá como parâmetro um número que definirá qual vetor vai utilizar para criar o cenário, depois utilizaremos como material nosso cenário, A parte relacionada a papervision não terá mistério nenhum pois estarei usando a estrutura do tutorial anterior relacionado a materiais.

Arquivos

Neste tutorial trabalharemos com os seguintes arquivos:
1- MovieMaterial.fla
2- main.as
3- faceField.as: Classe que criará um cenário tile system para se comportar como material

MovieMaterial.fla:

obtile

1- faceField: Movieclip
2- obTile:MovieClip
3- main (definir como classe principal)

obs: para criar um movirclip vazio basta segurar ctrl + F8.

faceField.as

Esta classe não existe mistério nenhum, seu construtor recebe um numero como parâmetro e se for 1 desenha o vetor map1 e se for outro desenha o vetor map2. Em seguida percorre a seqüência de loops para desenhar o tile.

package
{
    import flash.display.MvieClip;
    public class faceField extends MovieClip
    {
        public var map1:Array = [
        [1,1,1,1,1,1,1,1,1,1,1],
        [1,0,0,0,0,0,0,0,0,0,1],
        [1,0,0,0,0,1,0,0,0,0,1],
        [1,0,0,0,1,1,0,0,0,0,1],
        [1,0,0,0,0,1,0,0,0,0,1],
        [1,0,0,0,0,1,0,0,0,0,1],
        [1,0,0,0,0,1,0,0,0,0,1],
        [1,0,0,0,0,1,0,0,0,0,1],
        [1,0,0,0,1,1,1,0,0,0,1],
        [1,0,0,0,0,0,0,0,0,0,1],
        [1,1,1,1,1,1,1,1,1,1,1],
        ];
        public var map2:Array = [
        [1,1,1,1,1,1,1,1,1,1,1],
        [1,0,0,0,0,0,0,0,0,0,1],
        [1,0,0,0,1,1,1,0,0,0,1],
        [1,0,0,1,0,0,0,1,0,0,1],
        [1,0,0,1,0,0,0,1,0,0,1],
        [1,0,0,0,0,0,1,0,0,0,1],
        [1,0,0,0,0,1,0,0,0,0,1],
        [1,0,0,0,1,0,0,0,0,0,1],
        [1,0,0,1,1,1,1,1,0,0,1],
        [1,0,0,0,0,0,0,0,0,0,1],
        [1,1,1,1,1,1,1,1,1,1,1],
        ];
        public function faceField (n:Number)
        {
            for (var j =0; j<11; j++)
            {
                for (var i=0; i<11; i++)
                {
                    var t:MovieClip = new obTile();
                    addChild (t);
                    t.x = i * 20;
                    t.y = j * 20;
                    if (n==1)
                    {
                        t.gotoAndStop(map1[j][i]+1);
                    }
                    else
                    {
                        t.gotoAndStop(map2[j][i]+1);
                    }
                }
            }
        }
    }
 }

main.as

Nossa classe principal não possui nenhum mistério, utilizamos a estrutura do tutorial papervision materiais.

Utilizamos apenas MovieMaterial para formação das faces do cubo, com a diferença apenas na maneira de que são chamadas desta apenas uma fogem do padrão.

    skinTile1.gotoAndStop(1);
    skinTile2.gotoAndStop(2);
    faceMovTile1 =  new MovieMaterial(skinTile1);
    faceMovTile2 =  new MovieMaterial(skinTile2);

Apesar dos objetos terem sidos criados no começo da classe só neste ponto que instanciamos os objetos para se portar como material, desta maneira garante que os moviesclips vão estar em seus respectivos frames antes de instanciarmos os materiais.

package
{
    //flash
    import flash.display.Sprite;
    import flash.display.MovieClip;
    import flash.events.Event;
    //papervision
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.view.Viewport3D;
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.render.BasicRenderEngine;
    //Material
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.materials.MovieMaterial;
    // objeto
    import org.papervision3d.objects.primitives.Cube;
    public class main extends Sprite
    {
        public var cena:Scene3D;
        public var viewport:Viewport3D;
        public var camera:Camera3D;
        public var renderer:BasicRenderEngine;
        //Material
        public var skinMaterial1:MovieClip = new faceField(1);
        public var faceMov1:MovieMaterial = new MovieMaterial(skinMaterial1);
        public var skinMaterial2:MovieClip = new faceField(2);
        public var faceMov2:MovieMaterial = new MovieMaterial(skinMaterial2);
        public var skinTile1:MovieClip = new obTile();
        public var skinTile2:MovieClip = new obTile();
        public var faceMovTile1:MovieMaterial;
        public var faceMovTile2:MovieMaterial;
        //objetos Primitivos
        public var obCube:Cube;
        public function main ()
        {
            Set ();
            Objetos ();
        }
        public function Set ():void
        {
            viewport = new Viewport3D(400,300,true,false,true,true);
            addChild (viewport);
            cena = new Scene3D ;
            renderer = new BasicRenderEngine ;
            camera = new Camera3D ;
            camera.focus = 600;
            camera.zoom = 1;
        }
        public function Objetos ():void
        {
            skinTile1.gotoAndStop(1);
            skinTile2.gotoAndStop(2);
            faceMovTile1 =  new MovieMaterial(skinTile1);
            faceMovTile2 =  new MovieMaterial(skinTile2);
            //Cube
            obCube = new Cube(
                new MaterialsList(
                {front: faceMov1,
                 back: faceMov1,
                 left: faceMovTile1,
                 right: faceMovTile2,
                 top: faceMov2,
                 bottom: faceMov2}
                )
            ,220,220,220,1,1,1);
            cena.addChild (obCube);
            addEventListener (Event.ENTER_FRAME,Loop,false, 0, true);
        }
        public function Loop (e:Event):void
        {
            obCube.yaw (-4);
            obCube.pitch (-2);
            renderer.renderScene (cena,camera,viewport);
        }
    }
}

Espero que tenham gostado do tutorial, apesar de MovieMaterial ser uma textura bem útil não devemos esquecer das outras texturas, é sempre bom usar a textura certa para cada momento assim deixa o programa mais leve. Ao que parece vocês já devem estar enjoados de exemplos com cubo, por isso tentarei mudar um pouco de objeto para o próximo tutorial, estou dando uma olhada em coisas interessantes com o objeto “Plane” quem sabe ele não vira tema do nosso próximo tutorial de papervision. Obrigado pela visita e volte sempre.

Papervision Tile [Player]

abril 8, 2009

Olá pessoal, para lhes ser sincero eu não pretendia fazer uma continuação tão cedo para o papervison tile, mas eu me empolguei muito ao escrever o tutorial anterior, e decidi criar uma continuação. Prestem atenção no flash a seguir.

ssemeny
Clique na imagem para visualizar a apresentação

Este foi o ultimo passo do nosso tutorial tile sytem, pois bem, a primeira meta do nosso tutorial papervision tile será replicar esta aplicação para o 3d. Agora veja como ficará o projeto final deste tutorial de hoje.

game
Clique na imagem pra visualizar a apresentação

Sobre:

Poderemos utilizar o mesmo arquivo fla que construímos no tutorial anterior, mas eu não irei utilizar o mesmo arquivo main, pois desta vez adicionaremos alguns conceitos de POO (Programação Orientada a Objetos) em nosso tutorial.

Nosso tutorial será constituído pelos seguintes arquivos:

  • ppv_tile.fla: Este arquivo não tem mistério nenhum, é o mesmo que utilizamos no tutorial anterior.
  • Tile3D.as: Este arquivo será a classe modelo para cada bloco, ele será responsável por desenhar o cubo, manipular as propriedades de coordenadas tile, ground e wall, que nos dirá se o tile desenhado permitir caminhar sobre ele e se ele funcionará como uma parede que impedirá a passagem quando o player estiver no mesmo nível.
  • Player.as: Esta classe além de desenhar nosso player no cenário e manipular coordenadas, ela também contará com o método de mover o player pelo cenário.
  • main.as: Nosso arquivo principal, será responsável por montar nosso ambiente 3d, adicionar o player no cenário e manipular o teclado para movimentar o player.

Obs: Não podemos esquecer-nos de referenciar a biblioteca do papervision.

Diretórios:

Neste tutorial utilizaremos o conceito de pacotes, e as classes não estarão no mesmo diretório que o arquivo fla, veja a imagem como será organizado nosso diretório.

dir

Como funcionará o código.

No nosso arquivo main.as criaremos 3 vetores, um para informar os materiais, outro para informar a altura que cada tile irá ficar e um terceiro que terá o mesmo comprimento dos outros, mas utilizaremos ele para armazenar objetos da classe Tile3D para podermos ter uma fácil manipulação de dados usando coordenadas tile.

Em nosso loop de criação de tiles instanciaremos cada posicionamento do veto tiles[i][j] pra se comportarem como um novo objeto do tipo Tile3D.

Nossa classe Tile3D será uma classe estendida da classe Cube do papervision, a diferença que nossa herança vai precisar de parâmetros adicionais como tamanho do cubo, posicionamento x,z,y no tile.

No decorrer do loop definiremos a propriedade wall e ground de acordo com os vetores especificadores de altura e material, utilizaremos os métodos da classe.

Ao termino do loop instanciaremos o objeto player do tipo Player

A classe Player receberá como parâmetros: o tamanho do tile, e posicionamento x,z e y como parâmetro opcional.

Para mover o player pelo cenário invocaremos o método move da classe Player, que recebe como parâmetros: direcionamento Z, direcionamento X e o vetor com os objetos de tile.

Lógica das classes Tile3D e Player:

Criar um cubo com os parâmetros passados pelo construtor de Tile3D e Player. Logo em seguida repassar os parâmetros para classe mãe Cubo. Não permitiremos o usuário alterar os atributos diretamente, pois para alterarmos precisaremos de uma validação, por isso estaremos utilizando os atributos do tipo privado, a validação será da seguinte maneira: O usuário informara qual será o tile que ele quer posicionar o cubo, o método automaticamente modificará o atributo que armazena o posicionamento no tile e calculará a posição física dele no plano 3d (x,z,y).

Lógica Get/Set:

Vamos supor que o atributo no qual armazenaremos o posicionamento do tileX esta definido como public. Ao fazermos “Player.tileX = 2;” modificaremos o nosso atributo para 2, mas com isso o nosso Player não se moveu para a posição 2. Este problema é solucionado utilizando a lógica get/set. Um método Get para recupera um valor (x = Player.tileX) e um método set para modifica um valor (Player.tileX = 2). Como não podemos ter atributos com o mesmo nome que os métodos utilizaremos “_nome” quando for atributo e “get nome ou set nome” para função.

private var _tileX:int;
private function gotoTile(n:int):Number{
    return _cubeW * n;
}
public function set tileX(n:int):void {
    _tileX = n;
    x = gotoTile(n);
}
public function get tileX():int {
    _tileX = Math.floor(x /_tileWidth);
    return _tileX;
}

Eu sei que a teoria pode estar meio confusa para alguns mas prometo que montarei um tutorial mais detalhado sobre Orientação a Objetos para vocês poderem refazerem este tutorial dizer. “Uhmmm então é isso.”

Move Player

Nosso método move na classe Player funcionará da seguinte forma, ele receberá parametros de adição para x,z e um vetor. se passarmos como parametro (0,1,vetor) estaremos informando que queremos que o player mova 0 na escala X e +1 na escala Z. Mas antes de mover verificamos se o bloco no qual nosso player está querendo se mover é permitido andar sobre ele (ground = true) e também se não existe um bloco do tipo parede atrapalhando (wall = false), só depois de verificarmos se é permitido andar que movimentamos nosso player.

        public function  move(dirx:int,dirz:int,arrayObj:Array):void {
            var nextTileX:Number = tileX + dirx;
            var nextTileZ:Number = tileZ + dirz;
            if (arrayObj[nextTileX][nextTileZ]!= "undefined" && !(arrayObj[nextTileX][nextTileZ].wall) && arrayObj[nextTileX][nextTileZ].ground){
                if ((dirx == 1) ||  (dirx == -1) || (dirz == 1) ||  (dirz == -1)) {
                    tileX = nextTileX;
                    tileZ = nextTileZ;
                }
            }
        }

Códigos:

Segue abaixo o código referente as arguivos: Tile3D.as, Player.as, main.as. Lembrando que o nome dos arquivos precisam ser exatamente estes respeitando letra maiuscula e minuscula, o mesmo vale para as pastas que os arquivo serão alocados.

  • Tile3D.as
package org.tile3d{
    import org.papervision3d.materials.utils.MaterialsList;
    import org.papervision3d.objects.primitives.Cube;
    public class Tile3D extends Cube {
        private var _wall:Boolean;
        private var _ground:Boolean = true;
        private var _tileX:int;
        private var _tileY:int;
        private var _tileZ:int;
        private var _cubeW:Number;
        public function Tile3D(matList:MaterialsList,_cubeW:Number=20,_tileX:Number=1,_tileZ:Number=1,_tileY:Number=1) {
            super(matList,_cubeW,_cubeW,_cubeW);
            this._cubeW = _cubeW;
            tileX = _tileX;
            tileZ = _tileZ;
            tileY = _tileY;
        }
        private function gotoTile(n:int):Number{
            return _cubeW * n;
        }
        //Get e Set: Modificando os valores dos atributos privados
        public function set tileX(n:int):void {
            _tileX = n;
            x = gotoTile(n);
        }
        public function get tileX():int {
            return _tileX;
        }
        public function set tileY(n:int):void {
            _tileY = n;
            y = gotoTile(n);
        }
        public function get tileY():int {
            return _tileY;
        }
        public function set tileZ(n:int):void {
            _tileZ = n;
            z = gotoTile(n);
        }
        public function get tileZ():int {
            return _tileZ;
        }
        //Permite que o objeto seja usada como chão
        public function set ground(valor:Boolean):void {
            _ground = valor;
        }
        public function get ground():Boolean {
            return _ground;
        }
        //Transforma o objeto em uma parede
        public function set wall(valor:Boolean):void {
            _wall = valor;
        }
        public function get wall():Boolean {
            return _wall;
        }
    }
}
  • Player.as
package  org{
    import org.papervision3d.objects.primitives.Cube;
    import org.papervision3d.materials.MovieAssetMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    public class Player extends Cube {
        private var _tileX:int;
        private var _tileY:int;
        private var _tileZ:int;
        private var _tileWidth:Number;
        private var matP:MovieAssetMaterial = new MovieAssetMaterial("playermat1");
        private var p:MaterialsList = new MaterialsList({all: matP});
        public function Player(_tileWidth:Number=20,_tileX:Number=1,_tileZ:Number=1,_tileY:Number=1) {
            super(p,15,15,15);
            this._tileWidth = _tileWidth;
            tileX = _tileX;
            tileZ = _tileZ;
            tileY = _tileY;
        }
        public function  move(dirx:int,dirz:int,arrayObj:Array):void {
            var nextTileX:Number = tileX + dirx;
            var nextTileZ:Number = tileZ + dirz;
            if (arrayObj[nextTileX][nextTileZ]!= "undefined" && !(arrayObj[nextTileX][nextTileZ].wall) && arrayObj[nextTileX][nextTileZ].ground){
                if ((dirx == 1) ||  (dirx == -1) || (dirz == 1) ||  (dirz == -1)) {
                    tileX = nextTileX;
                    tileZ = nextTileZ;
                }
            }
        }
        private function gotoTile(n:int):Number{
            return _tileWidth * n+(_tileWidth-15)/2;
        }
        //Get e Set: Modificando os valores dos atributos privados
        public function set tileX(n:int):void {
            _tileX = n;
            x = gotoTile(n);
        }
        public function get tileX():int {
            _tileX = Math.floor(x /_tileWidth);
            return _tileX;
        }
        public function set tileY(n:int):void {
            _tileY = n;
            y = gotoTile(n);
        }
        public function get tileY():int {
            _tileY = Math.floor(y/_tileWidth);
            return _tileY;
        }
        public function set tileZ(n:int):void {
            _tileZ = n;
            z = gotoTile(n);
        }
        public function get tileZ():int {
            _tileZ = Math.floor(z/_tileWidth);
            return _tileZ;
        }
    }
}
  • main.as
package  {
     //flash
    import flash.display.MovieClip;
    import flash.events.*;
    import org.tile3d.*;
    import org.Player;
    //Papervision
    import org.papervision3d.objects.primitives.Plane;
    import org.papervision3d.objects.primitives.Cube;
    import org.papervision3d.scenes.Scene3D;
    import org.papervision3d.render.BasicRenderEngine;
    import org.papervision3d.cameras.Camera3D;
    import org.papervision3d.view.Viewport3D;
    import org.papervision3d.materials.MovieAssetMaterial;
    import org.papervision3d.materials.utils.MaterialsList;
    public class main extends MovieClip {
        //papervision
        public var cena:Scene3D;
        public var viewport:Viewport3D;
        public var camera:Camera3D;
        public var renderer:BasicRenderEngine;
        public var centro:Plane;
        //material
        public var matGrass:MovieAssetMaterial = new MovieAssetMaterial("grass");
        public var matBase0:MovieAssetMaterial = new MovieAssetMaterial("base0");
        public var matBase1:MovieAssetMaterial = new MovieAssetMaterial("base1");
        public var matFlower:MovieAssetMaterial = new MovieAssetMaterial("flower");
        public var matWater:MovieAssetMaterial = new MovieAssetMaterial("water", true);
        public var w:MaterialsList = new MaterialsList(
        {front: matWater,
        back: matWater,
        left: matWater,
        right: matWater,
        top: matWater,
        bottom: matWater});
        public var g:MaterialsList = new MaterialsList(
        {front: matBase1,
        back: matBase1,
        left: matBase1,
        right: matBase1,
        top: matGrass,
        bottom: matBase1});
        public var f:MaterialsList = new MaterialsList(
        {front: matBase1,
        back: matBase1,
        left: matBase1,
        right: matBase1,
        top: matFlower,
        bottom: matBase1});
        public var b:MaterialsList = new MaterialsList(
        {all: matBase0});
        //tiles
        public var arrayTile:Array =[
        [w, w, w, w, w, w, w, w, w, w, w, w, w, w, w],
        [w, g, g, g, g, g, f, g, w, w, w, w, w, w, w],
        [w, g, g, f, g, g, g, g, g, w, g, g, f, w, w],
        [w, g, g, g, g, f, g, g, g, w, g, g, g, w, w],
        [w, w, g, g, g, g, g, g, g, f, f, g, g, w, w],
        [w, w, g, g, g, g, g, g, g, f, g, g, w, w, w],
        [w, g, g, g, g, g, g, g, g, g, g, w, w, w, w],
        [w, g, g, g, f, w, g, f, g, g, w, w, w, w, w],
        [w, w, g, g, w, w, g, g, g, w, w, w, w, w, w],
        [w, w, w, w, w, w, w, w, w, w, w, w, w, w, w]];
        public var arrayTileHeight:Array = [
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,1,0,0,0,0,0,0,0,0],
        [0,0,0,1,0,0,0,0,0,0,0,0,1,0,0],
        [0,0,0,0,0,1,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,1,1,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,1,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,1,0,0,1,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];
        public var tiles:Array = [
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,1,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,1,0,0,0,0,0,1,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,1,0,0,0,0,0,1,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]];
        //Player
        public var player:Player;
        //Outros
        public var tileWidth:Number = 20;
        public function main () {
            Set ();
            Objetos ();
        }
        public function Set ():void {
            viewport = new Viewport3D(400,300,true,false,true,true);
            addChild (viewport);
            setChildIndex (viewport,1);
            cena = new Scene3D ;
            renderer = new BasicRenderEngine ;
            camera = new Camera3D ;
            camera.focus = 100;
            camera.zoom = 10;
            camera.x = 650;
            camera.z = 450;
            camera.y = 700;
        }
        public function Objetos () {
            for (var i = 0; i < arrayTile.length; i++) {
                for (var j = 0; j <  arrayTile[0].length; j++) {
                    //Criando blocos extras na altura 					
                    tiles[i][j] = new Tile3D(arrayTile[i][j],tileWidth,i,j,arrayTileHeight[i][j]); 					if (arrayTileHeight[i][j]>0) {
                    tiles[i][j].wall=true;
                    for (var k=0; k<arrayTileHeight[i][j];k++){
                        var tilesBlock=new Tile3D(b,tileWidth,i,j,k);
                        cena.addChild (tilesBlock);
                    }
                }
                if (arrayTile[i][j] == w){
                    tiles[i][j].ground=false;
                }
                //Criando bloco Tile
                cena.addChild (tiles[i][j]);
                }
            }
            //Player
            player = new Player(20,1,1);
            cena.addChild (player);
            stage.addEventListener (KeyboardEvent.KEY_UP, onKeyUpEvent,false,0,true);
            addEventListener (Event.ENTER_FRAME,Loop,false, 0, true);
        }
        public function Loop (e:Event):void {
            camera.lookAt (player);
            renderer.renderScene (cena,camera,viewport);
        }
        public function movePlayer(ob:Cube,dir:String,code:int) {
            if (code==37){
                player.move(0,-1,tiles);
            }else if (code==39){
                player.move(0,1,tiles);
            }else if (code==38){
                player.move(-1,0,tiles);
            }else if (code==40){
                player.move(1,0,tiles);
            }
        }
        public function onKeyUpEvent (event:KeyboardEvent ):void {
            var Code:Number=event.keyCode;
            if (Code==37 ||Code==38 ||Code==40 ||Code==39 ) {
                movePlayer (player,null,Code);
            }
        }
    }
}

Papervision Tile

abril 2, 2009

Olá pessoal, estava me preparando para montar um novo tutorial sobre tile system, já estou a algum tempo uma atualização para a estruturação de cenários isométricos, mas eu pensei “por que não criar um cenário 3D tile?”

swf

Clique na imagem para testar.

Gostou, este será o nosso produto final, pois bem vamos seguir com o tutorial.

Lógica:

A lógica é bem simples, usaremos 2 vetores diferentes, um deles será para mostrar qual será o tile que usaremos na posição e o outro vetor que indicara a altura. Criaremos os loops para percorrer o vetor e criar cubos num plano 3D. Como termos alguns cubos suspensos, completaremos os espaços vazios com cubos, e colocaremos uma função para rotacionar nosso Field.

Tiles:

linkage

Estes sãos os movieclips que usaremos no nosso arquivo .fla, todos eles com exceção do water são estáticos, não possuem nenhum freme alem do desenhado, já o water eu coloquei uma pequena movimentação para dar um efeito de água se movendo. Todos os movieclips estão com a propriedade linkage definidos.

Usaremos a classe MovieAssetMaterial para importarmos cada movieclip para um material diferente

 public var matGrass:MovieAssetMaterial = new MovieAssetMaterial("grass");
 public var matBase0:MovieAssetMaterial = new MovieAssetMaterial("base0");
 public var matBase1:MovieAssetMaterial = new MovieAssetMaterial("base1");
 public var matFlower:MovieAssetMaterial = new MovieAssetMaterial("flower");
 public var matWater:MovieAssetMaterial = new MovieAssetMaterial("water", true);

Tiles x Materiais

materiaislist

Como vocês podem ver na imagem acima montaremos cubos para usarmos como tile, por enquanto vamos nos focar em criar as listas de materiais para as respectivas faces dos cubos.

 public var w:MaterialsList = new MaterialsList(
    {front: matWater, back: matWater, left: matWater,
     right: matWater,  top: matWater,  bottom: matWater});
 public var g:MaterialsList = new MaterialsList(
    {front: matBase1,  back: matBase1,  left: matBase1,
     right: matBase1,  top: matGrass,  bottom: matBase1});
 public var f:MaterialsList = new MaterialsList(
    {front: matBase1,  back: matBase1,  left: matBase1,
     right: matBase1,  top: matFlower,  bottom: matBase1});
 public var b:MaterialsList = new MaterialsList(
    {front: matBase0,  back: matBase0,  left: matBase0,
     right: matBase0,  top: matBase0,   bottom: matBase0});

Assim nosso Tile ficara formatado da seguinte forma.

 public var arrayTile:Array = [
  [w,w,w,w,w,w,w,w,w,w],
  [w,w,w,g,g,g,g,w,w,w],
  [w,g,g,g,g,g,f,w,w,w],
  [w,f,g,f,g,g,g,g,w,w],
  [w,g,g,g,f,g,g,g,w,w],
  [w,w,g,g,w,g,g,g,w,w],
  [w,w,w,g,g,f,g,g,w,w],
  [w,w,w,g,g,g,g,w,w,w],
  [w,w,f,g,g,f,w,w,w,w],
  [w,w,w,w,w,w,w,w,w,w]];

Tile x Altura

Para não poluir o vetor de tile decidi usar um vetor separado para mostrar o posicionamento do bloco no plano R3.

 public var arrayTileHeight:Array = [
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,2,2,3,0,0,0],
  [0,3,2,0,1,1,2,0,0,0],
  [0,2,1,1,1,1,2,0,0,0],
  [0,0,1,1,1,1,1,0,0,0],
  [0,0,0,1,1,0,0,0,0,0],
  [0,0,0,0,1,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0],
  [0,0,0,0,0,0,0,0,0,0]];

Nós usaremos cada cubo com o tamanho 30x30x30 analogamente para subir um nível os blocos temos que multiplicarmos a posição demonstrada no vetor por 30.

espaco

Com isso acabamos criando espaços vagos.para resolvermos isso criaremos um loop que criará blocos do tipo base da altura 0 ate a altura definida.

Criando Tiles

A diferença dos tiles que vimos em R2 para o R3 é que alteramos a propriedades x e z com os loops ao invés de (x,y) a propriedade y utilizamos para altura.

public function Objetos () {
  for (var i = 0; i < arrayTile.length; i++) {
      for (var j = 0; j <  arrayTile[0].length; j++) {
          //Criando blocos extras na altura
          if (arrayTileHeight[i][j]>0) {
             for (var k=0; k< arrayTileHeight[i][j]; k++){
                var obCubeb:Cube = new Cube(b,30,30,30);
                cena.addChild (obCubeb);
                obCubeb.x = i * 30 -150;
                obCubeb.z = j * 30 -150;
                obCubeb.y = k * 30;
             }
          }
          //Criando bloco Tile
          var obCube:Cube = new Cube(arrayTile[i][j],30,30,30);
          cena.addChild (obCube);
          obCube.x = i * 30 -150;
          obCube.z = j * 30 -150;
          obCube.y = arrayTileHeight[i][j] * 30;
      }
    }
    addEventListener (Event.ENTER_FRAME,Loop,false, 0, true);
 }

Código extra: Movimentando a câmera

Para fazer a movimentação da câmera utilizei a seguinte lógica, criei um objeto do tipo plano no centro de nosso cenário, e travei a câmera nele com o método.

obcamera.lookAt (centro);

Assim independente o posicionamento do x, y e z da câmera, ele sempre terá como foco o centro do mapa. Agora podemos movimentar o x e z da câmera para circular o cenário que ele nunca mudara seu foco.

A cada frame colocaremos as propriedades x e z somarem um valor, valor este que estará armazenado em um vetor. Se sempre somarmos valores nossa câmera sempre se afastará, com as possibilidades definidas em um vetor podemos manipular para ele alem de somar subtrair também para trazer a câmera de voltar.

Código Completo

Arquivo main.as

package {
   //flash
   import flash.display.MovieClip;
   import flash.events.*;
   //Papervision
   import org.papervision3d.objects.primitives.Plane;
   import org.papervision3d.objects.primitives.Cube;
   import org.papervision3d.scenes.Scene3D;
   import org.papervision3d.render.BasicRenderEngine;
   import org.papervision3d.cameras.Camera3D;
   import org.papervision3d.view.Viewport3D;
   import org.papervision3d.materials.MovieAssetMaterial;
   import org.papervision3d.materials.utils.MaterialsList;
   public class main extends MovieClip {
      //papervision
      public var cena:Scene3D;
      public var viewport:Viewport3D;
      public var camera:Camera3D;
      public var renderer:BasicRenderEngine;
      public var centro:Plane;
      //material
      public var matGrass:MovieAssetMaterial = new MovieAssetMaterial("grass");
      public var matBase0:MovieAssetMaterial = new MovieAssetMaterial("base0");
      public var matBase1:MovieAssetMaterial = new MovieAssetMaterial("base1");
      public var matFlower:MovieAssetMaterial = new MovieAssetMaterial("flower");
      public var matWater:MovieAssetMaterial = new MovieAssetMaterial("water", true);
      public var w:MaterialsList = new MaterialsList(
         {front: matWater, back: matWater, left: matWater,
          right: matWater, top: matWater, bottom: matWater});
      public var g:MaterialsList = new MaterialsList(
         {front: matBase1, back: matBase1, left: matBase1,
          right: matBase1, top: matGrass, bottom: matBase1});
      public var f:MaterialsList = new MaterialsList(
         {front: matBase1, back: matBase1, left: matBase1,
          right: matBase1, top: matFlower, bottom: matBase1});
      public var b:MaterialsList = new MaterialsList(
         {front: matBase0, back: matBase0, left: matBase0,
          right: matBase0, top: matBase0, bottom: matBase0});
       //tiles
       public var arrayTile:Array = [
        [w,w,w,w,w,w,w,w,w,w],
        [w,w,w,g,g,g,g,w,w,w],
        [w,g,g,g,g,g,f,w,w,w],
        [w,f,g,f,g,g,g,g,w,w],
        [w,g,g,g,f,g,g,g,w,w],
        [w,w,g,g,w,g,g,g,w,w],
        [w,w,w,g,g,f,g,g,w,w],
        [w,w,w,g,g,g,g,w,w,w],
        [w,w,f,g,g,f,w,w,w,w],
        [w,w,w,w,w,w,w,w,w,w]];
       public var arrayTileHeight:Array = [
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,2,2,3,0,0,0],
        [0,3,2,0,1,1,2,0,0,0],
        [0,2,1,1,1,1,2,0,0,0],
        [0,0,1,1,1,1,1,0,0,0],
        [0,0,0,1,1,0,0,0,0,0],
        [0,0,0,0,1,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0]];
       //Camera
       public var cam:int = 0
       public var a:int = 0;
       public var arrayCam:Array = [[-45,0],[0,-45],[45,-0],[0,45]];
       public function main () {
          Set ();
          Objetos ();
       }
       public function Set ():void {
          viewport = new Viewport3D(400,300,true,false,true,true);
          addChild (viewport);
          cena = new Scene3D ;
          renderer = new BasicRenderEngine ;
          camera = new Camera3D ;
          camera.focus = 100;
          camera.zoom = 10;
          camera.x = 650;
          camera.z = 450;
          camera.y = 700;
          centro = new Plane();
          centro.y = 0;
          centro.z = 0;
          centro.x = 0;
      }
      public function Objetos ():void {
          for (var i = 0; i < arrayTile.length; i++) {
             for (var j = 0; j <  arrayTile[0].length; j++) {
                //Criando blocos extras na altura
                if (arrayTileHeight[i][j]>0) {
                    for (var k=0; k< arrayTileHeight[i][j]; k++){
                       var obCubeb:Cube = new Cube(b,30,30,30);
                       cena.addChild (obCubeb);
                       obCubeb.x = i * 30 -150;
                       obCubeb.z = j * 30 -150;
                       obCubeb.y = k * 30;
                    }
                }
                //Criando bloco Tile
                var obCube:Cube = new Cube(arrayTile[i][j],30,30,30);
                cena.addChild (obCube);
                obCube.x = i * 30 -150;
                obCube.z = j * 30 -150;
                obCube.y = arrayTileHeight[i][j] * 30;
             }
          }
          addEventListener (Event.ENTER_FRAME,Loop,false, 0, true);
      }
      public function Loop (e:Event):void {
          a++ ;
          rotaionCamera (camera,arrayCam[cam][0],arrayCam[cam][1])
          if (a % 30 == 0){
             nextCamera()
          }
          renderer.renderScene (cena,camera,viewport);
      }
      public function nextCamera():void{
          cam= cam+1
          if (cam>=4){
             cam = 0
          }else if (cam<=-1){
             cam = 3
          }
      }
      public function rotaionCamera (obcamera:Camera3D,newx,newz):void {
          obcamera.x+= newx;
          obcamera.z+= newz;
          obcamera.lookAt (centro);
      }
   }
}

Obs: Lembrando que estamos fazendo um aplicativo utilizando as classes do papervision, não podemos esquecer-nos de importalas.