Flash(AS3.0)で作っている「ミチク・ソード」の戦闘画面(初期ドラ○エ風)で、「たたかう」を選択したら・・・→先攻後攻をきめる→「~のこうげき!」っていうテキストだす→戦闘ルーチンはしらせてダメージを決める→「~が~に~のダメージ!」というテキストをだす→表示されているHPステータスを変更・・・なんてことをしたいと思いました。テキスト表示ごとにボタン押下するのはテンポが悪くなるので、Sleep関数みたいなものを用意しようと思いました。
Sleep関数がなぜないのかという話もあるかと思いますが、まあ難しいでしょう。FlashはMovieClipで独立したタイムラインを持つので、開発者が想定する動作そのものに揺らぎがあるような気がします。それにSleep中に他の関数がちょっかいを出してくる可能性があるので、Sleep関数があったらあったでお行儀の悪い振る舞いをすることになり、Flashで共同開発をしている人をさらなる深みに陥れるかもしれません(笑)。
そこで「まあ、ベタベタでも動けばいいのよ」精神で、ちょっと考えてみました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDown); function KeyDown(event:KeyboardEvent){ if(event.keyCode == 32){ // space //「たたかう」 battle(); } } var sleepCnt:int = 0; function battle(){ if(sleepCnt == 0){ // 入力無効 stage.removeEventListener(KeyboardEvent.KEY_DOWN, KeyDown); // 先攻後攻 cointoss(); sleep(1000); } else if(sleepCnt == 1){ attack(); } } var off:Object = new Object(); var def:Object = new Object(); function cointoss(){ // 先攻後攻 var luckTotal:Number = mainObject.bio.luck + charObject.bio.luck; if(Math.random() < (mainObject.bio.luck / luckTotal)){ off = mainObject; def = charObject; addText(mainObject.name + "のこうげき!"); } else { def = mainObject; off = charObject; addText(charObject.name + "のこうげき!"); } } function attack(){ // オブジェクト入れてバトル addText("攻撃結果"); } function addText(str){ // statusTextにテキストを流す statusText.text += str + "\n"; statusText.verticalScrollPosition = statusText.maxVerticalScrollPosition; } function sleep(num:Number){ sleepCnt++; var setIDName:Number = setTimeout(battle, num); } |
おーどろくさいどろくさい・・・。
補足を簡単にしますと「mainObject」には主人公、「charObject」には敵キャラのステータスが入っています。
先攻後攻を決める要素は各キャラのLUCKに依存していまして、主人公LUCK+敵LUCKを100%として、ランダムな値(0~1.0)が主人公のLUCKの割合の範囲内だったら主人公が先攻という設計です。
肝心のなんちゃってSleepですが、カウンターを増やして、setTimeoutで元のバトル関数に戻しているだけです。
バトル関数の中でカウンターを見て、その数字によって動作を変えています。
自作スリープ関数に与えているのはミリ秒で、これでウエイト時間を決めています。
この辺りの時間は攻撃の効果音やアニメーションとのタイミングをみながら調整したいので引数にした次第です。
泥臭いですが、考え方としては負荷も考慮されてていいんじゃないかと自負しています。
バトル関数で1ターンをくるめば、いいので、それなりに見通しもよくなります。
直接setTimeoutで繋いでしまうと同じようなちょっと違う関数が大量にできてしまう気がします。
おとなしくそーめんを使ったほうがいいような気もしますが、それが必要と感じたときに着手したほうが喜びも吸収速度も上がるのではないかと思う程度にはMです。