• ベストアンサー

【Flash8】時間処理、初期化

getTimer() を使って 時間を変数にいれて1000分の1とかで 割って、ダイナミックテキストで表示させてるのですが それをリセットする方法ありますか? http://fpower.org/old/f4timer.htm こっちは初期化する方法がなくて、 自分の探し方が悪いかもしれませんが 0秒にする方法が見つからなくて。 自分で試した方法が↓ 初期化したい時間を代入している変数 = null; 初期化したい時間を代入している変数 = 0; これでも駄目で。。。 方法知っている方がいらっしゃいましたら 教えてください! お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
noname#35109
noname#35109
回答No.2

Flash 8 をご使用であることは, ご質問に書いてくださているのでわかりましたが, Flash Lite(携帯用 Flash) の SWF ファイルを作成しようとされているのでしょうか? もしそうでなければ, 書いていらっしゃるURLのストップウォッチのサンプルは, 作り変えるにしてもあまり使用しない方が良いサンプルですよ。 (Flash Lite 1.x には好都合ですが。) 昔(Flash 4 時代)はそれで良かったのですが, 今や使われない方法(フレームのグルグルループ)が使われていたりします。 また, テキストフィールドに変数名を付けることも今(Flash MX 以降)推奨されていません。 Flashドキュメンテーション 「テキストフィールドのインスタンス名と変数名について」 http://livedocs.macromedia.com/flash/8_jp/main/00001418.html > プロパティインスペクタの [変数] テキストボックスで、 > 変数名をダイナミックテキストフィールドや > テキスト入力フィールドに割り当てることができます。 > これによって、変数に値を割り当てることができます。 > これは、旧バージョンの Flash Player > (Flash Player 4 など) 用のアプリケーションを > 作成するときに使用する可能性のある非推奨の機能です。 さらに, テキストフィールドの変数名に テキストフィールドの textプロパティ と同じ text という変数名が使われていたり, Flash 4 の FLAファイル → Flash 8 に自動変換されるときに, 特に必要のない Number() 関数が付加されたりしています。 考え方を学ぶ上でのサンプルとしては使用されても当然かまわないのですが, 今現在の Flash 8 でスクリプトを実際に使用するのはかなりお薦めできませんよ。 著作権とかそういう問題ではなく, 思わないところで正常に動かないトラブルが発生する可能性があります。 回答の前にそれが気になって。 もし,そのサンプルを作り替える方向で回答する場合は, 結局,全文スクリプトを修正した上で,さらに発展の説明をしなければなりません。 それは辛いですし, そういうことをしてもあまり意味がないので, サンプルを無視して,なるべく今風なものを最初から作る方法の一例を回答します。 /////////////////////////////////////////////////////////// 新規ドキュメントを作成して,ステージ上に, 「timer」というインスタンス名(変数名ではありません)のダイナミックテキストのテキストフィールドと, 「CLEAR_btn」というインスタンス名のボタンシンボルのインスタンス, 「START_btn」というインスタンス名のボタンシンボルのインスタンス, 「STOP_btn」というインスタンス名のボタンシンボルのインスタンス, この4つのインスタンスを用意します。 「timer」 はストップウォッチの時間の表示部分, 「CLEAR_btn」はクリアボタン, 「START_btn」はスタートボタン, 「STOP_btn」はストップボタンです。 ステージ上をイメージすると次のような感じです  -------------------------------------------    [ インスタンス名「timer」 のダイナミックテキスト ]    [CLEAR]   「START」   「STOP」   (CLEAR_btn) (START_btn)  (STOP_btn) …インスタンス名  ------------------------------------------- そして, スクリプト用にレイヤーを新規追加で作成して, そのレイヤーの空白キーフレームである フレーム1 に, 次のスクリプトを書けば完成です(コピペ可)。 ---------------------------------------- // 各変数の初期化と宣言 var start_flg:Boolean = false; var clear_flg:Boolean = true; var time1:Number, time2:Number; // // テキストフィールド (インスタンス名 timer) の初期化 _root.timer.text = 0; // // 1フレーム進む時間ごとに毎回実行 _root.onEnterFrame = function() { // start_flg の値が true であれば if (start_flg) { // 現在の時間と変数 time1 の差を timer に表示 _root.timer.text = getTimer()-time1; } }; // // クリアボタン(CLEAR_btn)のonRelease動作を定義 _root.CLEAR_btn.onRelease = function() { timer.text = 0; clear_flg = true; start_flg = false; }; // // スタートボタン(START_btn)のonRelease動作を定義 _root.START_btn.onRelease = function() { if (clear_flg && !start_flg) { time1 = getTimer(); } else if (!clear_flg && !start_flg) { time1 = getTimer()-time2; } clear_flg = false; start_flg = true; }; // // ストップボタン(STOP_btn)のonRelease動作を定義 _root.STOP_btn.onRelease = function() { if (start_flg) { start_flg = false; time2 = getTimer()-time1; } }; --------------------------------------------- Flash MX 2004 以降で使用可能なスクリプトです。 SWF のパブリッシュは Flash Player 6 まで下げても大丈夫です。 冒頭の3行(コメント行を入れると4行)の 各変数の初期化と宣言 の部分で, 各変数の初期化 は必要ですが,宣言は特になくても大丈夫です。 つまりこうしても↓でもOKです。 ----------------------- // 各変数の初期化 var start_flg = false; var clear_flg = true; ----------------------- フレームは,1フレームのみです。 今はストップウォッチのような再計算に, フレームのグルグルループはほとんど使用されません。 onEnterFrame という便利なものを使うのが普通です。 「クリアボタン」が難しいという内容のご質問を書かれていますが, 実際は最初から作ってみると, 「ストップボタン」より「クリアボタン」の方が簡単に作れるのですよ。 「クリアボタン」がクリックされたときに表示を 0 にして, 次に「スタートボタン」がクリックされるときに, 新しい時間を getTimer() で取得して, その値と随時取得される getTimer() の値との差をテキストフィールドに表示すれば良いだけですから。 「ストップボタン」がそう簡単には行かないのです。 「ストップボタン」がクリックされたときに表示を止めて, とにかくその時点での表示時刻を保存しておいて, 次に「スタートボタン」がクリックされるときに, 新しい時間を getTimer() で取得した上で保存しておいた値を引いてやって, その値と随時取得される getTimer() の値との差をテキストフィールドに表示しなければなりません。 文章を見るだけでもややこしいですが, 考えるのはもっとややこしいです。 ストップウォッチの心臓部分は,次の1行です。 // 現在の時間と変数 time1 の差を timer に表示 _root.timer.text = getTimer()-time1; ここで最終的に, 随時所得される時間と,変数 time1 の差を計算してテキストフィールドに表示しています。 getTimer() で得られる値はミリ秒です。 一般人にとっては,例えば, 「5269ミリ秒」と言われるより, 「5.269秒」と言われる方がわかりやすいと思います。 もしそういう秒にしたい場合は次のように変えるとわかりやすいと思います。 かなり横長になってしましましたが↓。 // 現在の時間と変数 time1 の差を timer に表示 _root.timer.text = Math.floor((getTimer()-time1)/1000)+"."+("00"+(getTimer()-time1)).substr(-3, 3); 改行しているように見えるかもしれませんが1行です。 別に上のようにしなくても,単純にミリ秒を1000で割って, 次のようにしてもかまいません。 // 現在の時間と変数 time1 の差を timer に表示 _root.timer.text = (getTimer()-time1)/1000; でも,このようにしただけの場合だと, サンプルにあるようにテキストフィールドを右詰め設定にすると, 小数点以下の数が変わって桁がガクガク変動して見にくいので, 桁合わせをしたのが,上の長いスクリプトです。 あと, 単なるフラグである start_flg や clear_flg の if文条件分岐が込みいっていますが, これの大半はエラー処理のためです。 素直に「スタートボタン」を押して, 各ボタンのクリックも1回ずつしかしないという方ばかりだと, このように複雑にはなりませんが, 人間というものは,そう素直で単純ではありません。 ストップウォッチのカウントが始まってもいないのに, いきなり 「ストップボタン」 をクリックしたり, 同じ「スタート」 ボタンや 「ストップボタン」 を2回も3回も続けて押す人も出てくるでしょう。 そういう変な使い方をされた場合でも, 変な表示が出ないように色々分岐させてあるのです。 これは1つ1つは説明できません。 以上, ストップウォッチの一例として見てください。

dizzdive
質問者

お礼

詳しい解説ありがとうございます。 とても参考になりました! 独学でゲームを作ってるのですが いちから、ストップウォッチ作るのは 難しい>< ってことがわかりました。 ありがとうございます!

その他の回答 (1)

  • suzuki-_-
  • ベストアンサー率77% (152/195)
回答No.1

方法を考える前に、getTimer()を使いどのように時間を計測しているのかを理解することから始めましょう まず、getTimer()はSWFを"開いてから"の経過時間(ミリ秒)を返す関数です Flashにはスクリプトを実行した瞬間からの経過時間を返してくれる関数がないので、 getTimer()を用いて計測することがあります getTimer()を使って時間を計測する仕組みは、 最初にボタン押下等で、計測を開始したその瞬間のgetTimer()による時間を取得し変数に代入しておきます そして計測を止めた時は、再度getTimer()で止めた時間を取得し、その差を計測時間として表示するのです つまり例で上げると  1)計測開始時 getTimer()で取得 -> 1000  2)計測終止時 getTimer()で取得 -> 5000  3)1と2の差を求める 5000 - 1000 = 4000  4)3で出た時間を変数に入れる 4000 という流れになり、この例だと計測していた時間が4000ミリ秒(=4秒)となるわけです getTimer()はSWFを開いてからの経過なので、上昇の一途で値が下がることはありません なので、ストップウォッチの様な場合、計測を一度止め、継続して計測を行うには、 再度スタートした時間(*1)を取得し、(*1)から経過した時間を 既に計った分の時間に足していくことで成り立ちます 先ほどの1~4に加え  5)前回の計測結果(4)を他の変数に残しておく  6)計測再開時 getTimer()で取得 -> 6000  7)計測終止時 getTimer()で取得 -> 10000  8)6と7の差を求める 10000 - 6000 = 4000  9)残しておいた前回時間5と8を足す 4000 + 4000 = 8000  0)9で出た時間を変数に入れる 8000 という流れが必要になります ずっと継続する場合、あとは5~0を繰り返すだけです 前途時間を計測する一連の流れができあがってる場合、 初期化したい場合に初期化すべき部分は 質問者さんの仰る「初期化したい時間を代入している変数(*2)」ではありません (*2)は流れの4や0にあたいするもので、そこを0にしても 次々に求められた時間が入ってくるのでどうしようもありません 初期化するべき点は計測時間を計算している部分にあります それは、9で使われる前回の計測時間=5の部分です 質問者さんがストップウォッチの機能を持たせた時間計測をしているなら、 記述しているスクリプトのどこかに5の部分があるはずです この変数を 0 にしましょう ストップウォッチのように継続計測がない場合は1~4を繰り返すだけです それで今回の問題で詰まっている場合は開始時に毎回1を行っているかを見直してみましょう

dizzdive
質問者

お礼

自分の中で、だいぶ関数を間違った認識を していたようで、すっきりしました。 しかし、ロジックはまだ組めてませんが、 がんばってみます><