🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

594閲覧

関数で面倒事を省略したい。

R-ogiura

総合スコア60

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

1クリップ

投稿2019/11/14 23:45

相談したことがあります。一文字ずつ文字を描画するようには書けたのですが、
一文字事にif (i == 1) { a = i; }
//printf("str[%d]は%c", i,str[i-1]);
if (a == 1) {
DrawFormatString(100+10, 500, Green, "%c%c", str[0], str[1]);
}
と書いて、かつ文章ごとにmoziのように新しい関数を書くのが大変面倒なのですが、
読み込む、あるいはchar型の変数からの文字を一文字ずつ描画するような関数に入れて面倒を省きたいのですが、どのように書けばいいでしょうか。

#include "DxLib.h" #include "stdio.h" #pragma warning(disable: 4996) int i = 0; int countchar = 0; int loop = 1; int Green = GetColor(0, 255, 0); int x = 0, y = 0; int a,b,c; int mark = 0; int strtalk = 0; char str[7] = "あいう"; void mozi(void) { if (countchar >= 0) { ++countchar; } if (countchar == 50) { countchar = 0; ++i; //ループを止めるためのプログラム。 if (i == 6) { countchar = 11; } } if (i == 1) { a = i; } //printf("str[%d]は%c", i,str[i-1]); if (a == 1) { DrawFormatString(100+10, 500, Green, "%c%c", str[0], str[1]); } if (i == 2) { b = i; } //printf("str[%d]は%c", i,str[i-1]); if (b == 2) { DrawFormatString(100 + 30, 500, Green, "%c%c", str[2], str[3]); } if (i == 3) { c = i; } //printf("str[%d]は%c", i,str[i-1]); if (c == 3) { DrawFormatString(100 + 50, 500, Green, "%c%c", str[4], str[5]); } } int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { SetFontSize(25); //サイズを64に変更 SetFontThickness(10); //太さを8に変更 ChangeFont("MS 明朝"); //種類をMS明朝に変更 ChangeFontType(DX_FONTTYPE_ANTIALIASING); //アンチエイリアスフォントに変更 SetGraphMode(780, 680, 32); // ウィンドウの大きさを指定 ChangeWindowMode(TRUE); // 全画面ではなくウインドウを使用 if (DxLib_Init() == -1) return -1; // DXライブラリ初期化処理 SetDrawScreen(DX_SCREEN_BACK); // 裏画面を使用する設定 // ウインドウのサイズを手動ではできず、且つウインドウのサイズに合わせて拡大もしないようにする SetWindowSizeChangeEnableFlag(FALSE, FALSE); // 画面サイズは最大の780*680にしておく SetGraphMode(780, 680, 32); // 最初は 640x480 にしておく SetWindowSize(780, 680); // while(裏画面を表画面に反映, メッセージ処理, 画面クリア) while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0) { DrawFormatString(300, 400, Green, "countcharは%d", countchar, Font00); // 文字を描画する mozi();//関数を置くことでiを含んだ描画の関数が働くようになる。 } DxLib_End(); // DXライブラリ終了処理 return 0; }
退会済みユーザー👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

coco_bauer

2019/11/15 00:12

文章ごとに、関数の機能をどう変えるのですか? 質問のmozi関数は、動作がグローバル変数に依存していますが、それらを引数にすると見通しが良くなるように思われます。 同じ関数でも、引数の値を変える事で動作を変えられるように出来ますから。
episteme

2019/11/15 00:25

まずは どこに(位置) と なにを(文字) などを 引数で与えるよう修正するとこからでしょね。
guest

回答3

0

ベストアンサー

C++

1#include <DxLib.h> 2 3class Str { 4 const char *str; 5 int frame; 6 int pos; 7 int count; 8public: 9 Str(const char *str, int frame) 10 : str(str), frame(frame), pos(0), count(0) {} 11 12 void drawString(int x, int y, int color) { 13 if (count == 0 && str[pos]) pos += 1 + IsDBCSLeadByte(str[pos]); 14 if (++count == frame) count = 0; 15 DrawFormatString(x, y, color, "%.*s", pos, str); 16 } 17 18 void reset() { pos = count = 0; } 19}; 20 21int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 22{ 23 SetFontSize(25); //サイズを64に変更 ??? 24 SetFontThickness(10); //太さを8に変更 ??? 25 ChangeFont("MS 明朝"); //種類をMS明朝に変更 26 ChangeFontType(DX_FONTTYPE_ANTIALIASING); //アンチエイリアスフォント 27 28 SetGraphMode(780, 680, 32); // ウィンドウの大きさを指定 29 ChangeWindowMode(TRUE); // 全画面ではなくウインドウを使用 30 if (DxLib_Init() == -1) return -1; // DXライブラリ初期化処理 31 SetDrawScreen(DX_SCREEN_BACK); // 裏画面を使用する設定 32 33 SetWindowSizeChangeEnableFlag(FALSE, FALSE); 34 35 SetGraphMode(780, 680, 32); // 画面サイズは最大の780*680にしておく 36 SetWindowSize(780, 680); // 最初は 640x480 にしておく ??? 37 38 int Green = GetColor(0, 255, 0); 39 40 Str str1("あいうabc", 50); // 6文字を 50フレームごとに 1文字追加 41 // 全部で 300フレーム(5秒) 42 int t = 0; 43 while (!ScreenFlip() && !ProcessMessage() && !ClearDrawScreen()) { 44 str1.drawString(100, 500, Green); 45 if (++t == 60 * 6) { t = 0; str1.reset(); } // 6秒ごとにリセット 46 } 47 48 DxLib_End(); // DXライブラリ終了処理 49 return 0; 50}

C++ のクラスについて十分に学習しましたか?
データメンバ(メンバ変数)、メンバ関数、コンストラクタ、メンバ初期化子リスト、
public などのアクセス指定子などの意味を全部理解していますか?

DxLib は C++ でコードを書くことになっていますが、
C の知識だけで書くこともできます。

クラスの代わりに構造体で書き直してみました。

C++

1#include <DxLib.h> 2 3struct Str { 4 const char *str; 5 int frame; 6 int pos; 7 int count; 8}; 9 10void drawString(struct Str *s, int x, int y, int color) 11{ 12 char c = s->str[s->pos]; 13 if (s->count == 0 && c != '\0') 14 s->pos += IsDBCSLeadByte(c) ? 2 : 1; 15 if (++s->count == s->frame) s->count = 0; 16 DrawFormatString(x, y, color, "%.*s", s->pos, s->str); 17} 18 19int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 20{ 21 SetFontSize(25); //サイズを64に変更 ??? 22 SetFontThickness(10); //太さを8に変更 ??? 23 ChangeFont("MS 明朝"); //種類をMS明朝に変更 24 ChangeFontType(DX_FONTTYPE_ANTIALIASING); //アンチエイリアスフォント 25 26 SetGraphMode(780, 680, 32); // ウィンドウの大きさを指定 27 ChangeWindowMode(TRUE); // 全画面ではなくウインドウを使用 28 if (DxLib_Init() == -1) return -1; // DXライブラリ初期化処理 29 SetDrawScreen(DX_SCREEN_BACK); // 裏画面を使用する設定 30 31 SetWindowSizeChangeEnableFlag(FALSE, FALSE); 32 33 int Green = GetColor(0, 255, 0); 34 35 struct Str str1 = { "あいうabc", 50, 0, 0 }; 36 37 int t = 0; 38 while (!ScreenFlip() && !ProcessMessage() && !ClearDrawScreen()) { 39 drawString(&str1, 100, 500, Green); 40 if (++t == 60 * 6) { t = 0; str1.count = str1.pos = 0; } 41 } 42 43 DxLib_End(); // DXライブラリ終了処理 44 return 0; 45}

C の構造体について十分学習しましたか?
演算子->の意味を理解していますか?

構造体も使わずに書いてほしいと言われたら、あまり良いことでは
ありませんが、グローバル変数を使えばできます。

C++

1#include <DxLib.h> 2 3const char *str; 4int frame; 5int pos; 6int count; 7 8void drawString(int x, int y, int color) 9{ 10 if (count == 0 && str[pos] != '\0') 11 pos += IsDBCSLeadByte(str[pos]) ? 2 : 1; 12 if (++count == frame) count = 0; 13 DrawFormatString(x, y, color, "%.*s", pos, str); 14} 15 16int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 17{ 18 SetFontSize(25); //サイズを64に変更 ??? 19 SetFontThickness(10); //太さを8に変更 ??? 20 ChangeFont("MS 明朝"); //種類をMS明朝に変更 21 ChangeFontType(DX_FONTTYPE_ANTIALIASING); //アンチエイリアスフォント 22 23 SetGraphMode(780, 680, 32); // ウィンドウの大きさを指定 24 ChangeWindowMode(TRUE); // 全画面ではなくウインドウを使用 25 if (DxLib_Init() == -1) return -1; // DXライブラリ初期化処理 26 SetDrawScreen(DX_SCREEN_BACK); // 裏画面を使用する設定 27 28 SetWindowSizeChangeEnableFlag(FALSE, FALSE); 29 30 int Green = GetColor(0, 255, 0); 31 32 str = "あいうabc", frame = 50, pos = count = 0; 33 34 int t = 0; 35 while (!ScreenFlip() && !ProcessMessage() && !ClearDrawScreen()) { 36 drawString(100, 500, Green); 37 if (++t == 60 * 6) { t = 0; pos = count = 0; } 38 } 39 40 DxLib_End(); // DXライブラリ終了処理 41 return 0; 42}

ところで、const char * の意味は理解していますか?

追記
クラスと構造体はあなたの現在の実力では無理です。

複数の文字列を表示する例をグローバルな配列変数で書いてみました。

C++

1#include <DxLib.h> 2 3const char *str[3] = { "あいうabc", "0123456789", "ABCDEFG" }; 4int frame[3] = { 50, 30, 40 }; 5int pos[3]; 6int count[3]; 7 8void drawString(int i, int x, int y, int color) 9{ 10 char c = str[i][pos[i]]; 11 if (count[i] == 0 && c != '\0') 12 pos[i] += IsDBCSLeadByte(c) ? 2 : 1; 13 if (++count[i] == frame[i]) count[i] = 0; 14 DrawFormatString(x, y, color, "%.*s", pos[i], str[i]); 15} 16 17int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) 18{ 19 SetFontSize(25); //サイズを64に変更 ??? 20 SetFontThickness(10); //太さを8に変更 ??? 21 ChangeFont("MS 明朝"); //種類をMS明朝に変更 22 ChangeFontType(DX_FONTTYPE_ANTIALIASING); //アンチエイリアスフォント 23 24 SetGraphMode(780, 680, 32); // ウィンドウの大きさを指定 25 ChangeWindowMode(TRUE); // 全画面ではなくウインドウを使用 26 if (DxLib_Init() == -1) return -1; // DXライブラリ初期化処理 27 SetDrawScreen(DX_SCREEN_BACK); // 裏画面を使用する設定 28 29 SetWindowSizeChangeEnableFlag(FALSE, FALSE); 30 31 int Green = GetColor(0, 255, 0); 32 int Yellow = GetColor(255, 255, 0); 33 int White = GetColor(255, 255, 255); 34 35 int t = 0; 36 while (!ScreenFlip() && !ProcessMessage() && !ClearDrawScreen()) { 37 drawString(0, 100, 500, Green); 38 drawString(1, 100, 530, Yellow); 39 drawString(2, 500, 530, White); 40 if (++t == 6*60) { 41 t = 0; 42 for (int i = 0; i < 3; i++) pos[i] = count[i] = 0; 43 } 44 } 45 46 DxLib_End(); // DXライブラリ終了処理 47 return 0; 48}

分からないところはどこですか?
・frame と pos と count の意味ですか?
・frame と pos と count の関係ですか?
・DrawFortmatString の書式 "%.*s" ですか?

それから、構造体を使ったことはありますか?
ポインタを使ったことはありますか?

キー入力に関する問題は別の質問にしてください。

投稿2019/11/15 03:24

編集2019/11/18 08:26
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

R-ogiura

2019/11/15 03:35

いつもどうもありがとう。 カズマさんのコードを理解した上で使わせて頂きます。
episteme

2019/11/15 04:07

理解できなくてもベストアンサーなのか...
fana

2019/11/15 04:27

> 面倒を省きたい という意味ではベストなアンサーなのでは.(ひどい言い方!)
R-ogiura

2019/11/15 15:29

カズマさん、質問があります。クラスの変数の宣言の部分は理解できました。 class Str { const char* str; int frame; int pos; int count; public: Str(const char* str, int frame) : str(str), frame(frame), pos(0), count(0) {} void drawString(int x, int y, int color) { if (count == 0 && str[pos]) pos += 1 + IsDBCSLeadByte(str[pos]); if (++count == frame) count = 0; DrawFormatString(x, y, color, "%.*s", pos, str); } において、 Str(const char* str, int frame)はフレームと表示される文字を管理する関数ですが、そのあとに続く : str(str), frame(frame), pos(0), count(0) {}はなぜこのように書けて、何を表しているのでしょうか。また if (count == 0 && str[pos]) pos += 1 + IsDBCSLeadByte(str[pos]); の部分はcountが0で文字列の型に入る変数posがある場合の時、posが+1バイトされていくという意味でしょうか? 最後に、if (++count == frame) count = 0;に関して、50フレーム事にcountが0になると思うのですが、countが増えるたびにその値がフレームに代入されてcountが0になるということはわかるのですが、 これがどこに働いているかわかりません。 この部分がフレームが50になったらcountが0になることを表しているのでしょうか。 どうかよろしくお願いいたします。
episteme

2019/11/15 23:10

> Str(const char* str, int frame)はフレームと表示される文字を管理する関数ですが、 違います。コンストラクタです。 > そのあとに続く > : str(str), frame(frame), pos(0), count(0) {}はなぜこのように書けて、何を表しているのでしょうか。 メンバ初期化子です。 https://ja.cppreference.com/w/cpp/language/initializer_list > また > if (count == 0 && str[pos]) pos += 1 + IsDBCSLeadByte(str[pos]); > の部分はcountが0で文字列の型に入る変数posがある場合の時、posが+1バイトされていくという意味でしょうか? "文字列の型に入る変数posがある場合の時" ← 理解不能 > 最後に、if (++count == frame) count = 0;に関して、50フレーム事にcountが0になると思うのです> が、countが増えるたびにその値がフレームに代入されてcountが0になるということはわかるのですが、 "countが増えるたびにその値がフレームに代入されて" ← フレーム(frame)に代入されてはいません > これがどこに働いているかわかりません。 "これ"とは何を指していますか? > この部分がフレームが50になったらcountが0になることを表しているのでしょうか。 "フレームが50になったら" ← フレーム(frame)は変化しません
R-ogiura

2019/11/16 12:29

カズマさんありがとうございます。 const char * すらも理解が危ういのでconst char * の勉強をします。
R-ogiura

2019/11/16 14:40

あのs->pos += IsDBCSLeadByte(c) ? 2 : 1;の部分の ? 2 : 1;ってなぜこのような書き方が出来るのでしょうか?
R-ogiura

2019/11/16 15:17

ありがとうございます。 クラス版と構造体版を解読するのには時間がかかりそうです。
R-ogiura

2019/11/16 18:10

すいません、改めて自分の質問分を読んだらわけのわからないことを言っていたんで編集して質問します。 if (++count == frame) count = 0;に関してなのですが、 countが毎フレーム1ずつ増えてframeと同じ値になったらcount = 0にするという処理だと思いますが、 この処理は何に対してどのように動いているのでしょうか。 もう一つ、DrawFormatString(x, y, color, "%.*s", pos, str);に関して、 変数の中身を表す演算子"%.*s"に対応したのはposだけだと思いますが、なぜ変数strも書いているのでしょうか。
episteme

2019/11/16 21:05 編集

> countが毎フレーム1ずつ増えてframeと同じ値になったらcount = 0にするという処理だと思いますが、 > この処理は何に対してどのように動いているのでしょうか。 書いたとおりです。 count に対して +1する/frameに達したら0に戻す をやっています。 > 変数の中身を表す演算子"%.*s" 演算子ではありません。書式指定子です。 > もう一つ、DrawFormatString(x, y, color, "%.*s", pos, str);に関して、 変数の中身を表す演算子"%.*s"に対応したのはposだけだと思いますが、なぜ変数strも書いているのでしょうか。 その"思う"が正しいか否か、何故調べようとしないのですか? https://docs.microsoft.com/ja-jp/cpp/c-runtime-library/format-specification-syntax-printf-and-wprintf-functions?view=vs-2019#precision-specification
episteme

2019/11/17 01:46 編集

まったくの別件ですけど、 ココでのやりとりを(引用元も明かさず)そのまま他所に持ち込む無礼な奴がいます。 # 後ろめたさはあるらしく ID非公開 ですか... #「僕も知りたい、教えてください」ってココで訊けばいいのに https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q10216338650
R-ogiura

2019/11/17 06:01 編集

知らせて頂きありがとうございます。 同感ですね。せめて一言断ってからコピペすればいいのにと思います。 ただ疑問の解決に繋がる部分もあるので、非公開で気持ち悪いですが、少し助かりますね。
R-ogiura

2019/11/17 06:03

おまえって誰の事ですか? いきなりおまえだなんて無礼な方ですね。
episteme

2019/11/17 06:08

それは失礼しました。 「R-ogiuraさん、あなたにはその一言を発する資格はありません」
R-ogiura

2019/11/17 06:13

あ!そうか、過去に私も同じことをしていたのだった。確かに人のこと言えなかったです。トホホ。 おま...いえ、epistemeさん、すいませんでした。
R-ogiura

2019/11/17 07:24

あの、カズマさん、文字列の最後の文字が表示されたらキーが押せるように書いたのですが if(count==0){ if (Key[KEY_INPUT_A] == 1) { ++talk; } ではcountは定義されていないと表示されてしまい、他の方法を考えたのですが、何か良い方法はないでしょうか? 会話画面で一文字ずつ表示されますが、もう一度同じキーを押すと全体の文章が一気に出るようにしたいと考えました。今のままだとキーを押すと次の会話の文に進むので謝ってキーを押した場合に会話が途切れてしまいます。
R-ogiura

2019/11/17 07:36

あるいは、解決する内容を変えて、 文字全文がでるまでキーを押しても反応しないように作ってみたのですが、 文章が配列から出力された後はcountは0になるので、if文でcountが0の時にキーを押すように書いたのですが、countが定義されていないとエラーでました。他に配列の最後の文字がでたらキーが押せるようにstr[pos]を用いて考えましたが解決できていません。
episteme

2019/11/17 07:54

# Kazuma-sさんへの質問に横槍で申し訳ないけど... Kazuma-sさんのコードが理解できているならそんな質問が発せられるはずがないと考えます。 そもそも「文章が配列から出力された後はcountは0になる」が間違ってるし。
R-ogiura

2019/11/17 08:17 編集

>>Kazuma-sさんのコードが理解できているならそんな質問が発せられるはずがないと考えます。 はい、おっしゃる通り、まだ理解は出来ていません。(完全に理解したと言った覚えはないのですが。) なんにしても、クラスで使われている変数をif文で使いたいです。
episteme

2019/11/17 12:04 編集

> なんにしても、クラスで使われている変数をif文で使いたいです。 であるなら、全部描いたか否かを返してくれるメンバ関数を追加するだけです。 # そのやり方は教本に書いてあります。 また、メンバ変数をpublicに晒すのは"禁じ手"と心得ましょう。 ...あいかわらずバカがパクってんな https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q14216368699
R-ogiura

2019/11/17 17:04 編集

なるほどです。 毎度その人の報告はありがたいですが、いちいちネットストーカーみたいに探して載せなくていいですよ! どこで誰がどのように使っても私は気にしませんから。 そういう他人の質問を探す趣味とかならあまり好きではないので他の質問者を当たってください。部外者の質問を書かれても解決にはならないし正直邪魔です。
episteme

2019/11/17 19:38

重ねて失礼いたしました。 > ただ疑問の解決に繋がる部分もあるので、非公開で気持ち悪いですが、少し助かりますね。 とのことでしたので。
R-ogiura

2019/11/18 01:32

カズマさんに質問なのですが、カズマさんの書いていただいたコードを解読していくうえで DrawFormatString(x, y, color, "%.*s", pos, str);に関してなのですが、 これってクラスのStrの中に書いたポインタのconst char* strにより(constにより固定したアドレスを変数名strと置いた、そのアドレスにStr str1やStr str2のデータが入る)、変数str(*sはポインタの変数を表す)の変数pos(%は変数の値を表す)であるため、str[pos]をポインタを利用した書き方をするため "%.*s", pos, strと書いたのでしょうか?
kazuma-s

2019/11/18 01:48

全く違います。 printf の書式の % と . と * と s の意味を自分で調べてみてください。 このページにこう書いてあるが、これとこれが理解できませんなどと、具体的に質問してください。
R-ogiura

2019/11/18 05:51

ありがとうございます。カズマさん。 https://programming.pc-note.net/cpp/class2.html を参考にクラスとクラスの中に書いた変数posを外部で使えるように読みました(他にもアロー演算子など)。 class Str なのでStr csと書いて、cs.pos;として見たのですが、クラスの中に書いた変数posを外部で使えるようにする方法が理解できませんでした。
fana

2019/11/18 06:07

(危惧した通りの問題山積状態に突入してしまった状態なのかこれは)
R-ogiura

2019/11/18 06:13

はい。そうです。すいません。
episteme

2019/11/18 06:25

「基礎を固めろ」以外の助言が見つからない...
fana

2019/11/18 06:25

話の内容の肝の部分(問題だった事柄への対処方法)さえ理解できれば,それを参考にすればよいのであって,実際に使うコードは自身が知っている文法の範囲で書けばよいのではないかなぁ,という外野の感想. (未知の文法が山積みな他人の書いたコードと過度に付き合わなくてもよいのでは)
fana

2019/11/18 06:33

文章毎に関数をたくさん書くのつらいです →いや,そうじゃなくて,文章毎のデータの側を複数用意すればいいよね この内容だけでもわかればとりあえず十分なのでは. その実現手段の「例」がclassだったりstructだったりを使っているけども,そういったものを扱うのがまだきついのであれば,「データを複数個扱う手段」といえば例えば「配列」があるわけで,それで書けるならそれでOKでしょう.
episteme

2019/11/18 06:40

そのアイデアをコードで表現できない ってことじゃないかとおもわれます。
fana

2019/11/18 08:51

(配列のが追加されてるw)
Zuishin

2019/11/18 08:55

配列がわかるかも微妙ですけどね。
R-ogiura

2019/11/18 17:48

>>「データを複数個扱う手段」といえば例えば「配列」があるわけで,それで書けるならそれでOKでしょう. 配列で作れる発想や作れること自体知りませんでした(;・∀・)
R-ogiura

2019/11/18 21:35

カズマさん返信ありがとうございます。 >>それから、構造体を使ったことはありますか? ポインタを使ったことはありますか? 構造体もポインタも使ったことはありません。 キーの質問は新しく作らせて質問させて頂きます。 あのint frame[3] = { 50, 30, 40 };の部分に関して、この50、30、40、は何を表しているのでしょうか。
Zuishin

2019/11/18 23:52

次の質問を見る限り、i が何を表しているのかもわかっていません。つまり、配列の概念がわかっていません。 ゲームの会話に使うだけなので、同時に複数使うことは考えなくていいんじゃないかと思います。 その他、条件式の中でのインクリメント、三項演算、ループもわかっていません。if も else が混ざるとわからなくなります。インクリメントや代入演算はやめて a = a + 1; のような文にし、条件式は外に出して、演算結果を変数に入れたもので分岐し、while や for はすべて goto に直すと理解できるのではないかと思います。
Zuishin

2019/11/18 23:54

間違えました。理解できる可能性が少しは高くなるのではないかと思います。
Zuishin

2019/11/19 00:00 編集

if (1) や if (TRUE) などもわからないと思います。if (1 == 1) ならわかると思います。
Zuishin

2019/11/19 00:06 編集

私の個人的な印象を述べただけなので、もちろん採用する必要はありません。特に goto を多用したコードなど、carnage0216 さん以外には恐怖でしかありませんし。
episteme

2019/11/19 04:22

足りないのは「こくご」のスキルかも。教本読んでもわからんのなら。理解不能な説明/質問が散見されるし。
R-ogiura

2019/11/19 04:41

debugしてframe[3] = { 50, 30, 40 };の50、30、40は一文字ずつ描画される間隔の最大値であるとわかりました。
guest

0

「文章を(「一文字ずつ」な感じで)描画してぇ…」というとき,

  • 描画したい文字列の内容は何?
  • 描画する位置はどこ?
  • 「一文字ずつ」の描画対象が増えていく速度はどのくらい?
  • 描画する色だのフォントだの… はどうする?
  • この文字列っていつまで描画するの? 未来永劫?
  • ...

等を決める必要がありそう
: すなわち,「文章を描画する機能を持った関数」を作ったならば,その関数にこれらの情報を引数なりで与える必要がありそう

ですよね.
で,これらの情報は描画する文章毎に個別に管理してやる必要がある,と.

なので,

文章ごとにmoziのように新しい関数を書く

のではなくて,「文章毎に上記のような情報を管理する」と考えてはどうでしょうか.
文章毎の情報には,上記に加えて,

  • 「一文字ずつ」に関する現在の進捗状況

も持たせておく必要もありそうです.

で,そういったある種の纏まった情報を扱うには「構造体」というものを使うと便利かもしれませんよ.


例えばこんな雰囲気のものを書くとかですかね.
(動作検証とかも一切してませんけど)

//文章表示用の情報 struct DrawStrContext { //最初に設定しておく要素 char *Str; //描画したい文章(文字列)を指す int Left; //描画座標x int Top; //描画座標y int Color; //描画色 unsigned int nStepForEachChar; //描画する文字を増やす速度的な処理パラメタ. //DrawStringWorkFunc()が更新する情報 // これらは最初は0にしておくこと. unsigned int StepCounter; //進捗状態管理用 unsigned int nWholeStrDrawnStep; //文字列全体が描画された回数(いつまで描画するん?の判定用を想定) }; //文章の表示用関数 void DrawStringWorkFunc( DrawStrContext *pContext ) { //※ここでは,話を簡単にするため,「1文字」とはchar2個分だという想定にしてあります. // 実際にはそこらへんをちゃんとやる必要があるでしょう. //文章の文字数 unsigned int nChar = strlen( pContext->Str ) / 2; //現在,何文字目まで描画すべきか unsigned int nDraw = 1 + ( pContext->StepCounter / std::max( pContext->nStepForEachChar, 1u ) ); if( nDraw>=nChar ) { nDraw = nChar; ++pContext->nWholeStrDrawnStep; } else { ++pContext->StepCounter; } {//nDraw文字目までを描画する int idx = nDraw*2; char Backup = pContext->Str[idx]; pContext->Str[idx] = '\0'; DrawFormatString( pContext->Left, pContext->Top, pContext->Color, "%s", pContext->Str ); pContext->Str[idx] = Backup; } }

投稿2019/11/15 02:18

編集2019/11/15 02:58
fana

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2019/11/15 03:03

C的な範疇で書いたつもりが,うっかり std::max とか書いてる…… (std::max( A,B ) は,AとBのうち大きい方の値になると思って読んでください.)
R-ogiura

2019/11/15 03:38

解答ありがとうございます。 fanaさんのおっしゃる様に(カズマさんのプログラムに関して)構造体を活用することでまとめることが出来ることがわかりました。
fana

2019/11/15 03:58

独り言気味ですが… 前述のように,この回答では意図的にclass等を使うことを避けていました. kazuma-s氏のコードを「理解して」使うのに必要な学習コストが,あなたにとっての新たな問題とならないことを祈るばかりです.
guest

0

面倒なことを関数一発でどうにかしたい、というのは至極正しいアプローチです
延々とコードを書きたくない、なんとか楽ができないか、という欲求があるから技術は進歩するのです。

ということで、

C

1void mozix(char* s) 2{ 3 int k=10; 4 while(s[0] && s[1]){ 5 DrawFormatString(100+k, 500, Green, "%c%c", s[0],s[1]); 6 s+=2; 7 k+=20; 8 } 9} 10

かなりいきあたりばったりのコードですが、
mozix(str);
で実行させてみよう

投稿2019/11/15 00:20

y_waiwai

総合スコア88040

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fana

2019/11/15 02:01

質問者のコードで countcharやi,a,b,c という変数でごちゃごちゃやっているのは,描画される文字数が一定時間ごとに増えるような動作を目指しているのだと思います. そこら辺の要素が入っていないこの関数には利便性は無くないですか?(文字列を描画したいだけなら単にmain()でDrawFormatStringを一発呼べば良いのではないかと)
y_waiwai

2019/11/15 02:07

提示されたコードだけを見て手っ取り早く書いただけのコードです ツッコミどころはたくさんあるので、それをツッコんでくだされば建設的な議論にもなろうかと思います よろしくおねがいします
R-ogiura

2019/11/15 03:36 編集

解答どうもありがとうございます! 載せて頂いたプログラムでも文字の描画が出来ると確認できました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問