イナヅマTVログ

2010.11.25
22:54
author: taikiken
2件のコメント

ActionScript 3, Event処理を簡単に – Signals, カスタムイベント その1

Signalsの4回目。
Custom Event(カスタムイベント)はどう使う、1回目。

Custom Event(カスタムイベント)の時は org.osflash.signals.Signal を使うみたい。
どうも使い方がまだ良くわからない。

Radio ボタンで選ばれた方向へステージのボールが3px動く。

import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.events.Event;
 
import com.bit101.components.RadioButton;
import com.bit101.components.PushButton;
 
import org.osflash.signals.Signal;
 
// minimalcomp radio buttons
function setupRadioButton ():void {
	var radioContainer:Sprite = new Sprite();
	addChild(radioContainer);
 
	var left:RadioButton = new RadioButton(radioContainer, 0, 30, "Left", true, onRadioSelect);
	var right:RadioButton = new RadioButton(radioContainer, 120, 30, "Right", false, onRadioSelect);
	var up:RadioButton = new RadioButton(radioContainer, 60, 0, "Up", false, onRadioSelect);
	var down:RadioButton = new RadioButton(radioContainer, 60, 60, "Down", false, onRadioSelect);
 
	left.groupName = "direction";
	right.groupName = "direction";
	up.groupName = "direction";
	down.groupName = "direction";
 
	var button:PushButton = new PushButton(radioContainer, 42, 25, "MOVE", onButtonClick);
	button.width = 60;
}
// event variables
var event:String = 'left';
var events:Object = {};
 
// radio select callback
function onRadioSelect (e:MouseEvent):void {
	event = e.target.label.toLowerCase();
}
 
// button callback
function onButtonClick (e:MouseEvent):void {
	if (event && events[event]) events[event].dispatch(new Event(event));
}
// ------------------------------------------
// Custom Events
function setupEvents ():void {
	events.left = new Signal();
	events.right = new Signal();
	events.up = new Signal();
	events.down = new Signal();
}
// ------------------------------------------
// Ball
var ball:Sprite;
function setupBall ():void {
	ball = new Sprite();
	ball.graphics.clear();
	ball.graphics.beginFill(0xff6633);
	ball.graphics.drawCircle(-10, -10, 20);
	ball.graphics.endFill();
 
	ball.x = stage.stageWidth * .5;
	ball.y = stage.stageHeight * .5;
 
	addChild(ball);
 
	for (var signalName:String in events){
		events[signalName].add(onMove);
	}
}
 
function onMove (e:Event):void {
	switch (e.type) {
		case 'up' :
			ball.y -= 3;
			break;
		case 'down' :
			ball.y += 3;
			break;
		case 'left' :
			ball.x -= 3;
			break;
		case 'right' :
			ball.x += 3;
			break;
	}
}
 
// ------------------------------------------
// MAIN
function main ():void {
	// background
	var container:Sprite = new Sprite();
	container.graphics.clear();
	container.graphics.beginFill(0xefefef);
	container.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
	container.graphics.endFill();
 
	addChild(container);
 
	setupRadioButton();
	setupEvents();
	setupBall();
}
 
main();

Signal と dispatch の時の引数はどうする?

そもそも今回は、mimalcompsのコールバックから直接操作する方がコードが少なくて済む。
わざわざ Signals を使うメリットはどこにあるのか?

悩みはつきない。

2010.11.08
11:11
author: taikiken
1件のコメント

ActionScript 3, Event処理を簡単に – Signals, dispatchとremoveAll

Signalsの3回目。
イベントを削除するためのメソッドとして NativeSignal には remove, removeAll が用意されています。

remove(listener:Function):Function
Unsubscribes a listener from the signal.

removeAll():void

前回のコードをちょい変更。

import org.osflash.signals.natives.NativeSignal;
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import flashx.textLayout.formats.TextAlign;
import flash.display.DisplayObject;
 
function createBox ():Sprite {
	var sp:Sprite = new Sprite();
	var shape:Shape = new Shape();
	shape.graphics.clear();
	shape.graphics.beginFill(0x6699CC, .6);
	shape.graphics.drawRoundRect(-20, -20, 40, 40, 8);
	shape.graphics.endFill();
	sp.addChild(shape);
	return sp;
}
 
var cancels:Array = [];
function onClicked(e:MouseEvent):void {
	var box:Sprite = createBox();
	box.x = mouseX;
	box.y = mouseY;
	addChild(box);
	// bind event
	var exit:NativeSignal = new NativeSignal(box, Event.EXIT_FRAME, Event);
	exit.add(onExit);
	var cancel:NativeSignal = new NativeSignal(box, Event.CANCEL, Event);
	cancel.addOnce(willCancel);
	// pool
	cancels.push({cancel:cancel, exit:exit});// Object型へ
}
// loop
function onExit (e:Event):void {
	e.target.rotation += 6;
}
// cancel event handler of box
function willCancel (e:Event):void {
	removeChild(e.target as DisplayObject)
}
// cancel event handler of button
function onCancel (e:Event):void {
	while (cancels.length > 0) {
		// Object型変更に伴い変更
		var targets:Object = cancels.shift();
		targets.cancel.dispatch(new Event(Event.CANCEL));
		targets.exit.removeAll();// ここでremove
	}
}
// MAIN
function main ():void {
	// background
	var container:Sprite = new Sprite();
	container.graphics.clear();
	container.graphics.beginFill(0xefefef);
	container.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
	container.graphics.endFill();
 
	addChild(container);
 
	// stop button
	var button:Sprite = new Sprite();
	button.graphics.clear();
	button.graphics.beginFill(0x339933);
	button.graphics.drawRoundRect(0, 0, 100, 40, 8);
	button.graphics.endFill();
 
	button.mouseEnabled = true;
	button.buttonMode = true;
	button.mouseChildren = false;
 
	button.x = stage.stageWidth - button.width - 10;
	button.y = stage.stageHeight - button.height - 10;
	// button label
	var tf:TextField = new TextField();
	var format:TextFormat = new TextFormat("Helvetica", 14, 0xffffff, "bold");
	format.align = TextAlign.CENTER;
	tf.defaultTextFormat = format;
	tf.width = 20;
	tf.height = 20;
	tf.autoSize = TextFieldAutoSize.LEFT;
	tf.text = "STOP";
	tf.x = (button.width - tf.width) * .5;
	tf.y = (button.height - tf.height) * .5;
 
	addChild(button);
	button.addChild(tf);
	//  bind event
	var cancel:NativeSignal = new NativeSignal(button, MouseEvent.CLICK, MouseEvent);
	cancel.add(onCancel);
 
	var clicked:NativeSignal = new NativeSignal(container, MouseEvent.CLICK, MouseEvent);
	clicked.add(onClicked);
}
main();

これだとNativeSignalインスタンス側からイベントハンドラを削除できるんだな。
でも、まだスッキリこない。
こんな使い方なんだろうか?

2010.11.07
16:18
author: taikiken
2件のコメント

ActionScript 3, Event処理を簡単に – Signals, dispatchしてみた

Signalsの2回目。
SignalsではdispatchEventのかわりにdispatchメソッドが準備されています。

dispatchでイベントを発信してハンドラが反応するようになります。
まだ、使い方が良くわからない。

ステージをクリックしたら登場する四角が[STOP]ボタンをクリックすると消える、というのを作ってはみたけど…

import org.osflash.signals.natives.NativeSignal;
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import flashx.textLayout.formats.TextAlign;
import flash.display.DisplayObject;
 
function createBox ():Sprite {
	var sp:Sprite = new Sprite();
	var shape:Shape = new Shape();
	shape.graphics.clear();
	shape.graphics.beginFill(0x6699CC, .6);
	shape.graphics.drawRoundRect(-20, -20, 40, 40, 8);
	shape.graphics.endFill();
	sp.addChild(shape);
	return sp;
}
 
var cancels:Array = [];
function onClicked(e:MouseEvent):void {
	var box:Sprite = createBox();
	box.x = mouseX;
	box.y = mouseY;
	addChild(box);
	// bind event
	var exit:NativeSignal = new NativeSignal(box, Event.EXIT_FRAME, Event);
	exit.add(onExit);
	var cancel:NativeSignal = new NativeSignal(box, Event.CANCEL, Event);
	cancel.addOnce(willCancel);
	// pool
	cancels.push(cancel);
}
// loop
function onExit (e:Event):void {
	e.target.rotation += 6;
}
// cancel event handler of box
function willCancel (e:Event):void {
	e.target.removeEventListener(Event.EXIT_FRAME, onExit);
	removeChild(e.target as DisplayObject)
}
// cancel event handler of button
function onCancel (e:Event):void {
	while (cancels.length > 0) {
		cancels.shift().dispatch(new Event(Event.CANCEL));
	}
}
// MAIN
function main ():void {
	// background
	var container:Sprite = new Sprite();
	container.graphics.clear();
	container.graphics.beginFill(0xefefef);
	container.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
	container.graphics.endFill();
 
	addChild(container);
 
	// stop button
	var button:Sprite = new Sprite();
	button.graphics.clear();
	button.graphics.beginFill(0x339933);
	button.graphics.drawRoundRect(0, 0, 100, 40, 8);
	button.graphics.endFill();
 
	button.mouseEnabled = true;
	button.buttonMode = true;
	button.mouseChildren = false;
 
	button.x = stage.stageWidth - button.width - 10;
	button.y = stage.stageHeight - button.height - 10;
	// button label
	var tf:TextField = new TextField();
	var format:TextFormat = new TextFormat("Helvetica", 14, 0xffffff, "bold");
	format.align = TextAlign.CENTER;
	tf.defaultTextFormat = format;
	tf.width = 20;
	tf.height = 20;
	tf.autoSize = TextFieldAutoSize.LEFT;
	tf.text = "STOP";
	tf.x = (button.width - tf.width) * .5;
	tf.y = (button.height - tf.height) * .5;
 
	addChild(button);
	button.addChild(tf);
	//  bind event
	var cancel:NativeSignal = new NativeSignal(button, MouseEvent.CLICK, MouseEvent);
	cancel.add(onCancel);
 
	var clicked:NativeSignal = new NativeSignal(container, MouseEvent.CLICK, MouseEvent);
	clicked.add(onClicked);
}
 
main();

もっとスマートな答えがありそうな気がしてしょうがない。
そもそもNativeSignal以外の使い方がまだ分からない。

2010.11.04
12:00
author: taikiken
0件のコメント

ActionScript 3, Event処理を簡単に – Signalsはじめの一歩

@robpenner : Robert Penner 先生の ActionScript 3 Event 処理ライブラリ Signals を使うためのはじめの一歩。

github : as3-signals

Robert Penner 先生はFlash easing関数の生みの親とも言うべき偉大なお方です。
Flash MX のころ、ActionScript とバージョンを付けずに呼ばれていた時、に Object Oriented Programming を謳う書籍を出版し、その本でイージング関数、3D、カラーマトリックスなどの様々なサンプルコードで衝撃を与えました。
その後 Macromedia の中の人になり、mx 系のモーション関数や今でも使われている Sine.easeIn…などのイージング関数がFlashに加えられるのに大きな働きをされたようです。

現在はディズニー系のWebゲーム制作会社で活躍されています。

そんな Robert Penner 先生のライブラリなので前から興味があったんだけど、Event 処理って地味だしガリガリ書けばどうにかできちゃうんでずーーっとほったからしでした。

ボタンをクリックを Signals で実装してみました。

import org.osflash.signals.natives.NativeSignal;
import flash.events.MouseEvent;
import flash.display.Sprite;
 
var button:Sprite = new Sprite();
button.graphics.clear();
button.graphics.beginFill(0x6699CC);
button.graphics.drawRoundRect(0, 0, 120, 40, 8);
button.graphics.endFill();
 
button.mouseEnabled = true;
button.buttonMode = true;
 
button.x = (stage.stageWidth - button.width) * .5;
button.y = (stage.stageHeight - button.height) * .5;
 
addChild(button);
 
var clicked:NativeSignal = new NativeSignal(button, MouseEvent.CLICK, MouseEvent);
clicked.addWithPriority(onClicked0, 0);
clicked.add(onClicked);
clicked.addOnce(onClickedOnce);
clicked.addWithPriority(onClicked9, 9);
 
function onClicked0(e:MouseEvent):void {
	trace("clicked 0");
}
function onClicked9(e:MouseEvent):void {
	trace("clicked 9");
}
function onClicked(e:MouseEvent):void {
	trace("clicked");
}
function onClickedOnce (e:MouseEvent):void {
	trace("clicked once");
}

trace

// trace 1回目
clicked 9
clicked 0
clicked
clicked once
// trace 2回目
clicked 9
clicked 0
clicked

ワンタイム・イベントを設定する時は威力を発揮しそう。
面倒な addEventListener, removeEventListener を書かなくとも addOnce だけで済んじゃうのは嬉しい限りです。

Event レシーブの順序(priority)設定ができるのも便利かもです。
まだまだはじめの一歩。
もっと研究しないと実践投入はできそうにない。

2010.11.04
06:00
author: taikiken
0件のコメント

minimalcomps, TextAreaで日本語を入力したい

@bit101 : Keith Peters 先生謹製 minimalcomps は Flash 標準のコンポーネントより軽量で操作性もよいスグレものです。
数多くのコンポーネントが用意されています。
詳細は Minimal Comps by BIT-101 で見ることができます。

英語しか使えないと誤解されているようだけど、チョコチョコっと2~3行足せば日本語も使えます。
誤解の元は “pf_ronda_seven.ttf” が添付され embedFonts が true に設定されてるからかもしれません。

TextAreaで日本語入力

左側は TextArea コンポーネントのノーマル状態です。
文字サイズは 8px とかなり小さなサイズに設定されており、pf_ronda_seven がフォントとして指定されています。

ノーマルのこの状態では日本語の入力ができません。

右側は TextArea コンポーネントを日本語を入力できるように変更したものです。
文字サイズ、文字色も変えています。

画像をクリックで入力デモが表示されます。

import flash.display.Sprite;
import flash.text.TextFormat;
 
import com.bit101.components.TextArea;
 
var sp1:Sprite = new Sprite();
sp1.x = 10;
sp1.y = 10;
var ta:TextArea = new TextArea(sp1);
ta.setSize(280, 100);
ta.autoHideScrollBar = true;
 
addChild(sp1);
 
var sp2:Sprite = new Sprite();
sp2.graphics.clear();
sp2.graphics.beginFill(0x32a41c);
sp2.graphics.drawRect(0, 0, 280, 100);
sp2.graphics.endFill();
sp2.x = 300;
sp2.y = sp1.y;
var ta2:TextArea = new TextArea(sp2, 1, 1);
ta2.setSize(278, 98);
ta2.autoHideScrollBar = true;
ta2.textField.embedFonts = false;
ta2.textField.defaultTextFormat = new TextFormat("_ゴシック", 13, 0xff0000);
 
addChild(sp2);

文字表示用コンポーネントの TextArea, Label などの親クラスの Text が描画処理を行っています。
Text クラスの textField プロパティを再設定すれば日本語も使えるようになります。

textField プロパティは Flash の TextField そのものです。
TextFormat インスタンスを textField.defaultTextFormat へ設定することで日本語入力も含めたあらゆるカスタマイズが可能になります。
デバイスフォントを指定する場合は textField.embedFonts = false; も忘れずに。

初期状態の設定は Style クラスで行われています。

Style.as

package com.bit101.components
{
	public class Style
	{
		public static var BACKGROUND:uint = 0xCCCCCC;
		public static var BUTTON_FACE:uint = 0xFFFFFF;
		public static var INPUT_TEXT:uint = 0x333333;
		public static var LABEL_TEXT:uint = 0x666666;
		public static var DROPSHADOW:uint = 0x000000;
		public static var PANEL:uint = 0xF3F3F3;
		public static var PROGRESS_BAR:uint = 0xFFFFFF;
 
		public static var embedFonts:Boolean = true;
		public static var fontName:String = "PF Ronda Seven";
		public static var fontSize:Number = 8;
	}
}

良くできたminimalcompsですが唯一の不満がTextArea作成時にできる周囲のボーダーと入力部分にできるインナーシャドーをインスタンスから再設定ができない点。
これは Panel クラスが描画処理をしています。
Text クラスで protected var _panel:Panel; と protected 変数とされており、残念ながら現時点では GETTER / SETTERも 設定されていません。
public ならば Panel クラスの各プロパティ shadow, color, gridSize, showGrid, gridColor でどうにかできるのに…

Panel 改造が必要な場合は TextArea を継承したクラスを作るしか解決方法がありません。

minimalcompsのダウンロードはGoogle codeから
minimalcomps

2010.11.03
11:37
author: taikiken
0件のコメント

Objective-C, NSXMLParser parseErrorOccurred エラーコード一覧

XMLパース(NSXMLParser 使用時)のエラー、parseErrorOccurredで取得できるエラーコード一覧メモ。

NSXMLParser.h

 

enum定義されている。

@protocol NSXMLParserDelegate <NSObject>
@optional
 
 
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError;
    // ...and this reports a fatal error to the delegate. The parser will stop parsing.
 
- (void)parser:(NSXMLParser *)parser validationErrorOccurred:(NSError *)validationError;
    // If validation is on, this will report a fatal validation error to the delegate. The parser will stop parsing.
@end
 
FOUNDATION_EXPORT NSString * const NSXMLParserErrorDomain	NS_AVAILABLE(10_3, 2_0);  // for use with NSError.
 
// Error reporting
enum {
    NSXMLParserInternalError = 1,
 
};
typedef NSInteger NSXMLParserError;

な感じで書いてあった。

2010.11.01
12:00
author: taikiken
0件のコメント

2011 Flash 3D GPU, デモ・ムービーをリンクした

photonstorm.com
9 Videos showcasing Flash 3D GPU

Oct. 2010 Adobe Max で発表があった Flash 3D GPU のデモムービへのリンクがあったのでまとめてリンクした。

http://taikiken.tumblr.com/tagged/Adobe_MAX_2010

見るからにすごいんだけど、AdobeはFlashをゲームプラットフォームにしたいんだろうか?
アニメーション、2Dアプリケーション、3Dアプリケーション開発ツールに分割しないとFlashそのものが爆発しそうな気がしてきた。
気のせいならいいけど。。。

2010.10.31
19:49
author: taikiken
1件のコメント

MAMP, データベースを他のマシンと共有してみた

Macでテスト用サーバー環境を構築するのにMAMPを使っています。

プロジェクトはDropboxフォルダへ作成し他のマシンと共有していたのですが、MAMPのデータベースも共有できればサーバーがらみも別のマシンでテストできるのにと思い頭をコネコネしてみました。

MAMPのデータベース・データはMAMPフォルダ内のdbフォルダに存在します。
アップグレードするときも旧dbフォルダをデスクトップなどへ退避しておき、MAMPをアップグレードした後でdbフォルダを上書きしてしまえば無事完了です。

だったらこのdbフォルダをDropboxフォルダへ移動すると共有はできます。

次はDropboxフォルダへ移動したdbフォルダをMAMPにどうやって認識させるかです。

Unixのシンボリックリンクというのを使うことにしました。

cd "/Applications/MAMP"
ln -s <Dropbox Path>/db db

MAMPを起動してみるとちゃんと認識できているようです。

MAMPのデータベースを共有
・Dropbox(Sugarsync, Soonr…)を使う
・MAMPのdbフォルダをDropboxフォルダへ移動
・MAMPフォルダ内へdbフォルダのシンボリックリンクを設定する

めでたしめでたし。

2010.10.29
03:21
author: taikiken
0件のコメント

次世代Flash Playerのための3Dライブラリ, Alternativa3D, Away3D, Yogurt3D

Oct. 2010のAdobe Max, 2011年にも登場するFlash Playerの3D描画が格段に進化するらしいと発表されています。
楽しみな反面、それを利用できるスキルを身につけられるのか不安にかられています。

ま、「3Dグリグリする前にやることあるだろう」とつっこみたくもあるのですが。。。

今回の Adobe Max のデモ映像は Alternativa3D が使われていました。
あっちこっちでリンクされてるので見た人も多いでしょう。

Flash で 3D と言えば Papervision3D だと思ってたけど、どうも時代は変わりはじめてるようです。
Papervision3Dは、真偽は良くわかりませんが、終わったらしく別の3Dライブラリを使うことを考えた方がよいらしいです。

Alternativa3D

Away3D

Yogurt3D

なんかが有力なんかな。。

次世代Flash Playerの話は@clockmakerさんのサイトが詳しいので、そちらをご覧になると良いでしょう。
次の世代のFlash Playerは凄いことに!GPUにより数十万ポリゴンが60FPSで動く

今回、一番反応してしまったのはPapervision3Dが終わったらしいでした。
ライブラリを開発をし続けるのは大変なことなんだなぁ。
個人制作のライブラリはその人の気持ちひとつだし・・・
開発者が仕事量や使用量にみあう対価を得られる仕組みはちゃんと考える必要があるんだろうなと思わされました。

次はグリグリ動く3Dで何作るかでしょう。
ゲームが最有力コンテンツなのは間違いないとしても、他のナニカを思いついた人が勝ち抜けなんだろうなぁ。
技術スキルと企画力とたくさん求められてます。