[AS]テキストフィールドにマウスホイールを利かなくする。

SwfWheelを使って、スクロールバーを作ってて気づいたこと。

ざくっとこんなとき、
スクロール対象がムービークリップ(MC)でそのMcにテキストフィルールド(TF)を配置。
そのTFにテキスト流し込んで文字量によってMCの高さが変わる。
つまりTFの文字量で、スクロールする量が決まる、そんな感じ。

TFは折り返しにしないといけないで、wordrapをtrueに設定。
すると、TF単体でマウスホイールに反応してしまい、1行だけずれるみたいな事態に。
前にも似たようなことがおきて、そのときは、テキストのheightがずれるとかそんな記事をどこかで読んで対応した記憶があるのだけど、その記事が発見できず・・・
そしたらもっと簡単に対応できる方法がありました。
この1行でOKでした。

TextField.mouseWheelEnabled = false;

※5/1追記
やっぱりマウスホイールだけじゃずれの解消ではないっぽい。
テキスト選択可能にしてドラッグすると1行だけずれるから。
(選択不可にすればOKなのだけど)
ぐぐり直して、根本的に解決できる方法の書かれたブログ再発見しました。

nondelion.com:TextField に leading + autoSize を設定すると…

ってか↑にはしっかりどちらの場合もちゃんと書いてありましたね。。。

[AS]DisplayObjectContainer.mouseXとMouseEvent.stageXの違い。

似たような感じだけども、
DisplayObjectContainer.mouseXは、基準となるDisplayObjectContainerからの相対的な座標を返す。
MouseEvent.stageXはつねにステージ座標を返す。
MouseEvent.stageXはグローバル的な座標を取得したいときに使う感じかな。
メインのタイムラインとかドキュメントクラスで(this.)mouseXならstageXと同じ値を返すからどっち使っても一緒っぽい。

//フレームアクション
var sp:Sprite = new Sprite();
sp.graphics.beginFill(0xFF0000);
sp.graphics.drawRect(0,0,100,100);
sp.graphics.endFill();
sp.x = 200;
sp.y =200;
addChild(sp);


stage.addEventListener(MouseEvent.MOUSE_MOVE , xMouseMove);

function xMouseMove (e:MouseEvent):void {
	trace("e.stageX : "+e.stageX , "this.mouseX : "+ this.mouseX, "sp.mouseX : "+ sp.mouseX);
}

[AS]papervision3d Basicviewについて

BasicViewクラスの中身をなんとなくメモ
(親クラスのAbstractViewも少しだけ)

まず、BasicViewが継承してるのは、AbstractView。
(AbstractViewはSpriteを継承してる)

BasicViewのコンストラクタの引数で初期値を渡す。
ちなみに何も入れなくてもデフォルト値が設定されてるのでOK。

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

BasicViewのコンストラクタの中では、scene,viewport,renderを作っている。

scene = new Scene3D();
viewport = new Viewport3D(viewportWidth, viewportHeight, scaleToStage, interactive);
addChild(viewport);
renderer = new BasicRenderEngine();

cameraTypeによって、どんなカメラを使うか決めてる。
(引数設定しないときはcamera3Dになる)
_cameraは、AbstractViewで定義されている。

			switch(cameraType)
			{
				case CameraType.DEBUG:
					_camera = new DebugCamera3D(viewport);
					break;
				case CameraType.TARGET:
					_camera = new Camera3D(60);
					_camera.target = DisplayObject3D.ZERO;
					break;
				case CameraType.SPRING:
					_camera = new SpringCamera3D();
					_camera.target = DisplayObject3D.ZERO;		
					break;			
				case CameraType.FREE:
				default:
					_camera = new Camera3D(60);
					break;
			}

コンストラクタの最後では、viewportのサイズでcameraの初期化してるってことかな?

cameraAsCamera3D.update(viewport.sizeRectangle);

[AS]定義されてないと思われる変数があるときは、親クラスを追ってみる。

PV3Dのクラスを読んでたらよくわからない書き方があったので、テストしてみた。

たとえばこんなドキュメントクラスがあった場合に、

package  {
	import flash.display.Sprite;
	
	/**
	 * ...
	 * @author 393
	 */
	public class Test extends Test2 {
		
		public function Test() {
			trace(spriteObj.getRect(this)) //出力(x=0, y=0, w=100, h=100)
		}
        public function get spriteObj():Sprite{
                return sp;
        }
	}
	
}

このコンストラクタでは、spriteObjというものに対して、getRectメソッドを実行させている。
だけども、どこにも var spriteObj という記述は無い。
でも下を見ると、getterでspriteObj というものが定義されている。
これで、spriteObj というものは使えることができるということらしい。

で、getterの中をみると、spを返すことになっている。
これまた、var spという記述はどこにもない。
じゃあ、どこを探すかといえば、Testクラスが継承している、Test2クラスを探してみる。

Test2クラスはこんな感じ。

package  {
	import flash.display.Sprite;
	
	/**
	 * ...
	 * @author 393
	 */
	public class Test2 extends Sprite {
		
		protected var sp:Sprite;
		
		public function Test2() {
			sp = new Sprite();
			sp.graphics.drawRect(0,0,100,100)
		}
		
	}
	
}

ここでspが定義されてるのがわかる。
さらに、protectedで定義されているので、Testクラスからでもアクセスできることがわかる。
(privateだとアクセスできないね)
で、spはSpriteクラスなので、getRect()メソッドが使えるとういわけだ。

ポイントはgetterの場合は、var spriteObj で定義してなくてもOKってことかしら。

[AS]アクセス修飾子の違いについて

なんかすぐ忘れるのでメモ。

◆private:
自身のクラスからのみアクセスできる。

◆public
どこからでもアクセスできる。
(コンストラクタはこれにしないとだめ)

ここまでは忘れない・・・
↓の二つは滅多に使わないから忘れる。。。

◆internal
同一パッケージからのみアクセスできる。
(何も書かないとこれになる)

◆protected
自身のクラスとそのクラスを継承したクラス(サブクラス)のみアクセスできる。

アクセスの厳しさ順だと、
private > protected > internal > public といったところかな。

[FD]日本語が文字化けするとき

なんかよくわからんけど、日本語文字化けしてるぞってときは、
tool→setting→MISC(その他)のFallback CodePageをUTF8に設定で直るとのこと。

↓詳細はこちら
参考サイト:タロタローグ ブログ

[AS][PHP]GMT(正確にはUTC)タイムを取得する方法

ローカルの時間(PCに設定されてる時計による)ではなく、正確な時間を取得したい場合。
ただFLASH単体では、UTC(GMTみたいなもの)の取得はできないようす。
なのでサーバーサイドのプログラムPHPを使ったら意外と簡単にできました。

↓PHPはこれだけ

<?php
//GMTを取得
$time09 = gmdate("D M d Y H:i:s", time()+9*60*60);
//ASでは、utc_timeというプロパティで扱える
echo "utc_time=".$time09
?>

FLASH側はこんな感じで、読み込みます。
以下、フレームアクション

//フレームアクション
//PHPファイルのURLを定義
var request:URLRequest = new URLRequest ( "get_utc.php" );
//送信方法をPOSTに
request.method = URLRequestMethod.POST;

//ローダーを作って、PHPを読み込み(実行)
var loader:URLLoader = new URLLoader (request);
loader.addEventListener(Event.COMPLETE, onComplete);
loader.load(request);

//PHP読み込み(実行)後の処理
function onComplete(event:Event):void {
	//↓PHPからの戻り値を変数に格納
	var vars:URLVariables = new URLVariables( event.target.data );
	//UTCデータを格納するための変数
	var utc:String;
	//データがちゃんとあった場合は、
	if (vars.utc_time!= undefined) {
		//変数に、文字列を渡す
		utc = vars.utc_time;
		next(utc);
		//ムービープレビューのときはローカルタイムを取得
	} else {
		var date:Date = new Date();
		utc = date.toString();
		next(utc);
		tf.text = "↓ローカルタイムです";
	}
}
//PHPから読み込んだ文字列を引数にしてDateインスタンスを作成で完了
function next(utc) {
	var date:Date = new Date(utc);
	tf2.text = String(date);
}

//結果表示用のテキストフィールド(2つ用意)
var tf:TextField = new TextField();
tf.autoSize ="left";
addChild(tf);
var tf2:TextField = new TextField();
tf2.autoSize ="left";
addChild(tf2);
tf2.y = 30;

ポイントはPHPから取得した文字列をそのままDateクラスのコンストラクタの引数に突っ込めば、その情報を持ったDateインスタンスが作れるところですかね。
(逆に言うと、PHPで取得する文字列は、Dateクラスで認識できる形にしてあげる必要があるってことかね)

ただこの場合の「UTCタイム」はサーバーの時計ってことになるのかな?
ってことは、サーバーの時計が狂ったらアウトってことなんだろうね。

[AS]AS3/CS3にて、”フォントの埋め込み”をスクリプトで埋め込んであるはずなのに表示されない

かなりはまりました。
が、現象の再現性が完全につかめてないので、なんとなく状況をメモ。
(いまのところ発生原因がわからない)

通常スクリプトでテキストフィールド作って、フォントを埋め込む際は、まずはこんなコード。

package  {
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.text.TextField
	import flash.text.TextFormat;
	
	public class aaaa extends Sprite {
		
		public function aaaa() {
			
			var textformat:TextFormat = new TextFormat();
			textformat.font="Verdana";
			textformat.size="100";
			var tf:TextField = new TextField();
			tf,mouseEnabled = false;
			tf.defaultTextFormat=textformat;
			tf.autoSize= "left";
			tf.htmlText="BACK";
			tf.embedFonts=true;
			addChild(tf);
			tf.alpha = 1;
		}
	}
}

ただこれだけではフォントは表示されない。
flaファイルのライブラリにフォントを追加して、それにリンケージ設定が必要。
(ライブラリの右上のメニューボタンから新しいフォント…(上記例ではVerdana)を追加する。)
その際の、クラス名はなんでもよし。

通常これでVerdanaフォントの”BACK”という文字が表示されます。
が、しかし、この手順でもフォントが表示されない場合がありました。
(テキストがまったく表示されない、埋め込みやめると表示される)

原因がつかめず、かなーり悩んみました。。。
どうも、ステージ上にフォント埋め込んだテキストフィールドが置かれている場合に挙動がおかしくなる模様。

たとえば~
ステージには別途テキストフィールドを配置して、
それにはVerdanaを”小文字”だけ埋め込み。(ボールド、イタリックは未チェック)
そして上記のスクリプトでVerdana設定したテキストを読み込み、
ライブラリのフォントをリンケージ設定して、プロパティでイタリックを設定してプレビューすると・・・
スクリプトで追加してるはずの”BACK”が表示されません。
※ここで表示されるときもあったりしました。(ただしイタリックにはなってない)

次にステージのテキストフィールドの埋め込み文字設定を大文字を選択すると。。。
BACKが表示されましたが、イタリックにはなっておらず。。。
さらにステージのテキストフィールドのプロパティのイタリックボタンをチェックすると。。。
やっとイタリックの”BACK”が表示されました。

一見関係性のなさそうに見える、ステージ上で設定した埋め込み設定と、ライブラリ内に追加したフォントの設定が干渉してるみたい。

自分で1から作ったものなら、ステージに何おいてるかって把握してるのだけど、
人が作ったものを追加修正のときとかで、
ステージにたくさん物が置いてあって、
さらにどれが生きてるのかも完全把握できない。。。
なんて状態だと、とても危険です。
どこかにフォントの埋め込まれたテキストフィールドが潜んでいると・・・
上記のような現象が起きても不思議ではありません。。。

まぁわたしは実際体験したのですが。。。

ちなみにそのときの解決策としては、ステージ外に空のテキストフィールドを置いて、そこにスクリプトで埋め込もうとしてるフォントを埋め込みました。(文字の種類は、スクリプトで設定しようとしてる文字の設定に)
そしたら表示されるようになりました。

同じような現象に悩まれてる方の救いになれば幸いです。

[AS]XMLで要素数が何個あるかわからないデータを取得する時の方法 (for each ( in )の使い方) 

フレームアクションでこんな感じ。

var xml:XML = 
<sampleXML>
<test>まるいち</test>
<test>まるに</test>
<test>まるさん</test>
<test>まるよん</test>
<test>まるご</test>
</sampleXML>;

trace(xml);

var xmlArray:Array = new Array();

var sampleXMLList:XMLList = xml.test;

//配列にtest要素を突っ込む
for (var i:uint = 0; i< sampleXMLList.length(); i++) {
	xmlArray.push(xml.test[i]);
}
//配列の中身を確認
for (i = 0; i < xmlArray.length; i++) {
	trace("xmlArray その1 : "+xmlArray[i]);
}

//配列を空にする。
xmlArray = [];

//配列にtest要素を突っ込む
for each (var container:Object in xml.test) {
	xmlArray.push(container);
}
//配列の中身を確認
for (i = 0; i < xmlArray.length; i++) {
	trace("xmlArray その2 : "+xmlArray[i]);
}

プレビュー時の出力はこんな感じ

まるいち
まるに
まるさん
まるよん
まるご

xmlArray その1 : まるいち
xmlArray その1 : まるに
xmlArray その1 : まるさん
xmlArray その1 : まるよん
xmlArray その1 : まるご
xmlArray その2 : まるいち
xmlArray その2 : まるに
xmlArray その2 : まるさん
xmlArray その2 : まるよん
xmlArray その2 : まるご

注意するのは
Arrayの中身を数えるのは、Array.length
XMLListの中身を数えるのは、XMLList.length();
微妙に違うところ。

あとfor each (in)分を使えば、データの数がわからなくとも、データがあるだけループさせられる。

[AS]読み込んだXMLの内容を改行したときに余分な改行があった場合

読み込んだXMLをTextFieldに表示させるときに、
XML側では、こんな感じで書くとその中の改行がそのまま表示できる。

<?xml version="1.0" encoding="UTF-8"?>
<sample>
<description>
<![CDATA[あかさなた
はまやらわ]]>
</description>
</sample>

ただその際に改行コードの問題で、一回しか改行してないつもりでも2行で改行されてしまうときがある。

↓こうでてほしいのに
あかさなた
はまやらわ

↓こうなる
あかさなた

はまやらわ

Windowsの改行コードの問題なので、
xmlから読み込んだストリングの改行コードを変換してあげればOK

//xmlから読み込んだストリングの
var strictDescription:String = xml.description[0];
//改行コードを\nに統一する。
strictDescription = strictDescription.replace(/\r\n/g, '\n');