ノベル風文字表示が処理落ち?
Posted: 2011年5月26日(木) 11:46
初めまして、ヤットと申します。最近ゲームプログラミングを始めたばかりなのですが、どうしてもうまくいかない件で相談しにきました。
でんさんラボというサイトで公開されているサンプルを参考にして、ノベルゲーム風の文字表示を行いたく以下のようなコードを作成しました。
下記のコードのMes_Drawをメイン関数のループから毎回呼び出すと、一見うまく動作するのですが、表示が100文字を超えた辺りから急に表示が遅くなります。
FPSを確認したところ、62.5FPSから下がり始め、20FPS程度まで落ちてしまいます。(PCはXP,PEN4 3GHz)
参考にしたサンプルではメイン関数のループ中にSleepを入れており、Mes_Draw関数の呼び出し頻度は文字を進める時のみなのに対し、
当方ではループ毎に呼び出しています(引数で文字を進めるか否かを判定)
これは、文字表示処理と同時に、他のグラフィックなどのアニメーション表示もしたい時のためを思ってのことなのですが……おそらくうまくいかない原因はこれだと思っています。
ただ、どのように改善して良いのかわからず。。。そもそも参考にしたサンプルが、バックグラウンドでのアニメーションを想定してないのかもしれませんが、うーん。。。と唸っている状態です、お知恵をお借りできますでしょうか?
でんさんラボというサイトで公開されているサンプルを参考にして、ノベルゲーム風の文字表示を行いたく以下のようなコードを作成しました。
下記のコードのMes_Drawをメイン関数のループから毎回呼び出すと、一見うまく動作するのですが、表示が100文字を超えた辺りから急に表示が遅くなります。
FPSを確認したところ、62.5FPSから下がり始め、20FPS程度まで落ちてしまいます。(PCはXP,PEN4 3GHz)
参考にしたサンプルではメイン関数のループ中にSleepを入れており、Mes_Draw関数の呼び出し頻度は文字を進める時のみなのに対し、
当方ではループ毎に呼び出しています(引数で文字を進めるか否かを判定)
これは、文字表示処理と同時に、他のグラフィックなどのアニメーション表示もしたい時のためを思ってのことなのですが……おそらくうまくいかない原因はこれだと思っています。
ただ、どのように改善して良いのかわからず。。。そもそも参考にしたサンプルが、バックグラウンドでのアニメーションを想定してないのかもしれませんが、うーん。。。と唸っている状態です、お知恵をお借りできますでしょうか?
#include "DxLib.h"
#include <string.h>
//メッセージフォントのサイズ
#define MESSAGE_FONT_SIZE 28
//メッセージの最大文字数
#define MESSAGE_MAX_LENGTH 25
//メッセージの最大行数
#define MESSAGE_MAX_LINE 12
char g_Mes[ MESSAGE_MAX_LENGTH * MESSAGE_MAX_LINE ];
char g_MesBuffer[MESSAGE_MAX_LINE][MESSAGE_MAX_LENGTH * 2];
static int g_CurrentMes; //現在何文字目まで表示しているか
static int g_CurrentLine; //現在何行目の文字を表示しているか
void Mes_init()
//動作テスト用の文字列を用意
{
strcpy( g_Mes, "財務省が25日発表した4月の貿易統計速報(通関ベース)によると、輸出額から輸入額を差し引いた貿易収支は、東日本大震災の影響で輸出が停滞、4637億円の大幅な赤字となった。赤字は3カ月ぶりで、4月としては第2次石油危機に見舞われた1980年以来31年ぶり。震災による部品供給網の寸断が響き、自動車などの生産が滞り、輸出額が前年同月比12.5%減と3月(2.3%減)から落ち込み幅が拡大。一方、エネルギー資源を中心に輸入が増加、赤字に転落した。");
}
//日本語かどうかチェックする 戻り値1:日本語 戻り値0:日本語ではない
int CheckJapanese( unsigned char code )
{
if ( (code >= 0x81 && code <= 0x9F ) ||
(code >= 0xE0 && code <= 0xFC ) ){
return 1;
}
return 0;
}
// char* messageで指定した文章を start の位置から len 文字分表示する
// 表示座標は int x,y 表示色は col で指定
void writeString(char* message, int start, int len, int x, int y, int col, int bufferLine)
{
int i;
int MaxLen = strlen (message); //メッセージの長さを取得
// startの位置を調整
// startの指定位置までに日本語があったら、その分1足す
for ( i=0; i < start && message[i] != '\0'; ) {
if( CheckJapanese( message[i] ) ) {
//日本語 2プラス
i += 2;
//start位置+1
start ++;
}else{
//半角文字 1プラス
i ++;
}
}
if ( start >= MaxLen){
return;
}
//指定位置(start +- 調整分)からlen文字分表示
for ( i=0; i < len && message[ start + i ] != '\0'; ){
if ( CheckJapanese( message[start+i] ) ) {
//日本語表示(バッファーに入れる)
g_MesBuffer[bufferLine][ i ] = message[ start + i ];
g_MesBuffer[bufferLine][ i + 1 ] = message[ start + i + 1];
//len(長さ)は 日本語なので1バイト分追加
len ++;
// iを2進める
i += 2;
}else{
//半角文字・1文字表示(Bufferに格納)
g_MesBuffer[bufferLine][i] = message[ start + i ];
i ++;
}
}
g_MesBuffer[bufferLine][i] = '\0';
//実際に描写します
DrawString( x, y, g_MesBuffer[bufferLine], col );
}
// メッセージ表示
void Mes_Draw( int Flag )
// Flag == 0 で文字を進める。メイン関数のループカウントを文字表示速度で割った余りを引数にする 例:Mes_Draw( count % 10 )
{
int i;
// 文字を1進める
if ( Flag==0 && g_Mes[g_CurrentMes] != '\0' ) {
g_CurrentMes ++;
}
//MESSAGE_MAX_LENGTHまで描写したら段落を進める
if ( Flag==0 && g_CurrentMes % MESSAGE_MAX_LENGTH == 0 ){
if ( g_Mes[ g_CurrentMes ] != '\0' ){
g_CurrentLine ++;
}
}
//メッセージ描写
for ( i = 0; i < MESSAGE_MAX_LINE ; i++ ){
if ( i == g_CurrentLine ){
//メッセージ風
writeString( g_Mes, i*MESSAGE_MAX_LENGTH, g_CurrentMes - MESSAGE_MAX_LENGTH * i, 0, 0 + MESSAGE_FONT_SIZE * i, GetColor(255,255,255), i );
break;
}else{
//一度に表示
writeString( g_Mes, i*MESSAGE_MAX_LENGTH, MESSAGE_MAX_LENGTH, 0, 0 + MESSAGE_FONT_SIZE * i, GetColor(255,255,255), i );
}
}
}