トップページ > 過去ログ > 記事閲覧
処理がコマ落ちします
名前:mister 日時: 2008/07/25 22:31

まだ簡単な処理しかしてないのですが、3〜6秒間隔でコマ落ちします。なにか無駄な処理があるのでしょうか・・・ ループ部分のソース while(1){ GetHitKeyStateAll(key); if(ProcessMessage()==-1) break; picdraw(); end=keydousa(key,mode); if(end==1) break; } } int keydousa(char key[],int mode){//ボタンによる影響 if(key[KEY_INPUT_RIGHT]==1) switch(mode){ case 1:ichix+=2; muki=1; break; } if(key[KEY_INPUT_LEFT]==1) switch(mode){ case 1:ichix-=2; muki=0; break; } if(key[KEY_INPUT_ESCAPE]==1) return 1; return 0; } void picdraw(void){//画面描写 ClearDrawScreen(); if(muki==0) DrawGraph(ichix,ichiy,graph,TRUE); else DrawTurnGraph(ichix,ichiy,graph,TRUE); ScreenFlip(); }

Page: 1 |

Re: 処理がコマ落ちします ( No.1 )
名前:キーチック 日時:2008/07/26 05:23

PCのスペックにも依存しそうな話ですが, CPUの速度とか,OSのバージョンとかメモリの空き容量とかはどうなっているか書いた方がよいと思います.
Re: 処理がコマ落ちします ( No.2 )
名前:mister 日時:2008/07/26 13:42

OS:Vista SP1 メモリ:2.5GB CPU:1.8GHz でアプリ実行中はCPU使用率は50〜60% メモリ使用量は500MBくらいです。 コマ落ちといっても0.2秒くらいなんですが、 サンプルのゲームとか起動してもそんなことはなかったので
Re: 処理がコマ落ちします ( No.3 )
名前:キーチック 日時:2008/07/29 20:08

0.2秒くらいとなると,画像データを読み込んでいる時かなという気がします. たとえばCPUのキャッシュメモリに読み込まれているデータを使用する場合には,ハードディスクから読み込まないので快適な描画が 出来るのですが,一旦画像データを解放して別の画像読み込んで〜とやると キャッシュに残っていない画像データを読みに行く→ちょっとアクセスに時間がかかる となり,数秒おきに0.2秒程度のコマ落ちを生ずることになるのではないでしょうか. これは,画像だけではなく,音楽データなども同様ですが.... この想像が正しかったという前提で,一つの解決策として,なんでもかんでもスタート前にメインメモリに読み込んでしまっておくと, スタートしてからハードディスクにアクセスに行かないので,そのようなロスが 避けられるのではないかという予感がするのですがどうでしょうか
Re: 処理がコマ落ちします ( No.4 )
名前:mister 日時:2008/07/31 14:22

キーチックさん、遅れてすみませんが そのメインメモリに読み込むという作業の設定方法がわかりません。 DXライブラリで設定できるのでしょうか?それともパソコンのシステム上で設定するのでしょうか?
Re: 処理がコマ落ちします ( No.5 )
名前:かたぱると 日時:2008/07/31 16:03

とりあえずソース的に見て、 @picdraw(); Aend=keydousa(key,mode); この順番ですと右左の入力をして、 その結果が画面に反映されるのが次フレームになると思うのですが、 その微妙なズレを「コマ落ち」と認識しまっているのではないでしょうか。 @end=keydousa(key,mode); Apicdraw(); の順番にすればキー入力が反映されてから描画されるので 同フレームに左右入力の結果が反映されると思いますが…。
Re: 処理がコマ落ちします ( No.6 )
名前:mister 日時:2008/07/31 20:34

かたぱるとさん、回答ありがとうございます picdraw関数をループの最後にもっていきましたが、 コマ落ちは変わりませんでした
Re: 処理がコマ落ちします ( No.7 )
名前:キーチック 日時:2008/07/31 21:52

DrawGraphを使用しているということは,LoadGraphでメモリ上に画像データを 読み込んでいるということですよね. これをループ内に入れるのではなく,例えばプログラム開始直後に,使用する予定の 画像データをすべて読み込ませてしまうと,少しは変わるのではないかなと 思ったのですが,いかがでしょうか
Re: 処理がコマ落ちします ( No.8 )
名前:mister 日時:2008/08/03 13:52

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){ ChangeWindowMode( TRUE ) ; // ウインドウモードに変更 if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了 SetDrawScreen(DX_SCREEN_BACK); SetTransColor(0,255,0); picload();//画像データの読み込み こんな感じにしても特に変化はありません やはりPCのスペックの問題なんでしょうかね
Re: 処理がコマ落ちします ( No.9 )
名前:Will 日時:2008/08/04 09:55

ソースを変えず問題の発生するPC以外で確認するのがPCの問題なのかソースの問題なのかわかりますが。 確認してもらいたいこと。 ・フルスクリーンモードでも発生するか ・DrawTurnGraphを使わないでも発生するか 上記で発生しなくなるのであれば、グラフィックス系(ドライバかもしくは設定)の問題だと思います。 現象の再現するソースを省略せずに全部提示してください。 提示されている部分については問題ないように思いますが、全体で見てみないとなんともいえないです。 使用している画像のサイズ、開発環境を書いてください。 当方XPしかありませんが、開発環境が同じであればこちらでも再現するかどうか確認してみます。
Re: 処理がコマ落ちします ( No.10 )
名前:mister 日時:2008/08/04 14:26

Willさん、ありがとうございます。 DrawTurnGraphを使わなくても変化はありませんでしたが、 フルスクリーンなら改善されました。 一応ソース載せておきます。あれからもいろいろ実装してしまい、かなりわかりにくくなってます。できる限り注釈つけましたが。スペックは上のほうに書いてあります。画像のサイズは74×66。開発環境Borland C++ 5.5.1です。 #include "DxLib.h" #define g 9.8 //画像読み込みの関数 int yuk[2]; //変数宣言 int ichix,ichiy; int muki=0; int joutai; double y,v0,vy; int btbf=0;/*zボタンが押したままかの判定*/ int jren=0;/*ボタンを押したままジャンプが連続にならないように*/ int idofl[4]={0};/*フラグが1の時移動できない。0:上1:右2:下3:左*/ int map[8][10]={ {0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,1}, {0,0,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1}, {1,1,1,1,1,1,1,1,1,1}, {0,0,0,0,0,0,0,0,0,0}}; void picload(void){//画像読み込み yuk[0]=LoadGraph("chara\\gazou.bmp");//左向き } void picdraw(void){//画面描写 int x,y; ClsDrawScreen(); for(x=0;x<10;x++) for(y=0;y<8;y++) if(map[y][x]==1) DrawBox(x*64,y*64-32,x*64+63,y*64+31,GetColor(255,255,255),TRUE); if(muki==0) DrawGraph(ichix-37,ichiy-33-32,yuk[0],TRUE); else DrawTurnGraph(ichix-37,ichiy-33-32,yuk[0],TRUE); ScreenFlip(); } void modef(int mode){//モードで初期化 switch(mode){ case 1:ichix=320; ichiy=0; y=(double)ichiy; break; } } int keydousa(char key[],int mode){//ボタンによる影響 switch(mode){ case 1: if(key[KEY_INPUT_RIGHT]==1){ if(idofl[1]==0) ichix+=2; muki=1; } if(key[KEY_INPUT_LEFT]==1){ if(idofl[3]==0) ichix-=2; muki=0; } if(key[KEY_INPUT_Z]==1){ btbf=1; if(joutai==0 && jren==0){ joutai=2; jren=1; v0=g*3; vy=-v0; } } else{ if(joutai==0) jren=0; if(joutai==2 && btbf==1){ vy=0; v0=0; joutai=1; } btbf=0; } break; } if(key[KEY_INPUT_ESCAPE]==1) return 1; return 0; } void jump(int t1,int t2){//空中にいる間の処理 switch(joutai){ case 1: case 2: if(vy<90) vy+=g*(t1-t2)/100; else vy=90; y+=(vy-v0/2)*(t1-t2)/100; ichiy=(int)y; if(vy>=0) joutai=1; break; default: break; } } void kabehan(void){//壁の判定 if(map[(int)((ichiy-30)/64)][(int)(ichix/64)]==1 || map[(int)((ichiy-30)/64)][(int)((ichix-30)/64)]==1 || map[(int)((ichiy-30)/64)][(int)((ichix+31)/64)]==1){ ichiy=(int)((ichiy-30)/64+1)*64+32; vy=0; v0=0; } if(map[(int)(ichiy/64)][(int)((ichix+32)/64)]==1 || map[(int)((ichiy-31)/64)][(int)((ichix+32)/64)]==1 || map[(int)((ichiy+31)/64)][(int)((ichix+32)/64)]==1) idofl[1]=1; else idofl[1]=0; if(map[(int)((ichiy+32)/64)][(int)(ichix/64)]==1 || map[(int)((ichiy+32)/64)][(int)((ichix-30)/64)]==1 || map[(int)((ichiy+32)/64)][(int)((ichix+31)/64)]==1){ ichiy=(int)((ichiy+32)/64)*64-32; joutai=0; vy=0; v0=0; } else if(joutai !=2) joutai=1; if(map[(int)(ichiy/64)][(int)((ichix-32)/64)]==1 || map[(int)((ichiy-31)/64)][(int)((ichix-32)/64)]==1 || map[(int)((ichiy+31)/64)][(int)((ichix-32)/64)]==1) idofl[3]=1; else idofl[3]=0; } void mein(void){//メインループ int mode=1; int end=0; int t1,t2; char key[256]; modef(mode); while(1){ GetHitKeyStateAll(key); if(ProcessMessage()==-1) break; t1=GetNowCount(); end=keydousa(key,mode); if(mode==1){ jump(t1,t2); kabehan(); t2=GetNowCount(); } picdraw(); if(end==1) break; } } int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){ ChangeWindowMode( TRUE ) ; // ウインドウモードに変更 if( DxLib_Init() == -1 ) return -1; // DXライブラリ初期化処理 エラーが起きたら終了 SetDrawScreen(DX_SCREEN_BACK); SetTransColor(0,255,0); picload(); mein(); DxLib_End() ; // DXライブラリ使用の終了処理 return 0 ; // ソフトの終了 }
Re: 処理がコマ落ちします ( No.11 )
名前:Will 日時:2008/08/04 15:22

提示いただいたソースを私のところでコンパイルして実行してみましたが ウィンドウモードでも特に処理落ちしているようなことは無く、 右向き移動も左向き移動も滑らかに動作しました。 ソースコードはさらっと見ただけですが、速度的に問題のありそうな 部分はないように思います。 私の環境は以下の通りです。 OS :XP SP3 CPU:AthronX2 1.9GHz Mem:2GB コンパイラ:BCC > フルスクリーンなら改善されました。 Vistaは持っていないので詳しくありませんが、ウィンドウモード時のみ遅いということであれば ほかに実行されているソフトにパワーがとられていて遅くなっているのではないでしょうか。 Aeroを使ってるとかなりパワーがとられるらしいですが。(半透明にしていると特に) 一応、私の環境でのCPU使用率は以下の通りでした。 実行前:10%前後 実行中:20%〜25%
Re: 処理がコマ落ちします ( No.12 )
名前:mister 日時:2008/08/04 17:27

アプリ以外のソフトを終了してもあまり変化は見られませんでした。 実はアプリを起動するごとにウィルスバスターが反応するのですが、 もしかしたらそのせいかもしれませんね。 とりあえず、ソースに問題はないということがわかりました。 お騒がせして申し訳ありませんでした。 数々のご回答ありがとうございました。
Re: 処理がコマ落ちします ( No.13 )
名前:かたぱると 日時:2008/08/04 17:29

ビルドを行いVistaのAero環境で試してみました。 結果としてコマ落ちが発生しました。 試したマシンのスペックは高いので スペック不足という問題ではなさそうです。 OS :Vista HomePremium SP1 CPU:IntelCore2Duo 2.26GHz×2 Mem:2GB コンパイラ:VC VistaだとデスクトップのテーマがAeroの場合、 Desktop Window Manager (DWM) という機構が働きます。 これはグラフィックスの管理がシンプルになるメリットがありますが メモリとCPUを多用するデメリットがあります。 ちなみにAeroではないデスクトップテーマを選んだ場合には コマ落ちは発生しませんでした。 改善策としては以下のようなものがありますが、 (全て英語。日本語のページはまだありません) どれも本気でやるならば〜といったレベルです。 一応情報提示ということでのっけてみます。 ・プログラム側でAeroを切りDWMを無効にする ↓このへんで操作、切り替えにはルールがあるのでよく説明を読むべし。 ttp://msdn.microsoft.com/en-us/library/aa969510(VS.85).aspx ・Multimedia Class Schedule Service (MMCSS) を適用してDWMの優先度を上げる ↓Aeroは有効のまま処理の優先度を上げる ttp://msdn.microsoft.com/en-us/library/aa969511(VS.85).aspx ・アプリケーションにタスクを割り当てて処理の優先順位を向上させる ↓Microsoftが定義したレジストリがあるので「Games」あたりを指定すると  処理が向上する。 ttp://msdn.microsoft.com/en-us/library/ms681974(VS.85).aspx ・GPUスレッドの優先順位を指定する ↓Direct3DDevice9EXの設定でGPUスレッドの優先度を操作するものがある。  しかしDirect3DDevice関連はDXライブラリが持っているので  操作するなら少し考える必要あり。 ttp://msdn.microsoft.com/en-us/library/ms681843(VS.85).aspx Vistaは面倒くさいなぁ

Page: 1 |