Actionscript, Web, Interactive and Design

Spark project 勉強会 SP3で発表しました

admin : 2010. 6. 16. 16:49 — ActionScript

2010年6月13日,Adobe Station 5にて「Spark project 勉強会 SP3」が開催されました。
僕は「AIR2.0でマルチタッチ」という題で発表しました。

当日の動画はUstreamで録画されていますので、御覧下さい。
ルーレットの魔力で大トリになってしまったので、最後から10分くらいで発表しております。

また、gihyo.jpにてレポートがアップされています。

当日の資料はこちらになります。

スライド
動画

コミットしました。

MultiTouchSpriteはSparkProjectにコミットしました。
Demoもコミットしてあります。

http://www.libspark.org/svn/as3/MultiTouchSprite/trunk/
DemoはFlashDevelopのプロジェクトとして読み込めます。

また、一つ前のエントリにて、少し解説をしています。
http://blog.alterna.in/2010/04/18-230815.php

いまのところ、touchPointIDをいい感じに取得することができないので、それも早いこと考えたいものです。

ちょっと蛇足

久しぶりの話す機会が、初SparkProject勉強会で、しかもStation5で、しかも大トリで。ということで緊張しました。今考えたら話す構成もめちゃくちゃだし、いろいろ反省すべき部分は多いですが、楽しかったです。
また、Ust録画してもらったりとか、レポートに掲載されたりとか初めての体験なのですごくうれしいです。
今年は人前に出る機会を増やしていけたらなーと思っていて、そのためにはいろいろ作らないとね!ってことです。

FlashPlayer10.1の新機能、マルチタッチを管理する。

admin : 2010. 4. 18. 23:08 — ActionScript

FlashPlayer10.1には、マルチタッチに対応したコンテンツに対応するために、新しいAPIが用意されています。

基本的には、Multitouch.inputModeを定義し、flash.events.TouchEventやflash.events.TransformGestureEventなどで値を受け取ることになります。

TransformGestureEventについては、すでにAdobe AIRデベロッパーセンターに掲載されている
「マルチタッチ機能を活用した AIR 2.0 アプリケーション Touch Viewer の紹介 | デベロッパーセンター」
が非常にわかりやすいです。

今回はTouchEventで効率的にタッチポイントを管理する方法について書きたいと思います。

TouchEventのタイプは

TOUCH_BEGIN
TOUCH_END
TOUCH_MOVE
TOUCH_OUT
TOUCH_OVER
TOUCH_ROLL_OUT
TOUCH_ROLL_OVER
TOUCH_TAP

以上の8つで、TouchEventではタッチ関連のプロパティが取得できます。タッチを管理していく上でメインになってくるのは touchPointID, localX, localYです。touchPointIDには、それぞれのタッチポイントにユニークなIDが割り振られており、localX, localYは、文字通りタッチポイントの座標です。

今回は、TOUCH_BEGIN, TOUCH_END, TOUCH_MOVEの3つにリスナを登録しておき、touchPointIDを添字としたPoint型のVectorにlocalX,localYを格納していく、という方法です。
実際には以下のようなコードになります。

public function MultiTouchSprite()
{
     Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
 
     _startPoint   = new Vector.<Point>(10);
     _currentPoint = new Vector.<Point>(10);
     _previewPoint = new Vector.<Point>(10);
 
     for (var i:int = 0; i < 10; i++)
     {
          _startPoint[i]   = new Point();
          _currentPoint[i] = new Point();
          _previewPoint[i] = new Point();
     }
 
     addEventListener(TouchEvent.TOUCH_BEGIN, _touchBeginHandler);
     addEventListener(TouchEvent.TOUCH_MOVE, _touchMoveHandler);
     addEventListener(TouchEvent.TOUCH_END,    _touchEndHandler);
}
 
private function _touchBeginHandler(e:TouchEvent):void
{
     _startPoint[e.touchPointID].x = e.localX;
     _startPoint[e.touchPointID].y = e.localY;
}

今回はstartPoint, currentPoint, previewPointとい3つのVectorを用意しました。これでcurrentPoint[touchPointID].x, currentPoint[touchPointID].yとかすると、座標が取れます。

あと、僕の環境だと、touchPointIDが2から始まるんですけど、これってなんなんですかね。
ほかの環境でもそうでしょうか。

現在のタッチ個数を得るために、touchPointというint型を用意しておき、TOUCH_BEGINで++, TOUCH_ENDで–しています。

private function _touchBeginHandler(e:TouchEvent):void
{
     _touchPoints++;
}
 
private function _touchEndHandler(e:TouchEvent):void
{
     _touchPoints--;
}

また、今回はタップ、ダブルタップを使えるようにしました。
TouchEvent.TOUCH_TAPを使うと、TOUCH_BEGIN, TOUCH_END, TOUCH_MOVE, TOUCH_TAPと4つのイベントすべてが発生してしまうので、それを回避するためです。
その部分のコードはこんな感じになります。

private function _touchBeginHandler(e:TouchEvent):void
{
     _touchDownTime = getTimer();
}
 
private function _touchEndHandler(e:TouchEvent):void
{
     _touchPoints--;
 
     if (_touchPoints == 0) _touching = false;
 
     if (getTimer() - _touchDownTime < TIME_DIFF) {
          var dist:Number = Math.sqrt(Math.pow(_currentPoint[e.touchPointID].x - _startPoint[e.touchPointID].x, 2) + Math.pow(_currentPoint[e.touchPointID].y - _startPoint[e.touchPointID].y, 2));
          if (Math.abs(dist) < POS_DIFF) _touchTap(e);
     }
}
 
public function _touchTap(e:TouchEvent):void
{
     _tapCnt++;
     if (!_timer.running) {
          _timer.addEventListener(TimerEvent.TIMER_COMPLETE, _timerHandler);
          _timer.start();    
     }
}
 
private function _timerHandler(e:TimerEvent):void
{
     switch(_tapCnt) {
          case 1 : atSingleTap.call(); break;
          case 2 : atDoubleTap.call(); break;
          case 3 : atTripleTap.call(); break;
          default:break;
     }
     _tapCnt = 0;
}
  1. TOUCH_BEGINが発生してからTOUCH_ENDが発生するまでの時間がしきい値以下
  2. TOUCH_BEGINの座標とTOUCH_ENDの座標がしきい値以下

2つの条件を満たした時にTimer.start()させます。タイマー作動中にもう一度2つの条件を満たした場合はtapCountを増やし、timerイベントがディスパッチされたタイミングでtapCountを判定し、シングルタップ、ダブルタップを判断します。この処理を利用すれば、3回や4回など、それ以上の回数も取れます。
ネックはラグが発生することですかねー。

また、イベントのハンドリングはProgressionのCommandやAS2と同じように関数を与えておき、適切な場所でそいつを実行してやることにしました。

MultiTouchSprite.atTouchBegin = function():void
{
     trace(currentPoint[touchObj.touchPointID]);
};

最初はExTouchEventというのを作ってディスパッチしていたんですけど、Flash Pratform Campで、Mike Chambersがディスパッチはパフォーマンス低下するよ!って言ってたので変更しました。
また当初Array型を使ってPointを管理していたのをVector型に変更し、パフォーマンス向上を図っています。

MultiTouchSpriteというクラスとしてまとめておいたので、使ってもらえるとうれしいです。
http://alterna.in/demo/MultiTouchSprite/MultiTouchSprite.zip

Progression4のカスタムコマンド、EmbedFontDyamicLoder

admin : 2010. 3. 2. 00:57 — ActionScript

埋め込みフォントって大変ですよね。
最近までずっとIDEから埋め込みをしていました。
パブリッシュに時間がかかるばかりで「もーいや!」と思っていたら、どうやらASから指定することができるようです。

FACEs: as3:フォントのダイナミックなローディング
CS3版 フォントのダイナミックなローディング | エントリー | _level0.KAYAC

ということでコマンドにしてみました。
Progression4です!

書き方

public function EmbedFontDynamicLoader(path:String, name:String = null, textfield:TextField = null, initObject:Object = null )

@param path フォントファイルへの相対パス
@param name フォントのリンケージ名
@param textfield フォントを適応するTextField
@param initObject initObject.sizeのようにTextFormatと同じように指定すると、TextFormatとして適応されます。

使い方1

使い方1「読み込みを行い、TextFieldにフォント適応をする」

new EmbedFontDynamicLoader("font.swf", "KozukaGo_Pro_R", textField )

上記のようなコマンドを書くと、第三引数として指定したTextFieldに”Helvetica_Bold_16″が適応されます。

AIRで利用する際には、EmbedFontDyamicLoderコマンドの以下のコメントを外してください。
//_context.allowLoadBytesCodeExecution = true;

使い方2「読み込みを行い、TextFieldにフォント適応を行い、TextFormatも設定する」

new EmbedFontDynamicLoader("font.swf", "KozukaGo_Pro_R", textField , { size:16, color:0xFF00FF } )

initObjectに、TextFormatの各種プロパティと一致する用に記述をすると、第三引数として指定したTextFieldにsetTextFormat()されます。
また、第三引数を省略した場合はinitObjectにtextFormatを指定していても無視されます。

使い方3「読み込みを行うが、TextFieldにフォントは適応しない」

必要なフォントファイルの読み込みだけを先に行い、適応は別に行う場合は上記のように記述します。

new EmbedFontDynamicLoader("font.swf")

読み込みを行い、Resourceに登録することで、読み込みの時間を短縮させたい時に利用します。
フォントファイルの読み込みにはLoadSWFコマンドを利用していますが、そのコマンドを実行するのみの処理になります。

僕はIndexSceneで使い方3で一気にswfファイルを読み込み、使い方2でTextFormatと一緒に指定するという使い方をよく使います。

コマンドの中身で、特別なことをしているわけではなく、CS3版のコードを使い、TextFormatを適応してあげただけです。

デモはこちら。

デモではIndexSceneにこんなコードを書いています。

package {
	import flash.text.TextField;
	import jp.progression.casts.*;
	import jp.progression.commands.display.*;
	import jp.progression.commands.lists.*;
	import jp.progression.commands.net.*;
	import jp.progression.commands.tweens.*;
	import jp.progression.commands.*;
	import jp.progression.data.*;
	import jp.progression.events.*;
	import jp.progression.executors.*;
	import jp.progression.scenes.*;
 
	/**
	 * ...
	 * @author ...
	 */
	public class IndexScene extends SceneObject {
 
		var textField:TextField;
 
		public function IndexScene() {
			textField = new TextField();			
			textField.text = "test";			
			container.addChild(textField);
			title = "EmbedFontDynamicLoaderDemo";
		}
 
		protected override function atSceneLoad():void {
			addCommand(
				new EmbedFontDynamicLoader("font.swf", "KozukaGo_Pro_R", null ),
				3,
				new EmbedFontDynamicLoader("font.swf", "KozukaGo_Pro_R", textField),
				3,
				new EmbedFontDynamicLoader("font.swf", "KozukaGo_Pro_R", textField, { color:0x999999 } )
			);
		}
	}
}

ソースファイル一式を置いておくので、ぜひいじってフィードバックください!書き換えてください!

http://alterna.in/demo/EmbedFontDynamicLoaderDemo/EmbedFontDynamicLoaderDemo.zip

Flash for iPhone その2

admin : 2009. 12. 17. 00:32 — ActionScript, iPhone

FlashでiPhoneアプリが書き出せるようになるのが楽しみでしかたない。

gotoAndLearnの人のデモfladdict先生のエントリーにある要約をみながらふんふんと聞いてました。
一番気になるのはここですね

・iPhone用へのコンパイルはAIR用とほぼ同じだが、専用UIあり。

コンポーネントだとは思うけども、全部Eventに変換してくれるのかしら。
「delegate、こうやって作って、定義した関数をこいつに通知して・・・」とかやっていたので、本当に助かります。

たのしみでしょうがないですね。

Flash for iPhoneへの準備

admin : 2009. 11. 23. 13:49 — ActionScript, iPhone

fladdict先生のエントリを見ていて、僕がiPhoneアプリを作っている時に気をつけていることを少し。

ステージは回転する

あらかじめ、縦向き、横向きの画を作りましょう。Flashだと、拡大縮小ですが、iPhoneの場合は回転です。サイズが変わるという面では同じですが、拡縮と回転では概念が違うので、画面も違ってくるでしょう。
没入系アプリをつくる際には、UIなどの画像も全て自作し、自分でレイアウトを行う場合が多いです。
さらに、没入系の場合、縦画面のみではなく、横画面をつくる時が多いので、その時の絵がないと、実装時に苦労します。

機能の割切り

コンセプトがスマートに伝わるシンプルなアプリは強いです。また、メモリの容量がすくないのでよく張るとパフォーマンスが低下します。アプリのコンセプトを伝えるために最低限必要な機能のみにしぼるとよいと思います。

実機で使い倒す

実機で動かして、自分の手のなかで動いているアプリを見ると、シュミレータ上とはまた違う感覚です。またパフォーマンスも全然違います。できればスペックの低いiPhone3Gでテストするといいです。通信を行う場合はwifi環境ではなく3G環境で。という感じ。

まとめ

なんかもうほとんど言及されていたので、あまり多くないですが。多分、iPhoneのUIはコンポーネントとして提供されるはずなので、スキンを変えるだけで、没入系のアプリはかなり作りやすくなると思います。
Flash的には、IDE上で絵が作れるのは強みなので、それを活かして、魅力的なUIを持つアプリが増えて欲しいです。

次ページへ »
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
(c) 2010 blog.alterna.in | powered by WordPress with Barecity