C++(DxLib)にて

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

C++(DxLib)にて

#1

投稿記事 by baby2478nishi » 8年前

C++/DxLibにて自分が目指しているものと異なるものが表示されます。
具体的には、添付した画像にありますが、「プログラムを終了します。 (自分でDrawString使って打ったもの)」とでます。

どなたか原因がわかる方はいますか?つまり、
なお、作っているものはタイトル画面で、ゲームを始める、終了・・などのものです。

真・ゲームプログラミングの館のメニュー画面の作り方を改変して作成しました。
まだ、終了させるプログラムは作っていませんが、本来ならばMキーを押さなければならないはずなのになぜ表示されるのでしょうか?

いかにソースを記載します。

コード:

//Mario.cpp

#include"DxLib.h"

typedef enum {
	eScene_Menu,    //メニュー画面
	eScene_Game,    //ゲーム画面
	eScene_Config,  //終了画面
	eScene_Title,   //タイトル画面
} eScene;

int Music1,Music2,Count = 0,Count1 = 0, BackGround1,Title1;//Music1:海戦,Music2:魔王の城,Count:音楽が流れている時間を継続,BackGround1:背景1

static int Scene = eScene_Menu;    //現在の画面(シーン)

void UpdateScene() {
	//DrawString(0, 20, "Gキーでゲーム画面、Cキーで設定、Mキー終了", GetColor(255, 255, 255));

	if (CheckHitKey(KEY_INPUT_G) != 0) {
		Scene = eScene_Game;
	}
	if (CheckHitKey(KEY_INPUT_C) != 0) {
		Scene = eScene_Config;
	}
	if (CheckHitKey(KEY_INPUT_M) != 0) {
		Scene = eScene_Menu;
	}
}

//メニュー画面
void Menu() {
//	ClearDrawScreen();//画面を初期化
	DrawString(0, 0, "プログラムを終了します。", GetColor(255, 255, 255));
}

//ゲーム画面
void Game() {
//	ClearDrawScreen();//画面を初期化
	DrawString(0, 0, "ゲーム画面です。", GetColor(255, 255, 255));
	StopSoundMem(Music1);
	PlaySoundMem(Music2, DX_PLAYTYPE_BACK); // GAME時の曲を再生する(ROOP)

}

//設定画面
void Config() {
//	ClearDrawScreen();//画面を初期化
	DrawString(0, 0, "設定画面です。", GetColor(255, 255, 255));
}

void Title() {//Default(初期)の画面・音声設定
	Title1 = LoadGraph("画像/Title.png");//タイトル画像をロード
	if (Count % 5580 == 0) { // Full
		PlaySoundMem(Music1, DX_PLAYTYPE_BACK); // 背景時の曲を再生する(ROOP)
	}
	Count++;
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK); //ウィンドウモード変更と初期化と裏画面設定

	Music1 = LoadSoundMem("Sound/amacya-kaisen.ogg"); // サウンド/1up.wavをロードし、識別番号をMusic1に格納
	Music2 = LoadSoundMem("Sound/甘茶工房-魔王の城.ogg"); //サウンドをメモリにロード,Music2に格納
	Title1 = LoadGraph("画像/Title.png");//タイトル画像をロード


	Title();
	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {
		DrawGraph(0, 0, Title1, TRUE); // データハンドルを使って画像を描画
		SetDrawScreen(DX_SCREEN_BACK);
		switch (Scene) {//現在のシーンにあった処理をする
		case eScene_Menu://現在のシーンがメニューなら
			Menu();//メニュー画面
			break;
		case eScene_Game://現在のシーンがゲームなら
			Game();//ゲーム画面
			break;
		case eScene_Config://現在のシーンが設定なら
			Config();//設定画面
			break;
		}
		UpdateScene();//シーンを更新する
	}

/*	for (;;)
	{
		if (CheckHitKey(KEY_INPUT_RETURN) == 0)
		{
			InitSoundMem();
			break;
		}
		else
		{
			Menu();
		}
	}*/
	DxLib_End(); // DXライブラリ終了処理
	return 0;
}

以上です。
よろしくお願いします。
添付ファイル
キャプチャ.PNG
キャプチャ.PNG (26.12 KiB) 閲覧数: 10001 回

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

Re: C++(DxLib)にて

#2

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

baby2478nishi さんが書きました:C++/DxLibにて自分が目指しているものと異なるものが表示されます。
具体的には、添付した画像にありますが、「プログラムを終了します。 (自分でDrawString使って打ったもの)」とでます。

どなたか原因がわかる方はいますか?つまり、
なお、作っているものはタイトル画面で、ゲームを始める、終了・・などのものです。

真・ゲームプログラミングの館のメニュー画面の作り方を改変して作成しました。
まだ、終了させるプログラムは作っていませんが、本来ならばMキーを押さなければならないはずなのになぜ表示されるのでしょうか?
変数SceneがeScene_Menuで初期化されており、キーを押さなければ更新されることは無いため、
Menu()が実行され、「プログラムを終了します。」が表示されます。
当たり前の挙動です。
改善するには、SceneをeScene_Menuではなく、-1 (どのシーンでもない)で初期化するといいかもしれません。
オフトピック
本題とは関係ないですが、画像/Title.pngが無駄に2回ロードされているのが気になりました。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: C++(DxLib)にて

#3

投稿記事 by Dixq (管理人) » 8年前

シーン分岐をする識別子の初期値が
static int Scene = eScene_Menu;
になっているので

コード:

        switch (Scene) {//現在のシーンにあった処理をする
        case eScene_Menu://現在のシーンがメニューなら
            Menu();//メニュー画面
            break;
        case eScene_Game://現在のシーンがゲームなら
            Game();//ゲーム画面
            break;
        case eScene_Config://現在のシーンが設定なら
            Config();//設定画面
            break;
        }
でMenu()がコールされていると思うので書いてあるそのままの処理がなされています。
もしTitile()をコールしたいのなら

コード:

        switch (Scene) {//現在のシーンにあった処理をする
        case eScene_Menu://現在のシーンがメニューなら
            Menu();//メニュー画面
            break;
        case eScene_Game://現在のシーンがゲームなら
            Game();//ゲーム画面
            break;
        case eScene_Config://現在のシーンが設定なら
            Config();//設定画面
            break;
        case eScene_Title://現在のシーンがタイトルなら
            Title();//タイトル画面
            break;
        }
このようにcase文にTitleを追加する必要があります。

しかしあちこちおかしいです。
Title()はこのままコールすると毎フレームロードとメモリリークがおきすぐパンクします。

コード:

    if (Count % 5580 == 0) { // Full
        PlaySoundMem(Music1, DX_PLAYTYPE_BACK); // 背景時の曲を再生する(ROOP)
    }
    Count++;
は何がしたいのでしょうか?

コード:

void Game() {
//  ClearDrawScreen();//画面を初期化
    DrawString(0, 0, "ゲーム画面です。", GetColor(255, 255, 255));
    StopSoundMem(Music1);
    PlaySoundMem(Music2, DX_PLAYTYPE_BACK); // GAME時の曲を再生する(ROOP)
}
は毎フレームすごいいきおいで曲が流れるでしょう。

コード:

    for (;;)
    {
        if (CheckHitKey(KEY_INPUT_RETURN) == 0)
        {
            InitSoundMem();
            break;
        }
        else
        {
            Menu();
        }
    }
これは書いては行けない処理です。やめましょう。

ClearDrawScreen();

は複数個所にかいてはいけません。
詳しくは「書いてはいけない4つの処理」
http://dixq.net/g/h_11.html
を参照ください。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: C++(DxLib)にて

#4

投稿記事 by Dixq (管理人) » 8年前

各関数は1秒間に60回コールされるということを意識して作成してみてください。

baby2478nishi
記事: 52
登録日時: 8年前
住所: 兵庫県姫路市

Re: C++(DxLib)にて

#5

投稿記事 by baby2478nishi » 8年前

みけCATさん,Dixqさん、ありがとうございます。

出来ました。僕としては、初期状態がTitleであったため、基本的にはtitleでよかったため、初期状態を

コード:

static int Scene = eScene_Title;    //現在の画面(シーン)
とさせていただきました。

Dixq (管理人) さんが書きました: しかしあちこちおかしいです。
Title()はこのままコールすると毎フレームロードとメモリリークがおきすぐパンクします。
すみません、これはどういうことなのでしょうか?教えてください。

また、

コード:

    if (Count % 5580 == 0) { // Full
        PlaySoundMem(Music1, DX_PLAYTYPE_BACK); // 背景時の曲を再生する(ROOP)
    }
    Count++;
については早速修正して、

コード:

		PlaySoundMem(Music1, DX_PLAYTYPE_BACK); // 背景時の曲を再生する(LOOP)
とさせていただきました。また、intで指定していたcountも消去しました。

同様に指摘されていた

コード:

void Game() {
//  ClearDrawScreen();//画面を初期化
    DrawString(0, 0, "ゲーム画面です。", GetColor(255, 255, 255));
    StopSoundMem(Music1);
    PlaySoundMem(Music2, DX_PLAYTYPE_BACK); // GAME時の曲を再生する(ROOP)
}
についてなのですが、不具合のようなものが発生しており、再生できない状況です。
具体的には【タイトル画面でSound1を再生】、「ゲーム画面(Gキー)に一度移動」、「Cキーを押すと曲が流れる」
ということになっていて、思うように「Gキーでの再生ができない」、という状況です。

何がいけないのでしょうか?教えていただければ幸いです。

また、
ClearDrawScreen();
は複数個所にかいてはいけません。
について。たしかにそうだということは理解できるのですが、自分としては初期にロードした画像(Title.png)から別の画像(または文字)に変えるときに残ってしまうので加えました。

これは、どのようにすればClearDrawScreen関数を使わなくてよいのでしょうか?



長くなりましたがよろしくお願いします。

また、自分は先ほどButtonについての質問をさせていただいたものなのですが、Dixqさんが作ってくださったサンプルも導入しある程度進んだ段階で導入しようと思います。ありがとうございました。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: C++(DxLib)にて

#6

投稿記事 by Dixq (管理人) » 8年前

>> Title()はこのままコールすると毎フレームロードとメモリリークがおきすぐパンクします。
> すみません、これはどういうことなのでしょうか?教えてください。

例えばこんなコードを書いているのと同じです。

コード:

while(1){
    tmp = (char *)malloc(1);
}
メモリリークがおきまくってそのうちすぐ落ちるでしょう。

Title()の関数内は
Title1 = LoadGraph("画像/Title.png");//タイトル画像をロード
となっていて1秒間に60回メモリへのロードが発生します。

> についてなのですが、不具合のようなものが発生しており、再生できない状況です。

先ほども書いた通り1秒間に60回通るコードだということを意識して書いてください。
1秒間に60回「このファイルを再生」というコードを書いたらどうなるでしょうか?

また、
SetDrawScreen(DX_SCREEN_BACK);
は2回も書く必要はありません。
ループ文の中にあるものを消してください。

> これは、どのようにすればClearDrawScreen関数を使わなくてよいのでしょうか?

ClearDrawScreenはメインのwhile文の中に既に入っていますから描画されたままになることはありません。
毎フレーム必要な物を描画してUpdateし、終わったら全部消すのが正しい書き方です。

baby2478nishi
記事: 52
登録日時: 8年前
住所: 兵庫県姫路市

Re: C++(DxLib)にて

#7

投稿記事 by baby2478nishi » 8年前

Dixqさん、度々ありがとうございます。

メモリアクセスの件については修正したと思うのですが、これをすると、画像が一瞬しか表示されません。

コード:

	Title();//タイトル画面
		DrawGraph(0, 0, Title1, TRUE); // データハンドルを使って画像を描画
	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {
		switch (Scene) {//現在のシーンにあった処理をする
		case eScene_Menu://現在のシーンがメニューなら
			Menu();//メニュー画面
			break;
		case eScene_Game://現在のシーンがゲームなら
			Game();//ゲーム画面
			break;
		case eScene_Config://現在のシーンが設定なら
			Config();//設定画面
			break;
		}
上のようにdrawGraphをwhileの外に出してみたのですが・・。

また、上記のことはwhileにいれると実行できます。


また、音声についてなのですが、

コード:

void Game() {
//	ClearDrawScreen();//画面を初期化
	DrawString(0, 0, "ゲーム画面です。", GetColor(255, 255, 255));
	StopSoundMem(Music1);
	PlaySoundMem(Music2, DX_PLAYTYPE_BACK); // GAME時の曲を再生する(LOOP)
}
となっていてwhileにはなっていないのですが・・。どこを直せばいいのでしょうか?

また、動画を添付します。見ていただければわかるのですが、Cキーを押すと再生になってしまっています。

また、ClearDrawScreenをしないとタイトル画像とともに表示されてしまいます。(これも動画を見ていただければわかると思います。)


よろしくお願いします。
baby2478nishi
[youtube][/youtube]

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: C++(DxLib)にて

#8

投稿記事 by Dixq (管理人) » 8年前

せっかくcase文がよくなったのに何故元に戻したのです。。。
さっき直したように戻してください。
どのように処理がなされているか、理解してください。

・DrawGraph系の関数はwhile文の外に書いてはいけません。
・LoadGraph系の関数はwhile文の前に書かなければなりません。(または一度しか通らないように工夫が必要です)
・ClearDrawScreenはwhileの条件式内以外に書いてはいけません
・Game関数自体がwhile文に入っていますから1秒間に60回よばれます。

処理がされている順序が理解できないのであればブレイクポイントを使って一行ずつ処理を止めながら進め、
どこをどのように処理が通っているのか確認しながら作ってみてください。

baby2478nishi
記事: 52
登録日時: 8年前
住所: 兵庫県姫路市

Re: C++(DxLib)にて

#9

投稿記事 by baby2478nishi » 8年前

Dixq (管理人) さんが書きました:DrawGraph系の関数はwhile文の外に書いてはいけません。
これだと1秒間に60回呼ばれることになると思うのですが。。

どういうことでしょうか?

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: C++(DxLib)にて

#10

投稿記事 by Dixq (管理人) » 8年前

> これだと1秒間に60回呼ばれることになると思うのですが。。
> どういうことでしょうか?

至って普通です。
毎フレーム全部消して全部書き直してフレームバッファに更新をかけるのが一般的な作り方です。

コード:

ロード処理();
while(1){
    計算処理();
    描画処理();
}
ロード解放処理();
という構造になるのが一般的です。
詳しくは
http://dixq.net/g/
の「ゲームプログラミング設計」をご覧ください。

baby2478nishi
記事: 52
登録日時: 8年前
住所: 兵庫県姫路市

Re: C++(DxLib)にて

#11

投稿記事 by baby2478nishi » 8年前

一応、音声関連以外のバグ(?)以外は治りました。

コード:

//Mario.cpp

#include"DxLib.h"

typedef enum {
	eScene_Menu,    //メニュー画面
	eScene_Game,    //ゲーム画面
	eScene_Config,  //終了画面
	eScene_Title,   //タイトル画面
} eScene;

int Music1,Music2,BackGround1,Title1;//Music1:海戦,Music2:魔王の城,Count:音楽が流れている時間を継続,BackGround1:背景1

static int Scene = eScene_Title;    //現在の画面(シーン)

void UpdateScene() {
	//DrawString(0, 20, "Gキーでゲーム画面、Cキーで設定、Mキー終了", GetColor(255, 255, 255));

	if (CheckHitKey(KEY_INPUT_G) != 0) {
		Scene = eScene_Game;
	}
	if (CheckHitKey(KEY_INPUT_C) != 0) {
		Scene = eScene_Config;
	}
	if (CheckHitKey(KEY_INPUT_M) != 0) {
		Scene = eScene_Menu;
	}
}

//メニュー画面
void Menu() {
//	ClearDrawScreen();//画面を初期化
	DrawString(0, 0, "プログラムを終了します。", GetColor(255, 255, 255));
}

//ゲーム画面
void Game() {
//	ClearDrawScreen();//画面を初期化
	DrawString(0, 0, "ゲーム画面です。", GetColor(255, 255, 255));
	StopSoundMem(Music1);
	PlaySoundMem(Music2, DX_PLAYTYPE_BACK); // GAME時の曲を再生する(LOOP)
}

//設定画面
void Config() {
//	ClearDrawScreen();//画面を初期化
	DrawString(0, 0, "設定画面です。", GetColor(255, 255, 255));
}

void Title() {//Default(初期)の画面・音声設定
		PlaySoundMem(Music1, DX_PLAYTYPE_BACK); // 背景時の曲を再生する(LOOP)
		DrawGraph(0, 0, Title1, TRUE); // データハンドルを使って画像を描画
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK); //ウィンドウモード変更と初期化と裏画面設定

	SetMainWindowText("Piron's Adventure");//タイトルを変更

	Music1 = LoadSoundMem("Sound/amacya-kaisen.ogg"); // サウンド/1up.wavをロードし、識別番号をMusic1に格納
	Music2 = LoadSoundMem("Sound/甘茶工房-魔王の城.ogg"); //サウンドをメモリにロード,Music2に格納
	Title1 = LoadGraph("画像/Title.png");//タイトル画像をロード


	Title();//タイトル画面
	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {
		switch (Scene) {//現在のシーンにあった処理をする
		case eScene_Menu://現在のシーンがメニューなら
			Menu();//メニュー画面
			break;
		case eScene_Game://現在のシーンがゲームなら
			Game();//ゲーム画面
			break;
		case eScene_Config://現在のシーンが設定なら
			Config();//設定画面
			break;
		case eScene_Title://現在のシーンがタイトルなら
			Title();//タイトル画面
			break;
		}
		UpdateScene();//シーンを更新する
	}

/*	for (;;)
	{
		if (CheckHitKey(KEY_INPUT_RETURN) == 0)
		{
			InitSoundMem();
			break;
		}
		else
		{
			Menu();
		}
	}*/
	DxLib_End(); // DXライブラリ終了処理
	return 0;
}

です。

ただ、初期状態(Title)のときに音声が出ない、また、Cキー(こちらとしてはGが良い)を押したときにMusic2がながれる、


という状況です。ループもさせてないと思うのですが何がいけないのでしょうか?

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

Re: C++(DxLib)にて

#12

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

baby2478nishi さんが書きました:ただ、初期状態(Title)のときに音声が出ない、また、Cキー(こちらとしてはGが良い)を押したときにMusic2がながれる、


という状況です。ループもさせてないと思うのですが何がいけないのでしょうか?
思いっきりループさせています。
毎フレーム音声の再生を開始しているのがいけないです。
新たに「メニューの初期化」「ゲームの初期化」「設定の初期化」「タイトルの初期化」というシーンを用意し、
各「初期化」シーンで音声の切り替え(再生)を行い、対応するシーンに遷移するようにするといいと思います。
オフトピック
Dixq (管理人) さんが書きました:

コード:

while(1){
    tmp = (char *)malloc(1);
}
メモリリークがおきまくってそのうちすぐ落ちるでしょう。
スワップが大活躍してなかなか落ちないというケースも…
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: C++(DxLib)にて

#13

投稿記事 by Dixq (管理人) » 8年前

実行して試していませんがこれでどうですか?
Title()はwhileの手前に必要ありません。

コード:

#include"DxLib.h"

typedef enum {
	eScene_Menu,    //メニュー画面
	eScene_Game,    //ゲーム画面
	eScene_Config,  //終了画面
	eScene_Title,   //タイトル画面
} eScene;

int Music1,Music2,BackGround1,Title1;//Music1:海戦,Music2:魔王の城,Count:音楽が流れている時間を継続,BackGround1:背景1

static int Scene = eScene_Title;    //現在の画面(シーン)
bool IsFirstTitle = true;

void UpdateScene() {
	if (CheckHitKey(KEY_INPUT_G) != 0) {
		Scene = eScene_Game;
	}
	if (CheckHitKey(KEY_INPUT_C) != 0) {
		Scene = eScene_Config;
	}
	if (CheckHitKey(KEY_INPUT_M) != 0) {
		Scene = eScene_Menu;
	}
}

//メニュー画面
void Menu() {
	DrawString(0, 0, "プログラムを終了します。", GetColor(255, 255, 255));
}

//ゲーム画面
void Game() {
	DrawString(0, 0, "ゲーム画面です。", GetColor(255, 255, 255));
	StopSoundMem(Music1);
	PlaySoundMem(Music2, DX_PLAYTYPE_BACK); // GAME時の曲を再生する(LOOP)
}

//設定画面
void Config() {
	DrawString(0, 0, "設定画面です。", GetColor(255, 255, 255));
}

void Title() {//Default(初期)の画面・音声設定
	if(IsFirstTitle){
		PlaySoundMem(Music1, DX_PLAYTYPE_BACK); // 背景時の曲を再生する(LOOP)
		IsFirstTitle = false;
	}
	DrawGraph(0, 0, Title1, TRUE); // データハンドルを使って画像を描画
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK); //ウィンドウモード変更と初期化と裏画面設定

	SetMainWindowText("Piron's Adventure");//タイトルを変更

	Music1 = LoadSoundMem("Sound/amacya-kaisen.ogg"); // サウンド/1up.wavをロードし、識別番号をMusic1に格納
	Music2 = LoadSoundMem("Sound/甘茶工房-魔王の城.ogg"); //サウンドをメモリにロード,Music2に格納
	Title1 = LoadGraph("画像/Title.png");//タイトル画像をロード

	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {
		switch (Scene) {//現在のシーンにあった処理をする
		case eScene_Menu://現在のシーンがメニューなら
			Menu();//メニュー画面
			break;
		case eScene_Game://現在のシーンがゲームなら
			Game();//ゲーム画面
			break;
		case eScene_Config://現在のシーンが設定なら
			Config();//設定画面
			break;
		case eScene_Title://現在のシーンがタイトルなら
			Title();//タイトル画面
			break;
		}
		UpdateScene();//シーンを更新する
	}

	DxLib_End(); // DXライブラリ終了処理
	return 0;
}

baby2478nishi
記事: 52
登録日時: 8年前
住所: 兵庫県姫路市

Re: C++(DxLib)にて

#14

投稿記事 by baby2478nishi » 8年前

Dixq三のプログラムを実行してみたのですが変わりませんでした。

また、初期化では何をすればよいのかというのが分かりません。

ご教授ください。

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

Re: C++(DxLib)にて

#15

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

Dixq (管理人) さんが書きました:実行して試していませんがこれでどうですか?
Gameの処理が全く改善されておらず、ダメです。
GameについてもTitleと同様に音声再生処理のガードを行うべきです。

コード:

#include"DxLib.h"

typedef enum {
	eScene_Menu,    //メニュー画面
	eScene_Game,    //ゲーム画面
	eScene_Config,  //終了画面
	eScene_Title,   //タイトル画面
} eScene;

int Music1,Music2,BackGround1,Title1;//Music1:海戦,Music2:魔王の城,Count:音楽が流れている時間を継続,BackGround1:背景1

static int Scene = eScene_Title;    //現在の画面(シーン)
bool IsFirstTitle = true;
bool IsFirstGame = true;

void UpdateScene() {
	if (CheckHitKey(KEY_INPUT_G) != 0) {
		Scene = eScene_Game;
		IsFirstGame = true;
	}
	if (CheckHitKey(KEY_INPUT_C) != 0) {
		Scene = eScene_Config;
	}
	if (CheckHitKey(KEY_INPUT_M) != 0) {
		Scene = eScene_Menu;
	}
}

//メニュー画面
void Menu() {
	DrawString(0, 0, "プログラムを終了します。", GetColor(255, 255, 255));
}

//ゲーム画面
void Game() {
	DrawString(0, 0, "ゲーム画面です。", GetColor(255, 255, 255));
	if (IsFirstGame) {
		StopSoundMem(Music1);
		PlaySoundMem(Music2, DX_PLAYTYPE_BACK); // GAME時の曲を再生する(LOOP)
		IsFirstGame = false;
	}
}

//設定画面
void Config() {
	DrawString(0, 0, "設定画面です。", GetColor(255, 255, 255));
}

void Title() {//Default(初期)の画面・音声設定
	if(IsFirstTitle){
		PlaySoundMem(Music1, DX_PLAYTYPE_BACK); // 背景時の曲を再生する(LOOP)
		IsFirstTitle = false;
	}
	DrawGraph(0, 0, Title1, TRUE); // データハンドルを使って画像を描画
}

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) {
	ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK); //ウィンドウモード変更と初期化と裏画面設定

	SetMainWindowText("Piron's Adventure");//タイトルを変更

	Music1 = LoadSoundMem("Sound/amacya-kaisen.ogg"); // サウンド/1up.wavをロードし、識別番号をMusic1に格納
	Music2 = LoadSoundMem("Sound/甘茶工房-魔王の城.ogg"); //サウンドをメモリにロード,Music2に格納
	Title1 = LoadGraph("画像/Title.png");//タイトル画像をロード

	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) {
		switch (Scene) {//現在のシーンにあった処理をする
		case eScene_Menu://現在のシーンがメニューなら
			Menu();//メニュー画面
			break;
		case eScene_Game://現在のシーンがゲームなら
			Game();//ゲーム画面
			break;
		case eScene_Config://現在のシーンが設定なら
			Config();//設定画面
			break;
		case eScene_Title://現在のシーンがタイトルなら
			Title();//タイトル画面
			break;
		}
		UpdateScene();//シーンを更新する
	}

	DxLib_End(); // DXライブラリ終了処理
	return 0;
}

baby2478nishi さんが書きました:Dixq三のプログラムを実行してみたのですが変わりませんでした。
こちら(Windows 7、gcc 4.8.1、DXライブラリ Ver3.13d)で実行した所、
No: 11のプログラムでは起動直後(操作をしない状態で)音は聞こえませんでしたが、No: 13のプログラムでは起動直後音が聞こえました。
音声ファイルが壊れていないか(不正または未対応の形式でないか)、プログラム中のファイル名が適切かを確認してください。
添付ファイル
cpp_dxlib_nite_sozai.zip
テストに使用した仮素材(画像と音声)
(1.95 MiB) ダウンロード数: 171 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: C++(DxLib)にて

#16

投稿記事 by Dixq (管理人) » 8年前

> Gameの処理が全く改善されておらず、ダメです。

みけ君はよくズバっとそういうこと言うけど承知の上でのコード提示です。
今作っているのはTitleであり、初期状態でGame関数は通りません。
あちこち一気にソースコードが変わると理解が出来ないかと思い
よってまずTitleがうまくいくかどうか確認してもらいたかったので、Titleにしか手を加えていません。

> baby2478nishi さん

Music1がロードできていないんじゃないですか?
Music1に-1が返って来ていないか確認してください。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: C++(DxLib)にて

#17

投稿記事 by softya(ソフト屋) » 8年前

まとめて色々やり過ぎて混乱している印象ですね。
プログラムを幾つかに分けて、それぞれクリアしてからまとめに掛かるのはどうでしょうか?
・音楽の再生テスト。
・初期化処理の組み方の練習。タイトルだけ。
・タイトル→ゲーム画面
これらが出来たら、始めて統合的なものを組んだほうが良いと思います。
分かる範囲に収めるため色々やらずにコンパクトにして実験をするのはプロでもやっていることです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

baby2478nishi
記事: 52
登録日時: 8年前
住所: 兵庫県姫路市

Re: C++(DxLib)にて

#18

投稿記事 by baby2478nishi » 8年前

みけさん、管理人さん、ありがとうございます。

音声についてなのですが、どちらのファイルも正常にロードし再生できます。(最初のタイトル画面でのローどができましたので。)

また、みけさん、音声再生処理のガードとはどういうことでしょうか?貴方様のコードを書いたら僕の望んでいる通りにはなったのですが。
Dixq (管理人) さんが書きました: Music1がロードできていないんじゃないですか?
Music1に-1が返って来ていないか確認してください。
一応、

コード:

//ゲーム画面
void Game() {
//	ClearDrawScreen();//画面を初期化
	DrawString(0, 0, "ゲーム画面です。", GetColor(255, 255, 255));
	StopSoundMem(Music1);
	PlaySoundMem(Music2, DX_PLAYTYPE_BACK); // GAME時の曲を再生する(LOOP)
	if (Music2 == -1)
	{
		unsigned int Wh;//Wh(白色)
		Wh = GetColor(255, 255, 255);// 白色の値を取得
		DrawString(250, 240 - 32, "音声の再生に失敗しました.", Wh);
	}
	}
としてみましたが、エラーは出ませんでした。

また、softyaさんのものに関しては後程してみようと思います。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: C++(DxLib)にて

#19

投稿記事 by Dixq (管理人) » 8年前

Gameは後回しにしましょう。
とりあえずTitleが期待通りの振る舞いになることを目標にしましょう。
先ほども言いましたがMusic1が-1になっていないか確認してください。
また、DrawStringだと消えている可能性があるので
printfDxを使ってください。

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

Re: C++(DxLib)にて

#20

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

baby2478nishi さんが書きました:また、みけさん、音声再生処理のガードとはどういうことでしょうか?
ここでは、音声再生処理が無駄に(毎フレーム)実行されないようにする、ということです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

baby2478nishi
記事: 52
登録日時: 8年前
住所: 兵庫県姫路市

Re: C++(DxLib)にて

#21

投稿記事 by baby2478nishi » 8年前

こんばんは。
返信ありがとうございます。


失礼しました。
Music1はロードでき再生できています。
ですが、Music2のロードが正常にできないということだったのですが、

みけCATさんが変更してくれたcppファイルでは正常にできました。
音声再生処理のガードの問題で・・。ということらしいです。

Isは14歳から始める(ry)で見たことがあるのですが今市どういうものなのかわかっていませんでした。

閉鎖

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