2008年8月アーカイブ
前回に続いて過去のAS2クラスをAS3に書き換えた。
整数を投げたらそれを配列にしてシャッフルして返すクラス。
理解が浅く、なぜextends MovieClipしないといけないのか分からない...。デバッガに怒られまくりながら、こんな感じになりました。有識者にご指摘頂ける日を待ち望みつつとりあえず晒しとく。
package com.nrd_studio
{
import flash.display.MovieClip;
public class OpArray extends MovieClip
{
private static var _max:uint;
private static var _a:Array = [];
public static function shuffle(n:uint)
{
_max = n;
_a = makeArray();
return xShuffleArray(_a);
}
private static function makeArray():Array
{
for( var i:uint = 0; i < _max; i++)
{
_a.push( i + 1);
}
return _a;
}
private static function xShuffleArray(arr:Array):Array
{
var i:uint = arr.length;
while(i--)
{
var j:uint = Math.floor(Math.random() * (i + 1));
var t:uint = arr[i];
arr[i] = arr[j];
arr[j] = t;
}
_a = [];
return arr;
}
}
}
オブジェクトをnew、とかしたりしなくてもサクっと結果が返せるので楽チンかと。
var a:Array = OpArray.shuffle(20); trace(a); //出力:3,16,14,19,5,8,2,7,6,20,9,15,10,4,18,11,17,12,1,13
AS2版をむかーし晒したんですがそれをAS3に作り替えた。
ただ単純にタイムラインを止めておいて、設定した秒数後にまた走らせるだけのクラス。世間ではいろんな高機能クラスライブラリを公開している方々が群雄割拠する中、どうなんだろう、これ。
でも気にしない。
package com.nrd_studio
{
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.events.MouseEvent;
import flash.display.MovieClip;
import flash.display.SimpleButton;
public class Staytime extends MovieClip
{
private static var _target:MovieClip;
private static var _counter:Number;
private static var timer:Timer = new Timer(0);
public static function wait(target:MovieClip, counter:Number):void
{
_target = target;
_counter = counter*1000;
_target.stop();
timer.delay = _counter;
timer.start();
timer.addEventListener(TimerEvent.TIMER, timerHandler);
}
static function timerHandler(e:TimerEvent):void
{
timer.reset();
_target.play();
}
public static function cancel():void
{
timer.stop();
timer.reset();
_target.play();
}
}
}
止めたいフレームで
Staytime.wait([止めたい対象],[止めたい秒数]); //example Staytime.wait(this,3);
強制的に停止を解除してタイムラインを走らせたい場合は別途ボタンとか使ってcancel()メソッドを呼び出す。
btn.addEventListener(MouseEvent.CLICK, clicked);
function clicked(e:MouseEvent):void
{
Staytime.cancel();
}
とりあえずテクスチャの貼り付けまでやってしまう。とりあえずリファレンスを軸にいろんな先人達のブログを参考にしつつ...。
気になってたViewport3Dのパラメータ、autoClippingとautoCullingについてはどうやら初期値のまま触ることは無さそうなので忘れてよさそう。
viewport = new Viewport3D(0, //viewportWidth 0, //viewportHeight true, //autoScaleToStage:Boolean false, //interactive:Boolean );
テクスチャの貼り付けは、別途用意したjpg画像をFlash上でライブラリに読み込んでおいてリンケージしてそれをBitmapAssetMaterialで読み込んで単純にSphereコンストラクタの第1パラメータとした。単純に外部データを読み込む場合はBitmapFileMaterialを利用するらしいが、これは問題があるっぽい。画像のロードが完了する前にプリミティブの描画が始まっちゃうと、テクスチャ無視されて表示されなくなる場合があるとかないとか。重い画像データを読み込んだりする場合は、ロードの完了タイミングを計測してからプリミティブの描画、といった順序が必要になるらしい。
//texture
var material:BitmapAssetMaterial = new BitmapAssetMaterial("earthMap");
//material
earthBase = new Sphere(material, //material:MaterialObject3D
240, //radius
40, //segmentsW:int
40 //segmentsH:int
);
まぁそんなこんなでとりあえず地球。あとはシリンダーの中にすっぽり入れてしまって、シリンダーの中身に宇宙テクスチャを貼り付ければとりあえず完成なんだろうか。その前に、何やらGreatWhiteではBasicViewなるクラスがあってこれが便利らしいので、その辺りの調査が先かなぁ。まぁ仕事の合間なので歩みは遅いがちょびちょびと。
Viewportのパラメータ、viewportWidthとviewportHeightの概念がよく分からない。数値を色々変えてコンパイルしてみるも、表示結果に変化がない。調査巡回してもとりあえず0,0にしてる人が多いみたいなので、ここはひとつ盲目的に0,0で進めるか。いずれ分かる日が来るんかな。
//viewport viewport = new Viewport3D(0, //viewportWidth 0, //viewportHeight true, //autoScaleToStage:Boolean false, //interactive:Boolean true, //autoClipping:Boolean true //autoCulling:Boolean );
あとcameraのzoomメソッドとfocusメソッド。無設定でコンパイルした時と、zoom = 40でコンパイルした時とで球体の表示サイズが同じなので、cameraの標準倍率は40ってことかいな?
さらにfocusメソッドが絡むとまた変な感じ。単純にzoom * focus的なサイズで表示されるけど、合焦値的なパラメータではないのか。
その辺りの検証をnote.xさんがやってた。でもやっぱfocusの概念がよくわからない。← そういえば、とOOPas3.0読み直して理解した。視野角な。(P250)じゃzoomが変なのか。単焦点なのにズームできる、みたいな。そりゃピクセル等倍どうすんの、て話になるよなw
それにしても「SyntaxHighlighter」の挙動にイライラ。なんで個別アーカイブになると反映されないのかなぁ。
とグダグダ言いつつ、最終目標に関係ないが球体の回転をマウスに反応させてみた。
protected function onRenderTick(e:Event):void
{
var xDist:Number = mouseX - stage.stageWidth * 0.5;
var yDist:Number = mouseY - stage.stageHeight * 0.5;
earthBase.rotationX += yDist * 0.02;
earthBase.rotationY += xDist * 0.02;
renderer.renderScene(scene, camera, viewport);
}
SyntaxHighlighter
適用テスト
まったく意味がわからん...。indexブラウズ時は適用されるのに、個別記事ブラウズだと適用されない...。
どうやら、ブログのテンプレを設定した場合に
タグに挿入される"onload"が原因くさい。SyntaxHighlighterの"onload"とコンフリクトとか??ピーク前にからくもAdobe CS3の Production Premiumを手に入れ、今更ながらFlashやらAfter Effectsにも本腰を入れられる環境が整った。
今までFlexSDKやらでAS3の勉強はしてたけど、やっとFlashのIDEでまともに作業できるようになってホッとした。Flash Developとか使いたいけどOSはまだ10.4.*なのでガマンガマン。AEも含めて試したいこと・試すべきこと山ほどある中、よせばいいのにPapervision3Dに手を出した。
うーん、背景黒にしたのに黒にならないわ(情けない話、wmodeをそう設定してただけでした)、読み込むたびにメッシュラインのカラーが違うわ、分からんことが多いけど、とりあえず宇宙空間に浮かんで自転する地球を表現できるまでやってみる。
そんなこんなでついでに「SyntaxHighlighter」も試してみようということで、駄コードを晒してみる。
package
{
import flash.display.Sprite;
import flash.events.Event;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.view.Viewport3D;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.objects.primitives.Sphere;
public class Main extends Sprite
{
private var viewport:Viewport3D;
private var scene:Scene3D;
private var camera:Camera3D;
private var renderer:BasicRenderEngine;
private var earthBase:Sphere;
public function Main():void
{
init();
}
public function init():void
{
//viewport
viewport = new Viewport3D(470, //viewportWidth
350, //viewportHeight
false, //autoScaleToStage:Boolean
false, //interactive:Boolean
true, //autoClipping:Boolean
true //autoCulling:Boolean
);
addChild(viewport);
//render
renderer = new BasicRenderEngine();
//camera
camera = new Camera3D();
//scene
scene = new Scene3D();
//material
earthBase = new Sphere(null,
240,
20,
20);
scene.addChild(earthBase);
addEventListener(Event.ENTER_FRAME, onRenderTick);
}
protected function onRenderTick(e:Event):void
{
earthBase.rotationX += 2;
earthBase.rotationY += 1.5;
earthBase.rotationZ += 1;
renderer.renderScene(scene, camera, viewport);
}
}
}
なぜだ。「SyntaxHighlighter」が効いてないみたい... orz
