タイムについて

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

タイムについて

#1

投稿記事 by luc » 8年前

現在STGを作ってます。C++、VitualStudio2013を使って作成してます。
クリアタイムランキングを作ろうと思ってるんですがどのように作ればいいでしょうか。
まずはタイムの実装をしようと思うのですがプログラムが起動してからの経過時間の習得の方法がわかりません。
手も足もでないのでどなたかお願いします。どんな関数を使えばいいのか教えて下さい。

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

Re: タイムについて

#2

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

VisualStudio2013を使っているということから、Windows向けと仮定します。
luc さんが書きました:まずはタイムの実装をしようと思うのですがプログラムが起動してからの経過時間の習得の方法がわかりません。
手も足もでないのでどなたかお願いします。どんな関数を使えばいいのか教えて下さい。
あまり精度が高くなくてよければ、GetTickCount関数を使うとWindowsの起動からの時間(ミリ秒単位)が取得できるので、
まずプログラムが起動した直後(エントリポイントの関数(mainまたはWinMainなど)の最初)に1回Windowsの起動からの時間を取得し、
プログラムが起動してからの経過時間を取得したいところで、そこでのWindowsの起動からの時間 - 最初に取得したWindowsの起動からの時間 を計算すると、
約49日まではだいたいの経過時間を取得できるはずです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: タイムについて

#3

投稿記事 by luc » 8年前

すいません、言い方間違えました。
プログラム起動した直後というかタイトル画面のスタート押してからをタイムをスタートしたいと思うのですが、それでもこの関数で平気でしょうか・

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

Re: タイムについて

#4

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

luc さんが書きました:プログラム起動した直後というかタイトル画面のスタート押してからをタイムをスタートしたいと思うのですが、それでもこの関数で平気でしょうか・
はい。
スタート押した時をエントリポイントの関数の最初の代わりに基準にすればいいです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: タイムについて

#5

投稿記事 by luc » 8年前

エラー 14 error LNK2019: 未解決の外部シンボル __imp__timeGetTime@0 が関数 _WinMain@16 で参照されました。
と出てきました。これはどうすればいいのでしょうか。

コード:

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	WNDCLASS wc;
	MSG msg;
	TCHAR  buff[80];
	DWORD gettime;  // 取得した時間を格納

	// ゲーム開始時間を取得し、表示
	gettime = timeGetTime();
	wsprintf((LPWSTR)buff, TEXT("ゲーム開始時間:%d ミリ秒\n"), gettime);
	OutputDebugString(buff);

	// ウインドウクラス構造体
	ZeroMemory(&wc, sizeof(WNDCLASS));
	wc.style = CS_HREDRAW | CS_VREDRAW;         // ウインドウスタイル
	wc.lpfnWndProc = (WNDPROC)WndProc;                // ウインドウプロシージャアドレス
	wc.cbClsExtra = 0;                               // 補助領域サイズ(使用しない)
	wc.cbWndExtra = 0;                               // 補助領域サイズ(使用しない)
	wc.hInstance = hInstance;                       // インスタンスハンドル
	wc.hIcon = LoadIcon(NULL, IDI_APPLICATION); // アイコン
	wc.hCursor = LoadCursor(NULL, IDC_ARROW);     // マウスカーソル
	wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);      // ウィンドウ画面の色
	wc.lpszMenuName = NULL;                            // ウインドウメニュー(使用しない)
	wc.lpszClassName = TEXT("Window01");                // ウインドウクラス名



	// ウインドウクラスの登録
	if (!RegisterClass(&wc)) return FALSE;

	// ウインドウの作成
	HWND hWnd = CreateWindow(
		TEXT("Window01"), TEXT("stg"),					// ウインドウのタイトル名
		WS_OVERLAPPEDWINDOW^WS_THICKFRAME^WS_MAXIMIZEBOX,			// ウインドウスタイル
		CW_USEDEFAULT,												// ウィンドウの表示X座標
		CW_USEDEFAULT,												// ウィンドウの表示Y座標
		1000 + GetSystemMetrics(SM_CXDLGFRAME) * 2,						// ウィンドウの幅
		450 + GetSystemMetrics(SM_CYDLGFRAME) * 2 + GetSystemMetrics(SM_CYCAPTION),	// 高さ
		NULL,														// 親ウインドウ
		NULL,														// ウインドウメニュー
		hInstance,													// インスタンスハンドル
		NULL);														 // WM_CREATE情報







	// ウインドウの表示
	ShowWindow(hWnd, nCmdShow);                         // 表示状態の設定
	UpdateWindow(hWnd);                                 // クライアント領域の更新

	// これまでのメッセージループ 
	//	while(GetMessage(&msg, NULL, 0, 0))
	//	{
	//		TranslateMessage(&msg);        // メッセージを仮想キーから文字に変換
	//		DispatchMessage(&msg);         // ウインドウプロシージャへメッセージを転送
	//	}
	//
	//	return msg.wParam;
	//}

	// ここからのメッセージループ /////////////////////////////
	// 今回から、PeekMessage関数を用いてCPUの空き時間を利用した方法を使います。
	// この方法では、CPUを最大限活用するため、マシンパワーを無駄に使ってしまう欠点があります。
	// しかし、3Dゲームなどにつながる汎用性の高いゲームループです。


	while (true)
	{
		if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if (msg.message == WM_QUIT) break;
			DispatchMessage(&msg);
		}
		else
		{
			// WM_USER+1へ (ここがゲームループ)
			SendMessage(hWnd, WM_USER + 1, 0, 0);

			// スリープ関数へ
			Sleep(20);
		}
	}

	// ゲーム終了時間を取得し、表示
	gettime = timeGetTime();
	wsprintf((LPWSTR)buff, TEXT("ゲーム終了時間:%d ミリ秒\n"), gettime);
	OutputDebugString(buff);


	return msg.wParam;
}

YuO
記事: 947
登録日時: 13年前
住所: 東京都世田谷区

Re: タイムについて

#6

投稿記事 by YuO » 8年前

luc さんが書きました:エラー 14 error LNK2019: 未解決の外部シンボル __imp__timeGetTime@0 が関数 _WinMain@16 で参照されました。
と出てきました。これはどうすればいいのでしょうか。
みけCATさんが書かれているGetTickCountではなく,timeGetTimeを使っているのですね。

それはともかく,まずはMSDNを調べましょう。
リンカ ツール エラー LNK2019
そうすると,
このエラーは、そのシンボルの定義が存在するソース コードまたはライブラリ ファイルがビルドに含まれていない場合に発生することがあります。
という記述があります。
その上で,先ほどのtimeGetTimie自体のMSDNには,
Library Winmm.lib
という記述があります。
つまり,timeGetTimeを使うにはWinmm.libをリンクする必要がある,ということです。

今回のプログラムで,Winmm.libは正しくリンクされていますか。
されていないのであれば,Winmm.libをリンクしてみた場合,結果は変わりますでしょうか。

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

Re: タイムについて

#7

投稿記事 by luc » 8年前

GetTickCountを使ったらエラーがでず出来ました。
ですが表示がうまくいきません。
Debug Error! run time check failure #3 というのを起こしてしまいます。

コード:

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

	// バックバッファ用コンテキストハンドルと、ビットマップハンドルの準備
	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);
		Ranking_Load();
		//バックバッファに保存された画像を表画面に描画
		BitBlt(hdc, 0, 0, 1000, 450, hdc_back, 0, 0, SRCCOPY);


		DWORD ts, te;
		for (int i = 0; i < 100 * 100; i++){
			DWORD ts = GetTickCount();
		}
		DWORD timeend = GetTickCount();    // 終了時間

		wsprintf(time, TEXT("経過時間"), ts - timeend);
		TextOut(hdc, 20, 90 + 40, time, lstrlen(time));

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


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

Re: タイムについて

#8

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

エラーの原因かはわかりませんが、とりあえずwsprintf関数の使い方がおかしいです。
format-control specifications (第2引数) に%が含まれていないのに第3引数以降のデータが渡されているのはおかしいです。
また、UNICODEが定義されていない場合、timeの領域が少なすぎるためバッファオーバーランが発生します。
さらに、wsprintfの第3引数で使用されているtsが初期化されておらず、不定または0という意味のない値になっています。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: タイムについて

#9

投稿記事 by luc » 8年前

wsprint関数の書き方を直したら動くようになったのですが、タイムの値が7桁ぐらいになってしまいます。
どういうことなのでしょうか。

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

Re: タイムについて

#10

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

luc さんが書きました:wsprint関数の書き方を直したら動くようになったのですが、タイムの値が7桁ぐらいになってしまいます。
どういうことなのでしょうか。
まず改善したコードを貼っていただけますか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: タイムについて

#11

投稿記事 by luc » 8年前

time.h

コード:

#include<Windows.h>

class Timer {
	 DWORD timeend;		//タイム計測終了時間
	 DWORD timestart;	//タイム開始時間
public:
	Timer();	
	~Timer();	
	int MainTimer(HDC hdc);	
};
time.cpp

コード:

#include "timer.h"
#include"debugmsg.h"

Timer::Timer()
{
}

Timer::~Timer()
{
}

int Timer::MainTimer(HDC hdc){

	TCHAR time[1000];
	timestart = GetTickCount();		//開始時間
	DebugStringVal("タイム:%d", timestart / 1000, hdc, 980, 10, 20); //描画
	return 0;
}
タイトルからゲーム画面になったらタイムオブジェの呼び出しをしてます。

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: タイムについて

#12

投稿記事 by へにっくす » 8年前

luc さんが書きました:タイトルからゲーム画面になったらタイムオブジェの呼び出しをしてます。
その部分も貼ってください。
timestartをただ表示しただけ?
No.2でみけCATさんが書かれていることをもう忘れているのでしょうか?
written by へにっくす

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

Re: タイムについて

#13

投稿記事 by luc » 8年前

すいません。解決しました。ありがとうございます。
time.h

コード:

#include<Windows.h>

class Timer {
	 DWORD timestart;		//プログラム起動時の時間
	 DWORD timewindows;	//windowsの起動からの時間
	 TCHAR time[1000];
public:
	Timer();	
	~Timer();	
	int StartTimer(HDC hdc);
	int WindowsTimer(HDC hdc);
	int ShowTime(HDC hdc);
};
Timer.cpp

コード:

#include "timer.h"
#include"debugmsg.h"

Timer::Timer()
{	
}

int Timer::StartTimer(HDC hdc){
	timewindows = GetTickCount();	
	DebugStringVal("タイム:%d秒", timewindows / 1000 - timestart / 1000, hdc, 950, 10, 20); //windowsの起動からの時間 - プログラム起動時に習得した時間
	return 0;
}

int Timer::ShowTime(HDC hdc){
	time[0] = timewindows/1000 - timestart/1000;			
	DebugStringVal("タイム:%d秒", time[0], hdc, 950, 10, 20); 
	return 0;
}

Timer::~Timer()
{
	
}

int Timer::WindowsTimer(HDC hdc){

	timestart = GetTickCount();			//windows起動からの時間

	return 0;
}


};
最後に編集したユーザー luc on 2015年10月16日(金) 10:35 [ 編集 2 回目 ]

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

Re: タイムについて

#14

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

解決したのでしたら、「解決チェック」をお願いします。
解決チェックをするには、投稿画面の「送信」ボタンの右にある「解決!」にチェックを入れた状態で返信を投稿してください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

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

Re: タイムについて

#15

投稿記事 by luc » 8年前

今頃、すいません。タイム表示はすることができたんですが、秒数表示になってしまいます。
なのでfloatで表示しようとしたんですが、1.000000,2.000000・・・10.000000となってしまいます。1.1・・・1.2という風にしたいです。

コード:

Timer::Timer()
{	
}

void Timer::StartTimer(HDC hdc){
	timewindows = GetTickCount();
	return ;
}

void Timer::ShowTime(HDC hdc){
	S_time = timewindows/100 - timestart/100;					//windows起動-プログラムが起動した時間
	DebugStringFloat("Time:%f秒",S_time, hdc, 950, 10, 20);
	return ;
}

Timer::~Timer()
{
}

void Timer::WindowsTimer(HDC hdc){
	timestart = GetTickCount();			//windows起動からの時間
	return ;
}

//hファイル

#include<Windows.h>
extern float S_time;

class Timer {
	 DWORD timestart;	//プログラム起動時の時間
	 DWORD timewindows;	//windowsの起動からの時間
	 
public:
	Timer();	
	~Timer();	
	void StartTimer(HDC hdc);
	void WindowsTimer(HDC hdc);
	void ShowTime(HDC hdc);
	void ShowTime2(HDC hdc);
};

最後に編集したユーザー luc on 2015年10月18日(日) 11:05 [ 編集 1 回目 ]

YuO
記事: 947
登録日時: 13年前
住所: 東京都世田谷区

Re: タイムについて

#16

投稿記事 by YuO » 8年前

整数を整数で割った結果は,整数になります。
片方を浮動小数点数にすれば,浮動小数点数の型になるので,小数部も計算されます。

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

Re: タイムについて

#17

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

DebugStringなんとかの仕様がわからないですが、書式が入っていない文字列を表示できる関数が使えるのであれば、わざわざfloatを使う必要は無いでしょう。

コード:

char buffer[128];
DWORD zikan = timewindows - timestart;
wsprintfA(buffer, "Time:%u.%u秒", (zikan / 100) / 10, (zikan / 100) % 10);
/* bufferの内容を表示する */
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

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