向きと移動量がわかっているときに、x軸方向の移動量とy軸方向の移動量に振り分けたいときの計算です。 これを利用するとどの方向にも一定の距離を移動する事ができます。 これを三角関数を用いてx方向とy方向に分けます。 x軸方向移動量を求める x軸方向移動量 = cos( 角度 ) * 距離 y軸方向移動量を求める y軸方向移動量 = sin( 角度 ) * 距離 これをアクションスクリプトで記述すると以下のようになります。 x軸方向移動量を求める x軸方向移動量 = Math.cos( 角度 * Math.PI / 180 ) * 距離 y軸方向移動量を求める y軸方向移動量 = Math.sin( 角度 * Math.PI / 180 ) * 距離 Math.cos()メソッドとMath.sin()メソッドを用いるとsin と cos が求まります。ただし、このメソッドの引数にはラジアンを指定する必要があります。 ラジアンとは0~2πの間で角度を表す単位です。 角度からラジアン、ラジアンから角度へ変換するには下の式を用いると実現できます。 角度からラジアンに変換する ラジアン = 角度 * Math.PI / 180; ラジアンから角度に変換する 角度 = ラジアン * 180 / Math.PI; では、これを使って作れるサンプルを紹介します。
x軸方向移動量 = cos( 角度 ) * 距離
y軸方向移動量 = sin( 角度 ) * 距離
x軸方向移動量 = Math.cos( 角度 * Math.PI / 180 ) * 距離
y軸方向移動量 = Math.sin( 角度 * Math.PI / 180 ) * 距離
ラジアン = 角度 * Math.PI / 180;
角度 = ラジアン * 180 / Math.PI;
車を例にします。 車には向きとスピードの2つのパラメータがあり、その値でx軸方向の移動量とy軸方向の移動量に変換しています。 車の移動 onClipEvent (load) { speed = 0; // 移動量 rot = -90; // 向き(注.右向きを0とする) dx = 0; // x方向移動量 dy = 0; // y方向移動量 } onClipEvent (enterFrame) { // 上を押したとき if(Key.isDown(Key.UP)) speed ++; // 下を押したとき if(Key.isDown(Key.DOWN)) speed --; // 左を押したとき if(Key.isDown(Key.LEFT)) rot --; // 右を押したとき if(Key.isDown(Key.RIGHT)) rot ++; // 移動量を求める dx = Math.cos(rot * Math.PI / 180) * speed; dy = Math.sin(rot * Math.PI / 180) * speed; // 摩擦 speed *= 0.9; // 座標更新 _x += dx; _y += dy; _rotation = rot; // 画面ループ if(_x < 0) _x = 400; if(_x > 400) _x = 0; if(_y < 0) _y = 300; if(_y > 300) _y = 0; }
onClipEvent (load) { speed = 0; // 移動量 rot = -90; // 向き(注.右向きを0とする) dx = 0; // x方向移動量 dy = 0; // y方向移動量 } onClipEvent (enterFrame) { // 上を押したとき if(Key.isDown(Key.UP)) speed ++; // 下を押したとき if(Key.isDown(Key.DOWN)) speed --; // 左を押したとき if(Key.isDown(Key.LEFT)) rot --; // 右を押したとき if(Key.isDown(Key.RIGHT)) rot ++; // 移動量を求める dx = Math.cos(rot * Math.PI / 180) * speed; dy = Math.sin(rot * Math.PI / 180) * speed; // 摩擦 speed *= 0.9; // 座標更新 _x += dx; _y += dy; _rotation = rot; // 画面ループ if(_x < 0) _x = 400; if(_x > 400) _x = 0; if(_y < 0) _y = 300; if(_y > 300) _y = 0; }
上下左右に5ずつ移動するキャラクターがいます。 このキャラクターが右上に動くとき上に5、右に5ずつ移動すると直線距離では、5√2になり斜めに移動すると少し早く移動できてしまいます。 そこで、三角関数を使って斜めの場合は直線距離を5として上と右の移動量を求めます。 キャラクターの移動 onClipEvent (load) { rot = 0; speed = 0; _root.AnimePlay(0); } onClipEvent (enterFrame) { // 左上を押したとき if (Key.isDown(Key.UP) && Key.isDown(Key.LEFT)) { rot = 215; speed = 2; _root.AnimePlay(1); // 左下を押したとき } else if (Key.isDown(Key.DOWN) && Key.isDown(Key.LEFT)) { rot = 135; speed = 2; _root.AnimePlay(0); // 右上を押したとき } else if (Key.isDown(Key.UP) && Key.isDown(Key.RIGHT)) { rot = 315; speed = 2; _root.AnimePlay(1); // 右下を押したとき } else if (Key.isDown(Key.DOWN) && Key.isDown(Key.RIGHT)) { rot = 45; speed = 2; _root.AnimePlay(0); // 上を押したとき } else if (Key.isDown(Key.UP)) { rot = 270; speed = 2; _root.AnimePlay(1); // 下を押したとき } else if (Key.isDown(Key.DOWN)) { rot = 90; speed = 2; _root.AnimePlay(0); // 左を押したとき } else if (Key.isDown(Key.LEFT)) { rot = 180; speed = 2; _root.AnimePlay(2); // 右を押したとき } else if (Key.isDown(Key.RIGHT)) { rot = 0; speed = 2; _root.AnimePlay(3); // 何も押さなかったとき }else{ speed = 0; } // 移動量を求める dx = Math.cos(rot * Math.PI / 180) * speed; dy = Math.sin(rot * Math.PI / 180) * speed; _x += dx; _y += dy; // 画面ループ if(_x < 0) _x = 400; if(_x > 400) _x = 0; if(_y < 0) _y = 300; if(_y > 300) _y = 0; } AnimePlay() 自作関数。引数に番号を指定するとその番号に用意されたアニメを再生。
onClipEvent (load) { rot = 0; speed = 0; _root.AnimePlay(0); } onClipEvent (enterFrame) { // 左上を押したとき if (Key.isDown(Key.UP) && Key.isDown(Key.LEFT)) { rot = 215; speed = 2; _root.AnimePlay(1); // 左下を押したとき } else if (Key.isDown(Key.DOWN) && Key.isDown(Key.LEFT)) { rot = 135; speed = 2; _root.AnimePlay(0); // 右上を押したとき } else if (Key.isDown(Key.UP) && Key.isDown(Key.RIGHT)) { rot = 315; speed = 2; _root.AnimePlay(1); // 右下を押したとき } else if (Key.isDown(Key.DOWN) && Key.isDown(Key.RIGHT)) { rot = 45; speed = 2; _root.AnimePlay(0); // 上を押したとき } else if (Key.isDown(Key.UP)) { rot = 270; speed = 2; _root.AnimePlay(1); // 下を押したとき } else if (Key.isDown(Key.DOWN)) { rot = 90; speed = 2; _root.AnimePlay(0); // 左を押したとき } else if (Key.isDown(Key.LEFT)) { rot = 180; speed = 2; _root.AnimePlay(2); // 右を押したとき } else if (Key.isDown(Key.RIGHT)) { rot = 0; speed = 2; _root.AnimePlay(3); // 何も押さなかったとき }else{ speed = 0; } // 移動量を求める dx = Math.cos(rot * Math.PI / 180) * speed; dy = Math.sin(rot * Math.PI / 180) * speed; _x += dx; _y += dy; // 画面ループ if(_x < 0) _x = 400; if(_x > 400) _x = 0; if(_y < 0) _y = 300; if(_y > 300) _y = 0; }
砲台を例にします。 砲台には"向き"と"スピード"の2つのパラメータがあり、その値でx軸方向の移動量とy軸方向の初期移動量を求めます。 また、"砲台の向き"と"回転軸から砲台の発射口までの長さ"から初期位置を求めます。 砲台管理 onClipEvent (load) { rot = 0; speed = 3; } onClipEvent (enterFrame) { if(Key.isDown(Key.UP)) rot --; if(Key.isDown(Key.DOWN)) rot ++; if(Key.isDown(Key.LEFT)) speed -= 0.2; if(Key.isDown(Key.RIGHT)) speed += 0.2; // リミッタ if(rot > 0) rot = 0; if(rot < -90) rot = -90; if( speed < 1 ) speed = 1; if( speed > 8 ) speed = 8; if(Key.isDown(Key.SPACE) && push == 0){ order = new Object(); // 初期座標 order.x = _x + Math.cos( rot * Math.PI / 180 ) * 30; order.y = _y + Math.sin( rot * Math.PI / 180 ) * 30; // 移動量 order.dx = Math.cos( rot * Math.PI / 180 ) * speed; order.dy = Math.sin( rot * Math.PI / 180 ) * speed; // 砲弾作成 _root.GunCreate(order); } push = Key.isDown(Key.SPACE); // 砲台回転 _rotation = rot; // 砲弾処理 _root.GunExective(); } GunCreate()自作関数。弾をひとつ生成する。引数にオブジェクト形式でステータスを入れる。 GunExective()自作関数。弾の処理をまとめて記述している。
onClipEvent (load) { rot = 0; speed = 3; } onClipEvent (enterFrame) { if(Key.isDown(Key.UP)) rot --; if(Key.isDown(Key.DOWN)) rot ++; if(Key.isDown(Key.LEFT)) speed -= 0.2; if(Key.isDown(Key.RIGHT)) speed += 0.2; // リミッタ if(rot > 0) rot = 0; if(rot < -90) rot = -90; if( speed < 1 ) speed = 1; if( speed > 8 ) speed = 8; if(Key.isDown(Key.SPACE) && push == 0){ order = new Object(); // 初期座標 order.x = _x + Math.cos( rot * Math.PI / 180 ) * 30; order.y = _y + Math.sin( rot * Math.PI / 180 ) * 30; // 移動量 order.dx = Math.cos( rot * Math.PI / 180 ) * speed; order.dy = Math.sin( rot * Math.PI / 180 ) * speed; // 砲弾作成 _root.GunCreate(order); } push = Key.isDown(Key.SPACE); // 砲台回転 _rotation = rot; // 砲弾処理 _root.GunExective(); }
マウスポインタを向く矢印 自分の座標を(my_x ,my_y )とします。 相手の座標を(target_x ,target_y)とします。 自分から見て相手はどの角度にいるかを計算します。 2点でできる線の角度を求める rad = Math.atan2(target_y - my_y,target_x - my_x); _rotation = rad * 180 / Math.PI; rad = Math.atan2(相手のy座標 - 自分のy座標, 相手のx座標 - 自分のx座標); 角度 = rad * 180 / Math.PI;
rad = Math.atan2(target_y - my_y,target_x - my_x); _rotation = rad * 180 / Math.PI;
自分の移動量を(spd_x ,spd_y )とします。 移動量からどの角度に進んでいるかを計算します。 x方向とy方向の値から角度を求める rad = Math.atan2(spd_y, spd_x); _rotation = rad * 180 / Math.PI; rad = Math.atan2(y移動量, x移動量); 角度 = rad * 180 / Math.PI;
rad = Math.atan2(spd_y, spd_x); _rotation = rad * 180 / Math.PI;