- ベストアンサー
Flash lite1.0で カウントダウン
こんばんは。 さっそくですが、質問です。 携帯用のシューティングゲームを作っています。 画面上に60秒から0秒までのカウントダウンを 表示させたいのですが、 時間を取得するような関数などはあるのでしょうか? あと、できる場合に0秒になったときにgotoAndPlayで他のフレームに 飛ぶことは可能なのかもしりたいです。 また、時間取得等ができない場合で代用の方法があるのであれば 教えてください。 よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
「時刻の取得(秒)」 ( fscommand2("GetTimeSeconds") ) は,Flash Lite 1.1 以降でないと使用できませんが, カウンター(タイマー)のような「時間の取得」は, Flash Lite 1.0 でも 『getTimer()』 でできます。 そもそも「時間」と「時刻」は全然違うものですから, Flash Lite 1.1 でも, ご質問に書かれているようなカウンター(タイマー) に「時刻の取得」は使いません。 『getTimer()』 を使うのが普通です。 ~先に参考URLから~ Flashゲーム講座&ASサンプル集【時間について】 「Flashを開いてから経過時間を表示したい」 http://hakuhin.hp.infoseek.co.jp/main/as/time.html#TIME_00 (↑Flash Lite ではなく,普通のFlashのサンプルですが。) FLASH4スクリプト ストップウォッチ http://fpower.org/old/f4timer.htm (↑歴史あるサイトです。ストップウォッチはまだ現存していました。) ///////////////////////////////////////////////////////////////// 次に示すスクリプトは Flash Lite では使えませんが, 前置きとして,Flash 5 以上ではどうするかを書きます。 それを Flash Lite に応用させれば良いのではないかと思います。 > 画面上に60秒から0秒までのカウントダウンを > 表示させたいのですが、 表示させるのですから, ダイナミックテキストに数字を表示するのが簡単です。 あと, 持ち運びに便利なように(どのフレームでも使えるように), ダイナミックテキストは,ムービークリップの中に入れる方が良いでしょう。 まず, _root(メインムービー)のステージ上に ダイナミックテキスト のテキストフィールドを作成し, 例えば 「counter」 という変数名(インスタンス名ではありません) を付けます。 この「counter」 という変数名のテキストフィールドを選択して, ムービークリップに変換します。 そのムービークリップに次のように書けば, 60,59,58,… と数字が整数でダウンし, 0 になるのと同時に, _root のフレームを フレーム10 に進めるカウンタームービークリップができます。(コピペ可能) ----------------------------------------- // このムービークリップが表示されたときに実行 onClipEvent (load) { // タイマー(カウンター)の初期値を設定(※可変) starttime = 60; // mytime1 に最初の タイム を記録 mytime1 = getTimer(); // 変数 flag の値を 0 にする flag = 0; } // 1フレーム進む時間ごとに毎回実行 onClipEvent (enterFrame) { // mytime2 に随時タイムを取得 mytime2 = getTimer(); // タイマー(カウンター) にカウントダウンを表示 counter = starttime-Math.floor((mytime2-mytime1)/1000); // もし タイマー(カウンター)が 0 以下になれば if (counter<=0) { // タイマー(カウンター)の値を 0 に固定 counter = 0; // さらにflag が 0 のときだけ if (flag == 0) { // _root のフレームを 10 に進ませてplay _root.gotoAndPlay(10); // 変数 flag の値を 1 にする flag = 1; } } } ----------------------------------------- (注:↑Flash Lite 1.0 では使えません。Flash 5 以上です。) getTimer(); で求められる数値は, 常にその SWFムービー が表示されてからの時間(単位ミリ秒)になります。 ですからまず, // mytime1 に最初の タイム を記録 mytime1 = getTimer(); のようにして, カウントを始める時間を変数に記録しておいて, // mytime2 に随時タイムを取得 mytime2 = getTimer(); で随時得られる時間との差分をタイマーとして使います。 // タイマー(カウンター) にカウントダウンを表示 counter = starttime-Math.floor((mytime2-mytime1)/1000); メインであるこの行の説明です。 まず,(mytime2-mytime1) ですが, mytime2 も mytime1 もミリ秒で取得されます。 例 mytime2=5234(ミリ秒) mytime1=1004(ミリ秒) mytime2-mytime1=4230(ミリ秒) ですから, (mytime2-mytime1)/1000 で,単位を 秒 に変換しています。 例 4230(ミリ秒)×1000=4.230(秒) カウントダウンに小数部分はいらないと思うので Math.floor((mytime2-mytime1)/1000) で,小数部分を切り捨てています。 例 Math.floor(4.230(秒))=4(秒) カウントダウンは 0 から1,2,3…と増えるものではないので, starttime-Math.floor((mytime2-mytime1)/1000); で,最初に設定した starttime からこの値を引いています。 例 60(秒)-4(秒)=56(秒) → counter に表示 あとは簡単ですね。 もし counter の値が 0 以下になって なおかつ変数 flag の値が 0 のときだけ フレーム10 に行かせてplay させています。 すぐに 変数 flag の値を 1 にするので, フレーム10 に行き続けるということはありません。 前置きは以上です。 ///////////////////////////////////////////////////////////////// 本題ですが, Flash Lite では,上記スクリプトで何が使えないかと言うと, onClipEvent (load) と onClipEvent (enterFrame) と Math.floor です。 また,_root.gotoAndStop(10); のような書き方ができません。 それだけのことで, 他のスクリプトで言いかえたり,仕組みを工夫して回避すると簡単にできます。 取りあえず難点は, onClipEvent (load) と onClipEvent (enterFrame) が使えないことです。 これをムービークリップ内のフレームスクリプトでやってしまします。 まず, _root(メインムービー)のステージ上に ダイナミックテキスト のテキストフィールドを作成し, 例えば 「counter」 という変数名を付けます。 この「counter」 という変数名のテキストフィールドを選択して, ムービークリップに変換します。 ここまでは上(Flash 5 以上)と変わりません。 次に,この「counter」入りムービークリップをダブルクリックして, ムービークリップ内の編集に入ります。 ムービークリップ内は1フレーム1レイヤーだと思うので, これを3フレーム2レイヤーにします。 そして, 新しく作成した方のレイヤーの,フレーム1 と フレーム3 をキーフレームにします。 1 3 □ レイヤー 筆・・|○ []|○| ←スクリプト用レイヤー □ レイヤー 筆・・|●/// []| ←counter のレイヤー そして,スクリプト用レイヤーのフレーム1 には次のように書きます。 ----------------------------------------- // タイマー(カウンター)の初期値を設定(※可変) starttime = 60; // mytime1 に最初の タイム を記録 mytime1 = getTimer(); ----------------------------------------- 上(Flash 5 以上)の onClipEvent (load) 内のスクリプトを書いただけです。 ムービークリップ内の フレーム1 にこれを書けば, 結局 onClipEvent (load) に書いたのとほとんど同じ意味になります。 そして,フレーム3 には次のように書きます。 ----------------------------------------- // mytime2 に随時タイムを取得 mytime2 = getTimer(); // タイマー(カウンター) にカウントダウンを表示 counter = starttime-int((mytime2-mytime1)/1000); // もし タイマー(カウンター)が 0 以下になれば if (counter<=0) { // _root に命令 tellTarget ("/") { // フレーム10 に行ってplay gotoAndPlay(10); } // タイマー(カウンター)の値を 0 に固定 counter = 0; // ムービークリップ内をフレーム1に戻す gotoAndStop(1); // タイマー(カウンター)が 0 より大きいとき } else { // ムービークリップ内をフレーム2に戻す(ループ) gotoAndPlay(2); } ----------------------------------------- Math.floor は int に変えました。 int は小数点以下を切り捨てる関数です。 _root.gotoAndPlay(10); これは,次のように変更しました。 tellTarget ("/") { gotoAndPlay(10); } gotoAndStop とか gotoAndPlay とかは, Flash 5 以上では,ムービークリップクラス(ムービークリップオブジェクト)のメソッドで, 本来の形は, ターゲットムービークリップ.gotoAndPlay(10); です。 ですから Flash 5 以上では,_root.gotoAndPlay(10); のような書き方ができます。 Flash Lite 1.0 では, ムービークリップクラスとかいう枠組みはなく, gotoAndStop とか getURL とか loadMovie とかいう, メソッドが独立して存在していています。 trace("こんにちは"); のような感じです。trace(); にはクラスの枠組みなど考なくても,いきなり使えます。 そしてメソッドの前にターゲットが来るというような文法ではありません。 trace(); のようにメソッドが必ず前に来るという文法です。 gotoAndStop(); は,その前にターゲットを持って来ることができないので, tellTarget というメソッドを使って,ターゲットに命令をする形で実行させます。 それが, tellTarget ("/") { gotoAndPlay(10); } 「_rootさん,フレーム10 に行きなさい。」 ということです。 また,Flash Lite では,ターゲットパスにはドットシンタックス(.)が使えません。 スラッシュシンタックス(/)を使います。 某所にはドットシンタックスが使えるとかいうことを書かれている掲示板のようなものもありますが, それは特殊な場合で,tellTarget などを使用する場合はスラッシュシンタックスしか使えません。 また,特殊な場合でもなるべく Flash Lite 1.1 までは,スラッシュシンタックスで通す方が良いと思います。 _root は / です。 _root.AAA は /AAA です。 _root.AAA.BBB は /AAA/BBB です。 this.AAA は AAA です。 _parent.AAA は ../AAA です。 最後の行の // ムービークリップ内をフレーム2に戻す(ループ) gotoAndPlay(2); は,ムービークリップ内のタイムラインをフレーム2に進めるということになります。 この gotoAndPlay(2); で, ムービークリップ内のタイムラインの フレーム2 と フレーム3 は1フレーム進む時間ごとに毎回ループするので, フレーム3 のスクリプトは1フレーム進む時間ごとに毎回実行されますから, onClipEvent (enterFrame) を使ったのと同じ事になります。 この説明では, onClipEvent (enterFrame) を先に書いて, Flash Lite ではそれが使えないので, その回避策としてムービークリップ内のフレームループの方法を書きましたが, Flash の歴史上は逆です。 ムービークリップ内のフレームループの方法が先で, その回避策が onClipEvent (enterFrame) です。 ですから,Flash 5 では, onClipEvent (enterFrame) は,ムービークリップに書くことしかできませんし, Flash MX 以降も MovieClip.onEnterFrame = function() {}; は,ムービークリップに対する onEnterFrame イベントハンドラ です。 enterFrame はムービークリップ内のフレームループの名残です。 上記の,ムービークリップ内のフレームループの方法も私が考えたのではありません。 onClipEvent (enterFrame) が誕生するまでのお決まり手段だったものです。 以上です。 長くなってしまいすみませんでした。
その他の回答 (1)
- suzuki-_-
- ベストアンサー率77% (152/195)
各スクリプトの意味はNo1の方が丁寧に説明されているので省きますが、私の場合は簡略化してこのような形にしています (FlashLiteのゲームはよく容量でひっかかるので・・・) ■1 cntという変数名を付けたダイナミックテキストをMCにする ■2 そのMCの1フレーム目に以下を記述 if (stcnt eq "") { stcnt = getTimer(); } cnt = 60-int((getTimer()-stcnt)/1000); if (cnt<=0) { stop(); cnt = 0; //カウントダウン終了時のアクションを追加 } else if (_currentframe eq 2) { gotoAndPlay(1); } ■3 フレーム1の[プロパティ] -> [フレームラベル]を func にする ■4 フレーム2にキーフレームを作り以下を記述 call("func");//フレームラベルfuncのスクリプトを実行 # MCの構成はフレーム数2、ダイナミックテキストのみ配置
お礼
お礼が遅くなってしまってもうしわけありません。。 とても参考になる解答で すぐに問題を解決することができました。 ありがとうございました。