サウンドノベル風文字列表示法

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

サウンドノベル風文字列表示法

#1

投稿記事 by lian » 15年前

ゲームプログラミングの館で、日々学習させてもらっています。
しかし、一つ解らない事があるので質問させていただきました。
ゲームプログラミングの館の、~サンプルプログラム編~のs1.サウンドノベル風文字列表示法1についてです。
サンプルプログラムでは…

#include "DxLib.h"

int i=0,j,ch_i=0,counter=0,White;
char Key[256],oldKey[256]={},disp[80]="",ch[5][80]={
"プログラムを習得するには、実際に自分で書いてみることが大事。",
"参考書を読むことも重要だが、数学のように演習を通して、",
"体に身につけるようにしよう。",
"きっと、よりはっきりと、関数の使い方、",
"プログラムの書き方がわかるだろう。"
};


int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ){
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1;
SetDrawScreen( DX_SCREEN_BACK ) ;

White=GetColor(255,255,255);

while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){

for(j=0;j<256;j++){
if(oldKey[j]==0 && Key[j]==1)
Key[j]=2;
oldKey[j]=Key[j];
}

if(Key[KEY_INPUT_RETURN]==2){ // 前回押されてなくて、今回押されていたら
i=0; // iを初期値に戻し
ch_i++; // 表示する配列を1つずらす
if(ch_i==5) // これ以上表示する配列がなくなったらbreak;
break;
}

// 配列の終端-2以下で、今回コピーするiまでの配列要素のi番目が\0じゃなくカウンターが5の倍数なら
if(i<=80-2 && ch[ch_i]!='\0' && counter%5==0){
i+=2; // 全角文字なので配列要素2つずつカウントアップ
strncpy(disp,ch[ch_i],i);// iバイトまでの配列要素をdisp配列にコピー
disp='\0'; // 終端記号を代入
}

DrawFormatString(10,420,White,"%s",disp);//disp配列の文字データを表示

counter++;
ScreenFlip() ;

}

DxLib_End() ;
return 0 ;
}

となっていますが、これでは一列しか表示できませんでした。
(文字列を一列表示してEnterを押すと表示されていた文字列が消え、次の文字列が表示されるといった具合に)
私は文字列を2,3列位表示させて、Enterを押すと次の文字列を表示されるといったようにしたいのです。
考えてみたのですが、良い方法が思い浮かびませんでした。
まだ初心者なのでこういった事もわからないのですが、どなたかご教授を宜しくお願いします。

<補足>
・Microsoft Visual C++ 2010 ExpressとDXライブラリを使用しています。
・OSはWindows7の32bitです。 画像

ぬるぽ

Re:サウンドノベル風文字列表示法

#2

投稿記事 by ぬるぽ » 15年前

DXライブラリのサンプルに下記のプログラムがあります。
参考にしてみてはいかがでしょうか。

#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[/url][ 256 ] =
{
" ゲームプログラムを習得するための一番の近道はとにかく沢山プログラムを組む",
"ことである。B" ,
"@ プログラムの参考書にはゲームのプログラムの方法なんて何も書かれていない、B",
"変数、B配列、B関数、Bループ、B条件分岐…Bこれらすべての説明はゲームで何に使うか",
"なんてどこにも書いていない、Bせいぜい住所録を題材にした例がある程度である。B" ,
"C プログラムは習うより慣れろなのでプログラムを組むに当たって少しでも知識が",
"つけば後はそこからは掘り下げ、広げていけば良いわけで、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' : // ボタン押し待ち文字

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

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() ;

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

Color = ( int )( sin( Count / 100.0 ) * 80.0 + 125.0 ) ;
DrawBox( 0 , 0 , 640 , 480 , GetColor( Color , 0 , 0 ) , TRUE ) ;
Count ++ ;
}

// テキストバッファの描画
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 -- ;
}
}

lian

Re:サウンドノベル風文字列表示法

#3

投稿記事 by lian » 15年前

ありがとうございます!
参考にして早速自分でチャレンジしてみます。

閉鎖

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