dポイントプレゼントキャンペーン実施中!

「クリックしたムービークリップ以外のムービークリップが、ステージ下部に左端から等間隔で整列する」
という動きを実現したいのですが、どうやって等間隔に並べるのか良くわからず、悩んでます。

■ムービー開始時
「カード1」「カード2」「カード3」「カード4」「カード5」

■例えばカード3をクリック
         「カード3」(その場に残る)


「カード1」「カード2」カード4」「カード5」
(他はステージ下部に左から等間隔に並ぶ)


-----------------------------------------------
作ったとこまで(って程でもないですが)途中までのfunctionです。

function f_choice(xNumber){
 var i=1, maxNum=9;
 while( i < xNumber ){
  ここに等間隔で並べる設定?
  i++;
 }
 i++;
 while( i <= maxNum ){
  ここに等間隔で並べる設定?
  i++;
 }
}

※実際に作るやつでは、カードは全部で9枚あり、ステージ下部に2行4列で並びます。

宜しくお願いします。

A 回答 (2件)

#1です。



うまく動いたのであれば,それで良いと思いますよ。

 xCard.gotoAndPlay("stay");

とか,

 xCard.gotoAndPlay("small");

がどういう状態かわからず,
つまり各カードの中がどうなっているのかわかりませんから,
その点が再現できませんでしたが,書かれているので良いと思います。


そのままで良いと思いますので,下記は参考までです。

やっぱり考え直したのですが,#1 で答えたように,各MCにほとんど同じ事を書くのは変ですし,
修正もやっかいなので,私も勝手に自分のをつくりかえました。
自分のものを作りかえただけなのであまり参考にはならないと思います。

(単なる言い訳ですが,
 #1 の回答は Flash の使えないところで,メモ帳で書いて
 それをコピペしただけなのです。
 たまたま Flash を実際に動かすことができない席(職場)にいたもので,
 スクリプトもメモ帳で書いて,家に帰って,Flash に貼り付けて,
 急がれているようでしたし,
 「エラーが出なかったしうまく動いたので良し。」
 としたものです。
 Flash がないところで考えるのはあれが私の限度です。
 あの状態から各MC のスクリプトをフレームにまとめるのは,
 Flash がないとできません。)

(ついでに… 私の Atoc は優秀で,
 「い」と打って変換したら 「 if (==) {} else if () {} 」 とか,
 「お」と打って変換したら 「 onClipEvent (load) {} 」とか,
 そんなのが出てくるように教育してあるのです。
 「も」と打ったら「モーショントゥイーン」とかもね。
 だからメモ帳でも結構楽に打てます。)

(さらについでに…
 ココで他の方から教えてもらったスクリプトで作った自作のエディタも
 よく活用させてもらっています。
 http://oshiete1.goo.ne.jp/kotaeru.php3?q=1514074
  ↑教えて!goo ↓OKWave (同じです)
 http://okwave.jp/kotaeru.php3?q=1514074  
 --- 余談終わり )


>> クリックされたカードは、ステージ左に移動していって、…

ということなので,
左に移動した地点にインスタンス名 main_pos という空のMCを用意しました(またかよ! ですね)。
その座標を計算するのがやはり苦手なのです…(o_ _)o))
数字 とか 座標 から逃げたい人種なのです(恥)。
カードにも 「card1」~「card9」までのインスタンス名を付けました。


ステージを図示すると次のような感じにしました。
□ で埋め尽くされて四角くなったエリア全体がステージ,
● がスタート地点
■ がゴール地点のMC
▲ が左に移動した地点のMC(インスタンス名:main_pos)
ということです。

    ┌---------- s1 ~ s9 -----------┐
 □□□□□□□□□□□□□□□□□□□□□
 □□□□□□□□□□□□□□□□□□□□□
 □□●□●□●□●□●□●□●□●□●□□
 □□□□□□□□□□□□□□□□□□□□□
 □□□□□□□□□□□□□□□□□□□□□
 □□▲□□□□□□□□□□□□□□□□□□
 □□□□□□□□□□□□□□□□□□□□□
 □□□□□□□□□□□□□□□□□□□□□
 □■□■□■□■□□□□□□□□□□□□□
 □□□□□□□□□□□□□□□□□□□□□
 □■□■□■□■□□□□□□□□□□□□□
 □□□□□□□□□□□□□□□□□□□□□
  └-- g1~g8 --┘


今回のスクリプトは,MCに一切書きません。
_root の フレーム1 に書くだけです。

※ これは for文 の 中に if文 があるなど,
 ややこしい構造になっているので インデントをつけました。
 もしコピペされる場合は全角の空白文字を削除してください。
------------------------------------------------
//変数フラグの初期値
var flg = 0;
//スピードの設定 (※可変)
var spd = 3;
//カードの枚数を設定
var maxNum = 9;

for (var i = 1; i<=maxNum; i++) {
  //カードのパスの変数化
  var xCard = _root["card"+i];
  //各カードをストップ
  xCard.stop();
  //各カードに 変数myNum を設定
  xCard.myNum = i;
  //初期座標を s○ に合わせる
  xCard._x = _root["s"+i]._x;
  xCard._y = _root["s"+i]._y;
}

this.onEnterFrame = function() {
  for (var i = 1; i<=maxNum; i++) {
    //カードのパスの変数化
    var xCard = _root["card"+i];

    //カード内のフレームが最終フレームに達したとき
    if (xCard._currentframe>=xCard._totalframes) {
      //フラグに myNum を代入
      _root.flg = xCard.myNum;
      //ガードをフレーム1で止める
      xCard.gotoAndStop(1);
    }

    //フラグが myNum と等しいとき
    if (_root.flg == xCard.myNum) {
      //main_pos の位置へ移動
      xCard._x += (_root.main_pos._x-xCard._x)/spd;
      xCard._y += (_root.main_pos._y-xCard._y)/spd;
      //フラグが 0 ではなく かつ myNum より小さいとき
    } else if (_root.flg != 0 && _root.flg<xCard.myNum) {
      //下のゴール位置に移動(ポジションは g(○-1))
      xCard._x += (_root["g"+(i-1)]._x-xCard._x)/spd;
      xCard._y += (_root["g"+(i-1)]._y-xCard._y)/spd;
      //フラグが myNum より大きいとき
    } else if (_root.flg>xCard.myNum) {
      //下のゴール位置に移動(ポジションは g○)
      xCard._x += (_root["g"+i]._x-xCard._x)/spd;
      xCard._y += (_root["g"+i]._y-xCard._y)/spd;
    }

  }
};

//各カードをクリックしたとき play(); させる
for (var i = 1; i<=maxNum; i++) {
  _root["card"+i].onRelease = function() {
    this.play();
  };
}
------------------------------------------------

部分的なポイントの説明です。

 xCard.gotoAndPlay("stay");
 xCard.gotoAndPlay("small");

がわからないので,勝手にカードの中は最初のフレームでストップさせています。

 //各カードをストップ
 xCard.stop();


それで,最終の for文

 //各カードをクリックしたとき play(); させる
 for (var i = 1; i<=maxNum; i++) {
   _root["card"+i].onRelease = function() {
     this.play();
   };
 }

で,任意のカードがクリックされたとき,
そのカード内のフレームを play(); させて,

    //カード内のフレームが最終フレームに達したとき
    if (xCard._currentframe>=xCard._totalframes) {
      //フラグに myNum を代入
      _root.flg = xCard.myNum;
      //ガードをフレーム1で止める
      xCard.gotoAndStop(1);
    }

で,カード内のフレームが最終フレームに達したとき,
フラグを変えるというものにしました。


書かれているスクリプトとは違う形なので参考にはしにくいとは思いますが,
ガードの最終フレームにスクリプトを書かなくても,
_root の フレームでも カード内の フレーム は監視できるので,
上のような,

  if (xCard._currentframe>=xCard._totalframes) {

を使うと,もう少しスッキリするかもしれませんね。


/////////////////////////////////////////////////////////////////////

それと,補足に書かれている最後のところの,
if(){} if(){} と分けてするのと if(){}else(){} とひとまとまりにする場合の件についてです。

もしどっちでも OK な場合は,どっちでも良いのですが,
どっちかと言うと if(){}else(){} の方が良いと思います。
一応1つの if文 ということになりますし,管理が簡単なような…・・・
と思うだけですけどね。

昨日,#1 で書いたものの場合は,if(){} if(){} と分けてはだめです。
myNum は 1~9 まで存在するので, flg は 0~9 までの数が入ります。
数直線的に表すと

「カード3」の場合(myNum = 3 の場合)

  負零一二三四五六七八九 … flgの値
  □●□□●□□□□□□ ← if flg が 0 か 3 の場合
  ●□●●□□□□□□□ ← else if で flg が 3 より小
  □□□□□●●●●●● ← else if で flg が 3 より大

2番目の「else で flg が 3 より小」の場合に絶対 else が必要です。
 if (_root.flg<myNum) を独立させてしまったら flg が 0 の時も,
 this._x += (_root["g"+(myNum-1)]._x-this._x)*_root.spd;
が実行されてしまいます。

  負零一二三四五六七八九 … flgの値
  □●□□●□□□□□□ ← if flg が 0 か 3 の場合

  ●●●●□□□□□□□ ← if flg が 3 より小 の場合

  □□□□□●●●●●● ← if flg が 3 より大 の場合


つまり何もクリックされないのにカードが動き出します。
いくら flg が myNum より小さいからと言っても 0 のときは実行されては困るわけで,
だから else if です。

スクリプトは普通,上の行から実行されるので "後勝ち" になります。
だから, 順番を変えれば if(){} if(){} でも可能になります。


  負零一二三四五六七八九 … flgの値
  ●●●●□□□□□□□ ← if flg が 3 より小 の場合(0 の分岐は負ける)

  □●□□●□□□□□□ ← if flg が 0 か 3 の場合(0 の分岐は勝つ)

  □□□□□●●●●●● ← if flg が 3 より大 の場合

しかし,プログラムの実行される性質まで考えるのは大変です。また意味合いが違います。


else は縦に「振るい」を3つならべて
トラックによって運ばれてきた土砂を1回の作業で,
小石,砂,粘土 に振り分けているイメージでしょうか。
    • good
    • 0
この回答へのお礼

色々とありがとうございました。
こんなにたくさん説明していただけて、助かりました。

あと、今回説明が乱雑ですいません。
ちょっと焦りがあったりとかもして・・・(汗;)
無事その後のscriptも組めました・・・たぶん(笑)
それと自分が書いたscriptもかなり無駄がありましたね・・・(恥;;)

今はそれらも整理整頓してひと段落って感じです。
whileのなかで「i」の他に「t」とか作っちゃったりとか、そんなん単に「i-1」とかにすりゃい~のに。
まだまだ全然勉強不足って感じですね。

一日も早くsassakunさんのようになれるよう頑張りまっす!!

追伸。。
以前クリックされたポイントを軸に拡大・縮小って教えていただいたじゃないですか?
あれ、仕様がすげ~変わって、いちから作り直しになりました(笑)
いまからその作業に入るところです(笑)

お礼日時:2006/02/20 16:21

移動した後,どうなるのかとかがわかりませんから,


ちょんとした回答はできませんが,
こんなのはどうでしょうか。

スタート地点とゴール地点にMCを置いて,
フラグによって,各ムービークリップをとゴール地点のMCまで移動させる方法です。

「カード1」 ~ 「カード9」 までのスタート地点に インスタンス名 s1 ~ s9 までの空(カラ)の MC を用意します。透明でも良いですが,透明だと編集中に見えにくいので,空のMCの方が良いと思います。
s1 ~ s9 の s は スタート の s とでも思ってください。

そして,等間隔に整列させたいゴール地点には インスタンス名 g1 ~ g8 までの空の MC を二列に等間隔に並べます。

「カード1」 ~「カード9」 の MC ですが,これは適当に何処かに配置してくだされば OK です。
どこに置いてもスタート地点はスクリプトによって, s1 ~ s9 のポイントになります。

ステージを図示すると次のような感じになるでしょうか。
□ で埋め尽くされて四角くなったエリア全体がステージ,
● がスタート地点 ■ がゴール地点のMCということです。

    ┌---------- s1 ~ s9 -----------┐
 □□□□□□□□□□□□□□□□□□□□□
 □□□□□□□□□□□□□□□□□□□□□
 □□●□●□●□●□●□●□●□●□●□□
 □□□□□□□□□□□□□□□□□□□□□
 □□□□□□□□□□□□□□□□□□□□□
 □□□□□□□□□□□□□□□□□□□□□
 □□□□□□□□□□□□□□□□□□□□□
 □■□■□■□■□□□□□□□□□□□□□
 □□□□□□□□□□□□□□□□□□□□□
 □■□■□■□■□□□□□□□□□□□□□
 □□□□□□□□□□□□□□□□□□□□□
  └-- g1~g8 --┘

スタート地点 s1 ~ s9 はどんな状態か想像しにくかったので,
頭の中で勝手に一列に配置してみました。
べつに図の通りでなくてもかまいません。
思うような場所に空のムービークリップを配置してください。


次にスクリプトです。
まず,ルートのタイムライン フレーム1 のスクリプトとして,
次の変数を設定しておきます。

--------------------------------
//変数フラグの初期値
var flg = 0;
//スピードの設定(※可変です)
var spd = 0.25
--------------------------------


次に カード となる9個の各MCに次のようなスクリプトを書きます。
カードの動き自体には,全て this を使うのでインスタンス名は特に不要です。
次の例は「カード3」のスクリプトです。
1~9のカードにほとんど全て同じスクリプトを書くわけですが,
1行 var myNum = 3; の部分だけが各カードMCによって違います。
「カード4」 だと var myNum = 4; となります。

---------------------------------------------------
onClipEvent (load) {
//カードNo.の設定(※ココだけMCによって違う)
var myNum = 3;
//初期座標を s○ に合わせる
this._x = _root["s"+myNum]._x;
this._y = _root["s"+myNum]._y;
}

onClipEvent (enterFrame) {

//フラグが 0 と等しいもしくは myNum と等しいとき
if (_root.flg == 0 || _root.flg == myNum) {
this._x += (_root["s"+myNum]._x-this._x)*_root.spd;
this._y += (_root["s"+myNum]._y-this._y)*_root.spd;

//フラグが myNum より小さいとき
} else if (_root.flg<myNum) {
this._x += (_root["g"+(myNum-1)]._x-this._x)*_root.spd;
this._y += (_root["g"+(myNum-1)]._y-this._y)*_root.spd;

//フラグが myNum より大きいとき
} else if (_root.flg>myNum) {
this._x += (_root["g"+myNum]._x-this._x)*_root.spd;
this._y += (_root["g"+myNum]._y-this._y)*_root.spd;
}
}

on (release) {
//フラグの値を myNum に変える
_root.flg = myNum;
}
---------------------------------------------------

上記スクリプトでは,一度目に任意のカードをクリックした後,
整列した他のカードをクリックすればクリックした物だけが元の位置に帰り,
他の物は配置換えをします。

一度目のクリックのみ有効にする場合は,
別のフラグを用意するなどして,条件を増やしてやれば,
2度目以降のクリックを無効にすることもできると思います。
また,無効の解除もできると思います。


ちなみに,
私は数字で座標を決めたりするのが苦手なので,
よく MC を目標地点に用意して ActionScript で物を動かします。
レイアウト調整なんかもいちいち数式を変えたり計算をし直さなくて良いので楽です。
スタート地点もゴール地点も後から好きなように主観的に変えられます。


/////////////////////////////////////////////////

あと,思うのですが,
「カードは9枚 "も" あってどれがクリックされるかわからないから難しい~!」
と考えると難しくなるわけで,
「カードは9枚 "しか" ないからどれをクリックされても大丈夫!」
と考えると簡単になります。

整列するアニメーションをモーショントゥイーンで9パターン作れば良いだけです。
モーショントゥイーン ですから,当然 gotoAndPlay(); と stop(); くらいでできるのではないでしょうか。
また,モーショントゥイーンだと,上のよう直線的な動きでなく,もっと自由自在に動かせます。

もし,何かの拍子に元の位置にカードを戻す場合も,
元の位置に帰る場合 9×9=81 パターンのアニメーションが必要なわけではなく,
場合によっては9つのアニメーションで済みます。
行きと返りは1セットだととすると,9パターンで OK です。

モーショントゥイーン も 選択肢のうちの1つになると思いますよ。


しかし,

 >> 「クリックしたムービークリップ以外のムービークリップが、
 >> ステージ下部に左端から等間隔で整列する」

というところまでしか条件がないため,
上記スクリプトの例でも,モーショントゥイーンの方法でも全く参考にならない気はしています。

この回答への補足

まずはじめに、説明不足で申し訳すいませんでした・・・
大体分かり、また参考になりました。

ムービーを説明させていただくと
クリックされたカードは、ステージ左に移動していって、そのカードの詳細コンテンツが上からフェードインしてくる。
それ以外のカードは、下に整列。下に整列したカードをクリックすると、ステージ左にあるカードと詳細コンテンツの中身がクリックされたサムネイルと入れ替わるって感じです。・・・伝わるかな(不安。。。)

ステージ--------------------------------------

「クリックされたカード」  「クリックされたカードの詳細コンテンツ」


「サムネイル」「サムネイル」「サムネイル」

---------------------------------------------

sassakunさんから回答を頂く前に自分でも色々考えて何とかやってみたりもしました。それが下記です。

ar_line = new Array( "posA", "posB", "posC", "posD", "posE", "posF", "posG", "posH" );
function f_choice(xNumber){
 var i=1, maxNum=9, t=0;
 while( i < xNumber ){
  xCard = this[ "card"+i];
  xCard.gotoAndPlay("small");
  xCard.v_target = ar_line[t];
  i++;
  t++;
 }
 xCard = eval( "card"+i );
 xCard.gotoAndPlay("stay");
 second.play();
 i++;
 while( i <= maxNum ){
  xCard = this[ "card"+i ];
  xCard.gotoAndPlay("small");
  xCard.v_target = ar_line[t];
  i++;
  t++;
 }
}

で、カードの中身にモーションがありまして、そのモーションが終わったら移動するってしたかったので、そのフレームに
switch(_parent.v_target){
 case "posA" : nDestX=16; nDestY=428; break;
 case "posB" : nDestX=190; nDestY=428; break;
 case "posC" : nDestX=362; nDestY=428; break;
 case "posD" : nDestX=536; nDestY=428; break;
 case "posE" : nDestX=16; nDestY=479; break;
 case "posF" : nDestX=190; nDestY=479; break;
 case "posG" : nDestX=362; nDestY=479; break;
 case "posH" : nDestX=536; nDestY=479; break;
}

this.onEnterFrame = function(){
 _parent._x += (nDestX-_parent._x)/3;
 _parent._y += (nDestY-_parent._y)/3;
 _parent._rotation = 0;
}

てな感じでかいてみました。


なんとか、できたはできたんですけど、やっぱりsassakunさんの作ったやつと比べるとすげー無駄が多い気もしますし・・・

で、ひとつ質問いいですか?
すいません、長々と。前々から疑問に感じてた事なんですが、
sassakunさんのやつでも出てくるif。
if(){}
if(){}
ってやるのと、
if(){}else(){}
って作っていくのとで違いってあります?

補足日時:2006/02/19 00:17
    • good
    • 0

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