ページ 11

DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月17日(土) 23:48
by かなたん
DXライブラリを使用してタイピングゲームを作りたいと思っています。
今メタセコイアで作ったキーボードのキーを読み込んで画面に表示しています。
パソコンのキーボードを押すと、それに対応して画面上のキーがへこむ(y座標を-10する)ようにしたいのですが、キーを押しても下がったようには見えません。
ClearDrawScreen();で画面消去されると思っているのですが、試しにその後にブレイクポイントを置いてデバッグをしてみると、そこで止まったときでも画面にはキーが残ったままになっています。
これって画面消去に失敗していると言うことでしょうか?
でもClearDrawScreen();の戻り値を調べてみると0が帰ってきていることから、失敗しているようには見えませんが・・・
もしやキーの座標を変えて表示してから戻して表示するまでが早いのでは?とSleep(1000);を挟んでみても、結果は同じでした。
どのようにするのがよいのでしょうか?

環境
OS:WIndows7
開発:Visual Studio 2008
DXライブラリ:DXライブラリ VisualC++用(Ver3.06c)

ソースコード

コード:

#include "DxLib.h"
#include <math.h>

void hyouzi();

struct robo_position{
	float x,y,z;
	float x_rotation,y_rotation,z_rotation;
};

int ModelHandle[26];
robo_position key[26];

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	VECTOR CameraPos;
	SetMainWindowText("タイピングゲーム");
	ChangeWindowMode(TRUE);
	// DXライブラリの初期化
	if( DxLib_Init() < 0 )
	{
		// エラーが発生したら直ちに終了
		return -1 ;
	}
	SetDrawScreen(DX_SCREEN_BACK);

	// Zバッファを有効にする
	SetUseZBuffer3D( TRUE ) ;

	// Zバッファへの書き込みを有効にする
	SetWriteZBuffer3D( TRUE ) ;

	ModelHandle[0]=MV1LoadModel("キー\\A.mqo");
	ModelHandle[1]=MV1LoadModel("キー\\B.mqo");
	ModelHandle[2]=MV1LoadModel("キー\\C.mqo");
	ModelHandle[3]=MV1LoadModel("キー\\D.mqo");
	ModelHandle[4]=MV1LoadModel("キー\\E.mqo");
	ModelHandle[5]=MV1LoadModel("キー\\F.mqo");
	ModelHandle[6]=MV1LoadModel("キー\\G.mqo");
	ModelHandle[7]=MV1LoadModel("キー\\H.mqo");
	ModelHandle[8]=MV1LoadModel("キー\\I.mqo");
	ModelHandle[9]=MV1LoadModel("キー\\J.mqo");
	ModelHandle[10]=MV1LoadModel("キー\\K.mqo");
	ModelHandle[11]=MV1LoadModel("キー\\L.mqo");
	ModelHandle[12]=MV1LoadModel("キー\\M.mqo");
	ModelHandle[13]=MV1LoadModel("キー\\N.mqo");
	ModelHandle[14]=MV1LoadModel("キー\\O.mqo");
	ModelHandle[15]=MV1LoadModel("キー\\P.mqo");
	ModelHandle[16]=MV1LoadModel("キー\\Q.mqo");
	ModelHandle[17]=MV1LoadModel("キー\\R.mqo");
	ModelHandle[18]=MV1LoadModel("キー\\S.mqo");
	ModelHandle[19]=MV1LoadModel("キー\\T.mqo");
	ModelHandle[20]=MV1LoadModel("キー\\U.mqo");
	ModelHandle[21]=MV1LoadModel("キー\\V.mqo");
	ModelHandle[22]=MV1LoadModel("キー\\W.mqo");
	ModelHandle[23]=MV1LoadModel("キー\\X.mqo");
	ModelHandle[24]=MV1LoadModel("キー\\Y.mqo");
	ModelHandle[25]=MV1LoadModel("キー\\Z.mqo");
	for(int n=0;n<26;n++){
		if(ModelHandle[n]==-1){
			return -1;
		}
	}

	SetCameraNearFar(1.0,3000.0);
	CameraPos.x=0.0f;
	CameraPos.y=125.0f;
	CameraPos.z=320.0f;

	for(int n=0;n<26;n++){
		key[n].x=n*30-240;
		key[n].y=-100.0;
		key[n].z=0.0;

		key[n].x_rotation=0.0;
		key[n].y_rotation=0.0;
		key[n].z_rotation=0.0;
	}

	SetCameraPositionAndTarget_UpVecY(CameraPos,VGet(0.0,50.0f,0.0f));

	ChangeLightTypeDir(VGet(0.0,-1.0f,-1.0f));

	while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){
		if(CheckHitKey(KEY_INPUT_ESCAPE)==1){
			return -1;
		}
		else if(CheckHitKey(KEY_INPUT_A)==1){
			key[0].y=key[0].y-10;
			hyouzi();
			key[0].y=key[0].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_B)==1){
			key[1].y=key[1].y-10;
			hyouzi();
			key[1].y=key[1].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_C)==1){
			key[2].y=key[2].y-10;
			hyouzi();
			key[2].y=key[2].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_D)==1){
			key[3].y=key[3].y-10;
			hyouzi();
			key[3].y=key[3].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_E)==1){
			key[4].y=key[4].y-10;
			hyouzi();
			key[4].y=key[4].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_F)==1){
			key[5].y=key[5].y-10;
			hyouzi();
			key[5].y=key[5].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_G)==1){
			key[6].y=key[6].y-10;
			hyouzi();
			key[6].y=key[6].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_H)==1){
			key[7].y=key[7].y-10;
			hyouzi();
			key[7].y=key[7].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_I)==1){
			key[8].y=key[8].y-10;
			hyouzi();
			key[8].y=key[8].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_J)==1){
			key[9].y=key[9].y-10;
			hyouzi();
			key[9].y=key[9].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_K)==1){
			key[10].y=key[10].y-10;
			hyouzi();
			key[10].y=key[10].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_L)==1){
			key[11].y=key[11].y-10;
			hyouzi();
			key[11].y=key[11].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_M)==1){
			key[12].y=key[12].y-10;
			hyouzi();
			key[12].y=key[12].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_N)==1){
			key[13].y=key[13].y-10;
			hyouzi();
			key[13].y=key[13].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_O)==1){
			key[14].y=key[14].y-10;
			hyouzi();
			key[14].y=key[14].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_P)==1){
			key[15].y=key[15].y-10;
			hyouzi();
			key[15].y=key[15].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_Q)==1){
			key[16].y=key[16].y-10;
			hyouzi();
			key[16].y=key[16].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_R)==1){
			key[17].y=key[17].y-10;
			hyouzi();
			key[17].y=key[17].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_S)==1){
			key[18].y=key[18].y-10;
			hyouzi();
			key[18].y=key[18].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_T)==1){
			key[19].y=key[19].y-10;
			hyouzi();
			key[19].y=key[19].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_U)==1){
			key[20].y=key[20].y-10;
			hyouzi();
			key[20].y=key[20].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_V)==1){
			key[21].y=key[21].y-10;
			hyouzi();
			key[21].y=key[21].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_W)==1){
			key[22].y=key[22].y-10;
			hyouzi();
			key[22].y=key[22].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_X)==1){
			key[23].y=key[23].y-10;
			hyouzi();
			key[23].y=key[23].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_Y)==1){
			key[24].y=key[24].y-10;
			hyouzi();
			key[24].y=key[24].y+10;
		}
		else if(CheckHitKey(KEY_INPUT_Z)==1){
			key[25].y=key[25].y-10;
			hyouzi();
			key[25].y=key[25].y+10;
		}
		hyouzi();
	}

	// DXライブラリの後始末
	DxLib_End() ;

	// ソフトの終了
	return 0 ;
}
void hyouzi(){
	ProcessMessage();
	int m=ClearDrawScreen();
	m=m*1; //ここで止めても画面にキーが残ったまま・・・
	
	for(int n=0;n<26;n++){
		MV1SetPosition(ModelHandle[n],VGet(key[n].x,key[n].y,key[n].z));
		MV1SetRotationXYZ(ModelHandle[n],VGet(key[n].x_rotation,key[n].y_rotation,key[n].z_rotation));
		MV1DrawModel(ModelHandle[n]);
	}
}

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月18日(日) 07:33
by naohiro19
表示されないのはScreenFlip()がないためです。

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月18日(日) 16:59
by かなたん
naohiro19さん回答ありがとうございます。
naohiro19 さんが書きました:表示されないのはScreenFlip()がないためです。
まだキー反応を実装する前、画面がちらついてしまっていたのでどうすればいいかを探していたところ、ScreenFlip()勝手にコメントアウトしたらちらつかなくなり、一応表示もされてていいかなぁって思って消してしまっていました。
指示どおりに表示のところでScreenFlip()を入れたらキーは移動してくれましたが、また画面がちらついてしまって・・・
他になにか使うべき関数等があったのでしょうか?
それとも環境のせいなのでしょうか?

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月18日(日) 17:42
by softya(ソフト屋)
色々とまずいことをしているのと長いコードを整理させてもらいました。
コンパイル確認しかしていませんが、こんな感じにシンプルに出来ます。

問題点は、こちらに整理されていますのでよく読んでみてください。
「新・C言語 ~ゲームプログラミングの館~ [DXライブラリ] 補足資料.11章 書いてはいけない4つの処理」
http://dixq.net/g/h_11.html

分からないことがあれば聞いて下さい。

コード:

#include "DxLib.h"
#include <math.h>

void hyouzi();

struct robo_position{
	float x,y,z;
	float x_rotation,y_rotation,z_rotation;
};

typedef struct {
	char *mqoname;
	int keyInput;
	int handle;
	int push;
	robo_position key;
} KeyModelData_t;

KeyModelData_t KeyModelData[26] = {
	{"キー\\A.mqo",KEY_INPUT_A },
	{"キー\\B.mqo",KEY_INPUT_B },
	//省略
};

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	VECTOR CameraPos;
	SetMainWindowText("タイピングゲーム");
	ChangeWindowMode(TRUE);
	// DXライブラリの初期化
	if( DxLib_Init() < 0 )
	{
		// エラーが発生したら直ちに終了
		return -1 ;
	}
	SetDrawScreen(DX_SCREEN_BACK);

	for( int n=0 ; n<26; n++ ) {
		KeyModelData[n].handle = MV1LoadModel(KeyModelData[n].mqoname);
		if(KeyModelData[n].handle==-1){
			return -1;
		}
	}

	SetCameraNearFar(1.0,3000.0);
	CameraPos.x=0.0f;
	CameraPos.y=125.0f;
	CameraPos.z=320.0f;

	for(int n=0;n<26;n++){
		KeyModelData[n].key.x=n*30-240;
		KeyModelData[n].key.y=-100.0;
		KeyModelData[n].key.z=0.0;

		KeyModelData[n].key.x_rotation=0.0;
		KeyModelData[n].key.y_rotation=0.0;
		KeyModelData[n].key.z_rotation=0.0;
	}

	SetCameraPositionAndTarget_UpVecY(CameraPos,VGet(0.0,50.0f,0.0f));

	ChangeLightTypeDir(VGet(0.0,-1.0f,-1.0f));

	while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){
		if(CheckHitKey(KEY_INPUT_ESCAPE)==1){
			return -1;
		} else {
			//	とりあえず戻す
			for( int n=0 ; n<26; n++ ) {
				KeyModelData[n].push = 0;	//戻す
			}
			//	キー入力
			for( int n=0 ; n<26; n++ ) {
				if( CheckHitKey(KeyModelData[n].keyInput)==1 ){
					KeyModelData[n].push = 10;	//沈む
				}
				break;
			}
		}
		//表示
		for(int n=0;n<26;n++){
			MV1SetPosition(KeyModelData[n].handle,VGet(KeyModelData[n].key.x,KeyModelData[n].key.y-KeyModelData[n].push,KeyModelData[n].key.z));
			MV1SetRotationXYZ(KeyModelData[n].handle,VGet(KeyModelData[n].key.x_rotation,KeyModelData[n].key.y_rotation,KeyModelData[n].key.z_rotation));
			MV1DrawModel(KeyModelData[n].handle);
		}
	}

	// DXライブラリの後始末
	DxLib_End() ;

	// ソフトの終了
	return 0 ;
}

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月19日(月) 10:49
by かなたん
softya(ソフト屋)さん回答・サンプルありがとうございます。
typedefでKeyModelData_t型の構造体を作成して、そこでキーの名前だとか対応するキーボードのこととかいろいろと設定してるんですよね。
で、そのKeyModelData_t型のKeyModelData[26]のとこで省略分を書き足してA~Zまで書いてみたのですが、Aしか反応してくれません・・・
表示は全部されています。
無事ちらつきもないです。
ですが、沈むとこのif文でA以外が引っかからないと・・・
宣言は間違えてないように見えて、for文はちゃんと0~25まで回るようになってて・・・
Aはちゃんと沈んでくれて、それ以外は反応なしなんです・・・
でも、沈む戻るのfor文をまとめて

コード:

            //  とりあえず戻す
            for( int n=0 ; n<26; n++ ) {
                if( CheckHitKey(KeyModelData[n].keyInput)==1 ){
                    KeyModelData[n].push = 10;  //沈む
                }
				else{

                KeyModelData[n].push = 0;   //戻す
				}
            }
としたところ、どのキーもちゃんと沈んでくれました。
どちらも同じようなことをしていると思うのですが、なぜこのような挙動の違いが出るのでしょう?

ScreenFlip()・ProcessMessage()・ClearDrawScreen()はwhile文の条件文のとこでですでに呼び出していることになっているので、他で呼び出す必要はないということですね。
何度も呼び出すからちらつきの原因になると・・・
あのプログラムは実は先生からもらったサンプルを改造したもので、先生もなぜちらつくのかわからないとかで・・・;
softoya(ソフト屋)さんのおかげで無事解決することができました。
ありがとうございました。

先生からもらったサンプル(ファイルパスは変更)

コード:

#include "DxLib.h"
#include <math.h>

struct robo_position{
	float x,y,z;
	float x_rotation,y_rotation,z_rotation;
};

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow )
{
	robo_position kyara;
	VECTOR CameraPos;
	SetMainWindowText("DXライブラリサンプル");
	ChangeWindowMode(TRUE);
	// DXライブラリの初期化
	if( DxLib_Init() < 0 )
	{
		// エラーが発生したら直ちに終了
		return -1 ;
	}
	SetDrawScreen(DX_SCREEN_BACK);

	// Zバッファを有効にする
	SetUseZBuffer3D( TRUE ) ;

	// Zバッファへの書き込みを有効にする
	SetWriteZBuffer3D( TRUE ) ;

	int ModelHandle;
	ModelHandle=MV1LoadModel("D:\\3Dイラスト\\三等身くん.mqo");
	if(ModelHandle==-1){
		return -1;
	}
	SetCameraNearFar(1.0,3000.0);
	CameraPos.x=0.0f;
	CameraPos.y=125.0f;
	CameraPos.z=320.0f;

	kyara.x=-0.0;
	kyara.y=-100.0;
	kyara.z=0.0;

	kyara.x_rotation=0.0;
	kyara.y_rotation=10.2;
	kyara.z_rotation=0.0;

	SetCameraPositionAndTarget_UpVecY(CameraPos,VGet(0.0,50.0f,0.0f));

	ChangeLightTypeDir(VGet(0.0,-1.0f,-1.0f));

	while(ScreenFlip()==0&&ProcessMessage()==0&&ClearDrawScreen()==0){
		Sleep(10);

		ScreenFlip();
		ProcessMessage();
		ClearDrawScreen();

		if(CheckHitKey(KEY_INPUT_ESCAPE)==1){
			return -1;
		}

		MV1SetPosition(ModelHandle,VGet(kyara.x,kyara.y,kyara.z));
		MV1SetRotationXYZ(ModelHandle,VGet(kyara.x_rotation,kyara.y_rotation,kyara.z_rotation));
		MV1DrawModel(ModelHandle);
	}

	// DXライブラリの後始末
	DxLib_End() ;

	// ソフトの終了
	return 0 ;
}

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月19日(月) 11:17
by softya(ソフト屋)
確かに書き間違えてますね。失礼しました。
正しくはこれです。

コード:

            for( int n=0 ; n<26; n++ ) {
                if( CheckHitKey(KeyModelData[n].keyInput)==1 ){
                    KeyModelData[n].push = 10;  //沈む
                    break;
                }
            }
ちなみに先生のコードもあまり宜しくないです。

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月19日(月) 11:33
by かなたん
softya(ソフト屋) さんが書きました:

コード:

            for( int n=0 ; n<26; n++ ) {
                if( CheckHitKey(KeyModelData[n].keyInput)==1 ){
                    KeyModelData[n].push = 10;  //沈む
                    break;
                }
            }
あ。
正しく動かない方はbreakがif文の外にあったのですね。
気が付いていませんでした;
softya(ソフト屋) さんが書きました: ちなみに先生のコードもあまり宜しくないです。
はい。
先生のサンプルもちらついてます。
(先生なら原因等分かっていてほしかったですが。)

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月19日(月) 11:39
by softya(ソフト屋)
ちらつく原因は、
(1)ScreenFlip();
(2)ClearDrawScreen()
(3)Sleep(10);
(4)ScreenFlip();
(5)ClearDrawScreen();
(6)描画
(1)~(6)が繰り返しとなっていますので、(1)と(4)で画面が切り替わりますので、両方共画像を表示しないと行けないのですが(6)だけ描画してますよね。なので真っ黒な画面が(4)の時に表示されてします。真っ黒な画面→描画された画面を交互に繰り返してわけです。これがちらつきの原因ですね。

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月19日(月) 12:04
by かなたん
softya(ソフト屋) さんが書きました: 真っ黒な画面→描画された画面を交互に繰り返してわけです。これがちらつきの原因ですね。
以前C言語でコマンドプロンプトで動く倉庫番を作ったことがあるのですが、なんかそのときにちらつく理由と似てますね。
画面に文字を出力して、動作があれば画面の文字をすべて消して(画面の初期化)、新たに画面に文字を出力して―
(この場合消すのではなく他ので上書きか裏面表示できればいいのですが、コマンドプロンプトにはそんな方法は存在しませんから・・・)

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月19日(月) 17:16
by ISLe
かなたん さんが書きました:(この場合消すのではなく他ので上書きか裏面表示できればいいのですが、コマンドプロンプトにはそんな方法は存在しませんから・・・)
コンソール系のWin32APIを使えば任意の座標の文字を上書きできますよ。

ncursesライブラリ使えばウィンドウズ以外にもソース持っていけます。

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月20日(火) 00:12
by かなたん
ISLe さんが書きました:コンソール系のWin32APIを使えば任意の座標の文字を上書きできますよ。
C言語のウィンドウプログラミングですか?
あれはウィンドウを用意するために自分で書いておかなければならないことがいろいろとあるので、いやになってやめました。
(ウィンドウを用意し、ちょっとポップアップのメッセージボックスで遊んだくらいでストップ。)
その点C++のMFCならそういったことは事前に用意してくれるので、あとは自分のしたいことをするだけなので気に入ってます。
(今度時間があればMFCで倉庫番を作る予定。)
たまにやりたいことを調べてもあまり出てこないのが残念ですが。
(MSDNの説明はちょっとわかりづらいときもあるし、具体的なサンプルが欲しかったり、サンプルどおりにやっているつもりでもうまくいかなかったり。)
ISLe さんが書きました:ncursesライブラリ使えばウィンドウズ以外にもソース持っていけます。
ncursesライブラリは初めて知りました。
UNIX系触った経験ないです。
UNIXやっておくといいよとか言われたことはありますが、今のところやるつもりもないですね。
マルチプラットフォームはいいと思いますが、まぁ最低ほかのWindowsでも作れて動けばいいかなぁと。

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月20日(火) 00:48
by softya(ソフト屋)
かなたん さんが書きました:その点C++のMFCならそういったことは事前に用意してくれるので、あとは自分のしたいことをするだけなので気に入ってます。
(今度時間があればMFCで倉庫番を作る予定。)
たまにやりたいことを調べてもあまり出てこないのが残念ですが。
(MSDNの説明はちょっとわかりづらいときもあるし、具体的なサンプルが欲しかったり、サンプルどおりにやっているつもりでもうまくいかなかったり。)
MFCを使いこなすには最終的にはWin32APIに行き着くんですけどね。今のところ次世代WindowsであるWindows8のMetroUIのネイティブAPIであるWinRTにはMFCが対応しないみたいです。そういう意味でもネイティブAPIは勉強しておいたほうが良いでしょう。

MFCだと、こんなサイトはどうでしょうか?
「VC++,MFCでのプログラミングでのTips CRIMSON Systems」
http://www.crimson-systems.com/tips/index.html
「MFC編 - 開発環境をそろえよう」
http://www.g-ishihara.com/mfc_ge_02.htm
「VC++テクニックindex」
http://www.alpha-net.ne.jp/users2/uk413/vc/index.html

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月20日(火) 04:05
by ISLe
かなたん さんが書きました:
ISLe さんが書きました:コンソール系のWin32APIを使えば任意の座標の文字を上書きできますよ。
C言語のウィンドウプログラミングですか?
違いますよ。
コンソールアプリケーションで、コマンドプロンプトに文字単位で任意の座標にある文字を上書きできます。
コマンドプロンプトにそんな方法は存在しないなんて誤った情報をどこのだれに刷り込まれたのでしょうか。
かなたん さんが書きました:ncursesライブラリは初めて知りました。
UNIX系触った経験ないです。
ncursesライブラリはウィンドウズ用もあります。

Visual C++ ExpressではビルドできないMFCよりは汎用性高いかと。

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月20日(火) 09:21
by かなたん
softya(ソフト屋) さんが書きました:MFCを使いこなすには最終的にはWin32APIに行き着くんですけどね。今のところ次世代WindowsであるWindows8のMetroUIのネイティブAPIであるWinRTにはMFCが対応しないみたいです。そういう意味でもネイティブAPIは勉強しておいたほうが良いでしょう。
MFCにもWin32APIが使われているんですね。
あまりそういうところいじったことないです。
バーの設定とウィンドウサイズの変更くらい?
Win8はMFC使えないのですか?
じゃあ今やっているMFCは将来なくなるなんてことになるのかな・・・?

サイト是非参考にさせてもらいます。
ありがとうございます。
使いたくなるようなこととかいろいろと載ってていいですね。
2つ目のサイトは、ときどき利用させてもらってました。
ISLe さんが書きました:コンソールアプリケーションで、コマンドプロンプトに文字単位で任意の座標にある文字を上書きできます。
コマンドプロンプトにそんな方法は存在しないなんて誤った情報をどこのだれに刷り込まれたのでしょうか。
上の先生とは別のC++を教えてくれた先生に、倉庫番を作ってるときにちらつきを抑えるにはどうしたらいいか質問したんです。
そうしたら、裏面に書いてそれを表示するなんて方法はないから仕方ないみたいな話になって、私はやっぱりできないんだなぁと思ってました。
でも、Win32APIを使えばあの黒い画面に上書きとかもできるのですね。
自分でAPIだとわかってて使ったのは、JavaでMIDI音源鳴らしたときと、MFCでwave鳴らしたときくらいかなぁ。
ISLe さんが書きました: ncursesライブラリはウィンドウズ用もあります。
Visual C++ ExpressではビルドできないMFCよりは汎用性高いかと。
ExpessじゃMFC作れないのですね。
で、そのライブラリを使えるようになればいろんな環境で動く物が作れるようになると。
MFCとどっちが難しいですか?

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月20日(火) 09:57
by softya(ソフト屋)
MFCの実体はWin32APIをクラスで隠蔽したものですから中身はWin32APIなんです。
デバッガで追いかけているとWin32APIの関数に行き着きますよ。
かなたん さんが書きました: Win8はMFC使えないのですか?
じゃあ今やっているMFCは将来なくなるなんてことになるのかな・・・?
Win8でWin32APIも使えますが新しいMetroUI(iPohneやAndroidみたいなやつ)だけはWinRTか.NetFrameWorkでしか操作できません。MFCに関してはマイクロソフトはフェードアウトを目論んでいて.NetFrameWorkへの統一を目指していると思います。
ただ、MFCを使っている企業ユーザーが居るのは確かなので、そう簡単には無くせません。そう意味でサポートは続けると思いますが新機能の搭載は望み薄だと思います。前に新機能は搭載しないと言ってたのに突然リボンインターフェイスのMFC版を出してきたりしたのでマイクロソフトの気が変わることも考えられます。

オープンソースなGTK+とかQt(キュート)などもありますので検討されてはどうでしょうか?
「GTK+ - Wikipedia」
http://ja.wikipedia.org/wiki/GTK%2B
「Qt - Wikipedia」
http://ja.wikipedia.org/wiki/Qt

Re: DXライブラリ 画面消去がうまくいっていない?

Posted: 2011年12月20日(火) 18:12
by ISLe
かなたん さんが書きました:で、そのライブラリを使えるようになればいろんな環境で動く物が作れるようになると。
MFCとどっちが難しいですか?
コンソールAPIもncursesもコンソールアプリケーションで使うものなので、基本的にGUIアプリケーション向けのMFCとは較べられないですよ。
MFCの替わりになるのはVisual C#とかですね。

ncursesというかcursesですが、暇潰しに作ったゲームを数本ブログで公開してますので興味あれば見てください。
VC++でコンパイルするにはusleepをSleepに変更する必要があります。
あとVC++ですぐに使えるncursesが見付かりませんでした。すみません。
ウチのブログにあるコードに関してはpdcursesで代用できます。