相談したことがあります。一文字ずつ文字を描画するようには書けたのですが、
一文字事に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ページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/11/15 00:25
回答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総合スコア8224
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/11/15 03:35
2019/11/15 04:07
2019/11/15 04:27
2019/11/15 15:29
2019/11/15 23:10
2019/11/15 23:36
2019/11/16 12:29
2019/11/16 14:40
2019/11/16 15:12
2019/11/16 15:17
2019/11/16 18:10
2019/11/16 21:05 編集
2019/11/17 01:46 編集
2019/11/17 06:01 編集
2019/11/17 06:01
2019/11/17 06:03
2019/11/17 06:08
2019/11/17 06:13
2019/11/17 07:24
2019/11/17 07:36
2019/11/17 07:54
2019/11/17 08:17 編集
2019/11/17 12:04 編集
2019/11/17 17:04 編集
2019/11/17 19:38
2019/11/18 01:32
2019/11/18 01:48
2019/11/18 05:51
2019/11/18 06:07
2019/11/18 06:13
2019/11/18 06:25
2019/11/18 06:25
2019/11/18 06:33
2019/11/18 06:40
2019/11/18 08:51
2019/11/18 08:55
2019/11/18 17:48
2019/11/18 21:35
2019/11/18 23:52
2019/11/18 23:54
2019/11/19 00:00 編集
2019/11/19 00:06 編集
2019/11/19 04:22
2019/11/19 04:41
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総合スコア11990
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/11/15 03:03
2019/11/15 03:38
2019/11/15 03:58
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
総合スコア88040
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/11/15 02:01
2019/11/15 02:07
2019/11/15 03:36 編集
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。