問答収集 カテゴリ:Flashプログラミング
現在のスレッド一覧 / 新規に質問を投稿
レス数:6 / 状態:解決済み / No:94 / ATOM
1 日付:2012/05/28(月)13:21:33 ID:lvPy7i/nSTFE
どうもお世話になります。Paraflaというフリーソフトでマウスをつかったちょっとした
ゲームを作成していて気づいたのですが、キーボード入力に関してはイベントハンドラに
何も処理を設定していないのに何かしらのキーを押しつづけると処理が重くなります。
OSのキーのリピート設定で間隔を遅くすると処理落ちがあまり感じられなくなるので、
おそらくオートキーリピートで大量のキー入力信号がFLASHに送られるのが原因なのでは
ないかと思ったのですが、そういうものなのでしょうか?古い記事になりますが、

http://www.flash-jp.com/modules/newbb/viewtopic.php?viewmode=flat&topic_id=1424&forum=12

に関連するかと思われる話が載っていますが、こちらでも原因が良くわからないようです。
キーボードは使用しないのでキーに触らなければ問題無いのですが、利用していない
イベントの検知?で変な負荷がかかるというのが気持ち悪いので、何かしらの回避策(
イベントの受け取り自体を行わない設定ができる等)や、あるいは処理落ちの原因自体が
別にあるなど何かご存知でしたら教えていただければと思います。よろしくお願いします。
2 日付:2012/05/28(月)15:44:27 ID:WanNqiphAFSQ
AS3.0の場合だと、
stage に「キャプチャリングフェーズ」でキーボード関連のイベントを追加して、
stopImmediatePropagation() メソッドを呼び出せば
イベントの伝達阻止ができますね。効果があるかはわかりませんが…

// コールバック関数
function KeyboardEventStop(e:KeyboardEvent):void{

/* --- この辺でキーの取得処理 --- */

// イベント伝達を阻止
e.stopImmediatePropagation();
}

// stage の「キャプチャリングフェーズ」にキーボード関連のイベントを登録
stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyboardEventStop,true);
stage.addEventListener(KeyboardEvent.KEY_UP, KeyboardEventStop,true);



AS1.0~2.0 でイベントの伝達阻止が可能かはちょっとわからないですね。
3 日付:2012/05/28(月)23:37:57 ID:4E+5UM+03WLJ
お答えありがとうございます。書き忘れていましたがParaflaというソフトは
AS1.0しか使えませんでした。3.0で使えるstopImmediatePropagation() という
関数をちょっと調べ見たのですが、何かしらのキー入力に対して複数の処理を
設定している場合に、途中で処理を止める?ような感じの用途で使うみたいでして
ちょっと私の感じてる問題とは別な気がします。上に書きました作成中のゲーム
ではマウスしか使わないので、存在しているMCに対してAS1.0で使えるキーボード
関連のkeyDown,keyUp等のイベントハンドラに関数を設定したり、Key.isDown()
のようなキー入力関連の関数も全く使用していないのですが、生成したSWFを
実行した際に、何かしらのキーを押しつづけると処理が重くなってしまいます。
それで、内部的にキー入力イベントに関係する処理を何もおこなっていなくても、
FLASHがOSからマウスやキーの入力などの信号を受け取っただけでけっこうな
負荷になっているのではないか?と思いまして、あまり聞いた事がないのですが、
FLASHに対して(あるいは存在する各MCに対して)キーボードは利用しないから
キーボード入力に関する信号は受け取らなくていいといったような設定ができたり
しないかなと思っています。今回の件ではキーボードは使わないから触らなければ
済む話なのですが、キーボードで操作するゲーム等を作る事になった場合、キー
を押し続けてキャラクターを移動させるということはよくあると思うのですが、
その時に内部の処理とは別に無駄な負荷がかかってしまうというのがなんとなく
気持ち悪いのです。FLASHはそういうものだと言われれば納得するしかないのかも
しれませんが、何かしら回避策や原因が別の所にあるなどご存知でしたらご指摘
お願いいたします。

4 日付:2012/05/29(火)03:24:09 ID:WanNqiphAFSQ
ムービークリップやボタンには、
onKeyDown や onMouseMove といったイベントハンドラが供給されています。
http://livedocs.adobe.com/flashlite/3.0_jp/docs/help.html?content=00005085.html#36254
http://livedocs.adobe.com/flashlite/3.0_jp/docs/help.html?content=00005308.html#46755

マウスやキーボードのイベントハンドラをまったく使ってなかったとしても
_root からノードを辿って、すべての表示用インスタンス(ムービークリップやボタンなど)に対して
コールバック関数が登録されているかを調べる必要がありますので
最低でも、「木構造リスト内をすべて巡って調べる」という処理は、内部で発生していると予想します。

さらにキーボードイベントとマウスイベントは、
「フレームレートとはまったく関係ない非常に短い時間隔」でイベントが発火されます。
これがヤバそうです。

例えばキーボートを連打しまくれば
その都度、「木構造リスト内すべて巡り」の処理が発生すると予想します。(ネイティブで)

また、onMouseMove のイベント発火の時間隔を測定してみたところ、
8 ミリ秒という非常に短い時間隔で実行されていました。
これは 1秒間に 120 回の「木構造リスト内すべて巡り」の処理が発生していると予想します。(ネイティブで)

AS1.0~2.0 では、
イベント伝達を阻止するメソッドは供給されてなさそうなので、
ムービークリップやボタンといった、イベントハンドラが供給されているクラスは
使用数をがんばって減らすしかないのかなと思います。

後は、描画系のメソッドを駆使してプログラムで描画しまくるとかでしょうか。
5 日付:2012/05/30(水)22:07:49 ID:01eBU3QjjWkf
お答えありがとうございます。確かに私の件ではMCをかなりの数使っていますので、
何かイベントが通知された際にそれら全てに処理が設定されていないかチェックが
入って重くなるのかもしれませんね。今まで負荷に関しては描画処理に関すること
しか気にしていなかったので、MCが多数存在していても実際に使用する以外のものは
描画範囲外に出しておいたり非表示にしておけば負荷にはならないと思ってたのですが、
こういったことも負荷になるのだとすると、おっしゃる通りMCの数を減らすしか無い
のかもしれませんね。今では頻繁にMCをcreate、attach、remove等すると負荷になる
のではないかと感じて必要なものを最初に全て作成してしまっていたのですが、場面に
合わせて逐次必要なものだけ作成し、使い終わったら削除してMCの総数を減らす方向で
修正してみようと思います。どうもありがとうございました。
してみようかと思います。
6 名前:状態変更 日付:2012/05/30(水)22:08:47 ID:01eBU3QjjWkf
この質問の状態を『解決』に変更しました。
このスレッドについて
質問の状態 :
解決済み
投稿開始日 :
2012/05/28(月)13:21:33
投稿終了日 :
2012/06/06(水)22:09:17
投稿者 :
レス総数 :
6
スレッド番号 :
94
MondoCollectionSystem ver.0x00020000 by Hakuhin