10月の活動記録

ヘルプサイトのつくりかた
コラム

Animate放送部をもっと使えるサイトに育てたい。

  • キャラクターアニメーション
  • ActionScriptアニメーション

ペルソナを設定する

名前
ぬえさぶろう
年齢
42歳
職業
コールセンターオペレーター
部署
2人
職務内容
ケーブルテレビの視聴に関するサポート業務
叶えられなかった将来の夢
ゲームクリエイター
これから叶えたい野望
アニメーションを完成させたい!

コールセンターの日常をゲーム・アニメのパロディでおもしろおかしく盛り上げる。

参考アニメ
BPS-バトルプログラマーシラセ-
重ね順を変更する方法
スクリプト

作業内容

【AS2.0】三角関数を使った位置制御で立体的な円周移動を再現

キーワード 区分 簡単な説明
swapDepths(...) メソッド(2.0) 深度(重なり順)を(...)内の数値に変更
deplicateMovieClip(newName,depth) メソッド ムービークリップを、インスタンス名newName、重なり順depthで複製
Math.abs(...) メソッド (...)内の数値を絶対値にする
Math.PI 定数 円周率
eval(...) (...)内の文字列などをターゲットパスや変数名に変換

変換前のAS2.0のコード

//楕円のX軸方向の半径、すしネタと職人との距離のさを代入
v_radiusX = mySushi._x - myCenter._x;
v_radiusY = mySushi._y - myCenter._y;
/*ムービーを上から見たと仮定したとき、ステージに配置した1個目のすしの回転度数*/
v_degree = 0; 
v_speed = 3; /*1フレーム当たりの回転度数*/
sushi_max = 10;
sushi_deg = 360/sushi_max;

mySushi._visible = false; //制御は全て複製したムービークリップに対して行うので、最初に配置したすしのムービークリップは非表示にする。
myCenter.swapdepths(50);
/*すしの数は10個*/
for(i=0; i<sushi_max; i++){
    mySushi.duplicateMovieClip("mySushi" + i, sushi_max - i);
    this["mySushi" + i].v_id = i + 1;
    this["mySushi" + i].gotoAndStop(i+1);
    f_moveSushi("mySushi" + i, v_id, v_id * sushi_deg);
}

function f_moveSushi(name,id,deg){
    v_name = eval(name);
    /*度数をラジアン値に変換*/
    v_radian = (v_degree + deg) * (Math.PI / 180);
    /*各寿司ネタムービークリップの座標を決める*/
    v_name._x = v_radiusX * Math.cos(v_radian)+myCenter._x; /*横*/
    v_name._y = v_radiusY * Math.sin(v_radian)+myCenter._y; /*縦*/
    if(Math.sin(v_radian) < 0){
        v_name.swapDepths(id);
        v_name._alpha = 120 - Math.abs((Math.sin(v_radian) * 100));
    }else{
        /* 寿司ネタがmyCenterの前を通るときは、各ネタの深度を100*idに */
        v_name.swapDepths(100 * id);
    }
} /* function f_moveSushi */

this.onEnterFrame = function(){
    /*ポインタのY座標とmyCenterの距離から楕円のY軸方向の半径を計算*/
    v_distanceY = (_root._ymouse = myCenter._y) / 3;
    v_radiusY = v_distanceY;
    
    /*ポインタのX座標とmyCenterの距離から寿司の1フレームあたりの回転度数を計算*/
    v_distanceX = (_root._xmouse = myCenter._x);
    v_speed = v_distanceX / 50;
    
    v_degree += v_speed;
};

this["mySushi" + i].gotoAndStop(i + 1);
this["文字列"]は、this が指すタイムライン上に存在するムービークリップを表す

AS3.0へ変換したい!

var deg: uint = 70; //角度
var puyo_2_deg:uint = 45;
var puyo_3_deg:uint = 30;
var puyo_4_deg:uint = 15;
var puyo_5_deg:uint = 0;
var r: uint = 200; //x半径
var ry: uint = 25; //y半径

/*中心座標*/
var tmpX: Number = nuesaburou.x;
var tmpY: Number = nuesaburou.y;

//イベントリスナーの設定
addEventListener(Event.ENTER_FRAME, round_puyo_1);
addEventListener(Event.ENTER_FRAME, round_puyo_2);
addEventListener(Event.ENTER_FRAME, round_puyo_3);
addEventListener(Event.ENTER_FRAME, round_puyo_4);
addEventListener(Event.ENTER_FRAME, round_puyo_5);

//フレーム再生イベントのリスナー関数
function round_puyo_1(eventObj: Event): void
{
	//マウスカーソルの位置に近づく
	tmpX += (nuesaburou.x - tmpX) / 10;
	tmpY += (nuesaburou.y - tmpY) / 10;
	//回転速度
	deg = (deg + 2) % 360;
	puyo_1.x = r * Math.cos(deg * Math.PI / 180) + tmpX;
	puyo_1.y = ry * Math.sin(deg * Math.PI / 180) + tmpY;
	/*接触判定*/
	if (nuesaburou.y> puyo_1.y)
	{
		//後
		setChildIndex(puyo_1,0);
		setChildIndex(puyo_2,1);
		setChildIndex(puyo_3,2);
		setChildIndex(puyo_4,3);
		setChildIndex(puyo_5,4);
		setChildIndex(nuesaburou,numChildren-1);
	}else{
		//前
		setChildIndex(puyo_1,5);
		setChildIndex(puyo_2,4);
		setChildIndex(puyo_3,3);
		setChildIndex(puyo_4,2);
		setChildIndex(puyo_5,1);
		setChildIndex(nuesaburou,0);
	}
}
function round_puyo_2(eventObj: Event): void
{
	//マウスカーソルの位置に近づく
	tmpX += (nuesaburou.x - tmpX) / 10;
	tmpY += (nuesaburou.y - tmpY) / 10;
	//回転速度
	puyo_2_deg = (puyo_2_deg + 2) % 360;
	puyo_2.x = r * Math.cos(puyo_2_deg * Math.PI / 180) + tmpX;
	puyo_2.y = ry * Math.sin(puyo_2_deg * Math.PI / 180) + tmpY;
}
function round_puyo_3(eventObj: Event): void
{
	//マウスカーソルの位置に近づく
	tmpX += (nuesaburou.x - tmpX) / 10;
	tmpY += (nuesaburou.y - tmpY) / 10;
	//回転速度
	puyo_3_deg = (puyo_3_deg + 2) % 360;
	puyo_3.x = r * Math.cos(puyo_3_deg * Math.PI / 180) + tmpX;
	puyo_3.y = ry * Math.sin(puyo_3_deg * Math.PI / 180) + tmpY;
}
function round_puyo_4(eventObj: Event): void
{
	//マウスカーソルの位置に近づく
	tmpX += (nuesaburou.x - tmpX) / 10;
	tmpY += (nuesaburou.y - tmpY) / 10;
	//回転速度
	puyo_4_deg = (puyo_4_deg + 2) % 360;
	puyo_4.x = r * Math.cos(puyo_4_deg * Math.PI / 180) + tmpX;
	puyo_4.y = ry * Math.sin(puyo_4_deg * Math.PI / 180) + tmpY;
}
function round_puyo_5(eventObj: Event): void
{
	//マウスカーソルの位置に近づく
	tmpX += (nuesaburou.x - tmpX) / 10;
	tmpY += (nuesaburou.y - tmpY) / 10;
	//回転速度
	puyo_5_deg = (puyo_5_deg + 2) % 360;
	puyo_5.x = r * Math.cos(puyo_5_deg * Math.PI / 180) + tmpX;
	puyo_5.y = ry * Math.sin(puyo_5_deg * Math.PI / 180) + tmpY;
}
【AS3】ムービークリップの重ね順を入れ替える方法
Animate

ムービークリップの重なり順を入れ替える

ステージにあるムービークリップの重なり順(インデックス位置)の調べ方
  • getChildIndex(child:DisplayObject):int
ロールオーバーしている間だけインスタンスを最前面にする
  • setChildIndex(mc,numChildren ):void
インスタンス(ムービークリップ)を入れ替える
  • swapChildren(mc1,mc2)

ロールオーバーしている間だけインスタンスを最前面にする

/*ロールオーバーしている間だけインスタンスを最前面にする*/
var currentIndex:int;
//メインタイムラインのインスタンスを対象にする
addEventListener(MouseEvent.ROLL_OVER, onRollover, true);
addEventListener(MouseEvent.ROLL_OUT, onRollout, true);

//マウスカーソルが重なったら最前面で大きく表示する
function onRollover(eventObj:MouseEvent):void{
	var mc:MovieClip = eventObj.target as MovieClip;
	var container:DisplayObjectContainer = mc.parent;
	/*インスタンスのインデックス番号*/
	currentIndex = container.getChildIndex(mc);
	/*サイズを大きくする*/
	mc.scaleX = mc.scaleY = 1.5;
	//子オブジェクトの個数-1
	var lastIndex:int = container.numChildren - 1;
	//最前面に出す(一番大きな数字にする)
	container.setChildIndex(mc,lastIndex);
}/*onRollover*/

//マウスカーソルが離れたら元に戻す
function onRollout(eventObj:MouseEvent):void{
	var mc:MovieClip = eventObj.target as MovieClip;
	var container:DisplayObjectContainer = mc.parent;
	mc.scaleX = mc.scaleY = 1;
	container.setChildIndex(mc, currentIndex);
}/*function onRollout*/
JSアニメーション
スクリプト

三角関数を使って、アニメーションさせてみました。

/*三角関数を使ってアニメーションさせる*/
const startAnimation = (duration) => {
    const shot = (timestamp) => {
        //時間内に3回転する回転角度の計算
        deg += (360 * 3 /duration) * (timestamp - prevstamp);
        // 度数をラジアンに変換
        const rad = (deg * Math.PI) / 180;
        const cos = Math.cos(rad) * (duration - timestamp) / 40; /*x軸方向の移動量*/
        const sin = Math.sin(rad) * (duration - timestamp) / 10; /*x軸方向の移動量*/
        element.style['transform'] = `translate(${cos}px, ${sin}px) 
        rotate(${deg}deg)
        `;/*テンプレート構文*/
        /*現在の経過時間が設定時間に達していないなら*/
        if(timestamp < duration){
            prevstamp = timestamp;
            requestAnimationFrame(shot);/*アニメーションの継続*/
        }
    };//shot
        
    const element = document.querySelector('#js_animation');
    let deg = 0;
    let prevstamp = 0;
    requestAnimationFrame(shot);
};/*startAnimation*/

startAnimation(10000);/*10秒間のアニメーション*/
2点間の距離と角度の出し方
AS3

2点間の距離と角度の出し方

Aの平方根の計算
Math.sqrt(A)
AのB乗を計算
Math.pow(A,B)
度数を求める数式
度数=ラジアン×(180/π)
ラジアン値を求める数式
ラジアン=度数×(π/180)
座標から角度を求めたい
Math.atan2(y:Number,x:Number):Number
//フレームアクション
var sun_mc: MovieClip;
var mcLimit: MovieClip;
var nuesaburou_mc: MovieClip;
var v_distance:Number;
var v_degree:Number;
var distance:Number;
var blurX:Number;
var blurY:Number;
var v_alpha:Number;
var angle:Number;

//mouseDownイベントにイベントリスナーを追加
sun_mc.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
//ドラッグ範囲制限用のRectangleインスタンスを生成
var rectLimit: Rectangle = new Rectangle();
rectLimit.x = mcLimit.x;
rectLimit.y = mcLimit.y;
rectLimit.width = mcLimit.width - sun_mc.width;
rectLimit.height = mcLimit.height - sun_mc.height;
//mouseDownイベント用のリスナー関数
function mouseDownHandler(eventObject: MouseEvent): void
{
	//ドラッグ開始
	sun_mc.startDrag(false, rectLimit);
	//ドラッグ終了のためにイベントリスナーを追加
	stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
	stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
//mouseUpイベント用のリスナー関数
function mouseUpHandler(eventObject: MouseEvent): void
{
	//ドラッグ終了
	sun_mc.stopDrag();
	stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
	stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
//mouseMoveイベント用のリスナー関数
function mouseMoveHandler(eventObject: MouseEvent): void
{
	v_distance = Math.sqrt(Math.pow(sun_mc.y - nuesaburou_mc.y, 2) + Math.pow(sun_mc.x - nuesaburou_mc.x, 2));
	//角度を同数で計算
	v_degree = (Math.atan2(sun_mc.y - nuesaburou_mc.y, sun_mc.x - nuesaburou_mc.x) * 180 / Math.PI) - 180;
	distance = v_distance / 10;
	blurX = v_distance / 10;
	blurY = v_distance / 10;
	v_alpha = 1 - v_distance / 10;
	angle = v_degree;

	//距離はv_distance,角度はv_degree,影の色はダークブルー、不透明度はv_alpha
	var myDropShadow: DropShadowFilter = new DropShadowFilter(distance, angle, 0x000066, alpha,blurX,blurY);
	nuesaburou_mc.filters = [myDropShadow];

	eventObject.updateAfterEvent();
}
【AS3.0】ドロップシャドウで太陽を動かしてキャラクターの影を操作する
dropshadowfilter
ゲーム開発

ActionScript3.0

AS3.0ドラッグ&ドロップ
          //フレームアクション
var mc:MovieClip;
var mcLimit:MovieClip;
//mouseDownイベントにイベントリスナーを追加
mc.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
//ドラッグ範囲制限用のRectangleインスタンスを生成
var rectLimit:Rectangle = new Rectangle();
rectLimit.x = mcLimit.x;
rectLimit.y = mcLimit.y;
rectLimit.width = mcLimit.width - mc.width;
rectLimit.height = mcLimit.height - mc.height;
//mouseDownイベント用のリスナー関数
function mouseDownHandler(eventObject:MouseEvent):void {
	//ドラッグ開始
	mc.startDrag(false, rectLimit);
	//ドラッグ終了のためにイベントリスナーを追加
	stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
	stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
//mouseUpイベント用のリスナー関数
function mouseUpHandler(eventObject:MouseEvent):void {
	//ドラッグ終了
	mc.stopDrag();
	stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
	stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
	//ドロップ先オブジェクトのインスタンス名を出力
	trace(mc.dropTarget.parent.name);//出力:mcLimit
}
//mouseMoveイベント用のリスナー関数
function mouseMoveHandler(eventObject:MouseEvent):void {
	eventObject.updateAfterEvent();
}
dropshadowfilter
//距離は8,角度は30,影の色はダークブルー、不透明度は0.6
var myDropShadow:DropShadowFilter = new DropShadowFilter(8,270,0x000066,0.6);
nuesaburou_mc.filters = [myDropShadow];
toTop