ページ 11

DXライブラリ サンプルプログラム  20.サウンドノベル風文字列描画、テキストバッファ使用バージョン について

Posted: 2015年12月12日(土) 15:00
by THムラオサ
お世話になります ムラオサと申します。

「サウンドノベル風文字列描画、テキストバッファ使用バージョン」をベースにノベルゲームを作成しています。


この度はプログラミグにてわからない箇所がありましたので質問の方をさせていただきました。

つまずいた点は、switch文の各処理についてです。
ケースBはエンターで改行と画像表示("画像/メッセージボックス 1.png"←の画像の表示)
ケースcは画面のクリア
ケース@は改行(自動で行われます)
ケースEは終了
                     となっております。

このswitch文のケースBの改行はできるのですが、画像表示ができません。この場合は何がおかしいのでしょうか
ご解答お待ちしています
ノートパソコンを使用しています
スペックについて
 プロセッサ       Intel(R) Core(TM)2 Duo CPU
     P9500 @2.53GHz 2.54GHz
実装メモリ(RAM)   4.00GB(3.49GB使用可能)
システムの種類    32bit オペレーションシステム

使用ソフトについて
             visual studio 2013
DXLib 2012

下記には私が実行したプログラムのコードを貼ります

コード:


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

// 文字のサイズ 
#define MOJI_SIZE 24 

// 仮想テキストバッファの横サイズ縦サイズ 
#define STRBUF_WIDTH 21
#define STRBUF_HEIGHT 20 



char StringBuf[STRBUF_HEIGHT][STRBUF_WIDTH * 2 + 1]; // 仮想テキストバッファ 
int CursorX, CursorY; // 仮想画面上での文字表示カーソルの位置 
int SP, CP; // 参照する文字列番号と文字列中の文字ポインタ 
int EndFlag; // 終了フラグ 
int KeyWaitFlag; // ボタン押し待ちフラグ 
int Count; // フレームカウンタ 

char String[60][256] =
{
	"中国がひそかに発明していたウィルスが実験の失敗により外の世界にもれた B",
	"各国がボランティアで来ていた人々が中国で感染し、飛行機、船で発症。B",
	"世界中に広がる B",
	"C・・・そんな事を知らずに僕は今日も学校にいく@人類はこの日から壊れていくB ",

	"@エピソード01話 @はじまりB",

	"Cに住む主人公は今日も学校に行く。Bしかし学校に行く途中で自身を疑う光景をみる。B",
		"C  主人公「やっぱ学校が一番だな 変わらない」B",
	"  そして昼休み、友人の勇(ゆう)が来た。B",
		"@「いつもの場所に行こうぜ」B",
	"@主人公「わかった あそこだな」B",
		"主人公「さて、俺もいきますか」B",
		"。E",
};



void Kaigyou(void); // テキストバッファの改行処理関数 


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPSTR lpCmdLine, int nCmdShow)
{
	char OneMojiBuf[3]; // 1文字分一時記憶配列 
	int i, j;

	SetGraphMode(640, 480, 16);
	if (DxLib_Init() == -1) // DXライブラリ初期化処理 
	{
		return -1; // エラーが起きたら直ちに終了 
	}



	// 描画位置の初期位置セット 
	CursorX = 0;
	CursorY = 0;

	// 参照文字位置をセット 
	SP = 0; // 1行目の 
	CP = 0; // 0文字 

	// フォントのサイズセット 
	SetFontSize(MOJI_SIZE);

	// 描画先を裏画面にセット 
	SetDrawScreen(DX_SCREEN_BACK);

	// フレームカウンタ初期化 
	Count = 0;




	// ループ 
	while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
	{
		// サウンドノベル風文字列描画処理を行う 
		// ただし終了フラグが1だった場合は処理をしない 
		if (EndFlag == 0)
		{
			char Moji;

			// ボタン押し待ちフラグがたっていた場合はボタンが押されるまでここで終了 
			if (KeyWaitFlag == 1)
			{
				if (ProcessMessage() == 0 && CheckHitKeyAll() != 0)
				{
					// ボタンが押されていたら解除 
					KeyWaitFlag = 0;
				}
			}
			else
			{
				// 文字の描画 
				Moji = String[SP][CP];
				switch (Moji)
				{
				case '@': // 改行文字 

					// 改行処理および参照文字位置を一つ進める 
					Kaigyou();
					CP++;

					break;

				case 'B': // ボタン押し待ち文字 

					// ボタンが離されるまで待つ 
					LoadGraphScreen(0, 10, "画像/メッセージボックス 1.png", FALSE); // 画像を描画する
					while (ProcessMessage() == 0 && CheckHitKeyAll() != 0){}

					// ボタン押し待ちフラグをたてる 
					KeyWaitFlag = 1;
					CP++;



					break;

				case 'E': // 終了文字 

					// 終了フラグを立てるおよび参照文字位置を一つ進める 
					EndFlag = 1;
					CP++;

					break;

				case 'C': // クリア文字 

					// 仮想テキストバッファを初期化して描画文字位置を初期位置に戻すおよび参照文字位置を一つ進める 
					for (i = 0; i < STRBUF_HEIGHT; i++)
					{
						for (j = 0; j < STRBUF_WIDTH * 2; j++)
						{
							StringBuf[i][j] = 0;
						}
					}

					CursorY = 0;
					CursorX = 0;
					CP++;

					break;


				case 'D':

					LoadGraphScreen(50, 100, "画像/背景007.png", TRUE); // 画像を描画する
					break;

					while (ProcessMessage() == 0 && CheckHitKeyAll() != 0){}

					// ボタン押し待ちフラグをたてる 
					KeyWaitFlag = 1;
					CP++;
					break;



				default: // その他の文字 

					// 1文字分抜き出す 
					OneMojiBuf[0] = String[SP][CP];
					OneMojiBuf[1] = String[SP][CP + 1];
					OneMojiBuf[2] = '\0';

					// 1文字テキストバッファに代入 
					StringBuf[CursorY][CursorX * 2] = OneMojiBuf[0];
					StringBuf[CursorY][CursorX * 2 + 1] = OneMojiBuf[1];

					// 参照文字位置を2バイト勧める 
					CP += 2;

					// カーソルを一文字文進める 
					CursorX++;

					// テキストバッファ横幅からはみ出たら改行する 
					if (CursorX >= STRBUF_WIDTH) Kaigyou();

					break;
				}

				// 参照文字列の終端まで行っていたら参照文字列を進める 
				if (String[SP][CP] == '\0')
				{
					SP++;
					CP = 0;
				}
			}
		}



		// 画面のクリア 
		ClsDrawScreen();

		// 背景エフェクトの描画 
		{
			LoadGraphScreen(0, 0, "画像/メッセージボックス 1.png", FALSE); // 画像を描画する

		}


		//音楽




		// テキストバッファの描画 
		for (i = 0; i < STRBUF_HEIGHT; i++)
		{
			DrawString(8, i * MOJI_SIZE, StringBuf[i], GetColor(255, 255, 255));
		}

		// 裏画面の内容を表画面に反映させる 
		ScreenFlip();
	}

	DxLib_End(); // DXライブラリ使用の終了処理 

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



// 改行関数 
void Kaigyou(void)
{
	// 描画行位置を一つ下げる 
	CursorY++;

	// 描画列を最初に戻す 
	CursorX = 0;

	// もしテキストバッファ縦幅からはみ出るならテキストバッファを縦スクロールさせる 
	if (CursorY >= STRBUF_HEIGHT)
	{
		int i, j;

		for (i = 1; i < STRBUF_HEIGHT; i++)
		{
			for (j = 0; j < STRBUF_WIDTH * 2; j++)
			{
				StringBuf[i - 1][j] = StringBuf[i][j];
			}
		}

		// 描画行位置を一つあげる 
		CursorY--;
	}
}

Re: DXライブラリ サンプルプログラム  20.サウンドノベル風文字列描画、テキストバッファ使用バージョン について

Posted: 2015年12月12日(土) 16:01
by みけCAT
画像を裏画面に描画した後、ScreenFlip()を呼ばずに待ちに入ってしまっているのが原因ですね。
なお、ProcessMessage()をメインループの1箇所以外で用いることや、LoadGraphScreen関数を用いることは推奨されません

Re: DXライブラリ サンプルプログラム  20.サウンドノベル風文字列描画、テキストバッファ使用バージョン について

Posted: 2015年12月24日(木) 11:08
by THムラオサ
ご解答ありがとうございます。
ご指摘を受けた点について
LoadGraphScreen関数はDrawGraphに変更しました。
ProcessMessage()はif文に複数使用していたのでwhileのとこだけにしました。
ですが画像の読み込みができませんでした。
「画像を裏画面に描画した後、ScreenFlip()を呼ばずに待ちに入ってしまっているのが原因」というのは

コード:

DrawGraph(0, 100, handol, TRUE); //画像の描画
//ScreenFlip();

という風に考えたのですが、そしたら3大処理を複数使用してしまうということで違うのではと思いよくわかりませんでした。

下記のは私が書いたコードとなりますもう一度見て頂きたいのでよろしくお願いします

コード:

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

// 文字のサイズ 
#define MOJI_SIZE 24 

// 仮想テキストバッファの横サイズ縦サイズ 
#define STRBUF_WIDTH 24 
#define STRBUF_HEIGHT 20 



char StringBuf[STRBUF_HEIGHT][STRBUF_WIDTH * 2 + 1]; // 仮想テキストバッファ 
int CursorX, CursorY; // 仮想画面上での文字表示カーソルの位置 
int SP, CP; // 参照する文字列番号と文字列中の文字ポインタ 
int EndFlag; // 終了フラグ 
int KeyWaitFlag; // ボタン押し待ちフラグ 
int Count; // フレームカウンタ 




char String[60][256] =
{
	"中国がひそかに発明していたウィルスが実験の失敗により外の世界にもれた B",
	"各国がボランティアで来ていた人々が中国で感染し、飛行機、船で発症。B",
	"世界中に広がる B",
	"C・・・そんな事を知らずに僕は今日も学校にいく@人類はこの日から壊れていくB ",
	"@エピソード01話 @はじまりB",
	"C茨城 つくば周辺に住む主人公は今日も学校に行く。Bしかし学校に行く途中で自身を疑う光景をみる。B",
	"そうB地面が血だらけである。B気味が悪いと思い主人公は学校に急ぐB",
	"C  主人公「やっぱ学校が一番だな 変わらない」B",
	"そして昼休み、友人の勇(ゆう)とジョン・D・ちんぱんが来た。B",
	"ジョンはちんぱん系日本人だ。@変わった名前だがいいやつだ。B",
	"ジョン「いつもの場所に行こうぜ」B",
	"主人公「わかった あそこだな」B",
	"ジョン「じゃあ勇と俺はさきにいってるぜ」B",
	"と言ってジョンちんぱんと勇は先に行った。B",
	"主人公「さて、俺もいきますか」B",
	"読んでいて少しでも何か出来るような気がしたらそこでとにかくプログラム",
	"を打ってみることが大事である。E",
};



void Kaigyou(void); // テキストバッファの改行処理関数 


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
	LPSTR lpCmdLine, int nCmdShow)
{


	ChangeWindowMode(TRUE);//ウィンドを小さく表示する




	char OneMojiBuf[3]; // 1文字分一時記憶配列 
	int i, j, handol;
	handol = LoadGraphScreen(0, 0, "画像/キャラクタ00.png", TRUE); // 画像を描画する


	SetGraphMode(640, 480, 16);
	if (DxLib_Init() == -1) // DXライブラリ初期化処理 
	{
		return -1; // エラーが起きたら直ちに終了 
	}



	// 描画位置の初期位置セット 
	CursorX = 0;
	CursorY = 0;

	// 参照文字位置をセット 
	SP = 0; // 1行目の 
	CP = 0; // 0文字 

	// フォントのサイズセット 
	SetFontSize(MOJI_SIZE);

	// 描画先を裏画面にセット 
	SetDrawScreen(DX_SCREEN_BACK);

	// フレームカウンタ初期化 
	Count = 0;




	// ループ 
	while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
	{
		// サウンドノベル風文字列描画処理を行う 
		// ただし終了フラグが1だった場合は処理をしない 
		if (EndFlag == 0)
		{
			char Moji;

			// ボタン押し待ちフラグがたっていた場合はボタンが押されるまでここで終了 
			if (KeyWaitFlag == 1)
			{
				if (CheckHitKeyAll() != 0)
				{
					// ボタンが押されていたら解除 
					KeyWaitFlag = 0;
				}
			}
			else
			{
				// 文字の描画 
				Moji = String[SP][CP];
				switch (Moji)
				{
				case '@': // 改行文字 

					// 改行処理および参照文字位置を一つ進める 
					Kaigyou();
					CP++;

					break;

				case 'B': // ボタン押し待ち文字 

					DrawGraph(0, 100, handol, TRUE); //画像の描画
					//ScreenFlip();

					// ボタンが離されるまで待つ 
					while (CheckHitKeyAll() != 0){}

					// ボタン押し待ちフラグをたてる 
					KeyWaitFlag = 1;
					CP++;

					break;

				case 'E': // 終了文字 

					// 終了フラグを立てるおよび参照文字位置を一つ進める 
					EndFlag = 1;
					CP++;

					break;

				case 'C': // クリア文字 

					// 仮想テキストバッファを初期化して描画文字位置を初期位置に戻すおよび参照文字位置を一つ進める 
					for (i = 0; i < STRBUF_HEIGHT; i++)
					{
						for (j = 0; j < STRBUF_WIDTH * 2; j++)
						{
							StringBuf[i][j] = 0;
						}
					}

					CursorY = 0;
					CursorX = 0;
					CP++;

					break;


				case 'D':

					LoadGraphScreen(50, 100, "画像/キャラクタ00.png", TRUE); // 画像を描画する
					break;

					while (CheckHitKeyAll() != 0){}

					// ボタン押し待ちフラグをたてる 
					KeyWaitFlag = 1;
					CP++;
					break;


				default: // その他の文字 

					// 1文字分抜き出す 
					OneMojiBuf[0] = String[SP][CP];
					OneMojiBuf[1] = String[SP][CP + 1];
					OneMojiBuf[2] = '\0';

					// 1文字テキストバッファに代入 
					StringBuf[CursorY][CursorX * 2] = OneMojiBuf[0];
					StringBuf[CursorY][CursorX * 2 + 1] = OneMojiBuf[1];

					// 参照文字位置を2バイト勧める 
					CP += 2;

					// カーソルを一文字文進める 
					CursorX++;

					// テキストバッファ横幅からはみ出たら改行する 
					if (CursorX >= STRBUF_WIDTH) Kaigyou();

					break;
				}

				// 参照文字列の終端まで行っていたら参照文字列を進める 
				if (String[SP][CP] == '\0')
				{
					SP++;
					CP = 0;
				}
			}
		}



		// 画面のクリア 
		ClearDrawScreen();

		// 背景エフェクトの描画 
		{


			DrawGraph(0, 100, handol, TRUE); //画像の描画

			






		}

		// テキストバッファの描画 
		for (i = 0; i < STRBUF_HEIGHT; i++)
		{
			DrawString(8, i * MOJI_SIZE, StringBuf[i], GetColor(255, 255, 255));
		
		}

		// 裏画面の内容を表画面に反映させる 
		ScreenFlip();
	}
	DxLib_End(); // DXライブラリ使用の終了処理 

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



// 改行関数 
void Kaigyou(void)
{
	// 描画行位置を一つ下げる 
	CursorY++;

	// 描画列を最初に戻す 
	CursorX = 0;

	// もしテキストバッファ縦幅からはみ出るならテキストバッファを縦スクロールさせる 
	if (CursorY >= STRBUF_HEIGHT)
	{
		int i, j;

		for (i = 1; i < STRBUF_HEIGHT; i++)
		{
			for (j = 0; j < STRBUF_WIDTH * 2; j++)
			{
				StringBuf[i - 1][j] = StringBuf[i][j];
			}
		}

		// 描画行位置を一つあげる 
		CursorY--;
	}
}