- 締切済み
FlashLite1.0 配列に代わる方法
初めまして、宜しくお願い致します。 現在FlashLite1.0でブロック崩しを作成しながら 勉強をしています。その中で行き詰ってしまった点があり、 是非よろしければアドバイスを頂けたら嬉しいです。 ブロックがすべて消えた事をチェックして 「ゲームクリア」の画面に移動したいのですが、ブロックが すべて消えた事をチェックする方法がわかりません。 Flash5以上のスクリプトでは「for」を使用して配列をチェック 出来るのですが、FlashLite1.0ではどのように記述 すればよろしいでしょうか? 宜しくお願い致します。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- suzuki-_-
- ベストアンサー率77% (152/195)
> 初期設定をしているフレームに宣言すべきだと思うのですが・・・ > どのようにすればよろしいのでしょうか? ブロック用の各MCにインスタンス名を付けて、 そのインスタンス名を使って変数を代入してあげるだけです 例えば、block1~block10というブロック用インスタンス10個が存在するとしたら、 それを配置している階層のフレームに for(i=1;i<=10;i++){ tellTarget("block" add i){//この中はblock(x)の階層から見た記述になる myNum = _parent.i; } } とすれば block1のmyNumは1 block5のmyNumは5、のように各数字が入れれます 回答No1に記述した擬似配列の初期化と合わせると、 for(i=1;i<=10;i++){ tellTarget("block" add i){ myNum = _parent.i; _parent["b" add _parent.i] = 0; } } とすることで、各ブロックに自分の番号を、配置したフレームに擬似配列を作成することが可能です ブロック内のフレームに記述するループ用スクリプト内で、 ブロックが消える時の処理に _parent["b" add myNum] = 1; そして後は回答No1で記述したクリア成立判定のような形で処理を行えばよいかと思います > (ブロックが消えるたびにカウウントが増えていき、最後に > カウントがブロックの数に達成されるとクリアに飛ぶ。という形で) > うまく動作できませんでした。 カウント用の変数をダイナミックテキスト等で表示して どのようにカウントが動いているのかを確認することが必要ですね カウントアップしなければブロック側に、 ちゃんとカウントしていれば、そのカウントを監視している側ににミスがあるということです まとめて作ってから"うまくいかない" -> "原因探し"ではなく、 一つ一つ順番に作っていけばそれだけで原因部分も把握しやすいです とりあえず私が今回の質問内容にアドバイスできるのはここまでです 成功することを祈っています
- suzuki-_-
- ベストアンサー率77% (152/195)
> ブロックは1つ作成しムービークリップにして、 > ライブラリに入れた物を数個並べています。このブロックの > 配置の仕方ではブロック自体には変数名を入れれないので、 > スクリプトで変数を宣言すればよろしいのでしょうか? そうですね、スクリプトで変数を宣言してブロック毎の数字等を代入してあげても良いかと思います ただ、よくよく考えるとブロック崩しのクリア判定に配列を使うのは手間がかかるだけですね _root上などにブロック総数用変数・カウント用変数を用意しておき、 ブロックが消える毎にカウント用変数に1を足していって、 ブロック総数に達してたらクリアとする、で十分かなとも思います
補足
遅くなりましたがご返答ありがとうございます。 >スクリプトで変数を宣言してブロック毎の数字等を代入してあげても良いかと思います 初期設定をしているフレームに宣言すべきだと思うのですが・・・ どのようにすればよろしいのでしょうか? >_root上などにブロック総数用変数・カウント用変数を用意しておき、 >ブロックが消える毎にカウント用変数に1を足していって、 >ブロック総数に達してたらクリアとする、で十分かなとも思います 私もそうも思えるので、一度やってみたのですが (ブロックが消えるたびにカウウントが増えていき、最後に カウントがブロックの数に達成されるとクリアに飛ぶ。という形で) うまく動作できませんでした。 何かスクリプトが反映されない原因があると思うので、 再度見直してみようと思います!!
- suzuki-_-
- ベストアンサー率77% (152/195)
ちょっと誤解招く可能性があるので、回答No2さんの内容に補足させて頂きます > しかし,配列アクセス演算子を使用する上での欠点は, > _root や this などのドットシンタックスと組み合わせてしか使えないというところです。 これは欠点ともとられるかもしれませんが、 参照先を明示的に示すということで構成自体を把握させるというメリットでもあります(視覚的にも) また、ドット演算子を使用しなくても 配列アクセス演算子のみで可能です 例 trace(_root["a"]["b"]) //ドット演算子を使用すると _root.a.b ちなみに、FlashLite1.xでは this による参照はできません > どこでも使おうと思えば, > ドットシンタックスの代わりにスラッシュシンタックスを使います。 プロパティや変数への参照・代入は、ドット演算子であっても、どこからでも使うことが可能です > Flash 5 以降では, > eval関数 を等式の左辺に使用できなくなったため, > 上記の 配列もどき 操作のように便利に使えません。 等式ではなく代入演算子を使用する際の左辺ですね 後方互換部分をできるだけ考えると、 左辺及び右辺を動的に変数へアクセスし代入する際の評価は 配列アクセス演算子 >= set関数 + eval関数 > eval関数のみ のような感じだと思いますよ > JavaScript の eval関数 も不人気ですしね。 eval関数は一般的に引数を式として評価するものであって、 言語によってその引数に使用可能な内容も違い、使い方は様々です
お礼
ご返答ありがとうございます。 まだまだ自分にはわからないことが多いので、 文章をよく読んで、今後の参考にさせて頂きます!! 色んな使い方があるんですね、勉強になります!
#1の方が, 配列アクセス演算子( [ ] )について回答されているので, 私は主に 「配列に代わる方法」ということで, eval関数 と 配列 について回答します。 #1の方が,書かれている通り, 配列アクセス演算子( [ ] )を使うことはできます。 しかし, 配列自体の作成や,Arrayクラスのメソッドを使った配列の操作などはできません。 (eval でも 配列の作成は無理ですが。) 配列の要素にアクセスするためではなく, 何かのオブジェクトに対してアクセスする場合に限って, 配列アクセス演算子は使えます。 しかし,配列アクセス演算子を使用する上での欠点は, _root や this などのドットシンタックスと組み合わせてしか使えないというところです。 ~ まず配列アクセス演算子について ~ 無断引用ですが, #1の方のスクリプトを使わせて頂くとします↓。 ----------------------------------- // 初期化 for (i=1; i<=20; i++) { _root["b" add i] = 1; } // ----------------- _root.EndFlag = "YES"; for (i=1; i<=20; i++) { if (_root["b" add i] != 1) { _root.EndFlag = "NO"; break; } } if (_root.EndFlag eq "YES") { //クリアの処理 } trace(_root.EndFlag); // └→結果:YES ---------------------------------- これは十分使えます。 しかしこれを, オーソドックスな Flash Lite のスクリプトにすると次のようになります。 ---------------------------------- // 初期化 for (i=1; i<=20; i++) { eval("/:b" add i) = 1; } // ----------------- /:EndFlag = "YES"; for (i=1; i<=20; i++) { if (eval("/:b" add i)<>1) { /:EndFlag = "NO"; break; } } if (/:EndFlag eq "YES") { // クリアの処理 } trace(/:EndFlag); // └→結果:YES ---------------------------------- 本当はドットシンタックスは使えません(使える場合と使えない場合があります)。 どこでも使おうと思えば, ドットシンタックスの代わりにスラッシュシンタックスを使います。 「/」 が頭に付くと 「_root」 の意味になります。 「/:」は「_root」の変数という意味です。 また,動的にオブジェクトの名前にアクセスしたい場合は, 配列アクセス演算子ではなく,eval関数 を使います。 場合を限定すれば, ドットシンタックス と 配列アクセス演算子が使えますが, これについてはなぜ使えるのかわかりません(解析していません)。 おそらく,パブリッシュの段階で同値の何かに変換されるのでしょう。 for文は SWF にパブリッシュするときに, while文 と同じ物に変換されるため,正式にサポートされています。 ここまでで何が言いたいのかと言うと, #1の方がまちがっているという意味では決してありませんよ。 「ドットシンタックス+配列アクセス演算子」を 「スラッシュシンタックス+eval関数」に書き替える。 という例に使わせていただいただけです。 伝えたいことは, 配列アクセス演算子 は eval関数 に置きかえることができるということです。 ======================== ~ 次に配列について ~ Flash Lite 1.x では, 本当の配列を作成することはできませんが, 上のような eval関数 を使うと, 動的に何かのオブジェクトにアクセスすることも, また,「配列もどき」 を作ることも可能です。 まず, Flash Lite ではできない例↓(Flash 5 以上では可能)。 ---------------------------------- // 配列 myArr の作成 myArr = [1, 3, 8, 0, 2, 6]; // 配列要素が 2 のものを探す for (i=0; i<=5; i++) { if (myArr[i] == 2) { trace("myArr["+i+"] = "+myArr[i]); } } // └→結果:myArr[4] = 2 ---------------------------------- これ↑は,Flash Lite 1.x ではできません。 次に,上のできない例をできる例にします↓。 ---------------------------------- // 配列もどき myArr の作成 myArr_0 = 1; myArr_1 = 3; myArr_2 = 8; myArr_3 = 0; myArr_4 = 2; myArr_5 = 6; // 配列もどき の要素が 2 のものを探す for (i=0; i<=5; i++) { if (eval("myArr_" add i) == 2) { trace("myArr_" add i add " = " add eval("myArr_" add i)); } } // └→結果:myArr_4 = 2 ---------------------------------- 昔のヘルプは, eval関数 と 配列エミュレート についてもっと詳しく書かれていたのですが, 現在はすごく簡単にしか書かれてありません。 でも一応,ヘルプを参考にしてみてください↓。 Flash Lite のグローバル関数 > eval() http://livedocs.macromedia.com/flash/8_jp/main/00005198.html 配列というものは, そもそも変数を規則正しく並べただけのものですから, 変数をたくさん作ってやると同じようなものができます。 当然, eval関数 によって 二次元配列もどき も作れます。 また,その変数の集合体である, 配列もどき の各要素に動的にアクセスしたい場合も, eval関数 を使うことで可能となります。 「配列」 と 「配列もどき」 は結局同じなのです。 大きく違うところは何かと言うと, Array クラス のメソッドが使えないということです。 例えば,「reverse()」「splice」「join」「sprit」「sort」… このようなものが使えません。 しかしそれだけのことで,データとしては 配列 も 配列もどき もほぼ同じ物です。 それに, Array クラス のメソッドが使えないというだけのことで, 「reverse()」「splice」「join」「sprit」 「sort」… が不可能であるということではありません。 例えば「reverse()」などは簡単にできます。 ----------------------------------------- // myArr_0~myArr_9 に,0,2,4,6,…,16,18 を代入 for (i=0; i<=9; i++) { eval("myArr_" add i) = i*2; } // myArr_0~myArr_9 を 18,16,…6,4,2,0 をひっくり返す for (i=0; i<=4; i++) { n = eval("myArr_" add i); eval("myArr_" add i) = eval("myArr_" add (9-i)); eval("myArr_" add (9-i)) = n; } // 検証 for (i=0; i<=9; i++) { trace("myArr_" add i add "=" add eval("myArr_" add i)); } /* 結果↓ myArr_0=18 myArr_1=16 myArr_2=14 myArr_3=12 myArr_4=10 myArr_5=8 myArr_6=6 myArr_7=4 myArr_8=2 myArr_9=0 */ ----------------------------------------- ついでに「join」もやってみます。 ----------------------------------------- // myArr_0~myArr_9 に,0,2,4,6,…,16,18 を代入 for (i=0; i<=9; i++) { eval("myArr_" add i) = i*2; } // myArr_0~myArr_9 の要素を連結 for (i=0; i<=9; i++) { myArr = myArr add eval("myArr_" add i); } // 検証 trace("myArr = " add myArr); // └→結果:myArr = 024681012141618 ----------------------------------------- 中には場合によって難しいものもありますが, たいてい他も考えればできます。 一応, 配列アクセス演算子と eval関数 の使い方の違いについて少しふれておきます。 配列アクセス演算子 でオブジェクトにアクセスする場合, [ ] 内に入れられるのは1階層のみです。 一方 eval は複数の階層をまとめて1つの ( ) に入れることができます。 --- 例 --------------- _root └ aMC └ bMC 配列アクセス演算子: _root["aMC"]["bMC"] eval ドットシンタックス: eval("_root.aMC.bMC") eval スラッシュシンタックス: eval("/aMC/bMC") --------------------- 結局, eval関数 は,配列アクセス演算子の代用にもなりますし, 配列もどき を作成することも, また,配列もどき を操作することも可能です。 Flash 5 以降では, eval関数 を等式の左辺に使用できなくなったため, 上記の 配列もどき 操作のように便利に使えません。 完璧に,配列アクセス演算子に取って代わられた感じです。 ちなみに, ActionScript 2 までかろうじて生き残っていた eval関数 は, Flash 9 から使用できるとされている ActionScript 3 では, 完全に抹殺されるようです。 JavaScript の eval関数 も不人気ですしね。 しかし,Flash Lite 1.x では,かなり融通の利く関数です。
お礼
ご返答ありがとうございます! 丁寧に書いてくださり、とてもわかりやすく、 自分でもチャレンジしてみますっ!! 今後さらに熟読し、さらに理解を深めていきたいと思います。
- suzuki-_-
- ベストアンサー率77% (152/195)
Flash5以降に関わらず、FlashLite1.xでも配列アクセス演算子が使えるので、 連番をつけた変数で擬似的に配列のような形を作り、それをforで回すのが簡単な方法です ブロックが20個あったとしたら擬似配列用に20個の変数で監視します 例えば_root上に b1 ~ b20 までという変数を用意して、全てが1だったらクリア、のような形だったら _root.EndFlag = "YES"; for(i=1;i<=20;i++){ if(_root["b" add i] != 1){ _root.EndFlag = "NO"; break; } } if(_root.EndFlag eq "YES"){ //クリアの処理 } //ここまで このような感じです あとはブロックが消えた毎に各ブロック用の_root.b(x) を 1 とするようなスクリプトを加え、前途for文で回せばよいかと思います 初期化は for(i=1;i<=20;i++){ _root["b" add i] = 0; } とするだけでいいでしょう
補足
初めまして、丁重なご返答ありがとうございます。 説明して頂きました文を何度か読み返し、 大分理解できたのですが、 >連番をつけた変数で擬似的に配列のような形を作り、それをforで回すのが簡単な方法です 初歩的な質問になってしまいますが連番をつけた変数はどのように すればよろしいのでしょうか? ブロックは1つ作成しムービークリップにして、 ライブラリに入れた物を数個並べています。このブロックの 配置の仕方ではブロック自体には変数名を入れれないので、 スクリプトで変数を宣言すればよろしいのでしょうか? ご返答もらえたら嬉しいです。
補足
ご回答ありがとうございます! さっそく自分でもやってみたのですが、 ゲームが始まってすぐにクリアの画面に飛んでしまいました。。 ブロックが配置されている階層のフレーム(ゲームプレイ中フレーム)に for(i=1;i<=10;i++){ tellTarget("block" add i){ myNum = _parent.i; _parent["b" add _parent.i] = 0; } } ボールの中の1フレーム目(初期位置設定、初期化用) で初期化 for (i=1; i<=20; i++) { _root["b" add i] = 1; } 2フレーム目がボールと壁の反射とボールとバーの反射の スクリプトがありまして、 3フレーム目にボールとブロックの当たり判定、 その後、クリア画面へ _root.EndFlag = "YES"; for (i=1; i<=20; i++) { if (_root["b" add i] != 1) { _root.EndFlag = "NO"; break; } } if (_root.EndFlag eq "YES") { tellTarget("../") { gotoAndPlay("clear"); //クリアフレームへ移動 } } gotoAndPlay(2); 何か記述ミスをしてしまったのか、ボールとブロックの 当たり判定との兼ね合いで問題があるのかわからないので、 再度調べてみようと思います!!