ある制作会社からの依頼でブログパーツを制作した。
AS2書き出しのプレーヤーv8に設定されたプロジェクトで、Function レイヤーの1フレーム目に次のような関数群を使って待機中に目がキョロキョロする挙動を表現している。また、Actions レイヤーフレーム1に書いてある変数は省略している。最終的には playSnakeEyes 関数を一定時に処理を行うようにして完成する。
// Make eyes snake.
function playSnakeEyes() {
if (movMode == false) {
if (randRange(0, 9) % 3 == 0 || randRange(0, 9) % 3 == 1) {// SNAKE
var randX:Number = randRange(0, Stage.width);
var randY:Number = randRange(0, Stage.height);
var pos_right:Object = getPos(rightEye, {x:randX, y:randY});
var pos_left:Object = getPos(leftEye, {x:randX, y:randY});
} else if (randRange(0, 9) % 3 == 2 && snakeCount % 3 == 2) {// LONPARI
var pos_right:Object = getPos(rightEye, {x:(rightEye.x - 10), y:rightEye.y});
var pos_left:Object = getPos(leftEye, {x:(leftEye.x + 10), y:leftEye.y});
}
setEyes({right:pos_right, left:pos_left}); }
snakeCount++;
}
// Generate randomized number.
function randRange(min:Number, max:Number):Number {
var randomNum:Number = Math.floor(Math.random() * (max - min + 1)) + min;
return randomNum;
}
// Set positions of instance for eyes.
function setEyes(pos:Object):Void {
var movRate:Number = randRange(1, 9) / 10;
rightEye_mc.onEnterFrame = function():Void {
var xRate:Number = (pos.right.x - this._x) * movRate;
var yRate:Number = (pos.right.y - this._y) * movRate;
this._x += xRate;
this._y += yRate;
if (Math.abs(xRate) < 0.1 && Math.abs(yRate) < 0.1) {
this._x = pos.right.x;
this._y = pos.right.y;
delete this.onEnterFrame;
}
};
leftEye_mc.onEnterFrame = function():Void {
var xRate:Number = (pos.left.x - this._x) * movRate;
var yRate:Number = (pos.left.y - this._y) * movRate;
this._x += xRate;
this._y += yRate;
if (Math.abs(xRate) < 0.1 && Math.abs(yRate) < 0.1) {
this._x = pos.left.x;
this._y = pos.left.y;
delete this.onEnterFrame;
}
};
}
// Get positions of instance for eyes from position of mouse cursor.
function getPos(eye:Object, pts:Object):Object {
var xdiff:Number = pts.x - eye.x;
var ydiff:Number = pts.y - eye.y;
var radius:Number = Math.min(Math.max(Math.sqrt(xdiff * xdiff + ydiff * ydiff) / distanceFromEye, 0), MAXeyeMovement);
var angle:Number = Math.atan2(ydiff, xdiff);
return {x:(Math.cos(angle) * radius * ovality + eye.x), y:(Math.sin(angle) * radius + eye.y)};
}
AS3用にクラス化するかどうかは次の案件に委ねられている。
// 誰かお願いします。:-)
iPhone で使える天気ソフトウェアを探していた。
Going My Way: 全国の天気情報がさっと調べられる、iPhone / iPod touch 用アプリ、 ウェザーニュース タッチ
全国の天気情報がさっと調べられる、iPhone / iPod touch 用アプリ、 ウェザーニュース タッチ
せっかくのピンポイント天気表示があるにも関わらず、起動毎時に全国の天気を表示しなければならない設計がつまらなかったので、Sora-Annaiを利用することにしたのだが、いずれにせよ天気予報APIに申請して自作することを避けられて安心した。
天気情報と言えば数年前に、東京の天気をフラッシュ上で表現した仮想空間に再現するという案件があった。天気予報というのは、インターネット接続サービスと同様に気象庁を頂点としたプロバイダで構成されていることをその時知ったものだったが、当時は FTP を使って予想天気と最低/最高気温が一定時間毎に送られてくるというもので、相応する金額を徴収されたと記憶している。
また、デスクトップ環境では空模様ウィジェットから、Safari 3 のウェブクリップ機能を使って日本気象協会のサービスを表示するウィジェットへの移行を試みている。日常生活での利用を考えるとより詳細なものが好ましいのだが、大きさを考えると13インチの画面などでは厳しいものがあるかもしれない。

出産を迎え仕事量を増やそうと約7年分の制作物を整理していたところ、試作したものの企画が潰れ眠っていた ActionScript 2 コードを見つけたので MIT License の元に公開することにした。この例では読み込み毎にランダムに配色するという挙動になっているが、setTab関数を改変し外部SWFファイルを読み込めば実用性があるだろう。とは言え、これは Flash のアップグレードを止め、今回公開を決断した理由の一つでもあるのだが、JavaScript でも表現できる時代となっている。
要件:
- 横750px * 縦150px
- 各領域をマウスオーバーで最大値横450pxになるようスライドして表示
- マウスアウト時には5秒後に自動スライド開始
参考:
実例:
コード:ダウンロード
class Slidemenu
{
private var __tabs_num:Number;
private var __start_time:Number;
private var __ad_width:Number;
public function Slidemenu (tabs_num:Number, start_time:Number, ad_width:Number)
{
this.__tabs_num = tabs_num;
this.__start_time = start_time;
this.__ad_width = ad_width;
}
public function main (move_speed:Number):Void
{
var my_points:Array = getMyPoints ();
var out_points:Array = getOutPoints ();
var in_points:Array = getInPoints ();
setTabs (move_speed, my_points, out_points, in_points);
}
private function setTabs (move_speed:Number, my_points:Array, out_points:Array, in_points:Array):Void
{
var i:Number;
for (i = 0; i < this.__tabs_num; i++)
{
var tab_name:String = "tab" + i;
_root.createEmptyMovieClip (tab_name, i);
_root[tab_name]._x = my_points[i];
_root[tab_name].id = i;
setTab (_root[tab_name], 100);
_root[tab_name].onRollOver = function ():Void
{
_global.tab_id = this.id;
clearInterval (_global.intervalId);
};
var to_point:Number;
_root[tab_name].onEnterFrame = function ():Void
{
if (_global.tab_id == null)
{
to_point = my_points[this.id];
}
else if (_global.tab_id >= this.id)
{
to_point = out_points[this.id];
}
else
{
to_point = in_points[this.id];
}
var xrate:Number = (to_point - this._x) * move_speed;
this._x += xrate;
if (Math.abs (xrate) < 0.1)
{
this._x = to_point;
}
};
}
}
public function beginInterval ():Void
{
if (_global.intervalId != null)
{
clearInterval (_global.intervalId);
}
_global.intervalId = setInterval (this, "autoTabStart", this.__start_time);
}
private function autoTabStart ():Void
{
if (_global.tab_id == null || _global.tab_id >= this.__tabs_num - 1)
{
_global.tab_id = 0;
}
else
{
_global.tab_id++;
}
}
private function getInPoints ():Array
{
return new Array (0, 450, (450 + 75 * 1), (450 + 75 * 2), (450 + 75 * 3));
}
private function getOutPoints ():Array
{
var i:Number;
var points:Array = new Array ();
for (i = 0; i < this.__tabs_num; i++)
{
points[i] = ((Stage.width - this.__ad_width) / (this.__tabs_num - 1)) * i;
}
return points;
}
private function getMyPoints ():Array
{
var i:Number;
var points:Array = new Array ();
for (i = 0; i < this.__tabs_num; i++)
{
points[i] = (Stage.width / this.__tabs_num) * i;
}
return points;
}
private function setTab (clip:MovieClip, alpha:Number):Void
{
clip.beginFill (getrndColors (), alpha);
clip.lineStyle ();
clip.moveTo (0, 0);
clip.lineTo (Stage.width, 0);
clip.lineTo (Stage.width, Stage.height);
clip.lineTo (0, Stage.height);
clip.lineTo (0, 0);
clip.endFill ();
}
private function getrndColors ():Number
{
var rNum:Number = Math.round (Math.random () * 255);
var gNum:Number = Math.round (Math.random () * 255);
var bNum:Number = Math.round (Math.random () * 255);
var c:Number = rNum * 0x10000 + gNum * 0x100 + bNum;
return c;
}
}