電子書籍の厳選無料作品が豊富!

Flash初心者で勉強中の身なのですがどうか質問させてください。
根本的に間違っていたりできないことをやろうとしていたら申し訳ないです。。
その際にはこう改変した方がいいとのご指示をご教示頂きたいです。よろしくお願いいたします。

attachMovieを使ってライブラリ内のMCをステージに呼び出し、そのMCを押す度にそのMCを切り替えたいと考えています。
ライブラリにはa1,a2,,,a5、b1,b2,,,,b5,c1,d1,e1…という識別子をつけたMCを用意しています。
a-eの横幅は80×80です。
20ずつ間を空けて○1のMCを横一列に配置しました。

_root.attachMovie("a1", "a1",1, {_x: 100, _y: 100});
_root.attachMovie("b1", "b1",1, {_x: 200, _y: 100});
_root.attachMovie("c1", "c1",1, {_x: 300, _y: 100});
_root.attachMovie("d1", "d1",1, {_x: 400, _y: 100});
_root.attachMovie("e1", "e1",1, {_x: 500, _y: 100});

このMCを押すと、MCが数字の大きいものに切り替わる(b1を押すとb2のMCに…で5まで)ようにしたいので、
ひとつひとつを下記のscriptで記述しました。

_root.attachMovie("b1", "b1",1, {_x: 200, _y: 100});
b1.onPress=function(){
b1.removeMovieClip();
_root.attachMovie("b2", "b2",1, {_x: 200, _y: 100});
b2.onPress=function(){
b2.removeMovieClip();
_root.attachMovie("b3", "b3",1, {_x: 200, _y: 100});
b3.onPress=function(){
b3.removeMovieClip();
_root.attachMovie("b4", "b4",1, {_x: 200, _y: 100});
b4.onPress=function(){
b4.removeMovieClip();
_root.attachMovie("b5", "b5",1, {_x: 200, _y: 100});}}}}

これをa-e同じことを繰り返しています。

ここからが問題なのですが、
ここで例えば a2,b5,c1,d3,e1 という風に適当に押されてMCが切り替わり、整列させるボタンが押された時、
その数字を参照して 縦に20pxずつ空けながら

b5
(空行/4があった場合の行)
d3
a2
c1(20pxの空白)e1

と並べ替えたいと思っています。

つまり、a-eが現在どの数字(○1,○2..)なのかを調べ、その数字の若い方から順に縦に配置させたいと考えています。
また、上のc1,e1のように1の数字のMCが2つ以上あった場合は、同じ行に20pxずつ空けて横に配置していきたいのです。
その調べた数字の順に縦と横に並べ替える(新たにステージ上に配置し直す)というルール付けをどういうscriptを書けば上手く行くかが自分ではどうにも分からず、ここから進めない状態です。。

誰がどんな回数押したとしてもそれに準じた整列をして欲しいのですが、そのやり方があるようでしたらどうかご教示頂きたいです。
また、上記の私の書き方では難しいようでしたらそこから改変したものをお教え願いたいです。
分からないことばかりで申し訳ないのですが、何卒よろしくお願いいたします。

A 回答 (3件)

#1、2です。




SetUp 関数内の

 ref = clip_addr.attachMovie(name_str, name_str, i);

の後に

 trace( ref );

と入れて、「ムービープレビュー」で確認してみてください。
_level0.a ~ _level0.e のターゲットパスが出力されれば、ムービークリップ a ~ e は存在しています。

存在しているにもかかわらず表示されない場合は、ステージから外れた位置に配置されてしまったのだと思います。
変数 org_x と org_y 、特に org_y の値を小さくして試してみてください。
整列した時は、番号が大きいものほど上に並びます。
最初は全て1なので、一番下である5段目(スクリプトでは0から数えているので4段目)に全部並ぶことになります。
つまり、それぞれの初期座標は

 X: org_x で指定された位置から、20 px 空けて横並び
 Y:(ムービークリップの高さ+ 20 )×4+ org_y

で、org_y を 0 にしてもY= 400 の座標になります。
#1のスクリプトは、org_x と org_y の場所に、一番上に並ぶ5番のムービークリップの左上が来る配置になっています。
この点を考慮して、位置やステージの大きさ・ボタンの配置等を決めてみてください。


trace 文でターゲットパスが表示されない場合は、何らかの原因でムービークリップの挿入が失敗しています。
よくあるミスはリンケージ名の誤りです。
文字コード 97 の代わりに 98 や 99 などを入れて、b 以降のムービークリップが表示されるかどうか、確認してみてください。
リンケージ名は”半角”の”小文字”で付けます。

- - - - -

例えば、

 for( i = 0 ; i < type_max ; i++ )
 {
  for( j = 1 ; j <= pic_max ; j++ )
  {
   name_str = String.fromCharCode( 97 + i ) + j;
   trace( name_str );
  }
 }

↑ このようなループにすると、a1 ~ e5 までの文字列を取得できます。
文字列ができれば、attachMovie で挿入したり、[ ] 演算子で参照に変換してムービークリップを参照することができます。

しかし、ムービークリップが全部独立していると、”次の番号の”ムービークリップに切り替える部分が面倒です。
アルファベットや番号がつながっていて名前に関連性はあっても、あくまでも独立したムービークリップ同士になるのですから、それぞれのアルファベットで今表示している番号がいくつであるかを取得する仕組みを作らないと難しいと思います。
また、今表示するもの以外は表示されない(もしくは重ねるなどして見えなくする)ようにする工夫も必要です。


一番手っ取り早いのは、a のムービークリップの1フレームに1つずつ、a1 ~ a5 のムービークリップを入れてしまうことです。
これなら、スクリプトも変更せずに済みます。
    • good
    • 0
この回答へのお礼

無事に動かすことができました!
ムービークリップのフレームに一つずつムービークリップを入れる方法も、灯台下暗しといいますか目から鱗で感動しました…
詳しく解説までしていただけて本当に勉強になりました。ありがとうございました!

お礼日時:2011/01/12 20:30

#1の解説です。




【絵の切り替え】

5×5種類くらいの絵で、ライブラリにシンボルがある絵でしたら、aやbの分類ごとにムービークリップにまとめた方が簡単だと思います。
タイムラインに1~5の絵を持っているムービークリップであれば、gotoAndStop で絵を切り替えられますし、現在表示しているフレーム( _currentframe プロパティ)を見ると、何番の絵を表示しているのかも分かります。
また、最後の絵を表示した後に切り替えると最初に戻るといった動作も、_totalframes プロパティの剰余を利用して簡単に実現できます。
これらの動作は全てのムービークリップで共通ですので、クリックした時の動作は関数(#1では Change_Frame 関数)を1つ作成し、この関数を各ムービークリップの onPress イベントハンドラに登録しています。


【並べ替え】

二重ループを組み、上から順に1段ずつ、その段に並べるべきムービークリップがあるかどうかを調べて、該当するものがあればその段に配置します。
#1の作例では、外側の i のループが段、内側の j のループがムービークリップを総当たりで調べるためのループです。

各ムービークリップの現在の表示フレームである _currentframe プロパティの値が、現在表示している絵の番号になります。
外側の i のループで番号を上(=5番)から数え、そのループ中にムービークリップを全て調べる j のループを入れて、_currentframe と i の値を照合します。
両者が一致しているものが、i が示す段に並ぶムービークリップです。

ムービークリップのインスタンス名は a ~ e です。
内側の j のループは、j が 0 ~ 4 の間、継続します。
この j の値と、”a”の文字コードである 97 を利用して、a から e までのムービークリップを順に参照します。
アルファベットの文字コードは、a から順に1ずつ増えていきます。
従って、a の文字コードの 97 に、0 からカウントアップする j の値を加算した文字コードを String.fromCharCode で文字に変換すると、a ~ e の文字を順に取得することができます。
こうして得た文字を [ ] 演算子で参照に変換すれば、ムービークリップ a ~ e を順番に参照できるというわけです。

内側のループで指定の段に並べるムービークリップを調べる際に、既にいくつ並べたのかを数える変数を1つ、用意しておきます。#1の作例では、px という変数です。
該当するムービークリップが見つかる度に、px を1ずつ増やします。
この px の値をもとにしてX座標を算出すれば、該当するムービークリップを、同じ段に横に並べていくことができます。


なお、並べ替えた時の全体の原点は左上、つまり、5番の絵を表示しているムービークリップが並ぶ段の左上です。
この位置は変数 org_x と org_y に入っていますので、適宜調整してください。

この回答への補足

ご丁寧な回答誠にありがとうございます!
String.fromCharCodeで文字を呼び出すという方法があるのですね…全く知らなかった方法でしたので試してみたところ感動してしまいました。

早速ライブラリにリンケージ名でa~eのMCを用意し、ステージ上にボタンを配置して全体を試させて頂いたのですが…動きませんでした…。
症状はステージ上にMCが読み込まれず、並べ替えにも至りませんでした。
分解してみたところ、クリックするとフレームが動くところは動作したのですが、素人の私見なのですが下記のiの部分が上手く動いていないような気がします。

function SetUp() {
var i:Number;
var name_str:String;
var ref:MovieClip;


//MCのセットアップ
for (i=0; i<type_max; i++) {
//MCを挿入し、フレーム1で止めておく
name_str = String.fromCharCode(97+i);
ref = clip_addr.attachMovie(name_str, name_str, i);
ref.gotoAndStop(1);

//ボタン機能を定義
ref.onPress = Change_Frame;
}

//位置を決める
Clip_Align();

//「整列」ボタンの機能を定義
align_btn.onRelease = Clip_Align;
}

//セットアップを実行
SetUp();

この  name_str = String.fromCharCode( 97 + i ) ;
の+iを除くとステージ上の左上に97(aのMC)が呼び出され、クリックするたびに中のフレームは移動しました。
しかし+iを入れるとステージ上に何も呼び出されないという現象が起きてしまいます。
折角教えて頂けたのに大変申し訳ないのですが、再度ご教授いただけませんでしょうか…?

また、こちらは簡単に分かるようだったらで全く構わないのですが、
String.fromCharCodeを利用してMCを押す度にa1,a2...a5とMC自体が切り替わることも可能でしょうか?
実はa1,a2...a5やb1,b2...のMCは全て違うムービーを入れてあったので、
私が最初に書いていたscriptではattachMovieとremoveMovieClipを使ってまだるっこしくもMC自体も切り替えていました。
こちらはもし分かるようでしたらで構いませんので、もしお手隙でお時間があるようでしたらご教授いただければ幸いです。
何卒よろしくお願いいたします。

補足日時:2011/01/11 16:24
    • good
    • 0

作り方の一例です。




aの1 ~5までの絵を1フレームに1つずつ配置したムービークリップを作り、リンケージ名を”a”にします。
この時、それぞれの絵の左上が、編集画面にある+印の角に来る(絵の左上がX= 0、Y= 0 になる)ように配置してください。
残るb~eも同様に、同じ名前の絵を1つのムービークリップにまとめ、リンケージ名を”b”や”e”にします。

「整列」のボタンを作り、ステージに配置してインスタンス名を付けます。
ここでは仮に”align_btn”とします。

メインのタイムラインに次のスクリプトを記述し、プレビューで確認してみてください。
ムービークリップをクリックすると絵が変わり、「整列」ボタンを押すと、上から5番を表示しているものから順に、横の並びは名前の順に並びます。

(↓ 各行頭に全角のスペースが入っています。コピーする際は、全て半角のスペースかタブに置き換えてください)


/*
 初期設定
*/

//ムービークリップ(MC)の大きさ
var clip_w:Number = 80;
var clip_h:Number = 80;

//配置する際の基準の座標と余白(縦横兼用)の大きさ
var org_x:Number = 100;
var org_y:Number = 100;
var margin = 20;

//MCの種類と絵柄の数
var type_max:Number = 5;
var pic_max:Number = 5;

//MCがあるタイムラインを保持
var clip_addr:MovieClip = _root;


/*
 MCの画像を切り替える関数
*/

function Change_Frame():Void
{
 //次のフレームに進める
 //最後まで行ったら1に戻る
 this.gotoAndStop( ( this._currentframe % this._totalframes ) + 1 );
}

/*
 並べ替えを行う関数
*/

function Clip_Align():Void
{
 var i:Number , j:Number , px:Number;
 var ref:MovieClip;


 //表示フレームを順に調べ、表示しているMCがあれば横に並べる
 for( i = pic_max ; i >= 1 ; i-- )
 {
  //全てのMCをチェック
  for( j = 0 , px = 0 ; j < type_max ; j++ )
  {
   //操作するMCの参照を作成
   //97は”a”の文字コード
   ref = clip_addr[ String.fromCharCode( 97 + j ) ];

   //該当するMCがあった場合、横に並べていく
   if( ref._currentframe == i )
   {
    ref._x = ( clip_w + margin ) * px + org_x;
    ref._y = ( clip_h + margin ) * ( pic_max - i ) + org_y;

    //次のためにpxを更新
    px++;
   }
  }
 }
}

/*
 セットアップ
*/

function SetUp()
{
 var i:Number;
 var name_str:String;
 var ref:MovieClip;


 //MCのセットアップ
 for( i = 0 ; i < type_max ; i++ )
 {
  //MCを挿入し、フレーム1で止めておく
  name_str = String.fromCharCode( 97 + i ) ;
  ref = clip_addr.attachMovie( name_str , name_str , i );
  ref.gotoAndStop( 1 );

  //ボタン機能を定義
  ref.onPress = Change_Frame;
 }

 //位置を決める
 Clip_Align();

 //「整列」ボタンの機能を定義
 align_btn.onRelease = Clip_Align;
}

//セットアップを実行
SetUp();


* * * * *

字数制限の都合上、詳細は次の回答で説明いたします。
    • good
    • 0

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