- 締切済み
携帯用パズルのシャッフルについて
こんにちは。 携帯用のパズルゲームを作っているのですが、シャッフルがうまくできません。 私の持っている本(フラッシュ8用)を読むと、ランダムな数字を先に作ってからピースに置き換えて ステージに配置すると書いてあります。 携帯用に書き換えなければいけないのですがさっぱり見当もつきません。。 ランダムは for(i = 0; i < 16; i++){ while(1){ eval("p" add i) = random(16); flag = 0; for(j = 0; j < i; j++){ if(eval("p" add i) == eval("p" add j)) flag = 1; } if(flag == 0) break; } } このように書きました。 パズルのピースにはそれぞれMC0~MC15というインスタンス名がつけてあります。 ステージには各マスにp0~p15とつけてあります。 パズルピースは縦40ピクセル横40ピクセルの正方形で 縦に4枚横に4枚ならんでいるようなステージです。 全くの初心者なので、参考になるサイトなどもあれば 教えていただけると助かります。 よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
#1です。 >> シャッフルはちゃんとできたのですが、ステージの上のピースが >> x軸とy軸に同じだけずれています。 結局, マスの位置とピースの位置を合わせるということで良かったのですか? それが良くわからなかったので,#1ではあまり深く書きませんでしたから, ここで,その点を補足します。 #1で書いたスクリプトで行くと, マス(テキストフィールド入りムービークリップ)と,ピース(MC0~MC15)の座標はぴったり合っているのです。 ただ,マスもピースも「面」ですよね。 「点」レベルで言うと,マスの基準点とピースの基準点の座標がぴったり合っている状態なのです。 「点」レベルで言うと, Flash はインスタンス(ステージ上のムービークリップなど)の基準点を基準に座標や拡大縮小や回転をします。 「インスタンスの基準点」 http://homepage3.nifty.com/ginga-b/MX/inst_refpoint.html #1では,補正値を入れれば良いと書きましたが, もし,ピッタリと一致させたい場合は,補正値ではなく, 基準点の持っていき方を考えるべきです。 テキストフィールドの基準点は, 上記URLにありますとおり,テキストフィールドの左上の角(左肩)が自動的に基準点になっています。 ムービークリップの場合は, 「シンボルに変換」する際に表示されるパネル↓の基準点(R)で決まります。 ///////////////////////////////////////////// 名前(N):[ 任意の名前 ] タイプ(T): ◎ ムービークリップ 基準点(R):■□□ ○ ボタン □□□ ○ グラフィック □□□ ///////////////////////////////////////////// もし, テキストフィールドと同様に,ムービークリップの基準点を左上にしたい場合は, 上に描いた図(図もどき)のように左上にチェックを入れてOKです。 ですから, 変数「num」のテキストフィールドをムービークリップに変換する時点で, 左上にチェックを入れてOKすれば,テキストフィールドと同じような扱いができます。 または, #1で書いた 「num作成」→「p0作成」→「p1~p15コピペ」 という作成手順通りに,p0~p15を作成していただいていると, p0 のみを選択して,それをダブルクリックし,ムービークリップ内の編集に入り, テキストフィールドの左肩が基準点である 「+」印に一致するように移動させれば良いわけです。 p1~p15 は p0 のコピーですから,全部そうしなくても,p0 のみの編集で大丈夫です。 そういう編集をする場合も考えられるので, あえて, 「num作成」→「p0作成」→「p1~p15コピペ」 を詳細に説明したのです。 この手順だと,一括編集が可能です。 ピースの基準点と,テキストフィールドをムービークリップに変換するときの基準点は, 何も考えないと,普通は同じになるので(中心なら中心,左肩なら左肩), おそらく,ピッタリ一致すると推測したので,#1ではこの点に触れなかったのです。 以上のように, ピースとマスの位置を厳密に合わせたい場合は, 補正値ではなく,「基準点」の取り方に気をつけてください。 何を何と合わせたいのかは,こちらではわかりませんので, 具体的にはどうすれば良いのかは回答できませんが,大切なのは基準点です。 -------------------------------------- 以上のことを前提として, もっと大幅に表示位置を変える場合は補正値となります。 補正値を入れる場所ですが, 最後の for文内のここ↓, myX = getProperty("p" add i, _x)+15; myY = getProperty("p" add i, _y)+15; に入れるのが適当ではないでしょうか。 上の例で言うと,MC0~MC15が,右下に 15 px ずつ動きます。 すごく疑問に思ったのですが, 最初のご質問で書かれているスクリプトは, Flash 8 の参考書のスクリプトを利用したとは言え, ご自分で Flash Lite 用に書き換えられたのでしょう? あれが,書けるくらいの方であれば, この辺りは,方向性だけ示しておけば大丈夫だろうと思ったので, 適当に, >> プラスマイナスで補正すれば,適度にズレルと思います。 と書いただけで済ませたのです。 なぜわからないのかが,どうも不思議です。 プログラムにはめっぽう強いけど, Flash に関しては,ご質問に書かれているように, >> 全くの初心者なので、 なのでしょうね。おそらく。 というわけで,最後の for 文に一応注釈行をプラスしておきます。 --------------------------------- for (i=0; i<16; i++) { // 変数 myX に P? の x座標プロパティを代入(補正+15) myX = getProperty("p" add i, _x)+15; // 変数 myY に P? の y座標プロパティを代入(補正+15) myY = getProperty("p" add i, _y)+15; // MC?(この?は p? の 変数num)の x座標プロパティを myX にセット setProperty("MC" add eval("p" add i add "/:num"), _x, myX); // MC?(この?は p? の 変数num)の y座標プロパティを myY にセット setProperty("MC" add eval("p" add i add "/:num"), _y, myY); } --------------------------------- のようになります。 本当は,myX とか myY とかいう変数を用意せず, setProperty() の () 内の最後の引数に getProperty("p" add i, _x)+15; を直接入れても良いのです(私は入れます)。 実は, ここでは(このコミュニティでは),横長いプログラムは非常に見にくいので, いったん 変数myX とか myY を用意して, プログラムを横長にしないようにしているだけなのです。 単なるそれだけ(見やすさ)の意味で,変数を用意しました。 長くなりました。すみません。 長くなりましたが,もう1点だけ補足。 >> 私はヘルプがいちばん参考になると思います。 と書きましたし,それはそうなのですが, 私,Flash歴が長いのです(単に歴が長いだけですが)。 それで, Flash 4 のときから,Flash のアクション(その頃は ActionScript とは呼ばれていませんでした)と格闘しているので, Flash Lite には,そんなに抵抗を感じないのです。 それで,ヘルプを見ることもたまにはありますが,今はほとんどヘルプも見ません。 これは Flash Lite についてのことです。 普通の Flash を作るときはしょっちゅうヘルプを見ています。 Flash Lite に関しては,ネットもしょっちゅう参考にしますが,どこも断片的で,ちゃんと通して解説されているサイトはありませんね。
ご質問の意味自体が今ひとつわかりません。 書かれているスクリプト自体は,正常に動作しますよね。 重複しないランダムな0~15までの整数が, 変数 p0 ~ p15 にそれぞれ代入されます。 ですから, 各マスに p0 ~p15 という変数名をつけてあると, ちゃんとランダムな数が表示されます。 したがって, 書かれているスクリプト自体の間違いを指摘して欲しいわけではないのですよね。 ということは, MC0 ~ MC15 のインスタンス名のムービークリップを, その求められた変数を元に,ランダムに配置したいと言うことでしょうか? 仮にそうだとしても, 変数名 p0 ~p15 のマス(テキストフィールド)と, インスタンス名 MC0 ~ MC15 のムービークリップ との表示上の位置関係がどうしたいのかがわかりません。 なので,勝手に p0 ~ p15 のマスの座標と, MC0 ~ MC15 の座標を一致させるという方法を書きます。 Flash MX 以上(Flash Player 6 以上)だと, テキストフィールドにインスタンス名が付けられるので, テキストフィールド の座標プロパティなどを取ってくることができますが, Flash Lite 1.1 までではそれができません。 したがって, マス(テキストフィールド)をムービークリップの中に入れてそのムービークリップの座標を取ってくるという方法を使います。 まず, ステージ上に,例えば 「num」 という "変数名" のテキストフィールドを用意します。 そしてそのテキストフィールドをムービークリップに変換します。 その,変換したムービークリップに 「p0」 という "インスタンス名" を付けます。 あとは,この 「p0」 をコピペで増やして,増やした物に, 残りの 「p1」~「p15」 という "インスタンス名" を付けます。 この書くインスタンスの中の,変数 num に,ランダムな数を入れれば良いと思います。 それで, 例えば,p0 という ムービークリップ の,変数num の値が 5 であれば, MC5 の座標を p0 と合わせる, 例えば,p1 という ムービークリップ の,変数num の値が 15 であれば, MC15 の座標を p1 と合わせる, … … という処理を for 文ですれば良いと思います。 ですから, 上で書いたような場合スクリプトは次のようになります。 --------------------------------------- // MC p0 ~ p15 の各変数 num に,ランダムな数を代入 for (i=0; i<16; i++) { while (1) { eval("p" add i add "/:num") = random(16); flag = 0; for (j=0; j<i; j++) { if (eval("p" add i add "/:num") == eval("p" add j add "/:num")) { flag = 1; } } if (flag == 0) { break; } } } // MC0~15の座標を上で得た 変数num の入った p? と一致させる for (i=0; i<16; i++) { myX = getProperty("p" add i, _x); myY = getProperty("p" add i, _y); setProperty("MC" add eval("p" add i add "/:num"), _x, myX); setProperty("MC" add eval("p" add i add "/:num"), _y, myY); } -------------------------------------- 勝手に座標を合わせることにしていますが, 合わせない場合は,プラスマイナスで補正すれば,適度にズレルと思います。 ご質問を勝手に解釈したところが多いですが, こんな感じの回答を求めていらっしゃるのでしょうか? >> 参考になるサイトなどもあれば >> 教えていただけると助かります。 私はヘルプがいちばん参考になると思います。 断片的にしかありませんよね,サイト上は。
お礼
こんなにわかりにくい質問なのに、丁寧に答えて頂きまして 本当にありがとうございます。 あと、できればでいいのですがプラスマイナス補正は どこに書けばよいのでしょうか? シャッフルはちゃんとできたのですが、ステージの上のピースが x軸とy軸に同じだけずれています。 よろしくおねがいします。
お礼
本当にありがとうございました。 大変わかりやすく説明をしていたので理解できそうです。 やっぱりサイトないですよね。 ですので、数をこなして徐々に慣れていこうと思います。 また何かありましたら よろしくお願いします。。