「プログラム」の編集履歴(バックアップ)一覧に戻る

プログラム - (2008/02/23 (土) 10:24:54) の編集履歴(バックアップ)


DXライブラリ使って、ヘボイプログラムが組める人が一人。

一部、http://homepage2.nifty.com/natupaji/DxLib/のサイトより引用しました。

配布した時のプログラムとは違いますが、動作は同じです。

説明

これのif(Body==1){}がギャルゲーの骨格となります。
主な動作はテキスト、絵の描画です。
そして以下はその中でも最も重要な部分です。
char String[256][256][ 256 ] =
{
{
	{"Cお兄ちゃん。Kお兄ちゃん。Kお兄ちゃんってば。K"},
	{"N起きて。もう朝だよ。K"},
	{"S1"},
},
{
	{"Cきゃあ。@2K@3もういきなり飛び上がらないでよ。お兄ちゃん。K"},
	{"S2"},
},
} ;

と言うような記述が上の方にありますが、ここがテキストになります。
この部分を変えれば、表示される、テキスト、絵が変わります。
CやKといった半角英数字の文字はコマンドです。

C_テキスト表示領域のテキストを消します。
K_キー入力待ちをします。
N_改行します。
S_直後の数字に対応した、選択肢を表示します。
@_直後の数字に対応した、キャラクターを表示したり、アクションをおこしたりします。

今回の場合、
S1_1回目の選択肢
S2_2回目の選択肢
@2_imouto.bmpのフェードイン
@3_imouto.bmpのスクロール

脚本段階で増やして欲しい選択肢、アクションがでてきた場合、追加して作成していくことになります。
@4_キャラクターを左の方に表示。

以上がプログラムの骨格にあたる部分です。

プログラム

"DxLib.h"
<math.h>

#define
FONT_SIZE 20

#define
STRBUF_WIDTH 20
#define
STRBUF_HEIGHT 20

char StringBuf[ STRBUF_HEIGHT ][ STRBUF_WIDTH * 2 + 1 ] ; // 仮想テキストバッファ
int CursorX , CursorY ; // 仮想画面上での文字表示カーソルの位置
int RP,SP , CP ; // 参照する文字列番号と文字列中の文字ポインタ
int EndFlag ; // 終了フラグ
int KeyWaitFlag ; // ボタン押し待ちフラグ
int Count ; // フレームカウンタ
int MouseX,MouseY;
int mousex,mousey;
int InputHandle,InputHandle2;
int Title,Your,Body,Fin;
int SelectFlag,ActionFlag;
int Select,Action;
int i , j ,n;

char start[]="はじめる";
char end[]="おわる";
char name1[256],name2[256];
char OneMojiBuf[ 3 ] ; // 1文字分一時記憶配列
char String[256][256][ 256 ] =
{
{
	{"Cお兄ちゃん。Kお兄ちゃん。Kお兄ちゃんってば。K"},
	{"N起きて。もう朝だよ。K"},
	{"S1"},
},
{
	{"Cきゃあ。@2K@3もういきなり飛び上がらないでよ。お兄ちゃん。K"},
	{"S2"},
},
} ;

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

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
					 LPSTR lpCmdLine, int nCmdShow )
{
//初期化
ChangeWindowMode(TRUE);
SetGraphMode( 640 , 480 , 16 ) ;
if( DxLib_Init() == -1 )	// DXライブラリ初期化処理
{
	 return -1;				// エラーが起きたら直ちに終了
}

int white,black,pink,red,blue,green,white2,orange;
int input,push,ok,cancel,ok2,cancel2,menu,sonomamaneteru,sugutobiokiru,imouto,imouto2,end2,back_title,g_title,g_title2,S1,S2,S3,S4,select2;
int sound1,music1;

//Color
white=GetColor(255,255,255);
white2=GetColor(254,254,254);
pink=GetColor(255,236,247);
red=GetColor(255,142,140);
blue=GetColor(0,0,255);
green=GetColor(0,255,0);
orange=GetColor(243,161,47);
black=GetColor(0,0,0);
//Font
SetFontSize(FONT_SIZE);
SetKeyInputStringColor(red,black,pink,black,black,black,green,blue,green,blue,red,white2);
//Screen
SetDrawScreen(DX_SCREEN_BACK);
//LodeGraph
input=LoadGraph("../input.bmp");
S1=LoadGraph("../sonomamaneteru.bmp");
S2=LoadGraph("../sugutobiokiru.bmp");
S3=LoadGraph("../back_title.bmp");
S4=LoadGraph("../endgame.bmp");
g_title=LoadGraph("../nhkni2.bmp");
g_title2=LoadGraph("../title2.bmp");
imouto=LoadGraph("../imouto2.bmp");
ok=LoadGraph("../ok.bmp");
ok2=LoadGraph("../ok2.bmp");
cancel=LoadGraph("../cancel.bmp");
cancel2=LoadGraph("../cancel2.bmp");
menu=LoadGraph("../write2.bmp");
push=LoadGraph("../push.bmp");
select2=LoadGraph("../select.bmp");
//LodeSound
sound1=LoadSoundMem("../nhkniyoukoso.wav");
music1=LoadSoundMem("../youkoso3.wav");

while(1)
{
// 描画位置の初期位置セット
CursorX = 0 ;
CursorY = 0 ;

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

// フォントのサイズセット
SetFontSize( FONT_SIZE ) ;
ChangeFontType( DX_FONTTYPE_ANTIALIASING_EDGE ) ;

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

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

if(Title==1)
{
		SetFontSize(FONT_SIZE+15);
		ChangeFontType( DX_FONTTYPE_NORMAL ) ;
					for(i=0;i<255;i=i+10)
					{				
						ClearDrawScreen();
						SetDrawBright(i,i,i);
						DrawGraph(0,0,g_title,TRUE);
						ScreenFlip();
					}
					PlaySoundMem(sound1,DX_PLAYTYPE_NORMAL);
					for(i=255;i>0;i=i-10)
					{				
						ClearDrawScreen();
						SetDrawBright(i,i,i);
						DrawGraph(0,0,g_title,TRUE);
						ScreenFlip();
					}
					for(i=0;i<255;i=i+10)
					{				
						ClearDrawScreen();
						SetDrawBright(i,i,i);
						DrawBox(0,0,640,480,white,TRUE);
						DrawGraph(35,20,g_title2,TRUE);
						DrawString(50,290,start,orange);
						DrawString(50,370,end,orange);
						ScreenFlip();
					}
					PlaySoundMem(music1,DX_PLAYTYPE_LOOP);
		while(1){
			GetMousePoint(&mousex,&mousey);
			//Draw
			ClearDrawScreen();
			DrawBox(0,0,640,480,white,TRUE);
			DrawGraph(35,20,g_title2,TRUE);
			DrawString(50,290,start,orange);
			DrawString(50,370,end,orange);
			//Menu
			if(mousex>50&&mousex<190&&mousey>290&&mousey<325)
			{
				DrawBox(20,305,30,315,orange,TRUE);
				if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 )
				{
					//title=0;
					Your=1;
					for(i=255;i>0;i=i-10)
					{				
						ClearDrawScreen();
						SetDrawBright(i,i,i);
						DrawBox(0,0,640,480,white,TRUE);
						DrawGraph(35,20,g_title2,TRUE);
						DrawString(50,290,start,orange);
						DrawString(50,370,end,orange);
						ScreenFlip();
					}
					StopSoundMem(music1);
					break;
				}
			}else if(mousex>50&&mousex<175&&mousey>370&&mousey<405)
			{
				DrawBox(20,383,30,393,orange,TRUE);
				if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 )
				{
						DxLib_End();
						return 0;
				}
			}
			ScreenFlip();
		}

}
if(Your==1)
{
		SetFontSize(FONT_SIZE-5);
			//Fadein
			for(i=0;i<255;i=i+10)
			{
				ClearDrawScreen();
				SetDrawBright(i,i,i);
				DrawBox(0,0,640,480,pink,TRUE);
				DrawString(160,130,"あなたの名前を決めてください。",red);
				DrawGraph(160,160,input,TRUE);
				DrawString(160,230,"ニックネーム",red);
				DrawGraph(160,260,input,TRUE);
				DrawGraph(300,360,cancel,TRUE);
				DrawGraph(400,360,ok,TRUE);
				ScreenFlip();
			}
			ClearDrawScreen();

// キー入力ハンドルを作る(キャンセルなし全角文字有り数値入力じゃなし)
InputHandle = MakeKeyInput( 50 , FALSE , FALSE , FALSE ) ;

// 作成したキー入力ハンドルをアクティブにする
SetActiveKeyInput( InputHandle ) ;

// キー入力終了待ちループ
// (ProcessMessageをループごとに行う)
while( !ProcessMessage() )
{
	// 入力が終了している場合は終了
	if( CheckKeyInput( InputHandle ) != 0 ) break ;

	// 画面の初期化
	ClearDrawScreen() ;

	// 入力モードを描画
	DrawKeyInputModeString( 640 , 480 ) ; 

	// 入力途中の文字列を描画

			DrawBox(0,0,640,480,pink,TRUE);
			DrawString(160,130,"あなたの名前を決めてください。",red);
			DrawGraph(160,160,input,TRUE);
			DrawString(160,230,"ニックネーム",red);
			DrawGraph(160,260,input,TRUE);
			DrawGraph(300,360,cancel,TRUE);
			DrawGraph(400,360,ok,TRUE);
			DrawKeyInputString(170,165,InputHandle);

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

// 入力された文字列を取得
GetKeyInputString( name1, InputHandle ) ;

// 用済みのインプットハンドルを削除する
DeleteKeyInput( InputHandle ) ;

// キー入力ハンドルを作る(キャンセルなし全角文字有り数値入力じゃなし)
InputHandle2 = MakeKeyInput( 50 , FALSE , FALSE , FALSE ) ;

// 作成したキー入力ハンドルをアクティブにする
SetActiveKeyInput( InputHandle2 ) ;

// キー入力終了待ちループ
// (ProcessMessageをループごとに行う)
while( !ProcessMessage() )
{
	// 入力が終了している場合は終了
	if( CheckKeyInput( InputHandle2 ) != 0 ) break ;

	// 画面の初期化
	ClearDrawScreen() ;

	// 入力モードを描画
	DrawKeyInputModeString( 640 , 480 ) ; 

	// 入力途中の文字列を描画

			DrawBox(0,0,640,480,pink,TRUE);
			DrawString(160,130,"あなたの名前を決めてください。",red);
			DrawGraph(160,160,input,TRUE);
			DrawString(170,165,name1,red);
			DrawString(160,230,"ニックネーム",red);
			DrawGraph(160,260,input,TRUE);
			DrawGraph(300,360,cancel,TRUE);
			DrawGraph(400,360,ok,TRUE);
			DrawKeyInputString(170,265,InputHandle2);

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

// 入力された文字列を取得
GetKeyInputString( name2, InputHandle2 ) ;

// 用済みのインプットハンドルを削除する
DeleteKeyInput( InputHandle2 ) ;

		while(1){
			ClearDrawScreen();
			GetMousePoint(&mousex,&mousey);
			//Draw
			DrawBox(0,0,640,480,pink,TRUE);
			DrawString(160,130,"あなたの名前を決めてください。",red);
			DrawGraph(160,160,input,TRUE);
			DrawString(170,165,name1,red);
			DrawString(160,230,"ニックネーム",red);
			DrawGraph(160,260,input,TRUE);
			DrawString(170,265,name2,red);
			DrawGraph(300,360,cancel,TRUE);
			DrawGraph(400,360,ok,TRUE);
			
			//Menu
			if(mousex>300&&mousex<389&&mousey>360&&mousey<380)
			{
				DrawGraph(300,360,cancel2,TRUE);
				if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 )
				{
					for(i=255;i>0;i=i-10)
					{				
						ClearDrawScreen();
						SetDrawBright(i,i,i);
			DrawBox(0,0,640,480,pink,TRUE);
			DrawString(160,130,"あなたの名前を決めてください。",red);
			DrawGraph(160,160,input,TRUE);
			DrawString(170,165,name1,red);
			DrawString(160,230,"ニックネーム",red);
			DrawGraph(160,260,input,TRUE);
			DrawString(170,265,name2,red);
			DrawGraph(300,360,cancel,TRUE);
			DrawGraph(400,360,ok,TRUE);
						ScreenFlip();
					}
					break;
				}
			}else if(mousex>400&&mousex<480&&mousey>360&&mousey<380)
			{
				DrawGraph(400,360,ok2,TRUE);
				if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0 )
				{
					//you=0;
					Body=1;
					for(i=255;i>0;i=i-10)
					{				
						ClearDrawScreen();
						SetDrawBright(i,i,i);
			DrawBox(0,0,640,480,pink,TRUE);
			DrawString(160,130,"あなたの名前を決めてください。",red);
			DrawGraph(160,160,input,TRUE);
			DrawString(170,165,name1,red);
			DrawString(160,230,"ニックネーム",red);
			DrawGraph(160,260,input,TRUE);
			DrawString(170,265,name2,red);
			DrawGraph(300,360,cancel,TRUE);
			DrawGraph(400,360,ok,TRUE);
						ScreenFlip();
					}
					break;
				}
			}
			ScreenFlip();
		}

}
if(Body==1)
{
// フォントのサイズセット
SetFontSize( FONT_SIZE ) ;
ChangeFontType( DX_FONTTYPE_ANTIALIASING_EDGE ) ;

						for(i=0;i<255;i=i+10)
							{
								ClearDrawScreen();
								SetDrawBright(i,i,i);
								DrawBox(0,0,640,480,black,TRUE);
								SetDrawBlendMode(DX_BLENDMODE_ALPHA,150);
								DrawGraph(20,360,menu,TRUE);
								SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
								ScreenFlip();
							}
// ループ
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[ RP ][ SP ][ CP ] ;
			switch( Moji )
			{
			case 'N' :	// 改行文字

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

				break ;

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

				// ボタンが離されるまで待つ
				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 'S' :

				SelectFlag=1;
				CP++;

				break;

			case '@' :

				ActionFlag=1;
				CP++;

				break;

			case '1' :

				if(SelectFlag==1)
				{
					Select=1;
					SelectFlag=0;
					EndFlag=1;
				}
				if(ActionFlag==1)
				{
					Action=1;
					ActionFlag=0;
				}
				CP++;

				break;

			case '2' :

				if(SelectFlag==1)
				{
					Select=2;
					SelectFlag=0;
					EndFlag=1;
				}
				if(ActionFlag==1)
				{
					Action=2;
					ActionFlag=0;
				}
				CP++;

				break;

			case '3' :

				if(SelectFlag==1)
				{
					Select=2;
					SelectFlag=0;
					EndFlag=1;
				}
				if(ActionFlag==1)
				{
					Action=3;
					ActionFlag=0;
				}
				CP++;

				break;

			default :	// その他の文字

				// 1文字分抜き出す
				OneMojiBuf[ 0 ] = String[ RP ][ SP ][ CP ] ;
				OneMojiBuf[ 1 ] = String[ RP ][ 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[RP][ SP ][ CP ] == '\0' )
			{
				SP ++ ;
				CP = 0 ;
			}
		}
	}

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

	// 背景エフェクトの描画
	{
		DrawBox(0,0,640,480,black,TRUE);
	if(Action==1)
	{
		DrawGraph(0,0-n,imouto,TRUE);
	}
	if(Action==2)
	{
				for(n=0;n<255;n=n+3)
				{
					ClearDrawScreen();
					DrawBox(0,0,640,480,black,TRUE);
					SetDrawBlendMode(DX_BLENDMODE_ALPHA,n);
					DrawGraph(0,0,imouto,TRUE);
					SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
					SetDrawBlendMode(DX_BLENDMODE_ALPHA,150);
					DrawGraph(20,360,menu,TRUE);
					SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
					for( i = 0 ; i < STRBUF_HEIGHT ; i ++ )
					{
						DrawString( 150 , 367+i * (FONT_SIZE+3) , StringBuf[ i ] ,white,red) ;
					}
					ScreenFlip();
				}
				n=0;
				Action=1;
	}
	if(Action==3)
	{
			if(n!=144)
				{
					n=n+2;
				}else
				{
					Action=1;
				}
				DrawGraph(0,0-n,imouto,TRUE);
	}


		if(Select==1)
		{
					GetMousePoint(&MouseX,&MouseY);
					if(MouseX>160&&MouseX<480&&MouseY>120&&MouseY<146){
						DrawGraph(160,120,S1,TRUE);
						SetDrawBlendMode(DX_BLENDMODE_ALPHA,150);
						DrawGraph(160,200,S2,TRUE);
						SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
						if(( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0){
							break;
						}
					}else if(MouseX>160&&MouseX<480&&MouseY>200&&MouseY<225){
						DrawGraph(160,200,S2,TRUE);
						SetDrawBlendMode(DX_BLENDMODE_ALPHA,150);
						DrawGraph(160,120,S1,TRUE);
						SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
						if(( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0){
							Select=0;
							RP=1;
							SP=0;
							CP=0;
							EndFlag=0;
						}
					}else{
						SetDrawBlendMode(DX_BLENDMODE_ALPHA,150);
						DrawGraph(160,120,S1,TRUE);
						DrawGraph(160,200,S2,TRUE);
						SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
					}
		}
	}
	if(Select==2)
	{
					GetMousePoint(&MouseX,&MouseY);
					if(MouseX>160&&MouseX<480&&MouseY>120&&MouseY<146){
						DrawGraph(160,120,S3,TRUE);
						SetDrawBlendMode(DX_BLENDMODE_ALPHA,150);
						DrawGraph(160,200,S4,TRUE);
						SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
						if(( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0){
							break;
						}
					}else if(MouseX>160&&MouseX<480&&MouseY>200&&MouseY<225){
						DrawGraph(160,200,S4,TRUE);
						SetDrawBlendMode(DX_BLENDMODE_ALPHA,150);
						DrawGraph(160,120,S3,TRUE);
						SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
						if(( GetMouseInput() & MOUSE_INPUT_LEFT ) != 0){
							DxLib_End();
							return 0;
						}
					}else{
						SetDrawBlendMode(DX_BLENDMODE_ALPHA,150);
						DrawGraph(160,120,S3,TRUE);
						DrawGraph(160,200,S4,TRUE);
						SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);
					}
	}
		SetDrawBlendMode(DX_BLENDMODE_ALPHA,150);
		DrawGraph(20,360,menu,TRUE);
		SetDrawBlendMode(DX_BLENDMODE_NOBLEND,0);

	// テキストバッファの描画
	for( i = 0 ; i < STRBUF_HEIGHT ; i ++ )
	{
		DrawString( 150 , 367+i * (FONT_SIZE+3) , StringBuf[ i ] , white,red ) ;
	}

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

}
if(Fin==1)
{
}
}
}

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

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

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

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

	// 描画行位置を一つあげる
	CursorY -- ;
}
}
目安箱バナー