Re: セーブできるようにしたい ( No.1 ) |
- 名前:B.E 日時:2019/11/05 00:46
ファイルの保存はC++の標準ライブラリで比較的簡単に行うことができるので、DXライブラリの関数は無かったと思います。
Google等で『stdio.h fopen()』で検索すると分かりやすい解説がいっぱい出て来ると思いますよ。
c++入門系のサイトにも「ファイル入出力」の解説は大抵載ってます。
DXライブラリにも読み込み用の関数がありますが、おそらく「DXアーカイブファイル」からの読み込みや、
非同期読み込みを簡単にやる為に用意されているんだと思います。
普通のファイルをメモリに読み込むなら、「FileRead_open()」と「fopen()」のどっちを使ってもコード書く手間的にも大差ないですしね…。
(あと、余談ですが現在描画対象になっている画面を画像ファイルとして保存する関数はあるようです…)
|
Re: セーブできるようにしたい ( No.2 ) |
- 名前:管理人 日時:2019/11/05 02:03
セーブデータの保存に適したファイルの保存機能は B.Eさんも仰られている通りDXライブラリに関数はありませんので、標準関数を使用してください
こちらに標準関数を使用したファイルの保存のサンプルプログラムがありますので、よろしければご覧ください
<17.セーブ・ロード基本>
https://dxlib.xsrv.jp/dxprogram.html#N17
> 後、質問ではなくて申し訳ないのですが、別件でお聞きしたいのですが、DXlibの関数やヘッダファイルは管理人様が一人でお作りになられたのでしょうか。
DXライブラリは jpeg ファイルを読み込む為の libjpeg.lib や物理演算を行う BulletPhysicsライブラリなど
外部のライブラリも使用させていただいているので私一人で作ったというと語弊があるかもしれませんが、
メインとなる DxLib.lib や DxLib.h は私一人で作成しています
ただ、DxLib.lib に含まれるコードの一部( PMD. PMX ファイルの物理演算関係やIK関係のコードや Mersenne Twister のコードや
DirectShow を扱うコードなど )は私以外の方が作成されてネットで公開されていたコードや参考書籍に載っていたコードを
DXライブラリで使えるようにアレンジしたり、コンパイルが通るように型名だけ変えてほぼそのまま使用させていただいたり
しているものなので、『自分で組んだ』と言えるコードは DxLib.lib の中の 95% くらいです
とはいえ、DXライブラリはその出自がそもそも『私が使って感動した"一般には公開されていなかったライブラリ"を作られた方の
許可を得てほぼ同じ内容のライブラリを作った』ものなので、DXライブラリのお手軽さや使いやすさなどの重要な部分は私が
考えたものではありません
なので、私一人で作ったといってもあくまで『DXライブラリのコードについては』ということになります
( ただし、その『DXライブラリのコード』についても最初は『元となったライブラリ』のコードほぼそのままの部分も
あったので、最初期についてはコード部分も自分で作ったとは言い難いです )
> 作り方や行き詰まったときに誰かに相談したり手伝っていただいたりしなかったのでしょうか。
DXライブラリを最初に作成した当時( 2000年10月頃 )についてのご質問ということで良いでしょうか?
DXライブラリを作成した当時は私は専門学校の学生で、『DXライブラリの元となったライブラリを作られた方』は
専門学校の先生だったので、当然質問や相談は沢山しています( DXライブラリのことよりも普通に課題についてや
興味のある技術についての質問の方が多かったと思いますが… )
ただ、その先生や同級生の友人にDXライブラリのプログラムを組む作業を手伝って頂いたということはありません
…というのも、そもそもそのまま使うことができる『DXライブラリの元となったライブラリ』のコードが手元にあるので、
誰の手も借りることなく組めて当たり前だったからです
( そして、ひとまず『元のライブラリの一部分が異なるだけ( 関数名、引数名が違ったり、元ライブラリでは複数の関数に
分けられてた機能を一つの関数にして引数で機能分けの対応をしたり、逆に一つの関数に纏められていた関数を複数の関数に
分けたり )のライブラリである"DXライブラリ"』が使えるレベルになった後、『元のライブラリ』には無かった文字列描画の
テクスチャキャッシュ機能( 元のライブラリは都度 Win32API の TextOut で文字列を出力していたため DrawString が
非常に遅かった )を追加したり、ソフトウェアレンダリング機能の追加や、DirectX SDK が無くてもコンパイルができるようにする
ちょっとした大改造、jpegファイル,pngファイルの読み込みに対応など、徐々に独自の機能を増やしていきました )
|
Re: セーブできるようにしたい ( No.3 ) |
- 名前:セイラム 日時:2019/11/07 03:51
管理人様返信ありがとうございます。
なるほど、詳しい経緯が聞けて良かったです。やはり色んな方の協力によってDXライブラリという素晴らしいものが生まれたのだとわかりました。
その専門学校は有名な学校ですか?そんな素晴らしい講師の方に出会えるなんて羨ましいです!
セーブにおいては、ネットを参考に調べて以下の様に作りました。
書き込むためのプログラムは以下のもので、キーYによりバッチファイルに変数Seenの値8を書き込みます。
if (Key[KEY_INPUT_Y] == 1) {
mark = 1;
FILE* fp;
fp = fopen("test.bat", "wb");
fprintf(fp, "Seen = 8");//ちゃんとバッチファイルに書き込めている。
fclose(fp);
}
こちらか読み込み様です。スペースキーを押すとバッチファイルに書き込まれたSeen=8から変数Seenが8ということを読み取り、
変数Seenに8を代入します。
if (Key[KEY_INPUT_SPACE] == 1) {
if (!(fp = fopen(filename, "rb")))
return;
if (fread(buf_r, sizeof(int), 1, fp) != 1) {
fclose(fp);
return;
}
fclose(fp);
Seen = buf_r[yomikomi];
しかし、読み込みの方のプログラムが働いてくれていないのか、スペースキーを押すとSeenの値が8ではなく、1852138835と出てきます。
バッチファイルの書き方がいけないのか、読み込むプログラムに間違っているのかよくわかりません。
Seenの値を100にした場合も読み込むとSeenは同じ1852138835とでます。
どうか何をどうすれば正しく動くようになるのか教えて頂けないでしょうか。
|
Re: セーブできるようにしたい ( No.4 ) |
- 名前:クロエ 日時:2019/11/08 14:59
まずインデントを揃えましょう。
バッチファイルに書き込んでいるのは何か意図があるのですか?
バッチファイルとは何か、を答えてもらってよろしいでしょうか。
そして文字列を書き込んで、intで読み込んでいますね。
管理人さんの提示したソースをアレンジして、その結果が理解できないという事で合っていますか?
文字列
"Seen"
文字コードにすると
0x53,0x65,0x65,0x6e
int32 で読み込むと
0x6e656553
10進数にすると
1852138835
結果にどこもおかしな所はないと思います。
>Seenの値を100にした
というのは
fprintf(fp, "Seen = 100");
このようにしてみた、という事でしょうか。
それならば、セイラムさんはかなり根本的な部分を理解せずにプログラムを組んでいる事になります。
この場でこれだけ解決しても、以降ずっと人に頼らざるを得なくなると思います。
今一度書籍やサイトなどで基礎をしっかりと学ぶ必要がありますが、そうアドバイスして解決するものでもないので難しい所ですね。
(前例というなら、厳しく当たる事で短期間で自力で解決できるようになった例はあります。私は推奨しませんが)
|
Re: セーブできるようにしたい ( No.5 ) |
- 名前:B.E 日時:2019/11/07 23:48
ちょと気になった箇所としては、
if (!(fp = fopen(filename, "rb")))の所のファイル名は合っていますでしょうか?
あとbuf_rやyomikomiの宣言も見当たりません。
(『1852138835』が読み込めているので多分コピペした範囲外で宣言してあるのでしょうか?)
肝心な所としては、「バイナリデータ」と「テキストデータ」の区別がついていないように感じます。
あと失礼ですが、おそらくfread()が何をする関数なのか理解されていないと思われます。
最初にfprintf(fp, "Seen = 8");はファイルに『Seen = 8』と書かれたテキストデータを書き出しています。
これは『//ちゃんとバッチファイルに書き込めている。』と書いてあるので何をしているか理解できていると思います。
次にfread(buf_r, sizeof(int), 1, fp)はファイルからbuf_rポインタに4バイト分データを読み込んでいます。
(sizeof()は型の名前を引数に指定するとその型のサイズが帰ってきます。なのでsizeof(int)は環境にもよりますが基本4バイトになります)
『バッチファイルに書き込まれたSeen=8から変数Seenが8ということを読み取り』と書いていますがfread()はそんな事は出来ません。
fread(void *buf, size_t size, size_t n, FILE *fp);の動作を簡単に説明すると
FILE *fpで指定したポインタのファイルから、void *bufで指定した変数(配列)のポインタに、
size_t sizeで指定したバイト数を、size_t n個読み込むということだけです。
要するにfprintf()関数でで8バイト(8文字)分のテキストデータを保存しているのに、
fread()関数でbuf_rポインタ(恐らくint型配列の先頭)に4バイト分を読み込んでいるだけです。
文字列(char型の配列)を保存してint型に読み込んでいるので一見意味不明な数値になっているのです。
(実際は意味不明でもなんでもなくクロエさんの書いている通りちゃんとした理由があります。)
そもそも、なぜ保存にfprintf()を使用したんのでしょうか?
管理人様の張ったリンク先のサンプルはfwrite()を使用してバイナリで保存していたと思うのですが…?
下記のように記載すればバイナリで書き込めます
(Seenはint型で宣言・初期化してあるものとします。エラー処理は省略してます。)
int buf_w ; //書き込み用のint型のbuf_w変数を宣言
FILE* fp; //ファイルポインタを宣言
buf_w = Seen; //Seenをbuf_wに代入
fp = fopen("test.dat", "wb"); //ファイルをオープンしてポインタをfpに代入
fwrite(&buf_w,sizeof(int),1,fp); //ファイルにint型のデータbuf_w変数を書き込み
fclose(fp); //ファイルを閉じる
(※拡張子.batはWindousのバッチファイルとして使用されているので.datにしました。)
読み込みはこんな感じです。
(Seenはint型で宣言してあるものとします。エラー処理は省略してます。)
int buf_r; //読み込み用のint型のbuf_r変数を宣言
FILE* fp; //ファイルポインタを宣言
fp = fopen("test.dat", "rb"); //ファイルをオープンしてポインタをfpに代入
fread(&buf_r,sizeof(int),1,fp); //ファイルからint型のデータをbuf_r変数に読み込み
fclose(fp); //ファイルを閉じる
Seen = buf_r; //Seenにbuf_rを代入
これで、バイナリで保存と読み込みができるので正常に動作すると思います。
(複数のデータを保存したい場合はint型を自分で宣言した構造体型に変えればいいだけです。)
それとも、なにかテキスト形式で保存したい理由があるのでしょうか?
(上記にも書いたとおり拡張子.batというのテキストファイルはWindousのコマンドプロンプトの命令を記入した
バッチファイルとして定義されているもので、一般的にセーブデータの形式では無いと思いますが…。)
テキストデータで保存すると、ファイルの中身をテキストエディタ等で簡単に確認できるので便利ですが、
読み込み時にchar型配列の文字列から、int型等に代入するために数値に変換する作業をしないといけないので、
特に理由がないなら、バイナリデータで保存することをお勧めします。
fread()は自動で文字列データを数値にしてくれるような機能はありません。
c言語の標準ライブラリには、文字列を数値に変換する関数もありますが、fread()を使いこなせないようなら、
他のファイル操作や文字列操作系のメモリ上のデータを操作する系の関数はまだ使いこなせないと思います。
ファイルの保存や読み込みをする場合、文字列や構造体等のデータの仕組みとかを、
分かってないとつまずいちゃうと思うので、その辺を理解出来ていないようでしたら、
C言語の基礎をきちんと勉強してからの方がいいかもです。(気分を害したらすいません)
どうしてもテキスト形式で保存したいのであれば、
とりあえず、文字列(char配列)の仕組みを理解できるようになる所から初めてみましょう。
|
Re: セーブできるようにしたい ( No.6 ) |
- 名前:セイラム 日時:2019/11/08 06:31
>>ファイルの保存や読み込みをする場合、文字列や構造体等のデータの仕組みとかを、
分かってないとつまずいちゃうと思うので、その辺を理解出来ていないようでしたら、
C言語の基礎をきちんと勉強してからの方がいいかもです。(気分を害したらすいません)
わかりました。どうもありがとうございました。
|
Re: セーブできるようにしたい ( No.7 ) |
- 名前:セイラム 日時:2019/11/08 06:55
基礎を勉強はしているのですが、資料が古いせいかサンプルを描画して実行しても思うような結果にならなかったり、
質問して親切な方から頂いたプログラムは誤字やエラーがないためちゃんと動くことが多いため、本ではなくサイトや質問サイトに頼ってしまいます。
これでも試行錯誤して一から基礎を勉強していますが、本を読んでその通りに書いて、ちゃんと動くこともあれば、
動かないこともあり、原因がわからず質問すると解決することもあります。しかし、構文や条件など新しいことを勉強する度に質問しては
基礎が足りていない、丸投げなど罵倒されたり裏で色々書き込まれたりと気持ち悪いことが多く
基礎を勉強するというのがよくわかりません。
私にも質問の仕方に関して悪い部分がありますが、そんなことも知らないで言いたいことだけ言っている人もどうかと思います。
愚痴になってしまいすいません。
|
Re: セーブできるようにしたい ( No.8 ) |
- 名前:クロエ 日時:2019/11/08 11:01
インデントの揃え方に今も昔もありません(タブ長の違いはありますが)。
インデントも基礎ですよね。
インデントをマスターしていませんよね?
基礎を勉強していませんよね?
したかもしれませんが理解する事なく先に進んでいますよね?
何か反対意見はありますか?
質問を見る限り、他にもたくさん理解する事なく先に進んでいますね。
バッチファイルに関して質問しましたが、バッチファイルについて調べましたか?
バッチファイルも基礎ですね。
基礎を勉強しませんでしたよね?
>基礎を勉強はしているのですが、資料が古いせいかサンプルを描画して実行しても思うような結果にならなかったり
思うような結果に出来る所までが勉強です。
基礎の勉強を途中で放棄していますよね?
基礎を勉強しませんでしたよね?
>原因がわからず質問すると解決することもあります
なぜ動かず、どうして動くようになったのかを理解する所までが解決です。
理解していませんよね?
理解していないから新しいものにつまずくのです。
B.E さんの解説を理解できましたか?(私は理解できると踏んでないのでしなかったのです)
>基礎を勉強するというのがよくわかりません
基礎の勉強がよく分からないのに、勉強をしているというのがそもそも矛盾していますよね。
裏で言われているのはそれが乱暴な言葉になっているだけで要するに「矛盾のある人」と言っているだけなんですね。
>罵倒されたり裏で色々書き込まれたりと気持ち悪いことが多く
私の知る限り唯一の解決例なので間違っているとは思いません(私は推奨しませんが)。
それをバネに頑張って自力で解決できるようになった人が実際います(その人が「それは嘘だった」とカミングアウトするなら話は別ですが)。
ここからは本アドバイスですが、
サイトや書籍より、マンツーマンで教えてくれる所や人を探すのがいいと思います。
有料でも良いのならいるはずです。
自分が基礎ができていないという事を念頭に、恥を忍んで顔見知りの人に頭を下げるのもいいかもしれません。
(クラス制の所は他の人の足を引っ張るので止めた方がいいです)
|
Re: セーブできるようにしたい ( No.9 ) |
- 名前:セイラム 日時:2019/11/08 12:40
クロエさんご丁寧にどうもですー。
|
Re: セーブできるようにしたい ( No.10 ) |
- 名前:B.E 日時:2019/11/08 22:00
『基礎を勉強するというのがよくわかりません。』と言われても困っちゃうんですが、
とりあえず配列、文字列、データ型、構造体、ポインタとかは基礎だと思うんで抑えて置いたほうがいいですよ。
この辺のサイトなんか結構丁寧に解説してますよ。
ttps://programming.pc-note.net/c/index.html
DXライブラリはすごく便利で、型のサイズとかポインタとかあんまり意識しなくても使えちゃうんで、
覚えなくても大丈夫じゃないかと錯覚しちゃいますけど、cやc++の標準関数とかでもポインタ普通に使いますからね…。
プログラムが複雑になってくると、どうしても避けられないです。
|
Re: セーブできるようにしたい ( No.11 ) |
- 名前:アナザー通りすがり 日時:2019/11/09 10:40
まず、質問の前提が大雑把すぎます。
ファイルの読み書きの話以前に、システムの状態をどこか外部に全て記録しておきたいという壮大な話に思えます。
セーブ処理を仮にゲームに限定すると、たとえばRPGを作る場合にセーブデータって具体的に何が必要だと思いますか?
パーティーメンバー、それぞれの現状ステータス、それぞれの所持アイテム、所持金、現在地、イベントの進捗状況、アイテムの取得状況
少し考えただけでもこれだけ記録しておく必要があります。当然もっとあると思います。
そしてそれは、DXライブラリを使用していればそのユーザー分パラメータに差異があるのは当然です。
それぞれのパラメータの型や数値であれば上限下限も想定しないとシステムが崩壊します。
それをDXライブラリ側からユーザーの意思を汲み取って、必要なデータを自動で取捨選択し、外部に記録するような
そんな機構が本気で存在すると思いますか?それも関数一発で。あるわけないですよね?
仮にRPGツクールで、セーブを作る方法が分かりませんという質問ならばまだ理解できます。(もちろんここでする質問ではありませんが)
言語の基本を理解する以前に、システムに対する想像力が全く働いていない証左だと思います。
DXライブラリを使う以前に、ゲームを作りたいだけならば各種ゲーム制作ツールを使用することを強くお勧めします。
DXライブラリの使用可否に関わらず、自分でプログラムを組んでゲームを作成するのはセイラムさんに限らず難易度が高いです。
大げさに思えるかもしれませんが、これは本当です。
各種サイトでゲームのサンプルソースが公開されていて、一見簡単な様に見えますが
メニューからゲーム本編、各種イベント、果てはエンディングまでを手作りしようとすると、本当に難しいです。
ネットで拾えるサンプルソースを組み合わせればいいなんて単純な話でもありません。
プログラム言語の基礎が出来て、DXライブラリの各種関数などを使いこなせて尚難しいのです。
今ではフリーで使えるゲーム制作ツールは沢山あるので、それらを使いこなした上で痒い所に手が届かない場合に
自分でプログラムを組むのが一番理解しやすいと思います。
厳しいことを言っていますが、ご参考にしてください。
|
Re: セーブできるようにしたい ( No.12 ) |
- 名前:管理人 日時:2019/11/09 19:00
このスレッドの本来の話題は終了したと判断しますのでロックします
|