Win32APIでのランキング作成

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
luc
記事: 32
登録日時: 10年前

Win32APIでのランキング作成

#1

投稿記事 by luc » 10年前

て並び替え→クリア後にタイムランキングの表示としたいと思ってます。
最後に編集したユーザー luc on 2015年10月03日(土) 13:04 [ 編集 6 回目 ]

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: Win32APIでのランキング作成

#2

投稿記事 by usao » 10年前

趣旨がいまいち不明です.

シューティングゲームが作られているのであれば
描画処理は然るべき箇所で既に行われている形になっているのでしょうから
そこに書けばいいのではないでしょうか.
(それともまだ シューティングゲームの本体 自体が全く存在していないのでしょうか?)

提示コードはおそらく「ファイル読みこみ」に関するものと思われますが
「描画の仕方」が質問内容なのであれば,ここを提示された意味もよくわかりません.
(あと,提示コードもこのままではダメな感じがします)

luc
記事: 32
登録日時: 10年前

Re: Win32APIでのランキング作成

#3

投稿記事 by luc » 10年前

初めての投稿で説明下手ですいません。
シューティングゲームは存在しています。
自キャラや背景はBitbltを使って描画などをしています。

コード:

int Paint_BG(HDC hdc)
{
	HDC hdc_work;	// デバイスコンテキストハンドルの習得
	hdc_work = CreateCompatibleDC(hdc);		//メモリデバイスコンテキストを作成
	SelectObject(hdc_work, hb_all);		// オブジェクトを選択
	BitBlt(hdc, 0, 0, 400, 600, hdc_work, 0, 200, SRCCOPY);	// 画像描画
	DeleteDC(hdc_work);	// デバイスコンテキストの解放

	return 0;
}
自分が知りたいのはファイルを使ったランキングの作りかたと、そのランキングの描画の仕方です。

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: Win32APIでのランキング作成

#4

投稿記事 by usao » 10年前

具体的に何に困っておられるのかが…?
(話がとてもざっくりしている,というか)


●描画
ゲーム描画処理が既にできているのですから
例えば,そこを

コード:

if( 今はランキングを表示すべきときか )
{
  //”ランキング”を好きなように描画
}
else if( 今はゲーム状態の表示をすべきときか )
{
  //既存のゲーム描画処理
}
とかするのではダメなのでしょうか?
とりあえず TextOut() とか DrawText() あたりで何か描画されてみては?


●ファイル
自分が最も読み書きしやすいファイルのフォーマットを決めて
そこにランキングの表示や更新に必要なデータを保存 → それを読込
というのをやればいいだけだと思います.
どんなデータがどれだけ必要で,どういうフォーマットなら良いのか 等は作り手側にしかわからないことだと思いますので,

「こうすればいいと思って書いたけど,動作結果が意図と異なって○○なことになっている
 →その原因は? 対処法は?」

的な話になっていれば回答が得られ易いのではないかと思います.

オフトピック
最終目標である「ランキング」に先んじて,
まずは「ハイスコア(≒1項目しかないランキング,かな)」を実現してみるとか
より簡単な例からやってみるのも良いのではないでしょうか.

luc
記事: 32
登録日時: 10年前

Re: Win32APIでのランキング作成

#5

投稿記事 by luc » 10年前

いきなりランキングは難しいのでハイスコアから考えてみました。
とりあえずranking1.txtファイルを用意して読み込みをして描画を考えてみました。

ランキング関数

コード:

int Ranking_Load(void){
		ifstream fin("ranking1.txt");
		if (!fin){
			return 1;
		}
		const int num = 8;
		int ranking[num];
		for (int i = 0; i < num; i++){			//ファイル読み込み
			fin >> ranking[i];
		}
		int max = ranking[0];
		for (int j = 0; j < num; j++){
			if (max < ranking[j])				//最大値
				max = ranking[j];
			}
                fin.close();
		return max;
		}
プロトタイプ宣言

コード:

int Ranking_Load(void);
外部変数をhファイルに

コード:

extern int max; // ハイスコア保存用
WinMain関数に

コード:

max = Ranking_Load(); //ハイスコアをロードする

ウィンドウプロシージャ関数に追加

コード:

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	// 画像を読み込む準備
	HDC hdc;		// デバイスコンテキストハンドル
	PAINTSTRUCT ps; // ペイント構造体
	RECT rect;

	// バックバッファ用コンテキストハンドルと、ビットマップハンドルの準備
	static HDC hdc_back;	// 裏画面(バックバッファ)用デバイスコンテキストハンドル
	static HBITMAP hb_back;	// 裏画面(バックバッファ)用ビットマップハンドル
	HDC     hdcMem;

	
	switch (msg)
	{
	case WM_USER + 1:	// ゲームループ(SendMessageから呼ばれる)

		obj1.toPoint(&player);

		Get_Key();	// キー入力関数へ
		Player_move();		//移動関数へ
		

		// 結果の再描画 WM_PAINTを実行する
		InvalidateRect(hWnd, NULL, false);
		return 0;

	case WM_PAINT:	// 画面を描画する時の処理
		// 描画の開始
		hdc = BeginPaint(hWnd, &ps);
		RECT rt;
		GetClientRect(hWnd, &rt);
		// Paint関数へ
		Paint(hdc_back);

		//バックバッファに保存された画像を表画面に描画
		BitBlt(hdc, 0, 0, 1000, 450, hdc_back, 0, 0, SRCCOPY);
		DrawText(hdc,max, -1, &rect, DT_LEFT | DT_WORDBREAK);
		// 描画の終了
		EndPaint(hWnd, &ps);
		return 0;

	case WM_CREATE:

		// ゲーム初期化関数へ ///////////////////
		Init_Game();

		// 描画の開始
		hdc = GetDC(hWnd);
		// 互換デバイスコンテキストの作成
		hdc_back = CreateCompatibleDC(hdc);
		// 互換ビットマップの作成
		hb_back = CreateCompatibleBitmap(hdc, 1000, 450);
		
		// オブジェクトの選択
		SelectObject(hdc_back, hb_back);
		// 描画の終了
		ReleaseDC(hWnd, hdc);

		// ビットマップハンドルに画像データを読み込み保存しておく
		hb_char = (HBITMAP)LoadImage(NULL, TEXT("char.bmp"), IMAGE_BITMAP,
			0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);

		return 0;

	case WM_DESTROY:	// 最後にウインドウが閉じられた時の処理

		// デバイスコンテキストの解放
		DeleteDC(hdc_back);
		// オブジェクトの解放 
		DeleteObject(hb_back);
		DeleteObject(hb_all);
		PostQuitMessage(0);
		return 0;

	default:	// デフォルト処理
		return DefWindowProc(hWnd, msg, wParam, lParam);
	}
}
error C2664: 'int DrawTextW(HDC,LPCWSTR,int,LPRECT,UINT)' : 引数 2 を 'int' から 'LPCWSTR' へ変換できません。
とでて動きません。どうすればいいでしょうか。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: Win32APIでのランキング作成

#6

投稿記事 by みけCAT » 10年前

luc さんが書きました:error C2664: 'int DrawTextW(HDC,LPCWSTR,int,LPRECT,UINT)' : 引数 2 を 'int' から 'LPCWSTR' へ変換できません。
とでて動きません。どうすればいいでしょうか。
そこの前でwsprintf関数またはwsprintfA関数などを用いてmaxを文字列に変換し、
それをDrawText関数またはDrawTextA関数で描画するようにするといいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

luc
記事: 32
登録日時: 10年前

Re: Win32APIでのランキング作成

#7

投稿記事 by luc » 10年前

コード:

///////ウインドウプロシージャ関数//////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	// 画像を読み込む準備
	HDC hdc;		// デバイスコンテキストハンドル
	PAINTSTRUCT ps; // ペイント構造体
	RECT rect;

	// バックバッファ用コンテキストハンドルと、ビットマップハンドルの準備
	static HDC hdc_back;	// 裏画面(バックバッファ)用デバイスコンテキストハンドル
	static HBITMAP hb_back;	// 裏画面(バックバッファ)用ビットマップハンドル
	HDC     hdcMem;
	TCHAR max_max[10];
	
	switch (msg)
	{
	case WM_USER + 1:	// ゲームループ(SendMessageから呼ばれる)

		obj1.toPoint(&player);

		Get_Key();	// キー入力関数へ
		Player_move();		//移動関数へ
		

		// 結果の再描画 WM_PAINTを実行する
		InvalidateRect(hWnd, NULL, false);
		return 0;

	case WM_PAINT:	// 画面を描画する時の処理
		// 描画の開始
		hdc = BeginPaint(hWnd, &ps);
		RECT rt;
		GetClientRect(hWnd, &rt);
		// Paint関数へ
		Paint(hdc_back);

		//バックバッファに保存された画像を表画面に描画
		BitBlt(hdc, 0, 0, 1000, 450, hdc_back, 0, 0, SRCCOPY);
		wsprintf(max_max, TEXT("%d"), max);
		DrawText(hdc,max_max, -1, &rect, DT_LEFT | DT_WORDBREAK);
		// 描画の終了
		EndPaint(hWnd, &ps);
		return 0;

	case WM_CREATE:

		// ゲーム初期化関数へ ///////////////////
		Init_Game();

		// 描画の開始
		hdc = GetDC(hWnd);
		// 互換デバイスコンテキストの作成
		hdc_back = CreateCompatibleDC(hdc);
		// 互換ビットマップの作成
		hb_back = CreateCompatibleBitmap(hdc, 1000, 450);
		
		// オブジェクトの選択
		SelectObject(hdc_back, hb_back);
		// 描画の終了
		ReleaseDC(hWnd, hdc);

		// ビットマップハンドルに画像データを読み込み保存しておく
		hb_char = (HBITMAP)LoadImage(NULL, TEXT("char.bmp"), IMAGE_BITMAP,
			0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);

		return 0;

	case WM_DESTROY:	// 最後にウインドウが閉じられた時の処理

		// デバイスコンテキストの解放
		DeleteDC(hdc_back);
		// オブジェクトの解放 
		DeleteObject(hb_back);
		DeleteObject(hb_all);
		PostQuitMessage(0);
		return 0;

	default:	// デフォルト処理
		return DefWindowProc(hWnd, msg, wParam, lParam);
	}
}
wsprintfを使ってみました。そしたらエラーがでました。
error LNK2001: 外部シンボル ""int max" (?max@@3HA)" は未解決です。
書き方が悪いんでしょうか??

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: Win32APIでのランキング作成

#8

投稿記事 by みけCAT » 10年前

luc さんが書きました:error LNK2001: 外部シンボル ""int max" (?max@@3HA)" は未解決です。
今回のプロジェクトでコンパイルするソースコード(ヘッダではない)のグローバルスコープ(関数や構造体などの宣言の外)の場所のどこかにint max;と書き、実体を作ってください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

luc
記事: 32
登録日時: 10年前

Re: Win32APIでのランキング作成

#9

投稿記事 by luc » 10年前

最大値を表示することができました!ありがとうございます。
あとはこれをランキングにするのを頑張ります

luc
記事: 32
登録日時: 10年前

Re: Win32APIでのランキング作成

#10

投稿記事 by luc » 10年前

ランキング関数
file.cpp

コード:

float Ranking_Load(void){				//ランキングを読み込む
	int i, j,tmp;
	ifstream fin("ranking1.txt");
	if (!fin){
		return 1;
	}
	float ranking[8];
	for (i = 0; i < 8; i++){			//ファイル読み込み
		fin >> ranking[i];
	}
	for (i = 0; i < 8; i++){
		for (j = i + 1; j< 8; j++){
			if (ranking[i] < ranking[j]){		//並び替え
				tmp = ranking[i];
				ranking[i] = ranking[j];
				ranking[j] = tmp;
			}
		}
	}

	fin.close();						//ファイルを閉じる
	return ranking[8];
}
}

file.h

コード:

float Ranking_Load(void);
extern float ranking[8];
定義

コード:

float ranking[8];
winメイン関数

コード:

	ranking[8] = Ranking_Load();
ウィンドウプロシージャ関数

コード:

LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
	// 画像を読み込む準備
	HDC hdc;		// デバイスコンテキストハンドル
	PAINTSTRUCT ps; // ペイント構造体
	RECT rect;
	

	// バックバッファ用コンテキストハンドルと、ビットマップハンドルの準備
	static HDC hdc_back;	// 裏画面(バックバッファ)用デバイスコンテキストハンドル
	static HBITMAP hb_back;	// 裏画面(バックバッファ)用ビットマップハンドル
	HDC     hdcMem;
	TCHAR max_max[8];
	

	switch (msg)
	{
	case WM_USER + 1:	// ゲームループ(SendMessageから呼ばれる)

		obj1.toPoint(&player);
		Get_Key();	// キー入力関数へ
		Player_move();		//移動関数へ
		

		// 結果の再描画 WM_PAINTを実行する
		InvalidateRect(hWnd, NULL, false);
		return 0;

	case WM_PAINT:	// 画面を描画する時の処理
		// 描画の開始
		hdc = BeginPaint(hWnd, &ps);
		RECT rt;
		GetClientRect(hWnd, &rt);
		// Paint関数へ
		Paint(hdc_back);
	
		//バックバッファに保存された画像を表画面に描画
		BitBlt(hdc, 0, 0, 1000, 450, hdc_back, 0, 0, SRCCOPY);

		wsprintf(max_max, TEXT("%d"), ranking[0]);
		//wsprintf(max_max, TEXT("%d"), max);			//INT型からTCHARに変換
		TextOut(hdc, 10, 90, max_max, lstrlen(max_max));		//文字描画
		//TextOut(hdc, 10, 90, max_max,lstrlen(max_max));

		// 描画の終了
		EndPaint(hWnd, &ps);
		return 0;

	case WM_CREATE:

		// ゲーム初期化関数へ ///////////////////
		Init_Game();

		// 描画の開始
		hdc = GetDC(hWnd);
		// 互換デバイスコンテキストの作成
		hdc_back = CreateCompatibleDC(hdc);
		// 互換ビットマップの作成
		hb_back = CreateCompatibleBitmap(hdc, 1000, 450);
		
		// オブジェクトの選択
		SelectObject(hdc_back, hb_back);
		// 描画の終了
		ReleaseDC(hWnd, hdc);

		// ビットマップハンドルに画像データを読み込み保存しておく
		hb_char = (HBITMAP)LoadImage(NULL, TEXT("char.bmp"), IMAGE_BITMAP,
			0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);

		return 0;

	case WM_DESTROY:	// 最後にウインドウが閉じられた時の処理

		// デバイスコンテキストの解放
		DeleteDC(hdc_back);
		// オブジェクトの解放 
		DeleteObject(hb_back);
		DeleteObject(hb_all);
		PostQuitMessage(0);
		return 0;

	default:	// デフォルト処理
		return DefWindowProc(hWnd, msg, wParam, lParam);
	}
描画すると0と表示されて値が入ってないみたいです。原因教えてください!

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: Win32APIでのランキング作成

#11

投稿記事 by みけCAT » 10年前

luc さんが書きました:描画すると0と表示されて値が入ってないみたいです。原因教えてください!
多分、描画に使用しているranking[0]に値を入れる処理が無いから値が入らないのでしょう。

まず、file.cppと「winメイン関数」でranking[8](要素)にアクセスしていますが、そこは確保された領域の外側であり、アクセスすると何が起こるかわかりません。やめてください。
次に、Ranking_Load関数の戻り値をの宣言をvoid型にして戻り値を返さないようにし、
ローカル変数のranking[8](配列)の宣言もやめて、グローバル変数のranking[8](配列)を直接操作するようにしましょう。
さらに、型を合わせるため、

コード:

wsprintf(max_max, TEXT("%d"), ranking[0]);
ではなく

コード:

wsprintf(max_max, TEXT("%d"), (int)ranking[0]);
としましょう。
実数を扱いたければ、max_maxをchar型の配列にして、TextOutA関数、lstrlenA関数、およびC言語標準ライブラリのsprintf関数を使ってもいいかもしれません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

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