HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2015
0313
ノダッシービジュアルノベルを作ろうと思うのですが改行の仕方25解決


ノダッシー

リンク

2015/3/13(Fri) 21:30:00|NO.67838

タイトルの通りです
テキストファイルから文章を読み込んで表示させる仕様ですが
一行に24文字以上表示されたら改行をし、テキストファイルに\があれば、クリック待ちが行われ、クリックするとページが変わって
画面の始めの場所から続きの文が始まるようにしたいのですが方法がわかりません
どんなやり方があるのかご教示願います

以下は自分で途中まで考えたコードですが、メッセージも上手く表示させれない状態です
よろしくお願いします


#include "hsp3util.as" font "MS Pゴシック", 28, 16 notesel buf noteload "test.txt" sdim data, 256 noteget data, 0 yen = "\" ;\の処理 if( strmid(data, -2, 1) == yen ) {;末尾の\があった場合 text 250 message = strmid(data, strlen(data) -strlen(data), strlen(data) - 1);末尾の\を削除 emes message }



この記事に返信する


tds12

リンク

2015/3/13(Fri) 22:09:09|NO.67845

yen = "\"

yen = "\\"
にしてみると良いかもしれません。



ノダッシー

リンク

2015/3/16(Mon) 11:31:06|NO.67921

遅くなりました、返信ありがとうございます
\を二つ続けて\\としたら表示はできました、、、が文章を途中(24文字以降)で改行させる方法がイマイチ不明です
posを使って直接改行するのではなく24文字以降に\nを挿入して自然に改行したいのですが
文字列の途中に\nを入れるなんて事可能なのでしょうか?



tds12

リンク

2015/3/16(Mon) 17:17:07|NO.67923

モジュールにしてみました。
自由に使ってください。

//--------モジュール開始 #module #defcfunc spltline str _src,int len //_srcは加工元の文字列 //lenは区切る文字数 src = _src sdim res repeat strlen(src) / len res = res + strmid(src,cnt * len,len) + "\n" loop res = res + strmid(src,strlen(src) / len * len,strlen(src) \ len) return res #global //--------モジュール終了(ここまでコピー) //--------サンプル開始 src = "0123456789112345678921234567893123456789412345678951234567896" mes spltline(src,24)



窓月らら

リンク

2015/3/16(Mon) 17:20:43|NO.67924

ちょっと質問者の意図どおりではないですが、サンプル書いてみました。


// \\n 改行 // /e メッセージの終わり m= "これは、テストメッセージです。\\nうまく表示されたかな?\\n" m=m+"文字処理の都合で2バイト文字(全角)で\\n書いてね♪\\n" m=m+"なお、Android環境では\\n文字コードの都合でこの方法は使えません。\\n\\n" m=m+"にゃーん。/e" bx=2: by=2 // 表示基準となる位置(文字数ぶん) x1=bx: y1=by // 初期値 cls 4 font "MS ゴシック", 28, 16 color 255,255,255 repeat tmp=strmid(m,i,2) // 2バイト読み出し if tmp="/e" { break } // 終わりなのでループから抜ける if tmp="\\n" { tmp="": x1=bx: y1++ } // 改行 if tmp!"" { pos x1*28,y1*32: mes tmp: x1++ } // テキスト表示(1文字ずつ) i=i+2 // 2バイト文字なので+2 await 25 loop pos bx*28,352: color 0,255,255: mes "処理終わり。" stop



tds12

リンク

2015/3/16(Mon) 17:43:28|NO.67925

すみません。
先ほどのモジュールは、全く全角文字のことを考えていませんでした。
解決法としては、すべての文字に全角文字のみを使い、
spltline関数で24ではなく48と指定してください。



窓月らら

リンク

2015/3/16(Mon) 17:58:14|NO.67926

途中で止めて、スペースキーで続行する機能つけてみた。


// /n 改行 // /s ストップ(入力待ち) // /e メッセージの終わり m= "これは、テストメッセージです。/nうまく表示されたかな?/n/s" m=m+"文字処理の都合で2バイト文字(全角)で/n書いてね♪/n/s" m=m+"なお、Android環境では/n文字コードの都合でこの方法は使えません。/n/n" m=m+"にゃーん。/e" *st bx=2: by=2 // 表示基準となる位置(文字数ぶん) i=0: x1=bx: y1=by // 初期値 cls 4 font "MS ゴシック", 28, 16 color 255,255,255 repeat tmp=strmid(m,i,2) // 2バイト読み出し if tmp="/e" { break } // 終わりなのでループから抜ける if tmp="/n" { tmp="": x1=bx: y1++ } // 改行 if tmp="/s" { // SPACEキーが押されるまで待ち tmp="" repeat getkey k,32: if k { break } await 0 loop } if tmp!"" { pos x1*28,y1*32: mes tmp: x1++ } // テキスト表示(1文字ずつ) i=i+2 // 2バイト文字なので+2 await 25 loop color 0,255,255 pos bx*28,352: mes "処理終わり。": mes"[SPACE]キーで最初から表示します。" repeat: getkey k,32: if k { break }: await 0: loop goto *st



y.tack

リンク

2015/3/16(Mon) 18:50:41|NO.67930

2byte情報を格納する配列のモジュール書いてみました
引数で指定した配列に
1byte文字→1
2byte文字、2
2byte文字□3
が代入されます

#module m_2byte_check #deffunc _2byte_check array tmp_d,var tmp_s tmp_l=strlen(tmp_s) dim tmp_d,tmp_l+1 i=0 while i < tmp_l n=peek(tmp_s,i) if ((n>=129)&(n<=159) )|( (n>=224)&(n<=252)){ tmp_d.i=2:i++ if tmp_l>i { tmp_d.i=3:i++ } }else{ tmp_d.i=1:i++ } wend return #global s="abあc" dim ar,4 _2byte_check ar,s repeat length(ar) mes ar.cnt loop



y.tack

リンク

2015/3/16(Mon) 20:03:05|NO.67933


#module m_2byte_check #deffunc _2byte_check var tmp_ss,var tmp_s tmp_l=strlen(tmp_s) tmp_ss="" i=0 while i < tmp_l n=peek(tmp_s,i) if ((n>=129)&(n<=159) )|( (n>=224)&(n<=252)){ tmp_ss+="2":i++ if tmp_l>i { tmp_ss+="3":i++ } }else{ tmp_ss+="1":i++ } wend return #global #module // _pをsep_nで前と後に分割 #deffunc simple_split var _p,var _p2,var _p3,int sep_n l_p=strlen(_p) piyo="" // _pの前を取り出す piyo=strmid(_p,0,sep_n) foo="" // _pの後を取り出す foo=strmid(_p,-1,l_p-sep_n) _p2=piyo _p3=foo return #global #module #defcfunc spltline var _src,int len tmp_sss="" _2byte_check tmp_sss,_src v_s1="" v_s2="" simple_split _src,v_s1,v_s2,len v_c1="" v_c2="" simple_split tmp_sss,v_c1,v_c2,len tmp_r="" do tmp_hoge=strmid(v_c1,-1,1) if tmp_hoge=="2"{ sdim tmp_v_s1,4 poke tmp_v_s1,0,peek(v_s1,(len-1)) poke tmp_v_s1,1,peek(v_s2,0) v_s1=strmid(v_s1,0,(len-1))+tmp_v_s1 tmp_piyopiyo="" simple_split v_s2,tmp_piyopiyo,v_s2,1 v_c1+=strmid(v_c2,-1,1) tmp_piyopiyo="" simple_split v_c2,tmp_piyopiyo,v_c2,1 } tmp_r+=v_s1+"\n" cnt_l=strlen(v_s2) if cnt_l<len{ tmp_r+=v_s2 _break } tmp_v_s1="" tmp_v_s2="" simple_split v_s2,tmp_v_s1,tmp_v_s2,len v_s1=tmp_v_s1 v_s2=tmp_v_s2 tmp_v_c1="" tmp_v_c2="" simple_split v_c2,tmp_v_c1,tmp_v_c2,len v_c1=tmp_v_c1 v_c2=tmp_v_c2 await 1 until 0 return tmp_r #global //--------モジュール終了(ここまでコピー) //--------サンプル開始 src = "0123笑愛456789abcdefg" mes spltline(src,5)



ノダッシー

リンク

2015/3/18(Wed) 10:54:54|NO.67956

tds12さん、窓月ららさん、y.tackさん
モジュールとコード大変勉強になります
これから貼って頂いた素敵なコードを研究し、後は画像と音が表示できるように改良していきたいと思います
ありがとうございました!



ノダッシー

リンク

2015/3/18(Wed) 14:33:50|NO.67958

う〜ん…
窓月ららさんのスクリプトをカスタムして使わせて頂いているのですが、カスタム後何故か行の先頭に1文字分の字下げが入ってしまいます
テキストファイルには行の頭にスペースは入れてないですしnoteselとnotegetの仕様なのでしょうか?
原因と対策方法が分かる方みえましたらご指摘お願いします

// /n 改行 // /s ストップ(入力待ち) // /e メッセージの終わり notesel m //文字を読み込むバッファを設定 noteload "test.txt" *st bx=2: by=2 // 表示基準となる位置(文字数ぶん) i=0: x1=bx: y1=by // 初期値 cls 4 font "MS ゴシック", 28, 16 color 255,255,255 repeat tmp=strmid(m,i,2) // 2バイト読み出し if tmp="/e" { break } // 終わりなのでループから抜ける if tmp="/n" { tmp="": x1=bx: y1++ } // 改行 if tmp="/s" { // 左クリックが押されるまで待ち tmp="" repeat getkey k,1: if k { break } //左クリック待ち await 0 loop } if tmp!"" { pos x1*28,y1*32: mes tmp: x1++ } // テキスト表示(1文字ずつ) i=i+2 // 2バイト文字なので+2 await 25 loop color 0,255,255 pos bx*28,352: mes "処理終わり。": mes"[SPACE]キーで最初から表示します。" repeat: getkey k,32: if k { break }: await 0: loop goto *st



暇人

リンク

2015/3/18(Wed) 18:44:55|NO.67963

>bx=2: by=2 // 表示基準となる位置(文字数ぶん)
>i=0: x1=bx: y1=by // 初期値
ここで表示位置に関係あるの代入してるんだから当然じゃ?


> repeat
> getkey k,1: if k { break } //左クリック待ち
> await 0
> loop
await 0だと無駄にCPU使うから1以上にした方が良い



掘木

リンク

2015/3/18(Wed) 21:06:14|NO.67966

>ノダッシーさん
原因を聞いて改善するより自分で原因を突き止めよう。きっと大したことじゃないはずです。

実際動かしておかしさがわかるのですから、どこまで意図通りに動いているのかを確認しましょう。(何順目のrepeatまで?)
もしくは想定仕様に見合ういろいろなファイルを試して確認しましょう。(こんなファイルで変な表示になった!)

提示されたコードにおいて、右方向に文字位置をずらす箇所は1か所しかないように見えます。
何か意図しない状況でそこに到達している可能性があります。(logmesとかも使えます)
また、デバッグ時にバイナリデータ(メモリダンプ)を確認するのも忘れずに…重要なヒントが隠れてることがあります。

予測はできてもブラックボックスとなっているテキストファイルの中身が不明なので
核心には迫れません。
きっとちょっとした勘違いです。

余談:
notegetの仕様っていうか提示されてるコードにnotegetがないのですが…?
noteselの仕様というなら、bloadも試してみよう。どちらにせよ同じ結果になると思うんだ…。



窓月らら

リンク

2015/3/18(Wed) 21:27:24|NO.67969

おっと・・await 0だと無駄にcpu使うんですね。。メモメモ


bx=2: by=2 // 表示基準となる位置(文字数ぶん) i=0: x1=bx: y1=by // 初期値

ここのbx,byが初期位置です。数字は文字数です。
0にして試してみてください。



窓月らら

リンク

2015/3/18(Wed) 21:33:48|NO.67970

あ、そうですね。キー入力待ちだけですから await 16 でも十分ですね。

ちなみに

if tmp!"" { pos x1*28,y1*32: mes tmp: x1++ } // テキスト表示(1文字ずつ)
ここの x1*28,y1*32 が文字間隔なので、色々変えてみてください。



ノダッシー

リンク

2015/3/19(Thu) 13:39:02|NO.67978

説明不足ですみません
テキストファイルの中身に
あああああ/n/s
いいいいい/n/s
改行を入れると表示位置がズレるようで
あああああ/n/sいいいいい/n/s
という感じに修正したら解決致しました
ご指摘ありがとうございました。



掘木

リンク

2015/3/19(Thu) 20:40:18|NO.67983

>ノダッシーさん
いや、その発想はどうなの。
改行をなくせばいいということにすると、今後
1.改行のないすさまじく横長の文章を相手にデバッグする
2.改行を削るコンバータを用意する
3.独自の改行コードを指定できるテキストエディタを使用する(こんなのあるんカナ)
などの状況に陥り、非常にやりづらいと思いますよ?

テキストファイルに改行があるとおかしくなるところまで付きとめたなら、回避しようよ。


2バイト読み込みの際にtmpに"\n"(テキストファイルとしての改行文字)が入ることを想定していない。
これがtmpに入ると表示上は何も出ないが、
tmpが""ではないので、次の読み込み文字の表示位置が右に1文字分ずれる。
⇒tmpが"\n"の場合に""に書き換えるように修正する。もしくは"/n"に書き換える。

オマケ:
テキストファイルの行末が/nや/s、/eになることを想定しているのなら、
どれでもない場合に自動的に/nを補完するように改造してもいいし、警告を出すようにしてもいいと思う。



窓月らら

リンク

2015/3/19(Thu) 22:14:09|NO.67984

改良しました。これで改行しても使えますよ♪

// /n 改行 // /s ストップ(入力待ち) // /e メッセージの終わり notesel m //文字を読み込むバッファを設定 noteload "test.txt" *st bx=2: by=2 // 表示基準となる位置(文字数ぶん) i=0: x1=bx: y1=by // 初期値 cls 4 font "MS ゴシック", 28, 16 color 255,255,255 repeat tmp=strmid(m,i,2) // 2バイト読み出し if tmp="/e" { break } // 終わりなのでループから抜ける if tmp="/n" { tmp="": x1=bx: y1++ } // 改行 if tmp="/s" { // 左クリックが押されるまで待ち tmp="" repeat getkey k,1: if k { break } // 左クリック待ち await 16 loop } if peek(tmp,0)=$00 { x1-- } // noteselの改行対策 if tmp!"" { pos x1*28,y1*32: mes tmp: x1++ } // テキスト表示(1文字ずつ) i=i+2 // 2バイト文字なので+2 await 25 loop color 0,255,255 pos bx*28,352: mes "処理終わり。": mes"[SPACE]キーで最初から表示します。" repeat: getkey k,32: if k { break }: await 0: loop goto *st



窓月らら

リンク

2015/3/19(Thu) 22:23:57|NO.67985

// noteselの改行対策 の行を削除して
await 25 のところを以下のように書き換えたほうがいいかも。
これだと改行部分で無駄なウエイトが入りません。

if peek(tmp,0)=$00 { x1-- } else { await 25 }



掘木

リンク

2015/3/21(Sat) 00:57:55|NO.68002

>窓月ららさん
ふむふむなるほど…
[text.txt]の中身

文字列の中には全角文字と改行、/n 既定の特殊制御文字列のみ/nが利用 できます。/n/nを用いることで/n 一段下の行に移り、/n/sを用いる ことで/nキー待ち/sを行うことがで きます。/nメッセージの終わりには 、/n/eを記述してくださいませ。 /nおしまい。/s/e
想定通りの動きなの?私には不自然に見えて仕方がない。

それとも何か仕様上問題のある文章列なのだろうか。何を見落とした?



窓月らら

リンク

2015/3/21(Sat) 01:59:11|NO.68003

あ、ホントだ、行の最後に/nがある前提でした。
以下で改善されます。

// /n 改行 // /s ストップ(入力待ち) // /e メッセージの終わり notesel m //文字を読み込むバッファを設定 noteload "test.txt" *st bx=2: by=2 // 表示基準となる位置(文字数ぶん) i=0: x1=bx: y1=by // 初期値 cls 4 font "MS ゴシック", 28, 16 color 255,255,255 repeat tmp=strmid(m,i,2) // 2バイト読み出し if tmp="/e" { break } // 終わりなのでループから抜ける if tmp="/n" { tmp="": x1=bx: y1++ } // 改行 if tmp="/s" { // 左クリックが押されるまで待ち tmp="" repeat getkey k,1: if k { break } // 左クリック待ち await 16 loop } if tmp!"" { pos x1*28,y1*32: mes tmp: x1++ } // テキスト表示(1文字ずつ) i=i+2 // 2バイト文字なので+2 if peek(tmp,0)=$0d { x1-- } else { await 25 } loop color 0,255,255 pos bx*28,352: mes "処理終わり。": mes"[SPACE]キーで最初から表示します。" repeat: getkey k,32: if k { break }: await 0: loop goto *st



窓月らら

リンク

2015/3/21(Sat) 02:24:43|NO.68004

ちなみに、全角文字を前提に書いてありますが
半角も2文字1組で書けば表示できます。

例) これはtestです。/e



ノダッシー

リンク

2015/3/24(Tue) 15:40:27|NO.68091

返事遅れましたすみません
改良版ありがとうございましたm(__)m



kanamaru

リンク

2015/3/24(Tue) 16:04:48|NO.68094

余計とは思いますが、文字コードをunicodeにすれば処理が楽だと思います。
何バイトの文字でも一文字ずつ区切ることが可能になるので、y.tackさんのようなモジュールを
使う必要がないので。



anal

リンク

2015/3/24(Tue) 16:57:08|NO.68097

unicodeでも2バイトとは限らないはず



kanamaru

リンク

2015/3/24(Tue) 16:58:23|NO.68098

追加ですが、unicodeに変換して1文字ずつ区切るのは過去ログにあります。
http://hsp.tv/play/pforum.php?mode=pastwch&num=41206
です。(といってもこの過去ログも別の過去ログを見ているようですが)



ONION software Copyright 1997-2021(c) All rights reserved.