クイズゲームでサウンドノベル風文字列描画

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
トビオ

クイズゲームでサウンドノベル風文字列描画

#1

投稿記事 by トビオ » 14年前

はじめまして。よろしくおねがいします。C言語初心者です。
今DXライブラリでクイズゲームを作成しようと思っており、
問題を表示する部分をノベルゲーム風に、一文字づつ表示させたいと思っており、
試しにDXライブラリのサンプルプログラムのサウンドノベル風文字列描画を使用し、
switch文でランダムに値を入れて、その番号によってクイズの問題と、
クイズの正解番号を代入する、という形にしたいと思っているのですが、
switch文を使って問題文章を変更するところがうまくいかず、困っております。
とりあえず今はswitch文の値を変更することによって、
問題文章に違うものが表示されれば大丈夫です。
よろしくお願いします。
以下プログラムです。

コード:


// サウンドノベル風文字列描画基本
#include "DxLib.h"

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

int DrawPointX , DrawPointY ;	// 文字列描画の位置
int SP , CP ;	// 参照する文字列番号と文字列中の文字ポインタ

int mondaibangou = 1;//switch文の変更部分
int seikaibangou;



char String[][ 256 ] =
{
	"問題文章 選択肢1 選択肢2 選択肢3 選択肢4 BE"
} ;

// 改行関数
int Kaigyou( void )
{
	int TempGraph ;

	// 描画行位置を一つ下げる
	DrawPointY ++ ;

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

	// もし画面からはみ出るなら画面をスクロールさせる
	if( DrawPointY * MOJI_SIZE + MOJI_SIZE > 480 )
	{
		// テンポラリグラフィックの作成
		TempGraph = MakeGraph( 640 , 480 ) ;

		// 画面の内容を丸々コピーする
		GetDrawScreenGraph( 0 , 0 , 640 , 480 , TempGraph ) ;

		// 一行分上に貼り付ける
		DrawGraph( 0 , -MOJI_SIZE ,TempGraph , FALSE ) ;
		
		// 一番下の行の部分を黒で埋める
		DrawBox( 0 , 480 - MOJI_SIZE , 640 , 480 , 0 , TRUE ) ;

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

		// グラフィックを削除する
		DeleteGraph( TempGraph ) ;
	}

	// 終了
	return 0 ;
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
						 LPSTR lpCmdLine, int nCmdShow )
{
	int EndFlag ;	// 終了フラグ
	char OneMojiBuf[ 3 ] ;	// 1文字分一時記憶配列

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

	// 描画位置の初期位置セット
	DrawPointX = 0 ;
	DrawPointY = 0 ;

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

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

	// 終了フラグを倒す
	EndFlag = 0 ;

	// ループ
	while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
	{
		switch(mondaibangou){//switch文
		case 1:{
			char String[][ 256 ] =
			{
				"問題文章1 選択肢1 選択肢2 選択肢3 選択肢4 BE"
			} ;
			seikaibangou=1;
			break;
			}
		case 2:
			{
			char String[][ 256 ] =
			{
				"問題文章2 選択肢1 選択肢2 選択肢3 選択肢4 BE"
			} ;
			seikaibangou=2;
			break;
			}
		case 3:
			{
			char String[][ 256 ] =
			{
				"問題文章3 選択肢1 選択肢2 選択肢3 選択肢4 BE"
			} ;
			seikaibangou=3;
			break;
			}
		}
		char  Moji ;

		// 文字の描画
		Moji = String[ SP ][ CP ] ;
		switch( Moji )
		{
		case '@' :	// 改行文字

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

			break ;

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

			// ボタン押し待ちおよび参照文字位置を一つ進める
			WaitKey() ;
			CP ++ ;

			break ;

		case 'E' :	// 終了文字

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

			break ;

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

			// 画面を初期化して描画文字位置を初期位置に戻すおよび参照文字位置を一つ進める
			ClearDrawScreen() ;
			DrawPointY = 0 ;
			DrawPointX = 0 ;
			CP ++ ;

			break ;

		default :	// その他の文字

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

			// 1文字描画
			DrawString( DrawPointX * MOJI_SIZE , DrawPointY * MOJI_SIZE ,
				OneMojiBuf , GetColor( 255 , 255 , 255 ) ) ;

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

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

			// 少し待つ
			WaitTimer( 10 ) ;

			// 画面からはみ出たら改行する
			if( DrawPointX * MOJI_SIZE + MOJI_SIZE > 640 ) Kaigyou() ;

			break ;
		}

		// 終了フラグが1だったら終了する
		if( EndFlag == 1 ) break ;

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

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

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


non
記事: 1097
登録日時: 15年前

Re: クイズゲームでサウンドノベル風文字列描画

#2

投稿記事 by non » 14年前

コード:

char String[][ 256 ] =
{
    "問題文章 選択肢1 選択肢2 選択肢3 選択肢4 BE"
} ;
これは,なぜ,2次元配列なのでしょうか?また,グローバルとローカルの関係は?
non

アバター
ookami
記事: 214
登録日時: 15年前
住所: 東京都

Re: クイズゲームでサウンドノベル風文字列描画

#3

投稿記事 by ookami » 14年前

コード:

switch(mondaibangou){//switch文
    case 1:{
        char String[][ 256 ] =
        {
            "問題文章1 選択肢1 選択肢2 選択肢3 選択肢4 BE"
        } ;
        seikaibangou=1;
        break;
    }
    :
    :
}
となっていますが、この場合、「String」変数のスコープは、switch文の中だけになり、
switch文が終わった時点で破棄されます。

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

Re: クイズゲームでサウンドノベル風文字列描画

#4

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

そうですね。
まず変数の寿命と変数のスコープを理解されたほうが良いと思います。

「C言語編 第22章 変数のスコープ」
http://www.geocities.jp/ky_webid/c/022.html
「変数の寿命」
http://www.curiocube.com/mikata/progtip ... lscope.php
「値渡しと参照渡し・スコープ・寿命 - 自分用メモとか」
http://www.tom.sfc.keio.ac.jp/~fjedi/wi ... C%F7%CC%BF

これらを理解されると分かると思うのですが、

コード:

char String[][ 256 ] =
{
    "問題文章 選択肢1 選択肢2 選択肢3 選択肢4 BE"
} ;

コード:

            char String[][ 256 ] =
            {
                "問題文章1 選択肢1 選択肢2 選択肢3 選択肢4 BE"
            } ;
は全く関係の無い宣言と言うことが分かるはずです。

あと、
SetGraphMode( 640 , 480 , 16 ) ;
は起動が遅くなるんで止めた方が良いと思います。
それとデバッグを簡単にするために
ChangeWindowMode(TRUE);
もいれたほうが良いと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

トビオ

Re: クイズゲームでサウンドノベル風文字列描画

#5

投稿記事 by トビオ » 14年前

返答ありがとうございました。
charをつけてswitch文の中で定義したのでまったく別の関数になっていたのですね・・
最初は、switch文を使ってstring変数に文字を代入しようと思い、

コード:

char String[][ 256 ]={"問題文章 選択肢1 選択肢2 選択肢3 選択肢4 BE"};
int mondaibangou = 1;//switch文の変更部分

		switch(mondaibangou){//switch文
		case 1:
			string[][ 256 ] =
			{
				"問題文章1 選択肢1 選択肢2 選択肢3 選択肢4 BE"
			} ;
			seikaibangou=1;
			break;
		}
としたのですが、string[][256] ={の部分に"式が必要です"と、エラーが表示されてしまうので、
string[][256] = にcharをつけたらエラーがでなかったので、そのままにしていました。
おかげで"再定義されています"とエラーが表示されなかった理由がわかりました。

元々のサンプルが、ノベルゲーム風に1文字づつ表示するために、
string変数は2次元配列になっているのだと思いますが、
このstring変数に文章を代入するにはどうすればよいでしょうか?

non
記事: 1097
登録日時: 15年前

Re: クイズゲームでサウンドノベル風文字列描画

#6

投稿記事 by non » 14年前

トビオ さんが書きました:元々のサンプルが、ノベルゲーム風に1文字づつ表示するために、
string変数は2次元配列になっているのだと思いますが、
このstring変数に文章を代入するにはどうすればよいでしょうか?
文章がたくさんあるから2次元配列なんじゃないの?

コード:

char String[][ 256 ] =
{
       "問題文章1 選択肢1 選択肢2 選択肢3 選択肢4 BE"
	 , "問題文章2 選択肢1 選択肢2 選択肢3 選択肢4 BE"
	 , "問題文章3 選択肢1 選択肢2 選択肢3 選択肢4 BE"
} ;
こんなふうに
non

閉鎖

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