- ベストアンサー
カラクリ時計の作り方
こんにちは。Flash初心者のdagunikoです。 カラクリ時計をFlashで作ろうと思うのですが、なぜかうまくいきません。 EnterFrameを使って、時間を数えているのですが、if を使って、時間が来たら、一定のイベントを行うようにしたいのですが、うまくいかないです。 どうしたらいいでしょうか? 誰か上級者の方回答お願いします。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
#1&2 です。 >> で、やってみたのですが、やはり12秒になっても、 >> aaaaがプレイされてないようです。 スクリプトは後のことを考えなければそれでOKです。 >> aaaaの最初に、stopが入ってるのが原因でしょうか。 aaaaの最初に stop を入れなくてどうするんですか。 入れないと勝手に動きます。 もしくは,他のムービークリップや,その aaaa 自身に, onClipEvent (load) { this.stop(); } と書いても良いですが,とにかく stop を書いておかないと,勝手に play してしまいます。 だからそこもOKです。 だからスクリプト系はOKです。 実際にやってみても(質問者さまが#2の補足で書いているスクリプトをそっくりそのままコピペで使っても), ちゃんと動作します。 aaaa は間違いなく「インスタンス名」ですか? インスタンス名は,シンボル名の「シンボル 1」とかいう部分の名前ではないですよ。 その, aaaa であると思われるムービークリップを選択したときに,下に表示されるプロパティパネルで, 左の方が, [ ムービークリップ ▼] [aaaa ] みたいになっていますか? シンボルは,ムービークリップでないといけませんよ。 グラフィックシンボルでは,複数フレームあったとしても,動きませんよ。 また,インスタンス名が aaaa となっていた場合,大文字小文字,全角半角は間違いないですか? スクリプトと合わせるなら,半角小文字の aaaa でないとダメですよ。 また,ちゃんと _root に aaaa は置いてありますか? また,スクリプトを書いたフレームに存在していますか? スクリプト以外のムービークリップの状態が非常に怪しいです。 よくよく点検してみてください。
その他の回答 (2)
#1です。 まず,書かれているスクリプトですが, そのファイルを開いたとき,偶然 byou が 12 であれば, _root の aaaa が play(); します。 でも,開いたとき,byou が 12 でなければ _root の aaaa は play(); しません。 偶然,12 であることは 60 回開いたうちの 1回 くらいしかないと思うので,当然普通は動きません。 if (byou == 12) { _root.aaaa.play(); } の部分を function() の { }内に入れるとうまく動作するはずです。 こんなように↓ ------------------------------------ this.onEnterFrame = function() { now_date = new Date(); zikan = now_date.getHours(); hun = now_date.getMinutes(); byou = now_date.getSeconds(); this.time = zikan+":"+hun+":"+byou; if (byou == 12) { _root.aaaa.play(); } }; stop(); ------------------------------------ 使っているスクリプトは以下のようなものです。 ヘルプによると ~~~~~~~~~~~~~~~~ 「MovieClip.onEnterFrame」 イベントハンドラ; ムービーのフレームレートで継続的に呼び出されます。enterFrame クリップイベントに関連するアクションは、該当するフレームに割り当てられているフレームアクションの前に処理されます。 イベントが呼び出されたときに実行する関数を定義する必要があります。 例 次の例では、出力ウィンドウに trace を返す onEnterFrame メソッドの関数を定義します。 myMovieClip.onEnterFrame = function () { trace ("onEnterFrame called"); }; ~~~~~~~~~~~~~~~~ というようなことです。 MovieClip.onEnterFrame の MovieClip の部分は,本来ムービークリップのインスタンス名などを入れます。 でも,例では,特に時刻を刻むスクリプト用のムービークリップは使用していません。 だから,this として,ムービー自体をムービークリップとして扱っています。 #1でも触れましたように, onEnterFrame は{ }内のイベントをムービーのフレームレートで継続的に呼び出します。 簡単に言うと,1フレーム進む時間ごとに1回{ }内のイベントを継続的に呼び出します。 もし,ドキュメントの設定で,フレームレートを 12fps にしていたら,1秒間に12回 { } 内が実行されると言うことです。 #1の補足で書かれているスクリプトの場所に, if (byou == 12) { _root.aaaa.play(); } を書いた場合は,この if 文は,SWFファイルを開いたときに1回実行されるだけです。 たまたま byou が 12 であった場合は, aaaa が動き出すかもしれませんが, ずっと見ていて,byou が 12 になったとしても,何もおこりません。 すでに,実行は1回終わっています。 onEnterFrame の { } 内に入れることによって初めて,しょっちゅう呼び出されるイベントになるので, ずっと byou が何であるのか 1秒間に12回判定が繰り返されているスクリプトになります。 byou == 9 では何も起こらない, (←1秒間に12回) 10 でも何も起こらない, (←1秒間に12回) 11 でも何も起こらない, (←1秒間に12回) 12 では条件を満たす→ aaaa を play() となるわけです。 ------------------------------------- 以上のようなことが前提で, #1 の回答につながります。 EnterFrame だと,1秒間に12回,時間や秒などを判定するので判定には良いけれども, もし,byou == 12 などの条件を満たした場合,1秒間に12回,play なら play が実行され続けます。 byou == 12 である時間は,たった1秒ですから,問題ありませんが,分の場合, if (hun == 12) { _root.aaaa.play(); } とした場合は,hun == 12 である時間,つまり60秒間,aaaa に play(); が命令され続けます。 aaaa を10秒くらいで止めたいとき, aaaa のフレームに stop(); と書いたとしてもそれは無視されて, play() が実行され続けます。 その対処法を,#1 で書いたのです。 あらかじめ,EnterFrame の始まる前に,時間や分や秒を保存しておいて, その保存値と実際の時刻にズレがあったときのみ,1回だけ play() などを実行する方法です。 >> 今の所、自分の考えている物としては、 >> 朝は、青色だったり、時間によって変わることと、 >> 日にちによって、変えたいです。 書かれているスクリプトには,日にちと月が抜けているので,時刻を刻むスクリプトにその部分を付け加えるなら ---------------------------- this.onEnterFrame = function() { now_date = new Date(); tsuki = now_date.getMonth()+1; hinichi = now_date.getDate(); zikan = now_date.getHours(); hun = now_date.getMinutes(); byou = now_date.getSeconds(); this.time = zikan+":"+hun+":"+byou; }; stop(); --------------------------- こんな感じになるでしょうね。 月と日にちくらいは,開いたとき一回実行されれば良いと思いますから, now_date = new Date(); tsuki = now_date.getMonth()+1; hinichi = now_date.getDate(); の部分は,onEnterFrame より前に書いても良いですが, もし,月末の日の深夜11時58分とかに開く可能性を考えると,上のようにonEnterFrameの中に入れた方が良いかもしれません。それは作成者が判断することですから,こちらでは何とも言えません。 以上のような感じですが…
補足
なるほど。EnterFrame内に入れなければならなかったのですね。 ------------------------------------ this.onEnterFrame = function() { now_date = new Date(); zikan = now_date.getHours(); hun = now_date.getMinutes(); byou = now_date.getSeconds(); this.time = zikan+":"+hun+":"+byou; if (byou == 12) { _root.aaaa.play(); } }; stop(); ------------------------------------ で、やってみたのですが、やはり12秒になっても、aaaaがプレイされてないようです。 aaaaの最初に、stopが入ってるのが原因でしょうか。 あと、月と日にちはEnterFrame内に入れるつもりです。ご指摘どうもありがとうございまさう。<(_"_)>ペコッ
カラクリ時計? カラクリ時計というものがどういうものかよくわかりませんが, たとえば12時になったら,ハトが,「パポーパポー」と出てくるようなものの,もっとすごいやつですか? そんなような物の場合,アニメーションの部分は除くとして,スクリプトならなんとなくわかる気がします。 私は上級者の方ではありませんが, 一応一例を回答します。 回答する前に,説明のためのスクリプトと用意が必要なので,まずその説明から。 余計な物を一切排除して極々簡単な例を説明します。 メインのムービーは1フレーム1レイヤーのみです。 そのフレーム1に, -------------------------------- this.onEnterFrame = function() { Tokei = new Date(); Jikoku = Tokei.getHours(); Hun = Tokei.getMinutes(); Byou = Tokei.getSeconds(); }; -------------------------------- と書いてステージ上に, Jikoku という変数名のダイナミックテキストと Hun という変数名のダイナミックテキストと Byou という変数名のダイナミックテキスト, つまり3つのダイナミックテキストを用意するとデジタル時計が完成します。 無駄を一切省いています。 だから非常に簡単です。 ここまでは良いのですが, この,onEnterFrame文の中に,例えば, if (Jikoku == 12) { movie = gotoAndPlay(2); } みたいなことを書くと, movie はフレーム2のまま動かなくなるとか, if (Jikoku == 12) { movie = play(); } としても, movie は play し続けて,指定フレームで stop してくれないとか, 「うまくいかないです。」と書かれているのはそういうことですか? 違ってたらすみません。答えられません。 もし,そのことでうまく行かないのであれば,解決策はあります。 EnterFrameは,ずっと動作し続けますからね。 スタートのタイミングの時だけ肩をポンと押してくれれば良いのに, いらないこと肩を押し続けてくれます。 上で最初に書いたスクリプトを例えば下記のように書きかえます。 ---------------------------------- Eve = ""; Tokei = new Date(); Hun = Tokei.getMinutes(); Hozon = Hun; this.onEnterFrame = function() { Tokei = new Date(); Jikoku = Tokei.getHours(); Hun = Tokei.getMinutes(); Byou = Tokei.getSeconds(); if (Hozon != Hun) { Eve += "あ"; Hozon = Hun; } }; ---------------------------------- すると,分が変わるごとに,分が変わったときだけ, Eve という変数に "あ" が足されるというイベントが発生するスクリプトになります。 Eve という変数名のダイナミックテキストを追加するとその様子がわかります。 説明のために, インデントを入れながら今書いたスクリプトに注釈を入れますね。 全角空白をたくさん入れてあるのでそのままコピペでの使用はできません。 ---------------------------------- // 変数 Eve を初期化 Eve = ""; //Tokei という Date オブジェクトを作成 Tokei = new Date(); //変数 Hun に 分を代入 Hun = Tokei.getMinutes(); //変数 Hozon に Hun の値を保存 Hozon = Hun; //以下,1フレーム進む時間ごとに毎回実行 this.onEnterFrame = function() { //Tokei という Date オブジェクトを作成 Tokei = new Date(); //変数 Jikoku に時刻を代入 Jikoku = Tokei.getHours(); //変数 Hun に 分を代入 Hun = Tokei.getMinutes(); //変数 Byou に 秒を代入 Byou = Tokei.getSeconds(); //もし,Hozon が Hun と違った場合 if (Hozon != Hun) { //変数 Eve に"あ"を付け加える Eve += "あ"; //そして,Hozon に Hun の値を改めて保存 Hozon = Hun; } }; ---------------------------------- EnterFrame の中に,Eve += "あ"; というイベントを入れていますが, 1フレーム進む時間ごとに毎回 "あ" が加算されて行くわけではありません。 Hozon != Hun のときだけ "あ" が加算されます。 こんなのを使うと,EnterFrame の中でも, 「時刻が変わったときだけ」 → 「ハトムービーを play(); させる」 とか言うことが可能になります。 if文の( )内は,&& で,「AA の場合 なおかつ BBの場合」 みたいに条件を指定することもできます。 例えば, if (Hozon != Jikoku && Jikoku == 12) { _root.Hato.gotoAndPlay(15); Hozon = Jikoku; } と書くと,時刻が変わったとき,なおかつ12時の時, _root に置いた Hato というインスタンス名のムービークリップを15フレームに行かせてPlayさせることができます。 「うまくいかないです。」 がどういう状態なのかよくわかっていません。 全然的はずれなことを答えていたら,補足してください。 補足してくださっても答えられる自信はまったくありませんが,他の方がもっと具体的な回答をくださるかもしれません。
補足
いや、今の所、自分の考えている物としては、朝は、青色だったり、時間によって変わることと、日にちによって、変えたいです。 たとえば、クリスマスの日なら、クリスマス仕様にしたいと言った感じです。 それと今のところASはこんな感じです。 ---------------------------------------- this.onEnterFrame = function(){ now_date= new Date(); zikan = now_date.getHours(); hun = now_date.getMinutes(); byou = now_date.getSeconds(); this.time = zikan + ":"+ hun +":"+ byou }; if (byou == 12) { this.aaaa.play(); } stop(); ---------------------------------------- これは試しでやっているので、12秒になったら、何か行動を起こすようにしています。 そして、aaaaと言うのは、ibentoと言うレイヤーの中にあるシンボルです。 説明わかりにくかったら、ごめんなさい。<(_"_)>ペコ
補足
どうも毎度毎度回答ありがとうございます。<(_"_)> インスタント名が違っていただけでした。 やっぱりstop入れておいてよかったんですね。 多分これで解決しましたが、 第二段が出る可能性も…(マテ どうも本当にありがとうございました。<(_"_)>ペコッ