SDLのプレイ-簡単

確かに、誰もが何らかの種類のグラフィックゲームまたはプログラムを作成するというアイデアを持っていました。 しかし、プログラミングのグラフィックスを習得する時間や欲求が常にあるとは限りません。 この記事が、シンプルだが非常に面白いゲームの書き方(または単に書き方)の学習に役立つことを願っています。

完成したプロジェクト





あまり知られていないFlood-Itになります。 アイデアは非常に簡単です。

左上の正方形に隣接する同じ色の部分のみをペイントできるという事実にもかかわらず、フィールド全体を1色で塗りつぶす必要があります。



初期化





各SDLプログラムは、非常に重要なことから始める必要があります-必要なサブシステムの初期化と基本パラメーターの設定。 この例では、ビデオを初期化するだけです。

このプロセスは、SDL_Initコマンドを使用して行われます

1つまたは別の部分を担当する定数(論理「or」で区切られた)をパラメーターとして受け取ります。 したがって、ビデオサブシステムの場合、次のように記述する必要があります。

SDL_Init(SDL_INIT_VIDEO)
      
      









他のシステムが必要な場合は、次のリストを使用できます。







ああ、ここですべてがとても簡単だったら。 実際、これは常に成功するとは限らず、失敗した場合はクラッシュする必要があります。 このためには、SDL_Initによって返される値を監視する必要があります。失敗した場合は、常に負の数が返されます。



 if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { printf( "Unable to init SDL"); return 1; }
      
      









あまり有益ではありません。 ユーザー(および私たち)が問題の原因を知るのに役立ちます。 SDL_GetError()は常に問題のテキストを返します。 この関数を使用して、エラーメッセージをより快適にします。



 if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { printf( "Unable to init SDL: %s", SDL_GetError()); return 1; }
      
      







表面





さて、作成を開始する準備ができたので、これがどのように起こるかを理解する必要があります。 画像はサーフェス(サーフェス)に保存され、これを使用して、重なり、描画など、多くの便利なことができます。

画面に表示される部分にも表面が必要です。 このサーフェスを定義することは難しくありません。これには、サイズを設定するコマンドSDL_SetVideoModeがあります。

この表面(したがってプログラム画面)、色ごとのビット数、およびハードウェア/ソフトウェアアクセラレーションなどを含むあらゆる種類の重要なパラメーター。



このサーフェスにバッファを追加する便利なパラメーターSDL_DOUBLEBUFもあります。 すべてのアクションは、必要な瞬間まで画面に表示されません。 これにより、プログラムの速度が向上します(要求はまったくありませんが、より快適で洗練されています)。



したがって、次のようにサーフェスを作成します



 SDL_Surface * screen = SDL_SetVideoMode(550, 420, 16, SDL_HWSURFACE | SDL_DOUBLEBUF); /// 550x420 —     .    16-.     -  SDL_HWSURFACE //     ,   SDL_SWSURFACE( )
      
      









繰り返しますが、望ましい結果が得られない場合があります。 表面がなければエラーメッセージを再度表示し、実行を終了します。



 If (!screen) { printf("Can't set videomode: %s", SDL_GetError()); return 1; }
      
      









画像





考えられるすべての問題を考慮したので、悪いことは何も起こらないはずです。

14x14の競技場は、6色のブロックで構成されます。 各ブロックは、単なる写真にすぎません。 イライラしますが、SDLはBMP形式のイメージでのみ機能します。 ただし、この問題はSDL_Imageライブラリを接続することで解決しますが、この例では膨大な量の画像がなく、BMPで十分です。

同様の方法で画像を表面にアップロードできます:



 int InitImages() { for (int i = 0; i < 6; i++) //    6  { char path[20]; for (int j = 0; j < 20; j++) path[j] = 0; sprintf(path, "Block%d.bmp", i); block[i] = SDL_LoadBMP(path); //  BMP     block[i] if (!block[i]) return -1; } return 1; }
      
      









また、イメージのロードプロセス中に何か問題が発生した場合、負の値が返されます(そして、何をすべきかがわかります)。

ロード後の画像は、すでにわかっているタイプ-表面によって表示されます。 したがって、ブロックサーフェスの配列にブロックを格納します。 競技場をもたらすものはすべて揃っているようです。 1つを除いて...画像のあるサーフェス、スクリーンサーフェスがありますが、別のサーフェス(またはパーツ)をスクリーンに転送する方法はありますか?



これらの目的のために、SDL_BlitSurfaceがあります。これは、座標x1、y1、寸法w、hのある表面からx2、y2の代わりに別の表面に長方形を書き換えることができます。 どういうわけか、多くのパラメータ、さらに座標は素数で送信されません。 画面の表面にすべてを表示するだけなので、小さな手順を書きます



 void DrawImage(SDL_Surface * img, int x, int y, int w, int h, int sx, int sy) { SDL_Rect desc; // ,    . desc.x = x; desc.y = y; SDL_Rect src; //  . src.x = sx; src.y = sy; src.w = w; src.h = h; SDL_BlitSurface(img, &src, screen, &desc); }
      
      









渡されたパラメーターを分析しましょう:

img-表面、追加する部分。 X、Yは表示する座標です。 SX、SY、W、H-表示された長方形のパラメーター(角度座標とサイズ)。 送信された値の魔法は、X、Y、W、Hの4つの値を持つSDL_Rectタイプで座標を設定する必要があることです。新しいタイプで座標を設定した後、オーバーラップが実行されます。



ここで、最も重要なこととして、競技場を作成します。 0から5(色を示す)の乱数でマップを埋めるGenMapフィールド生成プロシージャを作成してみましょう。



 void GenMap() { for (int i = 0; i < maps; i++) for (int j = 0; j < maps; j++) map[i][j] = rand() % 6; }
      
      









ブロックの座標に従って適切な場所に画像を表示する別の手順を追加します(ブロックX、Yの場合、ブロックは30 * X、30 * Y、30 *(X + 1)、30 *(Y + 1)の長方形になります。 30x30ピクセル)。



 void DrawBlock(int x, int y) { DrawImage(block[map[x][y]], 30 * x, 30 * y, 30, 30, 0, 0); //    30*x, 30*y  30x30 }
      
      









同時に、フィールド全体を作成します



 void DrawMap() { for (int i = 0; i < maps; i++) // maps(map size) —   . for (int j = 0; j < maps; j++) DrawBlock(i, j); }
      
      









何が起こったかをチェックする時間。 フィールドを生成し、推測し、...何もありません! どうして? それはすべて正しいようですが、...画面バッファ、表示することを忘れないでください。 簡単にできます



  GenMap(); DrawMap(); SDL_Flip(screen);
      
      









画面で目的のアクションを実行するのはSDL_Flipです。 そして今、あなたは結果を見ることができます:

結果



すべてがうまくいきます

これは、おそらく、この記事で説明する価値があります。 ここに続きます



All Articles