ゲームを作りたい!

プログラミングをしているからには、いつかはゲームを作ってみたい。勉強したことを備忘録的に綴るBLOG。

SDL2でMAPEditerを作る 〜第4回 文字入力Windowの作成〜

前回は、マップを作る上で役に立つちょっとした機能の追加を行った。今回は、保存・読込の実装をしたのでその辺りを書いていこうと思ったのだが、保存・読込自体よりファイル名を入力するための文字入力機能を作るほうがパワーを使う結果になったので、今回は文字入力Windowについて、次回で本題の保存・読込について書いていきたいと思う。

文字入力Windowとは?

まず、そもそも文字入力Windowとは一体どのようなものを作ったのかというところなのだが、以下のGIFのような入力Windowを作成した。
f:id:K38:20190314234011g:plain

大文字A〜Z、数字0〜9、アンダーバーが入力できて、バックスペースが使える。最大入力文字数は20文字。

文字入力Window作成

文字入力Windowについては、四角形を作る部分を関数化し白い四角形と黒い四角形を組み合わせてWindowにしている。以下がその関数になる。
引数として、四角形の左上頂点のX座標、Y座標、四角形の縦横、アルファ値、四角形の色(黒か白)を入力する。

int make_box(SDL_Renderer *renderer, int x, int y, int w, int h, int blend, COLOR color) {

    SDL_Rect rectangle;
    SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);

    rectangle.x = x;
    rectangle.y = y;
    rectangle.w = w;
    rectangle.h = h;

    if (color == WHITE) {
        SDL_SetRenderDrawColor(renderer, 255, 255, 255, blend);
    } else if (color == BLACK) {
        SDL_SetRenderDrawColor(renderer, 0, 0, 0, blend);
    }

    SDL_RenderFillRect(renderer, &rectangle);

    return 0;
}

文字入力方法

続いて、文字入力Windowの肝となっている文字入力の部分について書いていこうと思う。
まず、考え方として文字表示部分と文字列作成部分に分けて考えている。

文字表示部分

文字表示部分は、-> 前回選択したマップチップを表示するために作成した表示用Window同様に文字入力用のWindowを作成し、その上に入力文字を文字サイズ分ずらしながら表示していく作りになっている。そのため、文字入力ウィンドウのサイズは20文字+説明分(SAVE?などの文字)の入力に合うように作っている。フォントサイズも固定値とし22 ,11ptで固定している。
よって、1文字入力されれば表示位置を右に11ptずらし1文字削除されれれば表示位置を左に11ptずらすように作っている。また、文字の削除、バックスペースだがこれは文字を消しているわけではなく黒い四角形を文字の上に表示して見えなくする処理を行っている。
更に、入力文字の表示位置が文字入力用Windowより右、つまり、はみ出るようであれば入力できないようにしている。 この制御で最大文字数20文字を実現している。

文字列作成部分

文字列作成部分は、文字列保存用の配列を用意して入力があるたびに文字を格納する。それと、合わせて何文字目の入力か入力文字数も合わせて取得する。なぜ、入力文字数を取得するのかというと、バックスペースが押された時に入力文字数 - 1文字の文字列を作成する必要があるため取得している。バックスペースが押されたタイミングで全体文字数 - 1を取得する方法も取れるのかもしれないが、都度入力文字数を把握している方が文字列作成が容易だったので今回のような作りにした。

以下に、文字列部分を担っている関数を載せる。上記の考えをそのままコードに起こしたつもりだ。

int accept_character_input(SDL_Event e, SDL_Renderer *renderer, TTF_Font *font,
                           char *file_name, int start_pt, int end_pt) {
    char buf[21] = {0};
    int pt = start_pt;
    int file_name_element = 0;

    while(1) {

        if ( SDL_PollEvent(&e) ) {
            if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_ESCAPE) {
                break;
            }

            if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_RETURN) {
                break;
            }

            if (pt <= end_pt) {
                if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_a) {
                    display_character_string(renderer, font, "A", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "a");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_b) {
                    display_character_string(renderer, font, "B", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "b");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_c) {
                    display_character_string(renderer, font, "C", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "c");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_d) {
                    display_character_string(renderer, font, "D", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "d");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_e) {
                    display_character_string(renderer, font, "E", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "e");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_f) {
                    display_character_string(renderer, font, "F", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "f");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_g) {
                    display_character_string(renderer, font, "G", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "g");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_h) {
                    display_character_string(renderer, font, "H", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "h");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_i) {
                    display_character_string(renderer, font, "I", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "i");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_j) {
                    display_character_string(renderer, font, "J", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "j");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_k) {
                    display_character_string(renderer, font, "K", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "k");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_l) {
                    display_character_string(renderer, font, "L", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "l");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_m) {
                    display_character_string(renderer, font, "M", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "m");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_n) {
                    display_character_string(renderer, font, "N", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "n");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_o) {
                    display_character_string(renderer, font, "O", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "o");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_p) {
                    display_character_string(renderer, font, "P", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "p");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_q) {
                    display_character_string(renderer, font, "Q", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "q");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_r) {
                    display_character_string(renderer, font, "R", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "r");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_s) {
                    display_character_string(renderer, font, "S", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "s");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_t) {
                    display_character_string(renderer, font, "T", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "t");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_u) {
                    display_character_string(renderer, font, "U", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "u");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_v) {
                    display_character_string(renderer, font, "V", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "v");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_w) {
                    display_character_string(renderer, font, "W", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "w");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_x) {
                    display_character_string(renderer, font, "X", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "x");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_y) {
                    display_character_string(renderer, font, "Y", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "y");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_z) {
                    display_character_string(renderer, font, "Z", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "z");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_0) {
                    display_character_string(renderer, font, "0", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "0");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_1) {
                    display_character_string(renderer, font, "1", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "1");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_2) {
                    display_character_string(renderer, font, "2", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "2");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_3) {
                    display_character_string(renderer, font, "3", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "3");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_4) {
                    display_character_string(renderer, font, "4", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "4");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_5) {
                    display_character_string(renderer, font, "5", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "5");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_6) {
                    display_character_string(renderer, font, "6", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "6");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_7) {
                    display_character_string(renderer, font, "7", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "7");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_8) {
                    display_character_string(renderer, font, "8", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "8");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_9) {
                    display_character_string(renderer, font, "9", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "9");
                    file_name_element++;
                } else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_SLASH) {
                    display_character_string(renderer, font, "_", pt, 300);
                    pt = pt + 11;
                    strcat(file_name, "_");
                    file_name_element++;
                }
            }

            if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_BACKSPACE) {
                if (start_pt < pt) {
                    make_box(renderer, pt - 11, 301, 11, 22, 255, BLACK);
                    pt = pt - 11;

                    file_name_element--;
                    strncpy(buf, file_name, file_name_element);
                    memset(file_name, '\0', 20);
                    sprintf(file_name, "%s", buf);
                    memset(buf, '\0', 20);
                }
            }
        }

        SDL_RenderPresent(renderer);

    }

    return 0;
}

終わりに

以上が文字入力Windowについての説明となる。文字が入力できることで、ファイル名を指定することが可能になった。次回は、この機能の延長線上にあるファイルの保存・読込について書いていく。全コードは、次回保存・読込の説明を書いたら載せようと思うので次回もお付き合いいただきたい。