SDL2でC++でテトリスを作る練習してみた

 久しぶりにプログラミングしてみた。
 YouTubeを見てると、「テトリスを作ってみた」というのが沢山あって、なんか、燃えてくるわけだ。

 が

 

● 小一時間どころか

 6時間ぐらいかかった。

 

● しかも

 「次に降ってくるやつ」が表示されてないし、GAME OVERもない。恥と外聞もない。

● で、

 今回色々引っかかったので、メモしておく。

 

● 引っかかったのは下記
  (1)SDL_CreateWindow()でウインドウが表示されない
     前はCreateした後にSDL_Delay(3000);とかで表示されてたのに・・・

  (2)memcpy()ではsizeof()×カウント数を使う
     int配列を1バイトずつ数えないために

  (3)g++でSDL2リンク時「undefined reference to ‘SDL_Init’」になる
     linuxで動かそうとしたら、リンクエラーになり詰まった。ライブラリ指定位置をコマンドラインで変えたら、動く。

  (4)矩形領域のコピー処理
     そりゃそうだ、というバグ。結局、力技でなんとかする。

 

(1)SDL_CreateWindow()でウインドウが表示されない

 昔(4年前:「macでSDL2.0とC++でゲーム画面を表示」)は、

  SDL_CreateWindow(..., SDL_WINDOW_SHOWN);
   :
  SDL_Delay(5000);

 みたくやれば、ウインドウが表示されて、5秒待ってプログラムが終了って動いたはず。

 

● 結論

 stack over flowによると、

  SDL_PollEvent();

 しないと表示されないよ。とのこと。ウハー

 確かに表示された。
 めちゃビビった。

 

● 教えてくれたのは

やはりstack over flowだった。


>ステムにイベントループ処理を走らせる処理を入れる必要がある
>簡単なのは、ループで待つ代わりに、イベントをpoolする処理を書いとくやり方:

 とのこと。
 Toadさんありがとう。

 

● (2)memcpy()ではsizeof()×カウント数を使う

  int myshape[4][16] = {
    // テトリミノの形の定義ズ
    :
    :
  };
  memcpy(this->shape, myshape, 4*16); // bug!

 これでテトリス表示させたら、テトリミノの形がバグるバグる。
 正しくは

  memcpy(this->shape, myshape, sizeof(int)*4*16); // correct

 初心者でした。

 

● どこかのサイトか本かで

 「Cのポインタ演算は、必ずしもアセンブリでのアドレスと対応しない」というような話を聞いたのを思い出した。

  char a[10];
  int  i[10];
  
  char *pa = a;
  int  *pi = i;
  
  pa++;   // アドレスは1ずつ増加する
  pi++;   // アドレスは2ずつとか4ずつとか、分からんけど1ずつは増加しない

 ということだった。

 

● とにかく

 memcpy()のときは、sizeof()の存在を思い出すようにしようと思った。
 初心者でした。

 

(3)g++でSDL2リンク時「undefined reference to ‘SDL_Init’」になる

 linuxでコンパイルし直そうとしてハマった。
 下記だとエラーになる。

g++ -o executable -lSDL2 aaa.cpp bbb.cpp

 例えば

undefined reference to `SDL_Init'`

 みたいな。
 正しくは

g++ -o executable aaa.cpp bbb.cpp -lSDL2

 みたいに「-lSDL2」を行末に持ってくる。

 

● どこで知ったかってぇ?

 これもまたstack over flow
 世界の殆どの答えがここにある。

>inputのパラメータの順番を変えてみて
>これ前に自分もつまづいた(linuxで)
>これだとエラーが出る

g++ --libs sdl2 sdltest.cpp

>これだと大丈夫

g++ sdltest.cpp --libs sdl2

>inputの引数の順序を変えたらうまくいった。SDL2main(.cpp)をSDL(ライブラリ)より前に置いた

 みたい。4年前の方々ありがとうございます。

 

● (4)矩形領域のコピー処理

 25年ぶり3度めの出場だ。
 学生の頃「?」ってなった話。

 こういうのを、ちょい右下に重なる位置に矩形コピーする処理を書いたときの話。
 → 

 もとの矩形の左上から、1段ずつ赤い囲みの中にコピーしていくと、
 すでに1番上の行が、コピー元の情報を壊してる。

 で、こうなって

 なぞのコピー結果に。

 

● 解決策

 たぶん、どう重なるかで左上→右下のコピーする向きを変えるとうまくいきそう(4種類?)。
 なんだけど、

 

● バグりそうなので

 同サイズのバッファを使って、2回コピー。
 25年前には考えられない富豪的プログラミングでいくことにした。

 →  →  → 

 こんな感じ。