// forked from sake's PV3Dその3 /* Vectorvision3DがPV3Dに統合されたらしいと。 ただ、Word3D → text3Dと、VectorShapeMaterial → Letter3DMaterial となってる。 ここ以外はたぶん同じ。 */ /* 初心者の自分なりに少しずつ理解して期待と思います。 現段階ではまったくのいみぷーだけど(笑) がんばって理解しなきゃーひぃ あれ?? containerいらないのかな?? なくても動作するようなので消しちゃいました。 BasicView投入! DisplayObject3D( "rootNode" )がよくわからない。rootNodeってなんなんですか?? わからないんで、自分がよく使うやりかたに直してみました。 WordMoveTypeのデータ型をBooleanに変更して、シンプルにしました。 ぼかしの適応具合を導くために被写界深度なるものを使うんだけど、 公式がさっぱり・・・わからん。 工業高校出身にはつらいとこ・・・ってことで断念することに・・・ 追記。 上野被写界深度があっさり解決しました! KYUCON*BLOGさんのhttp://www.kyucon.com/blog/2009/06/papervision3d-20-8.htmlを参考に。 カメラとオブジェクトの距離を調べる命令がありました。これでもっと簡単に。 でも、これでコードは解読しました!!! */ package { import net.hires.debug.Stats;//メモリ使用量表示用 左上のやつ import caurina.transitions.Tweener; import flash.display.Sprite; import flash.events.Event; import flash.filters.BlurFilter; import flash.utils.setInterval; import org.papervision3d.view.BasicView; import org.papervision3d.materials.special.Letter3DMaterial; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.typography.Text3D; import org.papervision3d.typography.fonts.*; import org.papervision3d.view.layer.*; [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="40")] public class PV3D_sample03 extends BasicView { private var rootNode:DisplayObject3D;//Text3Dをまとめて入れるやつ private var words1:Text3D; //文字列1 private var words2:Text3D; //文字列2 private var words3:Text3D; //文字列3 private var theta:Number; //角度 カメラを移動させるために使う private var delayTime:Number; //文字を1文字ずつ遅らせるために使う private var WordMoveType:Boolean; //文字が中央に整列しているのか、ばらばらに散らばっているのか private const zoom:Number=20; private const focus:Number=30; private const distance:Number=600; //カメラを回転させる円の半径 //constって定数なんだね。初めて知った。 //後から別の値を入れるとエラーになるらしい。 public function PV3D_sample03() { addChild(new Stats());//メモリ使用量表示用 左上のやつ theta=0; //角度初期値 WordMoveType=false; //中央に集まっている(true) 散らばっている(false) delayTime=0; set3D();//3D設定 var mat:Letter3DMaterial=new Letter3DMaterial(0x0000FF);//Letter3DMaterial(文字色,透明度) mat.doubleSided = true;//裏も表示させる words1 = new Text3D("Sample of Papervision3D", new HelveticaBold(), mat); words2 = new Text3D("Welcome to PV3D !!!!!!", new HelveticaBold(), mat); words3 = new Text3D("YEAAAAAA!!!!HOOOOOOOOO!!!", new HelveticaBold(), mat); //Text3D("文字列",フォント,マテリアル); //使えるフォント HelveticaBold HelveticaLight HelveticaMedium HelveticaRoman //文字列は配列に入れられる。 rootNode = new DisplayObject3D; scene.addChild(rootNode); rootNode.addChild(words1); rootNode.addChild(words2); rootNode.addChild(words3); words1.y=50; words2.y=0; words3.y=-50; words1.scale = words2.scale = words3.scale = 0.4; dispersionWords(words1); dispersionWords(words2); dispersionWords(words3); //Flashをロードした瞬間に始まるトゥイーン 読み込んだ1度だけ実行する //中心から広がるように出現するくだり setInterval(moveWords, 10000);//10000msごとに実行 addEventListener(Event.ENTER_FRAME, onFrame); startRendering();//レンダリング開始 } private function set3D():void{ addChild(viewport); camera.target=DisplayObject3D.ZERO; camera.zoom=zoom; camera.focus=focus; } private function dispersionWords(words:Text3D):void { for each(var word:DisplayObject3D in words.letters)//words.letters 文字列が入った配列 //for each文の説明はこっちがわかりやすい http://blog.initt.org/?p=21 { word.extra = { x:word.x, y:word.y, z:word.z }; //extra ユーザーの任意のパラメタを設定できる部分 自由に名前を決められる。 word.x = word.y = word.z = word.scale = 0; Tweener.addTween(word, { scale:1,//もとの大きさに戻す x:Math.random() * 2000 - 1000, y:Math.random() * 2000 - 1000, z:Math.random() * 2000 - 1000, //ランダムな位置に配置。2000とか1000は自由に変更OK rotationX:Math.random() * 360, rotationY:Math.random() * 360, rotationZ:Math.random() * 360, //ランダムに回転させる 360は260度から time:3,//3sでトゥイーンさせる delay:2 * Math.random() + 1//delay 待ち時間 ここの値s後にトゥーンを実行する }); } } private function moveWords():void { if (!WordMoveType) { //文字列を中央に配置する resetWords(words1); resetWords(words2); resetWords(words3); delayTime=0;//delayの時間をリセット WordMoveType = true; } else { //文字列を散らばせる breakWords(words1); breakWords(words2); breakWords(words3); WordMoveType = false; } } private function resetWords(words:Text3D):void //文字列を中央に配置する { for each(var word:DisplayObject3D in words.letters) { Tweener.addTween(word, { x:word.extra.x, y:word.extra.y, z:word.extra.z, //extraに記憶していた初期値をセットする rotationX:0, rotationY:0, rotationZ:0, time:1, transition:"easeOutBounce", delay:delayTime }); Tweener.addTween(word, { rotationY:720, time:1, delay:delayTime + 2//2秒後に実行 }); //文字を回転させるトゥイーン delayTime += 0.1; //1文字ずつ移動を遅らせる。 } } private function breakWords(words:Text3D):void //文字列を散らばせる { for each(var word:DisplayObject3D in words.letters) //最初に1度だけ実行するdispersionWordsににているけど、scaleはいじらない。 { Tweener.addTween(word, { x:Math.random() * 2000 - 1000, y:Math.random() * 2000 - 1000, z:Math.random() * 2000 - 1000, rotationX:Math.random() * 360, rotationY:Math.random() * 360, rotationZ:Math.random() * 360, time:4, delay:3 * Math.random() }); } } private function onFrame(e:Event):void { camera.x = distance * Math.sin(theta * Math.PI / 180); camera.z = distance * Math.cos(theta * Math.PI / 180); theta+=0.2;//0.2を大きくしたら移動する速度が速くなる //カメラを円状に移動させる setBlur(words1); setBlur(words2); setBlur(words3); //BlurFilterを適応させる } private function setBlur(words:Text3D):void //BlurFilterを適応させる { for each(var word:DisplayObject3D in words.letters){ var vpl:ViewportLayer = word.createViewportLayer(viewport, true); //ViewportLayer viwportの前面にフィルターやエフェクトなどを適用するための新たなレイヤーをつくる var d_Child:Number = Math.abs(camera.distanceTo(word) - distance); //camera.distanceTo(調べたいオブジェクト) //カメラとオブジェクトまでの距離 var d:uint = Math.min(30, d_Child * 0.015); //距離に応じてぼかし量を調節 vpl.filters = [new BlurFilter(d, d, 1)]; //BlurFilter(blurX:水平方向のぼかし量,blurY:垂直方向のぼかし量,ぼかしの実行回数) } } } } PV3DでText3Dを使って。初心者なりに解剖してみやす。