基本的な移動について
・ | 一定の速さで移動させたい |
・ | 加速しながら移動させたい |
・ | 減速(摩擦)しながら移動させたい |
・ | 波のように移動させたい |
・ | 円のように移動させたい |
・ | 放物線(自由落下)のように移動させたい |
・ | 振り子のように移動させたい |
一定の速さで移動させたい
サンプルをダウンロード
■一定の速さで移動させるのに必要なパラメータ
インスタンスを一定の速さで移動させてみます。必要なパラメータは以下の通りです。
インスタンスの座標を、変数 (px, py) とします。
1フレームで座標が変化する量⇒速度を、変数 (dx, dy) とします。
1フレームで座標が変化する量⇒速度を、変数 (dx, dy) とします。
例) 一定の速さで移動させるのに必要なパラメータ
var px = 0; // x 座標
var py = 0; // y 座標
var dx = 2; // x 方向の速度
var dy = 3; // y 方向の速度
■考え方
まず好きな速度を設定します。
後は、速度を座標に繰り返し加算します。
毎フレーム置きに実行すると一定の速さで移動し続けるように見えます。
毎フレーム置きに実行すると一定の速さで移動し続けるように見えます。
■動かしてみる
Flash 5 での記述例です。
例) ムービークリップを x 方向に 2、y 方向に 3 ずつ移動させる(Flash 5)
// --------------------------------------------
// 一度だけ実行されるイベント
// --------------------------------------------
onClipEvent (load) {
px = 0; // x 座標
py = 0; // y 座標
dx = 2; // x 方向の速度
dy = 3; // y 方向の速度
}
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
onClipEvent (enterFrame) {
// 速度を座標に加算する
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
}
Flash MX 以降での記述例です。インスタンス mc を等速で移動させます。
例) ムービークリップ mc を x 方向に 2、y 方向に 3 ずつ移動させる(FlashMX以降)
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 0; // x 座標
var py = 0; // y 座標
var dx = 2; // x 方向の速度
var dy = 3; // y 方向の速度
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// 速度を座標に加算する
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
};
カーソルキーが押されたときにインスタンス mc を等速で移動させる例です。
例) ムービークリップ mc を カーソルキーが押された方向に移動させる(FlashMX以降)
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 0; // x 座標
var py = 0; // y 座標
var dx = 0; // x 方向の速度
var dy = 0; // y 方向の速度
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
if(Key.isDown(Key.LEFT)) dx = -3; // 左が押された
else if(Key.isDown(Key.RIGHT)) dx = 3; // 右が押された
else dx = 0; // 左と右どちらも押されなかった
if(Key.isDown(Key.UP)) dy = -3; // 上が押された
else if(Key.isDown(Key.DOWN)) dy = 3; // 下が押された
else dy = 0; // 上と下どちらも押されなかった
// 速度を座標に加算する
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
};
加速しながら移動させたい
サンプルをダウンロード
■加速しながら移動させるのに必要なパラメータ
インスタンスを加速させながら移動させてみます。必要なパラメータは以下の通りです。
インスタンスの座標を、変数 (px, py) とします。
1フレームで座標が変化する量⇒速度を、変数 (dx, dy) とします。
1フレームで速度が変化する量⇒加速度を、変数 (ax, ay) とします。
1フレームで座標が変化する量⇒速度を、変数 (dx, dy) とします。
1フレームで速度が変化する量⇒加速度を、変数 (ax, ay) とします。
例) 一定の速さで移動させるのに必要なパラメータ
var px = 0; // x 座標
var py = 0; // y 座標
var dx = 2; // x 方向の速度
var dy = 3; // y 方向の速度
var ax = 1; // x 方向の加速度
var ax = 1; // y 方向の加速度
■考え方
まず好きな速度と加速度を設定します。
後は、加速度を速度に加算して、速度を座標に加算します。これを繰り返し行います。
毎フレーム置きに実行すると加速しながら移動し続けるように見えます。
速度 (dx,dy) を少しずつ増加させながら移動させます
■動かしてみる
Flash 5 での記述例です。
例) ムービークリップを 加速しながら移動させる(Flash 5)
// --------------------------------------------
// 一度だけ実行されるイベント
// --------------------------------------------
onClipEvent (load) {
px = 0; // x 座標
py = 0; // y 座標
dx = 2.0; // x 方向の速度
dy = 1.0; // y 方向の速度
ax = 0.2; // x 方向の加速度
ay = 0.1; // y 方向の加速度
}
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
onClipEvent (enterFrame) {
// 加速度を速度に加算する
dx += ax;
dy += ay;
// 速度を座標に加算する
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
}
Flash MX 以降での記述例です。インスタンス mc を加速させながら移動させます。
例) ムービークリップ mc を加速させながら移動させる(FlashMX以降)
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 0; // x 座標
var py = 0; // y 座標
var dx = 2.0; // x 方向の速度
var dy = 1.0; // y 方向の速度
var ax = 0.2; // x 方向の加速度
var ay = 0.1; // y 方向の加速度
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// 加速度を速度に加算する
dx += ax;
dy += ay;
// 速度を座標に加算する
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
};
カーソルキーが押されたときにインスタンス mc を加速させながら移動させる例です。
例) ムービークリップ mc を カーソルキーが押された方向に加速しながら移動させる(FlashMX以降)
// --------------------------------------------
// パラメータ
// --------------------------------------------
var SPEED_ADD = 0.1; // 加速度
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 0; // x 座標
var py = 0; // y 座標
var dx = 0; // x 方向の速度
var dy = 0; // y 方向の速度
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
if(Key.isDown(Key.LEFT)) dx -= SPEED_ADD; // 左が押された
else if(Key.isDown(Key.RIGHT)) dx += SPEED_ADD; // 右が押された
if(Key.isDown(Key.UP)) dy -= SPEED_ADD; // 上が押された
else if(Key.isDown(Key.DOWN)) dy += SPEED_ADD; // 下が押された
// 速度を座標に加算する
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
};
■最高速度を設定する
インスタンスを、加速し続けるといずれものすごい速さになってしまいます。
そこで、ある一定の速さに到達したらそれ以上速度が増えないようにしてみましょう。
速度を座標に加算する直前に、速度の値を調べて上限を超えていたら上限に戻す処理を追加します。
速度が一定以上の値を超えないように制限します
カーソルキーが押されたときにインスタンス mc を加速させながら移動させる例に、速度の上限をつけてみました。
例) ムービークリップ mc を カーソルキーが押された方向に加速しながら移動させつつ、速度に上限を付ける(FlashMX以降)
// --------------------------------------------
// パラメータ
// --------------------------------------------
var SPEED_ADD = 0.1; // 加速度
var SPEED_MAX = 3.0; // 速度の最大値
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 0; // x 座標
var py = 0; // y 座標
var dx = 0; // x 方向の速度
var dy = 0; // y 方向の速度
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
if(Key.isDown(Key.LEFT)) dx -= SPEED_ADD; // 左が押された
else if(Key.isDown(Key.RIGHT)) dx += SPEED_ADD; // 右が押された
if(Key.isDown(Key.UP)) dy -= SPEED_ADD; // 上が押された
else if(Key.isDown(Key.DOWN)) dy += SPEED_ADD; // 下が押された
// 速度が最大を超えていたら戻す
if(dx < -SPEED_MAX) dx = -SPEED_MAX;
if(dy < -SPEED_MAX) dy = -SPEED_MAX;
if(dx > SPEED_MAX) dx = SPEED_MAX;
if(dy > SPEED_MAX) dy = SPEED_MAX;
// 速度を座標に加算する
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
};
減速(摩擦)しながら移動させたい
サンプルをダウンロード
■減速しながら移動させるのに必要なパラメータ
インスタンスを減速させながら移動させてみます。必要なパラメータは以下の通りです。
インスタンスの座標を、変数 (px, py) とします。
1フレームで座標が変化する量⇒速度を、変数 (dx, dy) とします。
1フレームで速度が変化する係数(0.0~1.0)⇒摩擦係数を、変数 friction とします。0 に近いほどいきなり停止し、1.0に近いほどゆっくり停止します。
1フレームで座標が変化する量⇒速度を、変数 (dx, dy) とします。
1フレームで速度が変化する係数(0.0~1.0)⇒摩擦係数を、変数 friction とします。0 に近いほどいきなり停止し、1.0に近いほどゆっくり停止します。
例) 一定の速さで移動させるのに必要なパラメータ
var px = 0; // x 座標
var py = 0; // y 座標
var dx = 2; // x 方向の速度
var dy = 3; // y 方向の速度
var friction = 0.9; // 摩擦係数(0.0~1.0)
■考え方
速度が大きいほどインスタンスが早く動きます。速度が 0 になると完全に動きが止まります。
という事で、速度を少しずつ 0 に近づけるように変化させれば、減速することになります。
まず好きな速度を設定します。
後は、速度を 0 に近づくように変化させて、速度を座標に加算します。これを繰り返し行います。
毎フレーム置きに実行すると減速しながら移動し続けるように見えます。
毎フレーム置きに実行すると減速しながら移動し続けるように見えます。
速度 (dx,dy) を少しずつ 0 に近づけながら移動させます
変数を 0 に近づけるには、『 0.0 ~ 1.0 の値を乗算し続けると いずれ 0 に近づく』のを利用します。
例えば 10 という値に 0.5 という係数を繰り返して乗算してみます。
回数 | 値 | 乗算値 | 結果 |
01回目 | 10.0 | × 0.5 = | 5 |
02回目 | 5.0 | × 0.5 = | 2.5 |
03回目 | 2.5 | × 0.5 = | 1.25 |
04回目 | 1.25 | × 0.5 = | 0.625 |
05回目 | 0.625 | × 0.5 = | 0.3125 |
06回目 | 0.3125 | × 0.5 = | 0.15625 |
07回目 | 0.15625 | × 0.5 = | 0.078125 |
08回目 | 0.078125 | × 0.5 = | 0.0390625 |
09回目 | 0.0390625 | × 0.5 = | 0.01953125 |
10回目 | 0.01953125 | × 0.5 = | 0.009765625 |
11回目 | 0.009765625 | × 0.5 = | 0.0048828125 |
12回目 | 0.0048828125 | × 0.5 = | 0.00244140625 |
13回目 | 0.00244140625 | × 0.5 = | 0.001220703125 |
14回目 | 0.001220703125 | × 0.5 = | 0.0006103515625 |
15回目 | 0.0006103515625 | × 0.5 = | 0.00030517578125 |
16回目 | 0.00030517578125 | × 0.5 = | 0.000152587890625 |
17回目 | 0.000152587890625 | × 0.5 = | 0.0000762939453125 |
18回目 | 0.0000762939453125 | × 0.5 = | 0.00003814697265625 |
19回目 | 0.00003814697265625 | × 0.5 = | 0.000019073486328125 |
20回目 | 0.000019073486328125 | × 0.5 = | 0.0000095367431640625 |
0.0 に近づいていくのが分かりますね。速度の符号がプラスでもマイナスでも 0 に近づきます。
しかし、0.0 には近づきますが、0.0 に限りなく近くなり続けるだけなので、完全に 0.0 になるにはかなりの時間を要します。
滑り続けるような表現をしたくないときは、一定の数値より低くなったら 0.0 にしてしまうといいかもしれません。
例えば速度が -0.1 ~ 0.1 の範囲になったら 0.0 にします。
■動かしてみる
Flash 5 での記述例です。
例) ムービークリップを減速しながら移動させる(Flash 5)
// --------------------------------------------
// 一度だけ実行されるイベント
// --------------------------------------------
onClipEvent (load) {
px = 0; // x 座標
py = 0; // y 座標
dx = 20.0; // x 方向の速度
dy = 10.0; // y 方向の速度
friction = 0.95; // 摩擦係数(0.0~1.0)
}
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
onClipEvent (enterFrame) {
// 速度を摩擦係数で乗算する
dx *= friction;
dy *= friction;
// 速度を座標に加算する
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
}
Flash MX 以降での記述例です。インスタンス mc を減速させながら移動させます。
例) ムービークリップ mc を減速させながら移動させる(FlashMX以降)
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 0; // x 座標
var py = 0; // y 座標
var dx = 20.0; // x 方向の速度
var dy = 10.0; // y 方向の速度
var friction = 0.95; // 摩擦係数(0.0~1.0)
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// 速度を摩擦係数で乗算する
dx *= friction;
dy *= friction;
// 速度を座標に加算する
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
};
カーソルキーが押されたときにインスタンス mc を減速させながら移動させる例です。
例) ムービークリップ mc を カーソルキーが押された方向に減速しながら移動させる(FlashMX以降)
// --------------------------------------------
// パラメータ
// --------------------------------------------
var SPEED_ADD = 0.5; // 加速度
var SPEED_MAX = 5; // 最高速度
var SPEED_FRI = 0.9; // 摩擦係数(0.0~1.0)
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 0; // x 座標
var py = 0; // y 座標
var dx = 0; // x 方向の速度
var dy = 0; // y 方向の速度
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
if(Key.isDown(Key.LEFT)) dx -= SPEED_ADD; // 左が押された
else if(Key.isDown(Key.RIGHT)) dx += SPEED_ADD; // 右が押された
else dx *= SPEED_FRI; // 左右が押されなかった
if(Key.isDown(Key.UP)) dy -= SPEED_ADD; // 上が押された
else if(Key.isDown(Key.DOWN)) dy += SPEED_ADD; // 下が押された
else dy *= SPEED_FRI; // 上下が押されなかった
// 速度が最大を超えていたら戻す
if(dx < -SPEED_MAX) dx = -SPEED_MAX;
if(dy < -SPEED_MAX) dy = -SPEED_MAX;
if(dx > SPEED_MAX) dx = SPEED_MAX;
if(dy > SPEED_MAX) dy = SPEED_MAX;
// 速度を座標に加算する
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
};
■目的地にちょうど止まるように減速しながら移動させたい
インスタンスを移動開始地点から移動終了地点まで減速させながら移動させたいとします。
目的地まで減速しながら移動します
■考え方
目的地までの距離を 0 に近づけるには、『 0.0 ~ 1.0 の値を乗算し続けると いずれ 0 に近づく』のを利用します。
例えば 100 という値に 0.5 という係数を繰り返して乗算してみます。
回数 | 値 | 乗算値 | 結果 |
01回目 | 100 | × 0.5 = | 50 |
02回目 | 50 | × 0.5 = | 25 |
03回目 | 25 | × 0.5 = | 12.5 |
04回目 | 12.5 | × 0.5 = | 6.25 |
05回目 | 6.25 | × 0.5 = | 3.125 |
06回目 | 3.125 | × 0.5 = | 1.5625 |
07回目 | 1.5625 | × 0.5 = | 0.78125 |
08回目 | 0.78125 | × 0.5 = | 0.390625 |
09回目 | 0.390625 | × 0.5 = | 0.1953125 |
10回目 | 0.1953125 | × 0.5 = | 0.09765625 |
11回目 | 0.09765625 | × 0.5 = | 0.048828125 |
12回目 | 0.048828125 | × 0.5 = | 0.0244140625 |
13回目 | 0.0244140625 | × 0.5 = | 0.01220703125 |
14回目 | 0.01220703125 | × 0.5 = | 0.006103515625 |
15回目 | 0.006103515625 | × 0.5 = | 0.0030517578125 |
16回目 | 0.0030517578125 | × 0.5 = | 0.00152587890625 |
17回目 | 0.00152587890625 | × 0.5 = | 0.000762939453125 |
18回目 | 0.000762939453125 | × 0.5 = | 0.0003814697265625 |
19回目 | 0.0003814697265625 | × 0.5 = | 0.00019073486328125 |
20回目 | 0.00019073486328125 | × 0.5 = | 0.000095367431640625 |
目的地までの距離が減速しつつも 0 に近づいているのがわかります。
目的地までの長さに『1.0 - 摩擦係数』を乗算した値を速度とすれば、目的地まで減速しながら移動させることができます。
下のソースは、Flash MX 以降での記述例です。インスタンス mc の x 座標を、変数 POS_START から変数 POS_END まで移動させます。
例) ムービークリップ mc を目的地まで減速させながら移動させる(FlashMX以降)
// --------------------------------------------
// パラメータ
// --------------------------------------------
var SPEED_FRI = 0.9; // 摩擦係数(0.0~1.0)
var POS_START = 0; // 開始座標
var POS_END = 500; // 終了座標
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = POS_START; // x 座標
var py = 100; // y 座標
var dx = 0.0; // x 方向の速度
var dy = 0.0; // y 方向の速度
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// 目的地までの距離
var sub = POS_END - px;
// 目的地までの距離に(1.0 - 摩擦係数)を乗算した物を速度とする
dx = sub * (1.0 - SPEED_FRI);
// 速度を座標に加算する
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
};
このままだと目的地までの距離が離れているほど物凄い速さになってしまうので最高速度を決めて、速度がその値を超えないようにしてみます。
目的地まで最高速度を守りつつ減速しながら移動します
例) ムービークリップ mc を目的地まで最高速度を守って減速させながら移動させる(FlashMX以降)
// --------------------------------------------
// パラメータ
// --------------------------------------------
var SPEED_MAX = 5; // 最高速度
var SPEED_FRI = 0.9; // 摩擦係数(0.0~1.0)
var POS_START = 0; // 開始座標
var POS_END = 500; // 終了座標
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = POS_START; // x 座標
var py = 100; // y 座標
var dx = 0.0; // x 方向の速度
var dy = 0.0; // y 方向の速度
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// 目的地までの距離
var sub = POS_END - px;
// 目的地までの距離に(1.0 - 摩擦係数)を乗算した物を速度とする
dx = sub * (1.0 - SPEED_FRI);
// 速度の最大制限を付ける
if(dx > SPEED_MAX) dx = SPEED_MAX;
if(dx <-SPEED_MAX) dx =-SPEED_MAX;
// 速度を座標に加算する
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
};
さらに加速を含めてみます。
目的地まで加速して最高速度を守りつつ減速しながら移動します
例) ムービークリップ mc を目的地まで加速しながら最高速度を守って減速させながら移動させる(FlashMX以降)
// --------------------------------------------
// パラメータ
// --------------------------------------------
var SPEED_ADD = 0.1; // 加速度
var SPEED_MAX = 5; // 最高速度
var SPEED_FRI = 0.9; // 摩擦係数(0.0~1.0)
var POS_START = 0; // 開始座標
var POS_END = 500; // 終了座標
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = POS_START; // x 座標
var py = 100; // y 座標
var dx = 0.0; // x 方向の速度
var dy = 0.0; // y 方向の速度
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// 目的地までの距離
var sub = POS_END - px;
// 目的地までの距離に(1.0 - 摩擦係数)を乗算
sub = sub * (1.0 - SPEED_FRI);
// 速度の加速と最大制限と減速
if(sub > 0){
dx += SPEED_ADD;
if(dx > SPEED_MAX) dx = SPEED_MAX;
if(dx > sub) dx = sub;
}else{
dx -= SPEED_ADD;
if(dx <-SPEED_MAX) dx =-SPEED_MAX;
if(dx < sub) dx = sub;
}
// 速度を座標に加算する
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
};
また、この手法は目的地までの距離が限りなく 0 に近づきますが、 0 と等しくなるにはかなりの時間がかかります。
ある程度目的地まで近づいたら、インスタンスの位置をその座標にしてしまうといいかもしれません。
例えば目的地までの距離が 0.1 以下の範囲になったら座標を目的地とします。
波のように移動させたい
サンプルをダウンロード
■波のように移動させるのに必要なパラメータ
正弦波(サインカーブ)を使ってインスタンスを波のように移動させてみます。必要なパラメータは以下の通りです。
インスタンスの座標を、変数 (px, py) とします。
サインを取得するための角度=(位相)を変数 phase とします。
位相が1フレームに変化する量=(振動の速さ)を変数 phase_speed とします。
波の振幅を変数 amp とします。
サインを取得するための角度=(位相)を変数 phase とします。
位相が1フレームに変化する量=(振動の速さ)を変数 phase_speed とします。
波の振幅を変数 amp とします。
例) 波を表現するのに必要なパラメータ
var px = 0; // x 座標
var py = 0; // y 座標
var phase = 0; // 波の位相(0 ~ 360)
var phase_speed = 5; // 波の位相変化量(0 ~ 360)
var amp = 10; // 波の振幅
■考え方
サインを使うと波の表現ができます。下の Flash をご覧下さい。
横に進んでいるのが角度です。0 度 から 5 度 ずつ増やしています。360 度を過ぎたら 0 度に戻ります。
上下に動いているのがサインの値です。『-1.0 から 1.0 まで』値が変動しているのがわかります。
例えば、45 度のときはサインの値は 0.7071 となります。60 度のときはサインの値は 0.8660 となります。
0 度から 360 度まで角度を一定の速さで変化させると、波のように滑らかに変化する値を得ることができます。これを利用して波を表現します。
また、得られるサイン値が『-1.0 から 1.0 まで』となっているので、ここに好きな値を乗算すればその大きさの振幅で動作する波を作り出すことができます。
上下か左右に波の運動を行いたい場合は、x 軸か y 軸の片方の軸だけサイン値の反映を行います。もう片方の軸は等速運動を行うといいでしょう。
■サイン値を取得する
サインを取得するには、Math.sin() メソッドを使用します。引数には角度ではなくラジアンを指定する必要があります。
角度からラジアンに変換してサイン値を得るには以下の計算を行います。
角度からラジアンに変換してサイン値を得る
ラジアン = 角度 * Math.PI / 180;
サイン値 = Math.sin ( ラジアン );
■動かしてみる
Flash 5 での記述例です。x 軸方向に波の動きを行います。
例) ムービークリップを x 軸方向に波の動きをさせる(Flash 5)
// --------------------------------------------
// 一度だけ実行されるイベント
// --------------------------------------------
onClipEvent (load) {
px = 100; // x 座標(波の中心)
py = 0; // y 座標
dy = 1.0; // y 方向の速度
phase = 0; // 波の位相(0 ~ 360)
phase_speed = 10; // 波の位相変化量(0 ~ 360)
amp = 50; // 波の振幅
}
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
onClipEvent (enterFrame) {
// 位相を変化させる
phase += phase_speed;
// 位相(角度)を 0 ~ 360 までに丸める
// phase = phase - Math.floor(phase / 360) * 360;
// 位相からサイン値を取得する
var d = Math.sin(phase * Math.PI / 180);
// x座標を計算する
var x = d * amp + px;
// 速度を座標に加算する
py += dy;
// 座標をインスタンスの座標に反映
this._x = x;
this._y = py;
}
Flash 5 での記述例です。y 軸方向に波の動きを行います。
例) 例) ムービークリップを y 軸方向に波の動きをさせる(Flash 5)
// --------------------------------------------
// 一度だけ実行されるイベント
// --------------------------------------------
onClipEvent (load) {
px = 0; // x 座標
py = 100; // y 座標(波の中心)
dx = 1.0; // x 方向の速度
phase = 0; // 波の位相(0 ~ 360)
phase_speed = 10; // 波の位相変化量(0 ~ 360)
amp = 50; // 波の振幅
}
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
onClipEvent (enterFrame) {
// 位相を変化させる
phase += phase_speed;
// 位相(角度)を 0 ~ 360 までに丸める
// phase = phase - Math.floor(phase / 360) * 360;
// 位相からサイン値を取得する
var d = Math.sin(phase * Math.PI / 180);
// y座標を計算する
var y = d * amp + py;
// 速度を座標に加算する
px += dx;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = y;
}
Flash MX 以降での記述例です。ムービークリップ mc の x 軸方向に波の動きを行います。
例) ムービークリップ mc の x 軸方向に波の動きをさせる(Flash MX 以降)
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 100; // x 座標(波の中心)
var py = 0; // y 座標
var dy = 1.0; // y 方向の速度
var phase = 0; // 波の位相(0 ~ 360)
var phase_speed = 10; // 波の位相変化量(0 ~ 360)
var amp = 50; // 波の振幅
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// 位相を変化させる
phase += phase_speed;
// 位相(角度)を 0 ~ 360 までに丸める
// phase = phase - Math.floor(phase / 360) * 360;
// 位相からサイン値を取得する
var d = Math.sin(phase * Math.PI / 180);
// x座標を計算する
var x = d * amp + px;
// 速度を座標に加算する
py += dy;
// 座標をインスタンスの座標に反映
this._x = x;
this._y = py;
};
Flash MX 以降での記述例です。ムービークリップ mc の y 軸方向に波の動きを行います。
例) 例)ムービークリップ mc の y 軸方向に波の動きをさせる(Flash MX 以降)
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 0; // x 座標
var py = 100; // y 座標(波の中心)
var dx = 1.0; // x 方向の速度
var phase = 0; // 波の位相(0 ~ 360)
var phase_speed = 10; // 波の位相変化量(0 ~ 360)
var amp = 50; // 波の振幅
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// 位相を変化させる
phase += phase_speed;
// 位相(角度)を 0 ~ 360 までに丸める
// phase = phase - Math.floor(phase / 360) * 360;
// 位相からサイン値を取得する
var d = Math.sin(phase * Math.PI / 180);
// y座標を計算する
var y = d * amp + py;
// 速度を座標に加算する
px += dx;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = y;
};
■振幅を少しずつ変化させる
振幅を少しずつ大きくすると以下の画像のような動きが作れます。
振幅を少しずつ大きくします
■動かしてみる
Flash MX 以降の記述例です。
例) 例)ムービークリップ mc の 振幅を徐々に大きくする(Flash MX 以降)
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 0; // x 座標
var py = 100; // y 座標(波の中心)
var dx = 1.0; // x 方向の速度
var phase = 0; // 波の位相(0 ~ 360)
var phase_speed = 10; // 波の位相変化量(0 ~ 360)
var amp = 0; // 波の振幅
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// 振幅を大きくする
amp += 0.5;
// 位相を変化させる
phase += phase_speed;
// 位相(角度)を 0 ~ 360 までに丸める
// phase = phase - Math.floor(phase / 360) * 360;
// 位相からサイン値を取得する
var d = Math.sin(phase * Math.PI / 180);
// y座標を計算する
var y = d * amp + py;
// 速度を座標に加算する
px += dx;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = y;
};
円状に移動させたい
サンプルをダウンロード
■円のように移動させるのに必要なパラメータ
正弦波(サインカーブ)を使ってインスタンスを円状に移動させてみます。必要なパラメータは以下の通りです。
円運動の中心座標を、変数 (px, py) とします。
円運動の中心座標から現在位置までの角度を変数 rot とします。
角度が1フレームに変化する量=(回転の速さ)を変数 rot_speed とします。
円運動の半径を変数 radius とします。
円運動の中心座標から現在位置までの角度を変数 rot とします。
角度が1フレームに変化する量=(回転の速さ)を変数 rot_speed とします。
円運動の半径を変数 radius とします。
例) 円運動を表現するのに必要なパラメータ
var px = 200; // 円の中心 x 座標
var py = 150; // 円の中心 y 座標
var rot = 0; // 円の角度(0 ~ 360)
var rot_speed = 5; // 円の角度変化量(0 ~ 360)
var radius = 30; // 円の半径
■考え方
波の解説で、片方の軸だけにサインカーブの運動をさせましたが x 軸と y 軸の両方にサインカーブの運動をさせるとどんな動きになるでしょう?
線の交点に注目です。
斜めに波の動きをしていますね。
では、片方の軸を +90 度分ずらしてみます。
円運動となりました。
ある角度から + 90 度分ずれたサイン値の結果を取得したい場合、同じ角度で得られるコサイン値でも同じ結果が得られます。
角度からラジアンに変換してコサイン値を得る
(角度 + 90度 で得られるサイン値と等しい)
(角度 + 90度 で得られるサイン値と等しい)
ラジアン = 角度 * Math.PI / 180;
コサイン値 = Math.cos ( ラジアン );
得られた、コサイン値を x軸に反映し、サイン値を y軸に反映すると、(x:1,y:0) を 0 度として時計回りに 360 度で一周する円運動となります。
サイン値とコサイン値で得られる値は、-1.0 から 1.0 までなので、この値に好きな半径値を乗算すれば、その半径値で移動する円運動となります。
■動かしてみる
Flash 5 での記述例です。
例) ムービークリップを円状に移動させる(Flash 5)
// --------------------------------------------
// 一度だけ実行されるイベント
// --------------------------------------------
onClipEvent (load) {
px = 200; // 円の中心 x 座標
py = 150; // 円の中心 y 座標
rot = 0; // 円の角度(0 ~ 360)
rot_speed = 5; // 円の角度変化量(0 ~ 360)
radius = 30; // 円の半径
}
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
onClipEvent (enterFrame) {
// 角度を変化させる
rot += rot_speed;
// 角度からラジアンに返還する
var rad = rot * Math.PI / 180;
var x = px + Math.cos(rad) * radius;
var y = py + Math.sin(rad) * radius;
// 座標をインスタンスの座標に反映
this._x = x;
this._y = y;
}
Flash MX 以降での記述例です。インスタンス mc を円状に移動させます。
例) ムービークリップ mc を円状に移動させる(FlashMX以降)
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 200; // 円の中心 x 座標
var py = 150; // 円の中心 y 座標
var rot = 0; // 円の角度(0 ~ 360)
var rot_speed = 5; // 円の角度変化量(0 ~ 360)
var radius = 30; // 円の半径
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// 角度を変化させる
rot += rot_speed;
// 角度からラジアンに返還する
var rad = rot * Math.PI / 180;
var x = px + Math.cos(rad) * radius;
var y = py + Math.sin(rad) * radius;
// 座標をインスタンスの座標に反映
this._x = x;
this._y = y;
};
■半径を少しずつ変化させる
半径を少しずつ大きくすると以下の画像のような動きが作れます。
半径を少しずつ大きくします
■動かしてみる
Flash MX 以降の記述例です。
例) 例)ムービークリップ mc の 半径を徐々に大きくしつつ円運動を行う(Flash MX 以降)
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 200; // 円の中心 x 座標
var py = 150; // 円の中心 y 座標
var rot = 0; // 円の角度(0 ~ 360)
var rot_speed = 5; // 円の角度変化量(0 ~ 360)
var radius = 0; // 円の半径
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// 半径を変化させる
radius += 0.5;
// 角度を変化させる
rot += rot_speed;
// 角度からラジアンに返還する
var rad = rot * Math.PI / 180;
var x = px + Math.cos(rad) * radius;
var y = py + Math.sin(rad) * radius;
// 座標をインスタンスの座標に反映
this._x = x;
this._y = y;
};
放物線(自由落下)のように移動させたい
■放物線の移動を行うのに必要なパラメータ
放物線の移動をさせるのに必要なパラメータは以下の通りです。
インスタンスの座標を、変数 (px, py) とします。
速度(1フレームで座標が変化する量)を、変数 (dx, dy) とします。
重力加速度(1フレームで速度が変化する量)を、変数 g とします。
速度(1フレームで座標が変化する量)を、変数 (dx, dy) とします。
重力加速度(1フレームで速度が変化する量)を、変数 g とします。
例) 放物線移動を表現するのに必要なパラメータ
var px = 0; // x 座標
var py = 0; // y 座標
var dx = 2; // x 方向の速度
var dy = 3; // y 方向の速度
var g = 0.2; // 重力加速度
■考え方
まず、重力加速度 g に好きな値を設定します。大きいほど、下方向へすばやく加速します。
次に速度 (dx,dy) に好きな値をセットします。初速をセットすると放物線の軌跡が決まります。
重力は、真下方向に常に働きます。y 軸のみ重力が働き、x 軸方向には何の力も働きません。
という事は、x軸方向は等速移動となり、y軸方向は加速移動となります。
放物線は x 方向が等速運動となり y 方向が加速運動となる
壁に衝突する、2段ジャンプを行いたいなどの、放物線の軌跡を変化させたい場合は速度に別の値を再設定します。
■動かしてみる
Flash 5 での記述例です。ムービークリップに放物線運動を行います。
例) ムービークリップに放物線運動をさせる(Flash 5)
// --------------------------------------------
// 一度だけ実行されるイベント
// --------------------------------------------
onClipEvent (load) {
px = 100; // x 座標
py = 200; // y 座標
dx = 2.0; // x 方向の速度
dy = -10.0; // y 方向の速度
g = 0.3; // 重力加速度
}
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
onClipEvent (enterFrame) {
// y 方向速度に重力加速度を加算
dy += g;
// 座標に速度を加算
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
}
Flash MX 以降での記述例です。ムービークリップ mc に放物線運動を行います。
例) ムービークリップ mc に放物線運動をさせる(Flash MX 以降)
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 100; // x 座標
var py = 200; // y 座標
var dx = 2.0; // x 方向の速度
var dy = -10.0; // y 方向の速度
var g = 0.3; // 重力加速度
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// y 方向速度に重力加速度を加算
dy += g;
// 座標に速度を加算
px += dx;
py += dy;
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
};
■放物線移動の公式
上記のプログラムで計算した場合、以下の公式が成り立つようです。
y 方向の初速(0フレーム目の時点)を変数 dy0 とします。
初速をセットしてから経過したフレーム数を変数 f とします。
y 方向の速度(f フレーム目の時点)を変数 dy とします。
重力加速度を変数 g とします。
初速をセットした位置からf フレーム経過したときの高さの差分を変数 h とします。
初速をセットしてから経過したフレーム数を変数 f とします。
y 方向の速度(f フレーム目の時点)を変数 dy とします。
重力加速度を変数 g とします。
初速をセットした位置からf フレーム経過したときの高さの差分を変数 h とします。
放物線公式 その1
dy = dy0 + g * f;
放物線公式 その2
h = (dy0 + g / 2) * f + 0.5 * g * f * f;
上記の 2 つの式から、上方向に投げたときに、最高の高さに到達するまでのフレーム数が解ります。(dy が 0 のときなので)
投げ上げて最高の高さに到達するまでのフレーム数
(結果が 0 より小さいなら投げ上げではない)
(結果が 0 より小さいなら投げ上げではない)
フレーム数 = - dy0 / g;
投げ上げを開始して到達する最高の高さ
最高の高さ = -(dy0 + g / 2) * dy0 / g + 0.5 * dy0 * dy0 / g;
■地面に反射させてみる
y 座標が 300 の位置を 地面としてみます。
y 座標が 300 より大きくなった場合、地面に当たったとみなして反射させます。
傾斜の無い地面の反射は簡単です。y方向速度のみ、符号を反転させるだけです。Flash MX 以降での記述例です。
傾斜の無い地面の反射は簡単です。y方向速度のみ、符号を反転させるだけです。Flash MX 以降での記述例です。
例) ムービークリップ mc の放物線運動に地面の反射を追加する(Flash MX 以降)
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 100; // x 座標
var py = 200; // y 座標
var dx = 2.0; // x 方向の速度
var dy = -10.0; // y 方向の速度
var g = 0.3; // 重力加速度
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// y 方向速度に重力加速度を加算
dy += g;
// 座標に速度を加算
px += dx;
py += dy;
// y 座標が 300 より大きいなら地面と当たった事にする
if(py > 300){
py = 300; // y 座標を地面の位置まで戻す(めり込んでるので)
dy *= -1; // y 方向の速度の符号を反転させる
dy *= 0.9; // お好みの反発係数(0.0~1.0)を乗算
}
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
};
さらに追加して x 座標が 400 の位置を壁としてみます。
x 座標が 400 より大きくなった場合、壁に当たったとみなして反射させます。
垂直な壁の反射は簡単です。x方向速度のみ、符号を反転させるだけです。
垂直な壁の反射は簡単です。x方向速度のみ、符号を反転させるだけです。
例) ムービークリップ mc の放物線運動に壁の反射を追加する(Flash MX 以降)
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 100; // x 座標
var py = 200; // y 座標
var dx = 2.0; // x 方向の速度
var dy = -10.0; // y 方向の速度
var g = 0.3; // 重力加速度
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// y 方向速度に重力加速度を加算
dy += g;
// 座標に速度を加算
px += dx;
py += dy;
// y 座標が 300 より大きいなら地面と当たった事にする
if(py > 300){
py = 300; // y 座標を地面の位置まで戻す(めり込んでるので)
dy *= -1; // y 方向の速度の符号を反転させる
dy *= 0.9; // お好みの反発係数(0.0~1.0)を乗算
}
// x 座標が 400 より大きいなら壁と当たった事にする
if(px > 400){
px = 400; // x 座標を壁の位置まで戻す(めり込んでるので)
dx *= -1; // x 方向の速度の符号を反転させる
dx *= 0.9; // お好みの反発係数(0.0~1.0)を乗算
}
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
};
さらに上下左右すべてに壁を追加してみます。
例) ムービークリップ mc の放物線運動に壁と天井の反射を追加する(Flash MX 以降)
// --------------------------------------------
// 初期化
// --------------------------------------------
var px = 100; // x 座標
var py = 200; // y 座標
var dx = 10.0; // x 方向の速度
var dy = -20.0; // y 方向の速度
var g = 0.3; // 重力加速度
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// y 方向速度に重力加速度を加算
dy += g;
// 座標に速度を加算
px += dx;
py += dy;
// y 座標が 300 より大きいなら地面と当たった事にする
if(py > 300){
py = 300; // y 座標を地面の位置まで戻す(めり込んでるので)
dy *= -1; // y 方向の速度の符号を反転させる
dy *= 0.9; // お好みの反発係数(0.0~1.0)を乗算
dx *= 0.95; // お好みの摩擦係数(0.0~1.0)を x 方向の速度に乗算
}
// y 座標が 0 より小さいなら天井と当たった事にする
if(py < 0){
py = 0; // y 座標を地面の位置まで戻す(めり込んでるので)
dy *= -1; // y 方向の速度の符号を反転させる
dy *= 0.9; // お好みの反発係数(0.0~1.0)を乗算
}
// x 座標が 0 より小さいなら壁と当たった事にする
if(px < 0){
px = 0; // x 座標を壁の位置まで戻す(めり込んでるので)
dx *= -1; // x 方向の速度の符号を反転させる
dx *= 0.9; // お好みの反発係数(0.0~1.0)を乗算
}
// x 座標が 400 より大きいなら壁と当たった事にする
if(px > 400){
px = 400; // x 座標を壁の位置まで戻す(めり込んでるので)
dx *= -1; // x 方向の速度の符号を反転させる
dx *= 0.9; // お好みの反発係数(0.0~1.0)を乗算
}
// 座標をインスタンスの座標に反映
this._x = px;
this._y = py;
};
座標が大きいか小さいかで判定する方法は簡単ですが、範囲が無制限に広がるため利用できる場面が限られます。
四角形の世界から外に出さないようなゲームなどで利用できます。
振り子のように移動させたい
サンプルをダウンロード
■振り子運動を行うのに必要なパラメータ
振り子運動に必要なパラメータは以下の通りです。
振り子の支点座標を、変数 (fx, fy) とします。
振り子の角度を、変数 rot とします。
振り子の角速度(1フレームで角度が変化する量)を、変数 rot_spd とします。
振り子の紐の長さを、変数 length とします。
重力加速度を、変数 g とします。
振り子の角度を、変数 rot とします。
振り子の角速度(1フレームで角度が変化する量)を、変数 rot_spd とします。
振り子の紐の長さを、変数 length とします。
重力加速度を、変数 g とします。
例) 振り子運動に必要なパラメータ
var fx = 0; // 支点 x 座標
var fy = 0; // 支点 y 座標
var rot = 2; // 角度
var rot_spd = 3; // 角速度
var length = 100; // 紐の長さ
var g = 0.2; // 重力加速度
■考え方
振り子の紐の部分ですが、たゆむと計算がややこしくなるので強固な棒とします。
まず、重力を無視してひたすら回転運動をさせて見ます。
角度と角速度に好きな値を設定してから、角速度を何度も角度に加算すると永遠に回転し続けます。
重りの座標は、角度と長さから以下の式で求まります。
振り子の重りの位置
重りの x 座標 = fx + Math.cos(rot * Math.PI / 180) * length;
重りの y 座標 = fy + Math.sin(rot * Math.PI / 180) * length;
次に重力を考慮してみます。
重力は真下方向に働きますが、振り子は強固な棒で構成されている為、重りの移動する方向は円を描くような方向に変換されます。この振り子運動を発生させるベクトルを調べてみます。
まず、支点から現在の重りまでのベクトルを算出します。これをベクトルAとします。
なお重りは、ベクトルAを90度回転させた方向のどちらかに移動が可能ですので、
重力加速度はこのベクトル方向のどちらかに変換されると思われます。
重りの座標を通過して、ベクトルAを90度回転させた方向に伸びる線を線Bとします。
重りの座標に重力移動量を加算してできる座標を座標Cとします。
座標CからベクトルA方向を向いた線と線Bとが交わる点を座標Dとします。
重りの座標から座標Dまでのベクトルが、振り子運動を発生させるベクトルとなります。
重力加速度を振り子運動を発生させるベクトルに変換することが出来ました。
このベクトルを角度に変換します。現在の角度とこの角度の差分を角移動量に足しこみます。
これで振り子運動となります。
■動かしてみる
Flash 5 での記述例です。ムービークリップに振り子運動を行います。
例) ムービークリップに振り子運動をさせる(Flash 5)
// --------------------------------------------
// 一度だけ実行されるイベント
// --------------------------------------------
onClipEvent (load) {
fx = 200; // 始点の x 座標
fy = 100; // 始点の y 座標
rot = 0; // 重りの角度
rot_spd = 0; // 角速度
length = 150; // 紐の長さ
g = 0.5; // 重力加速度
}
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
onClipEvent (enterFrame) {
// 現在の重りの位置
var rad = rot * Math.PI / 180;
var px = fx + Math.cos(rad) * length;
var py = fy + Math.sin(rad) * length;
// 重力移動量を反映した重りの位置
var vx = px - fx;
var vy = py - fy;
var t = -(vy * g)/(vx * vx + vy * vy);
var gx = px + t * vx;
var gy = py + g + t * vy;
// 2つの重りの位置の角度差
var r = Math.atan2(gy - fy,gx - fx) * 180 / Math.PI;
// 角度差を角速度に加算
var sub = r - rot;
sub -= Math.floor(sub / 360.0) * 360.0;
if(sub <-180.0) sub += 360.0;
if(sub > 180.0) sub -= 360.0;
rot_spd += sub;
// 摩擦
// rot_spd *= 0.995;
// 角度に角速度を加算
rot += rot_spd;
// 新しい重りの位置
rad = rot * Math.PI / 180;
px = fx + Math.cos(rad) * length;
py = fy + Math.sin(rad) * length;
// 重りの座標
this._x = px;
this._y = py;
}
Flash MX 以降での記述例です。ムービークリップ mc に振り子運動を行います。
例) ムービークリップ mc に振り子運動をさせる(Flash MX 以降)
// --------------------------------------------
// 初期化
// --------------------------------------------
var fx = 200; // 始点の x 座標
var fy = 100; // 始点の y 座標
var rot = 0; // 重りの角度
var rot_spd = 0; // 角速度
var length = 150; // 紐の長さ
var g = 0.5; // 重力加速度
// --------------------------------------------
// 毎フレーム実行されるイベント
// --------------------------------------------
mc.onEnterFrame = function (){
// 現在の重りの位置
var rad = rot * Math.PI / 180;
var px = fx + Math.cos(rad) * length;
var py = fy + Math.sin(rad) * length;
// 重力移動量を反映した重りの位置
var vx = px - fx;
var vy = py - fy;
var t = -(vy * g)/(vx * vx + vy * vy);
var gx = px + t * vx;
var gy = py + g + t * vy;
// 2つの重りの位置の角度差
var r = Math.atan2(gy - fy,gx - fx) * 180 / Math.PI;
// 角度差を角速度に加算
var sub = r - rot;
sub -= Math.floor(sub / 360.0) * 360.0;
if(sub <-180.0) sub += 360.0;
if(sub > 180.0) sub -= 360.0;
rot_spd += sub;
// 摩擦
// rot_spd *= 0.995;
// 角度に角速度を加算
rot += rot_spd;
// 新しい重りの位置
rad = rot * Math.PI / 180;
px = fx + Math.cos(rad) * length;
py = fy + Math.sin(rad) * length;
// 重りの座標
this._x = px;
this._y = py;
};