ページ 1 / 1
s2. サウンドノベル風文字列表示法1
Posted: 2008年12月20日(土) 22:44
by J
s2. サウンドノベル風文字列表示法1とありますが2は存在するのでしょうか?
気になったので書き込んでおきます。
関係ないですが・・・
トップページの背景は目の錯覚に微妙になってるんですかね?
ジーと見てるとだんだん変わってゆくように見えます(笑
Re: s2. サウンドノベル風文字列表示法1
Posted: 2008年12月20日(土) 23:32
by Dixq (管理人)
その2は2列で表示できるようにし、
その3では表示範囲を指定するとその枠内に自動的に入るように表示するサンプルにするつもりでしたが、
思ったよりコードが長くなったので、もう少し簡単にならないかな~と思っているうちに忘れていました^^;
時間を見つけて追加しておきますm(_ _)m
トップページの背景、そう言われるとそう見えますね。段々違う色に・・。
トップページの背景は青に見えるのに、掲示板の背景は緑に見える・・(違
Re: s2. サウンドノベル風文字列表示法1
Posted: 2008年12月21日(日) 18:57
by J
分かりました
返答ありがとうございました
錯覚というのは、だんだん青い球体が小さくなっていくように見えたと言うことです。
暗い部屋でみるとわかるかもしれません。
Re: s2. サウンドノベル風文字列表示法1
Posted: 2008年12月25日(木) 18:46
by J
こんにちは。
この表示方法を応用してFileRead~関数を用いて外部のファイルから文字列を読み取って表示したいのですが、
この表示方法で「一定の数を越えたら改行する」という風にするにはどうすればよいでしょうか?
うまくいきそうでうまくいきません。ご返答、お願いします
Re: s2. サウンドノベル風文字列表示法1
Posted: 2008年12月25日(木) 19:47
by 御津凪
一文字ごとのサイズを計算して、表示幅からあふれた文字を次の行へ移るように
すると良いでしょう。
で、その計算ですが、
文字幅が固定(等幅フォント)であれば文字数×文字幅で簡単に文字列幅を求められますが、
プロポーショナルフォント(等幅じゃないフォント)の場合は、文字ごとに幅が違うので、
Win32API の GetCharWidth32 関数等を使って文字幅を取得すると良いでしょう。
(私の構築しているライブラリでは GetCharWidth32 等を使って表示幅を決めて処理しています)
管理人さんの言う、コードが長くなるところは GetCharWidth32 で
表示範囲を計算する所でしょうね。
(等幅フォントならある程度短いですが)
表示方法については、左から一文字ずつ描画して、
表示幅を超えたら一段下げて左から一文字ずつ描画する方法と、
あらかじめ文字幅を計算し、文字列内に改行文字を挿入しておく方法があります。
(もし、読み込み文章が不変ならば、手作業で改行を入れておくほうがラクです)
Re: s2. サウンドノベル風文字列表示法1
Posted: 2008年12月25日(木) 21:15
by Justy
御津凪さんが書かれているとおり、一文字の表示サイズと文字間隔の情報から
どこまで1行で書けるかを調べて区切るのが基本です。
DXライブラリならや GetDrawStringWidth() や GetDrawFormatStringWidth() などを使って
求めるのもいいかと思います。
ただ日本語の場合、文字コードに注意して区切りを入れる必要があります。
サンプルの「s2. サウンドノベル風文字列表示法1」では2バイト固定の文字コードであることを
前提としていますが、それ以外の文字コードが使われていたり……例えば 1バイト文字が
混ざる場合などはその判定もしなければなりません。
又、適当に表示上の長さだけで行を区切ってしまうと、句読点や括弧終了などが先頭に
来てしまったり、反対に行末に括弧開始などが来たり、或いは連続した数字が行を
跨いでしまったりとおかしな表示になってしまうことがあります。
表示内容次第ですが、そういう場合の処理(禁則処理)も入れておいた方がいいかも
しれません。
#事前に元テキストの方で切っておくのが楽かと。
Re: s2. サウンドノベル風文字列表示法1
Posted: 2008年12月26日(金) 00:01
by Dixq (管理人)
とりあえず3行にわけて表示するサンプル作ってみました。
すごいやっつけです^^;
Zキーで読み進めて下さい。
サンプルは
http://dixq.net/g/#41
これに、文字列計算するためのCalcShowStrなる関数と後チョットつけたしただけです。
#include "DxLib.h"
#define ShowN 25
int Key[256];
typedef struct{
int State;
int count;
int pos;
char str[3][ShowN];
}ShowStr_t;
ShowStr_t ShowStr;
int WordsPos1,WordsPos2;
char Words[10][ShowN*3-2]={
{"今日1月1日は元旦です!! 元旦なので、家に帰ってます。"},
{"家に帰った時位"},
{"修論の事は忘れたいものですが(´~`;)、そうもいかないみたいです;"},
{"1月のこのくそ忙しい時に姉貴が結婚するので、その準備で、"},
{"忙しさが更に倍増ですorz 本当に卒業できるのだろうかDixq。"},
{"卒業できなかったら発狂して‥・・&\"'(#!)\\.+:@[/url]りそう。"},
{"そうならないようにナントカシマス。"},
{"終わり。"},
};
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[/url]){
char GetHitKeyStateAll_Key[256];
GetHitKeyStateAll( GetHitKeyStateAll_Key );
for(int i=0;i<256;i++){
if(GetHitKeyStateAll_Key==1) GetHitKeyStateAll_InputKey++;
else GetHitKeyStateAll_InputKey=0;
}
return 0;
}
void CalcShowStr(){
if(Key[KEY_INPUT_Z]==2){//Zキー押されたら次のワードに進んでShow初期化
WordsPos2=0;
WordsPos1++;
ShowStr.pos=0;
ShowStr.State=0;
ShowStr.count=0;
ShowStr.str[2][0]=ShowStr.str[1][0]=0;
}
switch(ShowStr.State){
case 0:
case 1:
case 2://1,2,3行目の時、
if(ShowStr.count%4==0){//4カウントに1回処理
//1文字とってくる
ShowStr.str[ShowStr.State][ShowStr.pos++] = Words[WordsPos1][WordsPos2++];
//とってきた文字がマイナスなら
if(ShowStr.str[ShowStr.State][ShowStr.pos-1]<0){
//もう一文字取ってくる
ShowStr.str[ShowStr.State][ShowStr.pos++] = Words[WordsPos1][WordsPos2++];
}
//とりあえずそこまでを文字列とする
ShowStr.str[ShowStr.State][ShowStr.pos]=0;
//今の位置がそろそろ終わりなら
if(ShowStr.pos>=ShowN-3){
//位置情報0にして次の行へ
ShowStr.pos=0;
ShowStr.State++;
}
//データワードが終わりなら
if(Words[WordsPos1][WordsPos2]==0){
//ステータスを終了に
ShowStr.State=-1;
}
}
ShowStr.count++;
break;
default:
break;
}
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode(TRUE);//ウィンドウモード
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
int White = GetColor( 255,255,255 );
while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
CalcShowStr();
DrawFormatString(0, 0,White,"%s",ShowStr.str[0]);
DrawFormatString(0,20,White,"%s",ShowStr.str[1]);
DrawFormatString(0,40,White,"%s",ShowStr.str[2]);
ScreenFlip();
}
DxLib_End();
return 0;
}
皆さん仰っているように文字列の長さはかって改行するのが一番だと思います。
後、全角かどうか判定する方法がいまいちわからなかったので、勝手にマイナスなら全角だろうということにしてます。
C言語って全角文字使う事とか前提にされてないんですかね・・。
http://www.geocities.co.jp/SiliconValle ... 7/c/is.htm
この辺参考にしたら全角か判定出来るのかな?
(ちなみにクイックソート解説アプリとかのはマイナスなら全角だろうということで作りました)
このままじゃ顔文字とかがそのまま区切れてしまうので、離れて欲しくない文字列はスペースで区切るなど何か対策立てたほうがいいかもしれません。
Re: s2. サウンドノベル風文字列表示法1
Posted: 2008年12月26日(金) 01:21
by Justy
>全角かどうか判定する方法がいまいちわからなかったので
char型と負の比較というのはちょっと問題があります。
DXライブラリを使うなら MultiByteCharCheck()なんて関数があるので、
そちらを使うというのも1つの手です。
あと、全角・半角というのは文字の見た目によるもので、それが何バイトなのかは
決められないので1バイト文字・2バイト文字とかの表現の方がいいかと思います。
>勝手にマイナスなら全角
Shit-JISだとすると半角カタガナが・・・。
Re: s2. サウンドノベル風文字列表示法1
Posted: 2008年12月26日(金) 08:31
by J
うひゃあ
すみません、すっかり質問したことを忘れていました。。
こんなこと初めてです。。疲れてるのかなぁ
みなさん色々アドバイスありがとうです
管理人さんので試してみます
それにしても全角・半角とあるおかげで判定が大変ですね~
Re: s2. サウンドノベル風文字列表示法1
Posted: 2008年12月26日(金) 16:24
by Dixq (管理人)
おぉ、そのような関数があるとは。
Justyさんよく非公開関数沢山ご存知ですね。
せっかく見易いように用意されているヘッダファイル、たまには端から見てみないといけませんね^^;
しかしMultiByteCharCheckで2バイト文字かどうかチェックできるということは自力でも出来るはずですよね?
半角カタカナ以外のマイナスの文字コードは2バイト文字なんでしょうか?
>半角カタカナ
そうなんですよね・・。
なので、半角カタカナは使わない方向で対処しました^^;
「半角カタカナは使うな」みたいなことが多いので抵抗は無かったんですが・・。
半角カタカナで起こるバグはこういうことに起因してるんですかね。
Re: s2. サウンドノベル風文字列表示法1
Posted: 2008年12月26日(金) 22:40
by Justy
>しかしMultiByteCharCheckで2バイト文字かどうかチェックできるということは自力でも出来るはずですよね?
勿論です。
そうでないと、文字を扱うソフトが全滅してしまいます!
初級C言語Q&A(15)
ttp://www.st.rim.or.jp/~phinloda/cqa/cqa15.html#Q4
>半角カタカナ以外のマイナスの文字コードは2バイト文字なんでしょうか?
Shift-JISにおいて 1文字目を unsignedにキャストして 0x80以上は
ほとんど2バイト文字ですが、半角系の。「」、も1バイト文字になりますね。
>Justyさんよく非公開関数沢山ご存知ですね。
DXライブラリ自体ほとんど使わないのに何故でしょうねぇw
質問に答えているうちに自然と、ってところでしょうか。
Re: s2. サウンドノベル風文字列表示法1
Posted: 2008年12月27日(土) 01:49
by Dixq (管理人)
>勿論です
ですよねw
参考サイトありがとうございます。
よし、今度からこの辺で関数作ってみます♪
>質問に答えているうちに自然と、ってところでしょうか
吸収が早い^^;
普通の人の成長度合いが y=x (x>0) で表せたらJustyさんの場合 y=x^2 (x>10) 位ですねw