プロが教えるわが家の防犯対策術!

MC四角形が,ドラッグすることで,左右に動くようにしました。左右に動くときに一定の間隔で「止まる」というか「吸着する」ように設定するには,どのようなスクリプトが考えられるでしょうか。
動きとしては,複数の縦線のある表をその線上に来るたびに吸着する(止まる)感じにしたいのです。

環境 (XP,Flash8 初心者です。)

A 回答 (3件)

ネット上のFlash(SWF)サンプルでよく見る,


「ドラッグ&ドロップで,ドロップしたときに吸着させる」というものではなく,
「ドラッグの最中も吸着させる」というものですよね。
つまり,Flash作成ソフト上(FLAファイル上)での「グリッドに吸着」のような吸着のことだと思います(多分)。


基本的には,
SWF流に複数の縦線をムービークリップで作成して,
その縦線ムービークリップに,ドラッグするムービークリップを吸着させる。
という方法が簡単ではないかと思います。
スクリプト自体は違いますけど。

ステージ上にまず縦線を1本引いて,ムービークリップに変換し,
そのムービークリップにインスタンス名を付けます。
例えば 「line_mc0」 というインスタンス名を付けたとします。

その「line_mc0」をコピペで増やし,違うインスタンス名を連番で付けます。
例えば「line_mc0」~「line_mc9」の10本のMCを用意したとします。

 line_mc0 line_mc1 line_mc2 … … line_mc9
   |      |      |         |
   |      |      |         |
   |      |      |         |
   |      |      |         |



そして,「MC四角形」にもインスタンス名を付けます。
この説明では,「drag_mc0」 というインスタンス名を付けたとしておきます。


そして_rootのフレームに次のように書きます。

///////////////////////////////////////////////////////////
// ドラッグしている MC の番号の初期値を設定
drg_num = -1;
// マウス監視用のインスタンスを作成
mListener = new Object();
// マウスが動いたときの動作定義
mListener.onMouseMove = function() {
// drag_mc? をマウスの座標と一致させる
_root["drag_mc"+drg_num]._x = _root._xmouse;
_root["drag_mc"+drg_num]._y = _root._ymouse;
for (i=0; i<=9; i++) {
// マウスのx座標が line_mc? の x座標の±5 内であれば
if (_root._xmouse<_root["line_mc"+i]._x+5
&& _root._xmouse>_root["line_mc"+i]._x-5) {
// drag_mc? のx座標を line_mc? の x座標と一致させる。
_root["drag_mc"+drg_num]._x = _root["line_mc"+i]._x;
}
}
updateAfterEvent();
};
// マウス監視用のインスタンスをマウスリスナーに登録
Mouse.addListener(mListener);
//
// drag_mc0 を押したとき
_root.drag_mc0.onPress = function() {
drg_num = 0;
};
// drag_mc0 を放したとき
_root.drag_mc0.onRelease = function() {
drg_num = -1;
};
_root.drag_mc0.onReleaseOutside = _root.drag_mc0.onRelease;
///////////////////////////////////////////////////////////

一応勝手に,

// マウスのx座標が line_mc? の x座標の±5 内であれば
if (_root._xmouse<_root["line_mc"+i]._x+5
&& _root._xmouse>_root["line_mc"+i]._x-5) {

で,ドラッグするMCが,線の ±5 以内に入れば吸着するようにしてありますが,
この +5 や -5 を, +20 -20 のようにもっと大きな数にすれば吸着力はパワーアップします。
しかし,線と線の間隔の半分以下の数値にしてください。
そうでないと,思いもよらない線に吸着してしまいます。


また,
ドラッグしたいものがたくさんある場合は,
drag_mc0,drag_mc1,drag_mc2 …
のように連番付きインスタンス名を付けて,
それぞれのMC.onPress でその番号を drg_num に代入するようにしてやれば,
ドラッグするMCも増やせます。
 

この回答への補足

前回も教えていただきました。本当にありがとうございます。
今回の件ですが,
スクリプトはうまくかけたようなのですが(エラーが出ないので),動作には反映されませんでした。
実は,”MC四角形”自体にスクリプトを書き込んでいるのが,それが悪いのでしょうか。
よろしければ,再度ご教授いただければと思います。

補足日時:2007/07/10 23:07
    • good
    • 0

#1です。



ご質問で書かれていらっしゃる,

> 左右に動くときに一定の間隔で「止まる」というか「吸着する」

というものは,
すでに 『ActionScript の startDrag や stopDrag から逸脱した勝手なもの』なのです。
そこをまず自覚してください。
『ActionScript の startDrag や stopDrag から逸脱した勝手なもの』
が悪い物であるという意味では決してありません。
『ActionScript の startDrag や stopDrag から逸脱した勝手なもの』
ほど,面白みがあってオリジナリティがある良い物に近い可能性があります。
しかし,
『ActionScript の startDrag や stopDrag から逸脱した勝手なもの』は,
『ActionScript の startDrag や stopDrag から逸脱した勝手なもの』ですから,
そこを十分認識して,それなりの方法を自分で考えなければならないということです。


例えば,
「a=4,b=5 のとき a+b の解 x を 17,
 a=5,b=5 のとき a+b の解 x を 8 ,
 a=6,b=6 のとき a+b の解 x を 236 にしたい。」
と言っているようなものなのですよ。
そういうものに

a=6;
b=6;
x=a+b;

という ActionScript の加算演算子は使えませんよね。
最初から加算でも何でもないのですから,加算演算子を使うという発想に固執すること自体が間違っています。
そう言う勝手なルールがあるのなら,そういうルールでうまく行くように,自分なりにプログラミングしないと,
4+5=17,5+5=8,6+6=236 にはなりません。

a=6;
b=6;
if(a==4 && b==5){
x=17;
} else if(a==5 && b==5){
x=8;
} else if(a==6 && b==6){
x=236;
}

こうすれば,望み通りの解 x が求められます。
例が極端ですが,簡単に言うとそういうことです。


~~~~~~~~~~~~~~~~~~~~~~

> _rootのフレームに書くと言うのは,
> drag_mc0を置いているステージ上の
> タイムラインのフレームにということですよね。

そうですね。
階層で言うなら,

 _root(←このフレームに書く)
  ├ drag_mc(ムービークリップのインスタンス名)
  ├ line_mc0(       〃         )
  ├ line_mc1(       〃         )
  ├ line_mc2(       〃         )
    …
  └ line_mc9(       〃         )

ということです,

当然,ムービークリップには何も書かない方が良いですが。
しかし,
ムービークリップに startDrag や stopDrag が書いてあっても,一応吸着の動作はしましたよ。
startDrag や stopDrag にじゃまされるので,不安定にはなりますが,一応吸着は効いていることは効いています。



~~~~~~~~~~~~~~~~~~~~~~

#1 のスクリプトは基本的に startDrag や stopDrag は使いません。

 マウスダウンした状態で,
 マウスダウンされたムービークリップの座標をマウスの座標に一致させる。
 ただし,
 線の x座標にマウスが近い場合は,
 ムービークリップの座標をその線の x座標 と一致させる。

という流れのスクリプトを考えて作ったのです。


結局,補足に書かれていらっしゃる

> startDrag(this, false, 210.4, 198.1, 668.3, 198.1);

このドラッグする範囲の制限があるために,
startDrag や stopDrag を削除することができないということでしょうか?


そうであれば,#1のスクリプトを次のように変えれば良いと思います。

///////////////////////////////////////////////////////////
// ドラッグしている MC の番号の初期値を設定
drg_num = -1;
// マウス監視用のインスタンスを作成
mListener = new Object();
// マウスが動いたときの動作定義
mListener.onMouseMove = function() {
// drag_mc? の x座標 をマウスの x座標 と一致させる
_root["drag_mc"+drg_num]._x = _root._xmouse;
// drag_mc? の y座標 を 198.1 にする(★ココ変更)
_root["drag_mc"+drg_num]._y = 198.1;
for (i=0; i<=9; i++) {
// マウスのx座標が line_mc? の x座標の±5 内であれば
if (_root._xmouse<_root["line_mc"+i]._x+5
&& _root._xmouse>_root["line_mc"+i]._x-5) {
// drag_mc? のx座標を line_mc? の x座標と一致させる。
_root["drag_mc"+drg_num]._x = _root["line_mc"+i]._x;
}
}
// drag_mc? x座標が 210.4 未満であれば(★以下変更)
if (_root["drag_mc"+drg_num]._x<210.4) {
// drag_mc? のx座標を 210.4 にする。
_root["drag_mc"+drg_num]._x = 210.4;
// drag_mc? x座標が 668.3 より大きい場合は
} else if (_root["drag_mc"+drg_num]._x>668.3) {
// drag_mc? のx座標を 668.3 にする。
_root["drag_mc"+drg_num]._x = 668.3;
}
updateAfterEvent();
};
// マウス監視用のインスタンスをマウスリスナーに登録
Mouse.addListener(mListener);
//
// drag_mc0 を押したとき
_root.drag_mc0.onPress = function() {
drg_num = 0;
};
// drag_mc0 を放したとき
_root.drag_mc0.onRelease = function() {
drg_num = -1;
};
_root.drag_mc0.onReleaseOutside = _root.drag_mc0.onRelease;
///////////////////////////////////////////////////////////


日本語で書くと,

 マウスダウンした状態で,
 マウスダウンされたムービークリップの座標をマウスの座標に一致させる。
 ただし,
 線の x座標にマウスが近い場合は,
 ムービークリップの座標をその線の x座標 と一致させる。
 ただし,
 マウスダウンされたムービークリップ x座標が
 210.4 未満 もしくは 668.3 より大きいとき,その範囲内に戻す。

という流れになります。


ムービークリップの,スクリプトは消してください。

吸着がわかりにくいときは,
#1にも書きましたが,

 // マウスのx座標が line_mc? の x座標の±5 内であれば
 if (_root._xmouse<_root["line_mc"+i]._x+5
   && _root._xmouse>_root["line_mc"+i]._x-5) {

の 5 を 10 とか 20 にしてください。
「line_mc0」~「line_mc?」 の間隔がどうなっているかがわかりませんから,
てきとうに 5 を入れているだけです。

あと,線のMC「line_mc0」~「line_mc?」のインスタンス名もまちがえずに付けてください。

この回答への補足

再三に渡る懇切丁寧なご教授,本当に本当にありがとうございます。
ご指示通りにスクリプトを書き直してみましたが,
drag_mc0は動いてくれません。
ご指示されたスクリプトは,レイヤー「AS」を作りそこに全く同じように書き込みました。
インスタンス名も指示通りに付けてみましたが,だめです。
考えられることをもう少しやってみたいと思います。

補足日時:2007/07/12 23:14
    • good
    • 0
この回答へのお礼

おかげさまで,吸着を何とか確認することができました。
詳しいアドバイス本当にありがとうございました。
また何かありましたらよろしくお願いいたします。

お礼日時:2007/07/24 23:31

#1です。


書いたことを再び引用します。

> そして,「MC四角形」にもインスタンス名を付けます。
> この説明では,「drag_mc0」 というインスタンス名を付けたとしておきます。
>
>
> そして_rootのフレームに次のように書きます。
>
> /////////////////////////////////////////////
> // ドラッグしている MC の番号の初期値を設定
> drg_num = -1;
> // マウス監視用のインスタンスを作成

この回答への補足

再びのご教授ありがとうございます。思いつく点を修正しながら何度か試しているのですが,なかなかうまくいきません。

_rootのフレームに書くと言うのは,drag_mc0を置いているステージ上のタイムラインのフレームにということですよね。
私は,ここでは1フレームしか使ってないので,レイヤーASを作ってそこに書き込みました。
また,drag_mc0には次のようなスクリプトを書き込んでいます。
//////////////////////////////////////////////////////////////
on (press) {
startDrag(this, false, 210.4, 198.1, 668.3, 198.1);
}
on (release) {
stopDrag();
}
onClipEvent (mouseMove) {
updateAfterEvent();
}
//////////////////////////////////////////////////////////
分かっていない点が多々あり,そこが一番の問題なのだと心得ていますが,よろしければ,再度のご教授をお願いします。

補足日時:2007/07/12 05:06
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!