トップ > Action Script 3.0 > キャラクター + Twitter で動いて喋る

キャラクター + Twitter で動いて喋る

maku puppet (マクパペット)

マクパペットというサイトで、Flashでのアニメーションキャラクター素材を発見。なにやら面白そうだなと、早速いろいろ試してみた。

実際に触ってみるとかなり良くできているなーと感心してしまうほどの出来栄え。しかも、クレジットを表示さえしておけば、商用利用・改編・再配付などが OK となっててかなり自由に使える。

キャラクターパーツなどもダウンロードできるんで、自分のサーバーにデータを格納して利用できたり、パーツをオリジナルで作成してしまうことも可能。キャラクターのテイストがちょっと…、という時でも自作してしまえば、動きや関節パーツなどの制限はあるかもしれないが、自分の好きなキャラクターを作成できると思う。

ちゃんと Flash のクラスも用意されているので、Action Scirpt 3.0 の基本知識があれば、キャラクターを簡単に制御することもできる。

そこで、Twitter とキャラクターを組み合わせたコンテンツを作成してみた。

サンプル

このサイトをご覧頂くには最新の Flash Player Plug-in をお使いのブラウザにインストールする必要があります。
Flash Player Plug-in はこちらからダウンロードする事が出来ます(無料)。

Twitter @hikatsuka

ソースはこちら

大まかな流れは、「Twitterの発言を取得」⇒「キャラクター生成」⇒「タイマーを利用して一定間隔ごとにキャラクターをランダム操作」という感じ。ついでにキャラクターの影も生成してみた。同じキャラクターを作成し上下に反転させてグレーに着色しぼかしを加えて同じ動きをさせるだけで特に難しいことはしていない。あと、下記のような吹き出しのシンボルを用意してメッセージを表示させる。

※ちなみに、Twitter はクロスドメインポリシーの関係でFlashからはAPIに接続不可…。search.twitter.com は大丈夫なんだけどねー。仕方がないので、ここの PHP を経由して取得。

package
{
	import flash.display.*;
	import flash.events.*;
	import flash.net.*;
	import flash.utils.*;
	import flash.text.*;
	import makupuppet.*;
	import caurina.transitions.Tweener;
	import caurina.transitions.properties.ColorShortcuts;
	import caurina.transitions.properties.FilterShortcuts;
	import com.adobe.serialization.json.JSON;
	import Dumper;
	
	public class Main extends MovieClip
	{
		private var chrMC:MovieClip;
		private var chr:Maku;
		private var chrKage:Maku;
		private var talkPanel:Fukidashi;
		private var actionArr1:Array = ["walk", "dash2", "laugh", "cry", "angry", "jump", "swimwait", "search", "wait"];
		private var actionArr2:Array = ["laugh", "cry", "angry", "jump", "swimwait", "search", "wait"];
		private const TWITTER_USER_TIMELINE:String = "http://1ka2ka.com/uploadfile/090416/crossdomain-proxy.php?url=http://twitter.com/statuses/user_timeline/hikatsuka.json";
		private var twTxtArr:Array = new Array();
		/*============================================================
		コンストラクタ
		============================================================*/
		public function Main()
		{
			ColorShortcuts.init();
			FilterShortcuts.init();
			init();//初期設定
			getStatus();//twitterからステータス取得
		}
		/*============================================================
		初期設定
		============================================================*/
		private function init():void
		{
			//ステージ
			stage.showDefaultContextMenu = false;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
		}
		/*============================================================
		twitterからステータス取得
		============================================================*/
		private function getStatus():void
		{
			//APIへリクエストを発行
			var urlReq:URLRequest = new URLRequest(TWITTER_USER_TIMELINE);
			var urll:URLLoader = new URLLoader();			
			urll.load(urlReq);
			//読み込みエラー
			urll.addEventListener(IOErrorEvent.IO_ERROR, function(event:Event):void
			{
				twTxtArr.push("読み込みエラーでした…");
				initMain();
			});
			//読み込み完了
			urll.addEventListener(Event.COMPLETE, function(event:Event):void
			{
				//  データが無い場合は実行しない
				if (!urll.data) return;
				// jsonをオブジェクトに変換				
				var twitterObj:Object = JSON.decode(urll.data);
				//trace(Dumper.toString(twitterObj));
				//trace(twitterObj[0]["text"]);
				for (var i:int = 0; i < twitterObj.length; i++)
				{
					twTxtArr.push(twitterObj[i]["text"]);
				}
				//trace(twTxtArr[0]);
				//メイン処理へ
				initMain();
			});
		}
		/*============================================================
		メイン処理
		============================================================*/
		private function initMain():void
		{
			//メイン
			chrMC = new MovieClip();
			chrMC.x = 350;
			chrMC.y = 200;
			//キャラ
			chr = new Maku();
			chr.init("a1b1c13e22i23k4f5g33j36", "wait", "http://1ka2ka.com/_lib/makuParts/");
			chr.scaleX = chr.scaleY = 1.5;
			//キャラ影
			chrKage = new Maku();
			chrKage.init("a1b1c13e22i23k4f5g33j36", "wait", "http://1ka2ka.com/_lib/makuParts/", false);
			chrKage.scaleX = 1.5;
			chrKage.scaleY = -0.75;
			Tweener.addTween(chrKage, {
				time:0,
				_color:0xAAAAAA,
				_Blur_blurX:5,
				_Blur_blurY:5,
				_Blur_quality:3
			});
			//吹き出し
			talkPanel = new Fukidashi();
			talkPanel.y = -115;
			talkPanel.visible = false;
			talkPanel.str.multiline = true;
			talkPanel.str.wordWrap = false;
			talkPanel.str.autoSize = TextFieldAutoSize.LEFT;
			talkPanel.str.text = "";
			//キャラクター配置
			addChild(chrMC);
			chrMC.addChild(chrKage);
			chrMC.addChild(chr);
			chrMC.addChild(talkPanel);
			//タイマー処理開始
			setTimer();
		}
		/*============================================================
		タイマー処理
		============================================================*/
		private function setTimer():void
		{
			var waitTimer:Timer = new Timer(500, 1);
			waitTimer.addEventListener(TimerEvent.TIMER, actionTimer);
			waitTimer.start();
		}
		private function actionTimer(event:Event):void
		{
			//吹き出しリセット
			talkPanel.visible = false;
			
			//向き
			chrMC.muki = (Math.random() < 0.5) ? -1 : 1 ;
			chr.scaleX = Math.abs(chr.scaleX) * chrMC.muki;
			chrKage.scaleX = Math.abs(chrKage.scaleX) * chrMC.muki;
			
			//向きと位置確認をしてアクション選定
			if (chrMC.muki == 1 && chrMC.x <= 200 || chrMC.muki == -1 && chrMC.x >= 400) {
				//端にいる場合は、歩きを含まないアクションからランダム選定
				chr.setAnimation(actionArr2[Math.floor(Math.random() * actionArr2.length)]);
				chrKage.setAnimation(chr.animID);
			} else {
				//端にいない場合は、歩きを含むアクションからランダム選定
				chr.setAnimation(actionArr1[Math.floor(Math.random() * actionArr1.length)]);
				chrKage.setAnimation(chr.animID);
			}
			
			//選定されたアクション
			var animType:String = chr.animID;
			
			//歩きの場合
			if (animType == "walk" || animType == "dash2")
			{
				var targetX:int;
				if (animType=="walk") {
					targetX = chrMC.x - chrMC.muki * 80;
				} else if (animType=="dash2") {
					targetX = chrMC.x - chrMC.muki * 180;
				}
				Tweener.addTween(chrMC, {
					time:2,
					x:targetX,
					transition:"linear"
				});
			}
			
			//待機の場合、または約40%の確率でランダムメッセージを表示
			if (animType == "wait" || Math.random() < 0.4)
			{
				talkPanel.visible = true;
				talkPanel.str.wordWrap = false;
				talkPanel.str.text = twTxtArr[Math.floor(Math.random() * twTxtArr.length)];
				talkPanel.str.autoSize = TextFieldAutoSize.LEFT;
				//吹き出しの大きさを調整
				if (talkPanel.str.width > 243) {
					talkPanel.bg.width = 250;
					talkPanel.str.width = 243;
					talkPanel.str.wordWrap = true;
					talkPanel.str.x = -9;
				} else {
					talkPanel.bg.width = talkPanel.str.width + 7;
				}
				//高さを調整
				talkPanel.bg.height = talkPanel.str.height + 20;
				talkPanel.str.y = -talkPanel.bg.height + 3;
			}
			
			//待機用タイマー
			var waitTimer:Timer = new Timer(2000, 1);
			waitTimer.addEventListener(TimerEvent.TIMER, stopTimer);
			waitTimer.start();
		}
		private function stopTimer(event:Event):void
		{
			//アクションリセット
			chr.setAnimation("wait");
			chrKage.setAnimation("wait");
			//アクションタイマー
			var waitTimer:Timer = new Timer(2000, 1);
			waitTimer.addEventListener(TimerEvent.TIMER, actionTimer);
			waitTimer.start();
		}
	}
}

この記事をブックマークしておく

コメント:0

コメント投稿

コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。

この情報を記憶する

トップ > Action Script 3.0 > キャラクター + Twitter で動いて喋る

記事検索
カテゴリ
RSSフィード

このページの先頭へ戻る