トップページ > 過去ログ > 記事閲覧
いろんなパソコンやモニターで全画面表示
名前:魚肉 日時: 2012/01/01 07:29

フルスクリーンについての疑問が。 すべてのモニターに対応するためには? 世の中には、アスペクト比16:9のスクリーンや、 640×480ピクセルの画面サイズを持ち合わせていないパソコンが、 いろいろあるみたいなので、対応したいのですが、 //hpcgi2.nifty.com/natupaji/bbs/patio.cgi?mode=view&no=2320 やりたいことが、書かれているようだけど、 仕組みがよくわからず、実装できませんでした。 パソコンやモニターの設定を変更してもらうのが、 一番早いけど、やり方わからない人もいるし、 「お前らパソコンの設定変えろ」なんて言えないです。

Page: 1 |

Re: いろんなパソコンやモニターで全画面表示 ( No.1 )
名前:タカトゥ 日時:2012/01/01 17:09

そのスレを立てた本人ですが、私は頂いた例を元に disp_x = GetSystemMetrics(SM_CXSCREEN); disp_y = GetSystemMetrics(SM_CYSCREEN); でモニタ解像度を取得し、フルスクリーン時は表示スクリーンとしてその解像度を使用しています。 それとは別に任意のサイズ(下の例では640×480)の描画スクリーンを作成し通常はそこに描画し、毎フレームそれを表示スクリーンに拡大描画することで行なっています。 実のところこの方法が正しいのか自分でもわからないのですが幾つかの環境で行いましたが今のところ不具合は有りません。 下の例では 整数倍表示ではドットが潰れることなく表示できますが環境によっては表示が小さくなります。 アスペクト比保持では縦横比が崩れないようにできるだけ大きく表示します。 #define SCREEN_W (640) //ゲーム自体の画面の横幅 #define SCREEN_H (480) //ゲーム自体の画面の縦幅 //整数倍表示の時のレターボックスの大きさ int letterboxsize_x int letterboxsize_y //アスペクト比保持の時のレターボックスの大きさ int letterboxsize_n_x int letterboxsize_n_y // ディスプレイ解像度取得 disp_x = GetSystemMetrics(SM_CXSCREEN); disp_y = GetSystemMetrics(SM_CYSCREEN); // レターボックスの計算 if(disp_x / 4 >= disp_y / 3){// 4:3より横に長いかちょうどの場合 letterboxsize_y = (disp_y % SCREEN_H) / 2; letterboxsize_x = (disp_x - (disp_y / SCREEN_H) * SCREEN_W) / 2; letterboxsize_n_y = 0; letterboxsize_n_x = (disp_x - (disp_y / 3) * 4) / 2; } else{ //4:3より縦に長い場合 letterboxsize_x = (disp_x % SCREEN_W) / 2; letterboxsize_y = (disp_y - (disp_x / SCREEN_W) * SCREEN_H) / 2; letterboxsize_n_x = 0; letterboxsize_n_y = (disp_y - (disp_x / 4) * 3) / 2; } // スクリーンモードに切り替えた時の処理 SetGraphMode( disp_x , disp_y , 32 ); // 描画スクリーンをmain_screenとした時の描画 // 整数倍に描画 SetDrawScreen( DX_SCREEN_BACK );//裏画面に変更 ClearDrawScreen();// 表示スクリーンの初期化 DrawExtendGraph(letterboxsize_x,letterboxsize_y,disp_x - letterboxsize_x,disp_y - letterboxsize_y,main_screen, FALSE );//拡大描画 SetDrawScreen( main_screen );// 描画スクリーンへの変更 // アスペクト比保持で描画 SetDrawScreen( DX_SCREEN_BACK );//裏画面に変更 ClearDrawScreen();// 表示スクリーンの初期化 DrawExtendGraph(letterboxsize_n_x,letterboxsize_n_y,disp_x - letterboxsize_n_x,disp_y - letterboxsize_n_y,main_screen, FALSE );//拡大描画 SetDrawScreen( main_screen );// 描画スクリーンへの変更 その後に ScreenFlip();// 裏画面を表画面に反映 等を行なってください。
Re: いろんなパソコンやモニターで全画面表示 ( No.2 )
名前:softya(ソフト屋) 日時:2012/01/01 12:24

>パソコンやモニターの設定を変更してもらうのが、一番早いけど、やり方わからない人もいるし、「お前らパソコンの設定変えろ」なんて言えないです。 今時の液晶はドットバイドットで使うのが一番きれいに表示されますのでデスクトップ画面の解像度に合わせた方がキレイに表示されます。なので、難しいでしょうがタカトゥさんの説明で頑張ってください。
Re: いろんなパソコンやモニターで全画面表示 ( No.3 )
名前:魚肉 日時:2012/01/02 00:26

タカトゥさん うぉお! 思いっきりコピペできる! と思って、実験してみたけど、 ChangeWindowMode(FALSE);な条件(フルスクリーン)で、 やってみたら、問題が発生して、Windowsが申し訳なくなって終了してしまいました。 いろんな行にMessageBox(NULL,"とめた","息の根を",MB_OK);みたいなのを挿入して、 何処の誰が原因なのかを調べたら、 MakeScreen関数で、ひっかかっているみたいです。 いま、こいつの仕様を確認しているところなのですが。 SetWindowMode(TRUE);だと、これはこれで、左上に640×480で表示されるのでした。 こっちの条件では、申し訳なくなることはないのですが。 DXライブラリの関数仕様の部分はは仕方ないとして、 (個人的に#defineで置き換えてる) それ以外は、全部小文字だけでかいてあって、見やすいですね。 個人的に、大文字小文字が混ざってる関数名変数名が気持ち悪くて。 softyaさん お目当ての画面が、中央に小さくしか表示されなくなったので、 それで対策調べてるうちに、 ローカルなモニター(640×480に対応しないなど)の問題にも、 対策しないといけないと思いまして。 全部のパソコンやモニターで保証されている画面モードって、 もしかしたら、存在しないかもしれませんね。
Re: いろんなパソコンやモニターで全画面表示 ( No.4 )
名前:魚肉 日時:2012/01/02 00:36

タカトゥさんへの返事の補足 // アスペクト比保持で描画 SetDrawScreen( DX_SCREEN_BACK );//裏画面に変更 ClearDrawScreen();// 表示スクリーンの初期化 DrawExtendGraph(letterboxsize_n_x,letterboxsize_n_y,disp_x - letterboxsize_n_x,disp_y - letterboxsize_n_y,main_screen, FALSE );//拡大描画 SetDrawScreen( main_screen );// 描画スクリーンへの変更 ここの部分で使われている変数「main_screen」が定義されてなかったので、 元記事を参考にして、 MakeScreen(disp_x,disp_y)に置換した。 この定義の仕方も、間違いかもしれませんけど。
Re: いろんなパソコンやモニターで全画面表示 ( No.5 )
名前:タカトゥ 日時:2012/01/02 13:12

main_screenは描画画面なので自分の作りたいゲームの解像度で構いません つまりmain_screen = MakeScreen( SCREEN_W , SCREEN_H ) ってことですね。
Re: いろんなパソコンやモニターで全画面表示 ( No.6 )
名前:魚肉 日時:2012/01/02 15:14

タカトゥさん、申し訳ありません。 もしかしたら、私、どこか間違っているかもしれません。 左上に表示されるのが改善されません。 #include"DxLib.h" #define SCREEN_W (640) //ゲーム自体の画面の横幅 #define SCREEN_H (480) //ゲーム自体の画面の縦幅 //整数倍表示の時のレターボックスの大きさ int letterboxsize_x; int letterboxsize_y; //アスペクト比保持の時のレターボックスの大きさ int letterboxsize_n_x; int letterboxsize_n_y; // ディスプレイ解像度取得 int disp_x = GetSystemMetrics(SM_CXSCREEN); int disp_y = GetSystemMetrics(SM_CYSCREEN); // //int main_screen = MakeScreen(SCREEN_W, SCREEN_H); void letter_box(){ if(disp_x / 4 >= disp_y / 3){// 4:3より横に長いかちょうどの場合 letterboxsize_y = (disp_y % SCREEN_H) / 2; letterboxsize_x = (disp_x - (disp_y / SCREEN_H) * SCREEN_W) / 2; letterboxsize_n_y = 0; letterboxsize_n_x = (disp_x - (disp_y / 3) * 4) / 2; } else{ //4:3より縦に長い場合 letterboxsize_x = (disp_x % SCREEN_W) / 2; letterboxsize_y = (disp_y - (disp_x / SCREEN_W) * SCREEN_H) / 2; letterboxsize_n_x = 0; letterboxsize_n_y = (disp_y - (disp_x / 4) * 3) / 2; } } void screen_hyouji(){ SetDrawScreen( DX_SCREEN_BACK );//裏画面に変更 ClearDrawScreen();// 表示スクリーンの初期化 DrawExtendGraph(letterboxsize_x,letterboxsize_y,disp_x - letterboxsize_x,disp_y - letterboxsize_y,MakeScreen(SCREEN_H,SCREEN_W), FALSE );//拡大描画 SetDrawScreen( MakeScreen(SCREEN_H,SCREEN_W) );// 描画スクリーンへの変更 // アスペクト比保持で描画 SetDrawScreen( DX_SCREEN_BACK );//裏画面に変更 ClearDrawScreen();// 表示スクリーンの初期化 DrawExtendGraph(letterboxsize_n_x,letterboxsize_n_y,disp_x - letterboxsize_n_x,disp_y - letterboxsize_n_y,MakeScreen(SCREEN_H,SCREEN_W), FALSE );//拡大描画 SetDrawScreen( MakeScreen(SCREEN_H,SCREEN_W) );// 描画スクリーンへの変更 } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){ SetGraphMode( disp_x , disp_y , 16 ); ChangeWindowMode(TRUE); if(DxLib_Init()==-1)return -1; //黒枠計算を関数化してみた letter_box(); //ループ。ここに鬼のようにコードを書き込む while(ProcessMessage()==0){ //表示部分を関数化 screen_hyouji(); //テスト用仮表示 DrawBox(0,0,639,479,GetColor(255,211,63),TRUE); DrawString(200,100,"もしかして、見えちゃった?",GetColor(63,0,0)); ScreenFlip(); } DxLib_End(); return 0; }
Re: いろんなパソコンやモニターで全画面表示 ( No.7 )
名前:タカトゥ 日時:2012/01/02 23:22

これでどうですか? エンターキーで表示を変更し、エスケープキーで終了します。 あと4:3以外のゲームでも使えるようにしておきました。たぶん ちなみに DrawBox(); 等は自動で-1されるので DrawBox(0,0,639,479,GetColor(255,211,63),TRUE); ではなく DrawBox(0,0,640,480,GetColor(255,211,63),TRUE); で構いません。 #include"DxLib.h" #define SCREEN_W (640) //ゲーム自体の画面の横幅 #define SCREEN_H (480) //ゲーム自体の画面の縦幅 // 表示タイプ int hyouji_type; // 整数倍表示の時のレターボックスの大きさ int letterboxsize_x; int letterboxsize_y; // アスペクト比保持の時のレターボックスの大きさ int letterboxsize_n_x; int letterboxsize_n_y; // ディスプレイ解像度 int disp_x; int disp_y; // 描画スクリーン int main_screen; //エンターキーを押したフレームカウント int enter; void letter_box(){ // ディスプレイ解像度取得 disp_x = GetSystemMetrics(SM_CXSCREEN); disp_y = GetSystemMetrics(SM_CYSCREEN); if( disp_x / (float)SCREEN_W >= disp_y / (float)SCREEN_H ){// 描画画面の比率より横に長いか同じ場合 letterboxsize_y = ( disp_y % SCREEN_H ) / 2; letterboxsize_x = ( disp_x - ( disp_y / SCREEN_H ) * SCREEN_W ) / 2; letterboxsize_n_y = 0; letterboxsize_n_x = ( disp_x - ( disp_y * SCREEN_W / SCREEN_H ) ) / 2; } else{// 描画画面の比率より縦に長い場合 letterboxsize_x = ( disp_x % SCREEN_W ) / 2; letterboxsize_y = ( disp_y - ( disp_x / SCREEN_W ) * SCREEN_H ) / 2; letterboxsize_n_x = 0; letterboxsize_n_y = ( disp_y - ( disp_x * SCREEN_H / SCREEN_W ) ) / 2; } } void screen_hyouji(){ switch(hyouji_type){ case 0:{//オリジナル SetDrawScreen( DX_SCREEN_BACK ); ClearDrawScreen(); DrawRotaGraph( disp_x / 2, disp_y / 2, 1.0f, 0.0f, main_screen , FALSE , FALSE ) ; SetDrawScreen( main_screen ); break; } case 1:{//整数倍 SetDrawScreen( DX_SCREEN_BACK ); ClearDrawScreen(); DrawExtendGraph(letterboxsize_x,letterboxsize_y,disp_x - letterboxsize_x,disp_y - letterboxsize_y,main_screen, FALSE ); SetDrawScreen( main_screen ); break; } case 2:{//アスペクト比保持 SetDrawScreen( DX_SCREEN_BACK ); ClearDrawScreen(); DrawExtendGraph(letterboxsize_n_x,letterboxsize_n_y,disp_x - letterboxsize_n_x,disp_y - letterboxsize_n_y,main_screen, FALSE ); SetDrawScreen( main_screen ); break; } case 3:{//フル SetDrawScreen( DX_SCREEN_BACK ); ClearDrawScreen(); DrawExtendGraph(0,0,disp_x,disp_y,main_screen, FALSE ); SetDrawScreen( main_screen ); break; } } } int Enter_Check(){ if(CheckHitKey( KEY_INPUT_RETURN )) enter++; else enter = 0; return enter; } int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd){ hyouji_type = 0; //黒枠計算を関数化してみた letter_box(); SetGraphMode( disp_x , disp_y , 16 ); if(DxLib_Init()==-1)return -1; main_screen = MakeScreen( SCREEN_W, SCREEN_H );// 描画用のスクリーン作成 SetDrawScreen( main_screen );// 描画するスクリーンを変更 //ループ。ここに鬼のようにコードを書き込む while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ){ ClearDrawScreen(); if( Enter_Check() == 1 ){// エンターキーを押した時のみ hyouji_type++; if( hyouji_type > 3 ) hyouji_type = 0; } //テスト用仮表示 DrawBox(0,0,SCREEN_W,SCREEN_H,GetColor(255,211,63),TRUE); DrawString(200,100,"もしかして、見えちゃった?",GetColor(63,0,0)); switch(hyouji_type){ case 0:{DrawString(0,0,"オリジナル",GetColor(63,0,0));break;} case 1:{DrawString(0,0,"整数倍",GetColor(63,0,0));break;} case 2:{DrawString(0,0,"アスペクト比保持",GetColor(63,0,0));break;} case 3:{DrawString(0,0,"フル",GetColor(63,0,0));break;} } //表示部分を関数化 screen_hyouji(); ScreenFlip(); } DxLib_End(); return 0; }
Re: いろんなパソコンやモニターで全画面表示 ( No.8 )
名前:魚肉(解決しました) 日時:2012/01/03 08:25

感動した。超ありがとう! Cの基本的な部分を、とりあえず勉強した程度の能力では、 なかなか太刀打ち出来なかった問題だったので、 (やりたいことを組み立てる能力も含めて)、 本当に助かりました。

Page: 1 |