なぜか重い壁┃oT)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ф魔理沙ф

なぜか重い壁┃oT)

#1

投稿記事 by ф魔理沙ф » 17年前

いつもこのサイトを拝見させてもらって参考にしている魔理沙です♪

えっとこないだここで質問をしてシューティングゲームのタイトルを表示することができたのですが、

ビルドをして始めると、なぜかものすごい重たいのです。そしてなかなかタイトル画面が表示されません。

最小化して再び最大化すると表示されるのですが何ででしょうか?

一応タイトル画面に関するコードを乗せてみます。
===========title.cpp==============
void title(){
	int i,position_y,position_x;
	DrawGraph(0,0,img_background[2],FALSE);//タイトル画面表示
	
	DrawGraph(420,220,img_menu[0],TRUE);
	DrawGraph(430,260,img_menu[1],TRUE);
	DrawGraph(440,300,img_menu[2],TRUE);
	DrawGraph(450,340,img_menu[3],TRUE);
	position_y=230;
	position_x=400;
	for(i=1;State==TITLE;){
		DrawGraph(position_x,position_y,img_menu[4],TRUE);
		if(CheckHitKey(KEY_INPUT_DOWN)==1){
			i+=1;
			position_x+=10;
			position_y+=40;
		}
		if(CheckHitKey(KEY_INPUT_UP)==1){
			i-=1;
			position_x-=10;
			position_y-=40;
		}
		if(CheckHitKey(KEY_INPUT_RETURN)==1){
		State=RUN;
		break;
		}

		if(CheckHitKey(KEY_INPUT_RETURN)==1){
			switch(i){
				case 1:
					State=RUN;
					break;
				case 2:
					State=RUN;
					break;
				case 3:
					State=RUN;
					break;
				case 4:
					State=RUN;
					break;
			}
		}
	}

		
}


==========main.cpp===============
         メインループ{
			switch(State){ 
				case TITLE:
						title();
						break;
						if(Key[KEY_INPUT_ESCAPE]==1)    
							
						
						 
				case RUN: 
						RefreshTime = GetNowCount();              //今の時間を取得
						ClearDrawScreen();                                        //裏画面のデータを全て削除

						Background();

						PlayerShotCalc();

						PlayerShotDisp();

						PlayerControl();

						EnemyControl();

						EnemyCalcDisp();

						EnemyShotControl();

						EnemyShotCalcDisp();

						CollisionDetection();

						Background2();

						FpsTimeFanction();

						ScreenFlip() ;                                            //裏画面データを表画面へ反映

						counter++;
						break; 

						if(Key[KEY_INPUT_ESCAPE]==1)    
							break;  //Escapeが押されたら終了
						while(GetNowCount() - RefreshTime < 17);//1周の処理が17ミリ秒になるまで待つ

				case GAMEOVER: 
						break;
				case CLEAR:
						break;
				}
		}
と言う感じになっています。すいませんが。ご教授お願いします。

やそ

Re:なぜか重い壁┃oT)

#2

投稿記事 by やそ » 17年前

タイトル画面の表示が遅い(重い)というのならば・・・
プログラム開始からState==TITLEになってtitle()が呼ばれるまでのプログラムも必要じゃないでしょうか?
これだと、いつ、Stateの状態が変わるのか分からないです。初期値でTITLEが設定されてるの?

それとも、title()に移ってから重くなっているというのははっきり分かっているのでしょうか?

その前の段階と言うことは考えられませんか?
他には、メインループ{からtitleが呼ばれたとき、LoadGraphなしにDrawGraphしてるようですが、その辺は問題なし?

ф魔理沙ф

Re:なぜか重い壁┃oT)

#3

投稿記事 by ф魔理沙ф » 17年前

あ、すいません。言葉がいろいろ足りませんでした|_T)

列挙型で定義してそのなかでState=TITLEとなっています。
enum{
TITLE,
RUN,
GAMEOVER,
CLEAR,
};
int State=TITLE;

こんな感じになっています。それでさらに、LoadGraphhはしっかりやってあります。

管理人

Re:なぜか重い壁┃oT)

#4

投稿記事 by 管理人 » 17年前

こんにちは。ф魔理沙фさん。

プログラムを書いていると、何気なく書いた普通のことが、悪さをしてしまって大変ですよね。

今回重くしている原因はこれじゃないかと思います。

while(GetNowCount() - RefreshTime < 17);//1

改善策を先に言うと、こう書き換えるといいでしょう。

WaitTimer(17-(GetNowCount() - RefreshTime));//2

というのも1は見えないだけで、待機しているだけで何百万回も処理が行われているはずです。
一方で、WaitTimerは一度しか呼ばれません。
WaitTimerは普通のsleep関数のDxLib版です。
http://homepage2.nifty.com/natupaji/DxL ... .html#R6N1

またさらによいことに、処理を休ませてくれるのに、
プロセスのメッセージ処理ProcessMessageをしてくれるという便利な関数です。

しかし、スペックの高いPCだと、while文でも、特に処理は重くならない場合が多いです。
もしPCのスペックがそこまで高くないのならこういう処理が行われる「回数」に注意してみるといいかもしれません。

もう一つ重くなる原因はメモリがあふれてしまうこと。
Windowsタスクマネージャーの「パフォーマンス」で確認できる現在のメモリ使用量が、オーバーしていないでしょうか。

例えば、512MB積んでるとします。DxLibを起動する前は450位だったとします。
DxLibを起動した瞬間100MB食って、550MBとかになると、急に重くなります。

多分この2つをチェックすればよくなるのではないでしょうか。

やそ

Re:なぜか重い壁┃oT)

#5

投稿記事 by やそ » 17年前

>while(GetNowCount() - RefreshTime < 17);

が原因でしたか・・・。

単純に17ミリ秒waitしてくれるだけだと思ってました^^;
まあ、while文なのでその間処理は固まっていると思いますが(笑)
(17ミリ秒の間に何回繰り返されるかは分かりませんが)

PC環境でそれほど変わる部分だったとは^^;

管理人

Re:なぜか重い壁┃oT)

#6

投稿記事 by 管理人 » 17年前

実はこれはプログラムの世界では泣く子も黙るJustyさんの受け売りです。
私も待機はwhile文で書いていたのですが、お渡しすると、重いといわれ、原因はここだろうと指摘して頂きました。
当時、処理が重いのはこれで解決して、単にその体験談を申しているだけで・・これが原因かどうかはわかりません。

その記事見つけました。
http://www.play21.jp/board/formz.cgi?ac ... q&rln=1554
いや~懐かしい記事・・。


ただ、ProcessMessageは結構重要なので、なるべく、処理はとめずに、とめるときは、WaitTimerで止めた方がいいかなと思いました。

ф魔理沙ф

Re:なぜか重い壁┃oT)

#7

投稿記事 by ф魔理沙ф » 17年前

お返事遅れてすいません。(ノ_<。)

えっと早速試して見たのですが、なぜか重さが解消されません。
原因を考えてみてよくわかりませんが、なんとなく重いのとは違うのかという気がします。

プログラムを立ち上げしばらく待つと窓がでます。しかし画面は真っ黒のままなのです壁┃oT)
そして最小化をしてすぐに最大化すると画面が出ます。
自分が思うには画面の表示関係だと思うのですがよくわかりません・・・^^;

ちなみにこの現象は↑に乗せたプログラムを書いた後から出るので原因はその中にあると思うのですが・・・
なぜでしょうか・・・?

管理人

Re:なぜか重い壁┃oT)

#8

投稿記事 by 管理人 » 17年前

私もビスタでコンパイルしたコードはなぜか数秒表示までに時間がかかりました。同じコードでXPとビスタで挙動が変わるのはよくわかりませんから、制作者にお聞きになった方がいいと思います。
もしビスタではないならちょっとこちらで試してみないとそのコードだけではよくわかりません。
DXライブラリの制作者の方は忙しい方なので返事がなかなかもらえない可能性もありますし、よかったら先に一度見せて頂けないでしょうか。
もし人に見せてもいいものならアップローダなどを利用してあげてもらえますか?
あまり人に見せたくなければ私宛にメール添付で送っていただけたらと思います。
コンパイルしてすぐ結果が見れるようプロジェクトファイルなど、必要なファイルは同梱してzipかなにかにしていただけると助かります。

tk-xleader

Re:なぜか重い壁┃oT)

#9

投稿記事 by tk-xleader » 17年前

ビスタのAPIは変化している可能性があるのでは?
その他、Dxライブラリ自体がVista環境では違う挙動をするように設計されています。(というのはDxライブラリの機能自体に違いがあるのではなく、その機能を一定にするための設計みたいです。)

ф魔理沙ф

Re:なぜか重い壁┃oT)

#10

投稿記事 by ф魔理沙ф » 17年前

返信遅れてすいません(ノ_<。)
ちょっと家のネットが金を払ってなかったので使えませんでした(;>_<;)

それでできれば余り見せたくはないので、メールで送りたいと思うのですが、
メルアドを教えてもらえませんか?トップのメールはなぜか開かないので;w;

ほかに方法があるならほかでもいいのですが・・・w

管理人

Re:なぜか重い壁┃oT)

#11

投稿記事 by 管理人 » 17年前

メールアドレスは
dixqhp@gmail.com
です。
アップローダなどを利用してもらってもかまいません。
拝見して解決するかどうかはわかりませんが・・。

私もネット料金未払いで今つながらないので、時間かかるかもしれません^^;

クロカモ

Re:なぜか重い壁┃oT)

#12

投稿記事 by クロカモ » 17年前

どうも、お初にお目にかかります。
まだまだプログラミングは初めて時間はたってないのですがこのサイトで勉強してじっくりと実力を付けようと思います。
今後ともよろしくお願いします。

発投稿をこの雑談に書き込みさせていただいたのは他でもありません。
自分もなぜこのプログラムが重くて大変なのかを是非とも教えていただきたく書き込ませていただきました。
自分勝手で申し訳ありませんがよかったらMAILの方に理由を送ってください。

よろしくお願いします。

管理人

Re:なぜか重い壁┃oT)

#13

投稿記事 by 管理人 » 17年前

プロジェクト一式送っていただきましたので、よくわかりました。
掲示板で公開されていないので、公言すべきでない内容も含まれていてはいけませんので、
ф魔理沙фさんの投稿があるまで、だいたいな事だけ申し上げます。

原因は重いわけではありませんでした。
何か入力があるまで画面初期化や画面反映関数の無いただのループを延々と回るプログラムであった為、キー入力をするまで
シューティング画面に進まなかったというものでした。
また、データのロードが二重にされていたので、メモリの少ないパソコンだと、動きが遅くなったということもあるかもしれません。

なかなかトラブルがあると困りますよね・・。

ф魔理沙ф

Re:なぜか重い壁┃oT)

#14

投稿記事 by ф魔理沙ф » 17年前

大変返事が遅れてすいません(ノ_<。)
PCがちょっと逝っちゃいましたヘ(-_-ヘ
とりあえず直りましたので、返信しておきます(⌒▽⌒)

送っていただいたプログラムの方見させてもらいました。
ちょっといろいろ解らないこともありましたが、大体理解できたと思いますw
原因としてはやっぱりループを抜けていなかったのですね;
いろいろやってもらってありがとうございました(≧∇≦)/

ほかにもステージの作り方など聞きたいことがありますが、レスが立っているようなので
そちらで質問させてもらいます。
本当にありがとうございました。

ギョピ

Re:なぜか重い壁┃oT)

#15

投稿記事 by ギョピ » 17年前

こんばんは。
解決したトピックに書き込むのも変ですが、どうしても気になることがあります。

魔理沙さんのプログラムの問題点である「処理が重くなる」ことについてなのですが、私もその壁にぶち当たってしまいました。
横から急にこのような質問をして申し訳ありませんが、どなたかこの問題点についてご教授願えないでしょうか?
お願いします。

管理人

Re:なぜか重い壁┃oT)

#16

投稿記事 by 管理人 » 17年前

重くなる原因は山のようにあるのでそれだけではよくわかりません。
まずは実行時にメモリーオーバーしてないか、タスクマネージャなどで調べ、続いて描画しすぎてないか、全画面アルファブレンドなど他用していないか、セットフォントなど他用してはいけない関数を他用していないかなどを調べる感じでしょうか。

ギョピ

Re:なぜか重い壁┃oT)

#17

投稿記事 by ギョピ » 17年前

管理人さん回答ありがとうございます。

自分のソースコードを見て、無駄に多用されてないか考えてみようと思います。

tk-xleader

Re:なぜか重い壁┃oT)

#18

投稿記事 by tk-xleader » 17年前

三角関数の多用も遅くなる原因になります。
というよりも数学関数は下手すると遅くなります。一回ぐらいなら大丈夫だと思うけど。
という訳でこの自作sinと標準でどちらが速くなるかやってみました。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

#define REDIAN(X)((X)*(3.14159/180))

double mysin(double);
double y1[1000],y2[1000];

int main(void)
{
	double begin=0,total1=0,total2=0;
	int i,j,k,l;
	FILE *file;
	file=fopen("speedsin.csv","w");
	if(!file)return 0;
	for(i=0;i<10;i++){
		begin=clock();
		for(j=0;j<1000;j++){/*自作sin関数*/
			y1[j]=mysin(REDIAN(j));
		}
		total1+=clock()-begin;
		begin=clock();
		for(k=0;k<1000;k++){/*標準関数*/
			y2[k]=sin(REDIAN(k));
		}
		total2+=clock()-begin;
		
		puts("自作関数\t標準関数\t誤差");
		for(l=0;l<1000;l++){
			if(fabs(y2[[/url]-y1[[/url])<0.01){/*近い範囲だけはコンソールにも結果を出す*/
				printf("%f\t%f\t%f\n",y1[[/url],y2[[/url],fabs(y2[[/url]-y1[[/url]));
			}
		}
	}
	puts("平均タイム(単位:秒)");
	printf("%f\t,%f\t,%f\n",total1/10,total2/10,fabs(total1-total2)/10);
	fputs("自作関数\t,標準関数\t,誤差\n",file);
	fprintf(file,"%f\t,%f\t,%f\n",y1[[/url],y2[[/url],fabs(y2[[/url]-y1[[/url]));
	fputs("平均タイム(単位:秒)\n",file);
	fprintf(file,"%f\t,%f\t,%f\n",total1/10,total2/10,fabs(total1-total2)/10);
	fclose(file);
	return 0;
}

double mysin(double red)
{
	return red-(red*red*red)/6+(red*red*red*red*red)/120;
}
ただし、自作関数はその特性上、引数の値が大きくなるにつれて誤差が大きくなります。90度くらいまでなら何とか…という感じです。

閉鎖

“C言語何でも質問掲示板” へ戻る