挫折不可能!初級ゲームプログラミング完全マニュアル  RSSを登録する

「ゲームが作りたいけどプログラミングなんて全然知らない」「文系だし数学や物理が苦手だけどゲームが作れるだろうか?」そんなアナタのためのメールマガジンです。PCの電源を入れてからどうすればいいのか?から自分のゲームが完成するまでを応援します!

最新号をメルマガでお届けします    
登録 解除

規約に同意して

登録した方には、まぐまぐの公式メルマガ(無料)をお届けします。
2008/06/29

初級ゲームプログラミング完全マニュアル [vol.0052 2008/06/29]

┏┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳┓
┣┛                                                              ┗┫
┃       挫折不可能!  初級ゲームプログラミング完全マニュアル       ┃
┃                                                                  ┃
┃                       第 52 号  2008/06/29                       ┃
┣┓                                                              ┏┫
┗┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻┛
                            - Ads space -
┌┬───────────────────────────────┬┐
││ はじめに                                                     ││
└┴───────────────────────────────┴┘

 みなさま、こんにちは!

 個人ゲーム制作アドバイザーの Byerkut です!

 梅雨真っ盛りですね。被災された地方のダム決壊などが心配ですので、

 コンビニなどでおつり募金という形でお手伝いさせていただきましょう。

 四川の復興支援のお礼として義援金も届いているそうですよ。

 さて、今回はまどかを左右に動かします。

┌┬───────────────────────────────┬┐
││本日のラインナップ                                            ││
└┴───────────────────────────────┴┘

  ・今日のメインテーマ
      【地球防衛戦士まどかに命を吹き込む】

  ・あとがき

┌┬───────────────────────────────┬┐
││ みんなの備忘録                                               ││
└┴───────────────────────────────┴┘

  ■Visual C++ 2008 Express Edition をインストールする手順
    http://www.game-create.com/archives/235

  ■Visual C++ 2008 Express Edition でプロジェクトを新規作成する手順
    http://www.game-create.com/archives/270

  ■VC++ 2005 EE でプロジェクトにソースファイルを登録する手順
    http://blog.mag2.com/m/log/0000240151/108824854.html

  ■画像ファイルを LoadImage() 関数で読み込めるようにする手順
    http://www.game-create.com/archives/308

  ■ゲーム用ウィンドウのテンプレート
    http://www.game-create.com/menu/downloads

  ■ビットマップ学習用クラス - Study::Bitmap
    http://www.game-create.com/menu/downloads

┏┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳┓
┃┃                                                              ┃┃
┃┃                      今日のメインテーマ                      ┃┃
┃┃                                                              ┃┃
┃┃             【地球防衛戦士まどかに命を吹き込む】             ┃┃
┃┃                                                              ┃┃
┗┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻┛

 今月、時間をたっぷり使って、ソースファイルを追加する意味や、

 関数を増やす意味や、画面にグラフィックを表示するために、

 引数などを通じてデバイスコンテキストなどの情報を関数と関数の間で

 やりとりする方法について学んできました。

 今日は6月の最終週ですので、一連の基礎シリーズ最終段階である

 「キャラクターに命を吹き込む」部分を見ていきましょう。



 何をするのかというと、今制作している「地球防衛ゲーム」の

 プレイヤーキャラクターである「まどか」を、

 カーソルキーの左右で動かせるようにします。

 今回はソースファイルを使って説明しますので、

 以前配布したサンプルをダウンロードください。

    http://www.game-create.com/archives/386

 ダウンロードできたら解凍してみてください。実行してもかまいません。



 見ていただきたいのは player.cpp と player.h になります。

 多少の違いはありますが、前回、前々回、その前の内容で扱ってきた

 ソースコードと同じようになっていると思います。

 違うのは今回お話しする「プレイヤーを動かす」部分になります。



 さて、本題です。

 プレイヤーを動かすためにはどうしたらいいのでしょうか?



 プレイヤーを動かすためには変数を使います。

 実は、コンピュータでソフトを作る場合、今回の「地球防衛ゲーム」の

 プレイヤーキャラクターのように、左右に動いたりするなど、

 何か変化や動きがあるものを作るためには変数を使わなければなりません。

 変数しか方法がないのです。覚えておいてください。



  動くものや変化するものは変数で作ります!



 しかし、ここで注意点があります。変数と言ってもただの変数を使って

 プレイヤーを作ってはいけません。なぜかというとただの変数は

 「単一の数値」しか扱えない(記憶できない)からです。

 変数の基礎知識については当ブログの記事を参照ください。

    http://www.game-create.com/archives/60
    http://www.game-create.com/archives/92
    http://www.game-create.com/archives/91

 「なんでひとつの数値しか扱えないのが問題なの?」と思われた方は

 初心者の方か、そうとう腕のあるプログラマーかのどちらかです。

 このメルマガは初心者の方のメルマガですので、そのつもりで解説します。



 まず、身体測定を想像してください。

 身体測定をするときに、記録用紙を持ち歩いて、

 身長を測定する場所や体重を測定する場所など、保健室の中を歩き回って、

 記録を取ってもらった経験のある人がほとんどだと思いますが、

 その記録用紙こそ今回の目的とするものなのです。

 どいういうことかといいますと、「ただの変数を使う」というのは、

 1枚の用紙に「身長だけしか記録できない」のと同じなのです。

 身体測定は身長だけ記録できれば問題ありませんか?

 そうではありませんよね。体重や座高やローレル指数(死語)などが

 必要です(ちなみに今ローレル指数ってなんていうんでしたっけ?)。

 1枚の用紙には「身長だけしか記録できない」のですから、

 身体測定するためには体重・座高・ローレル指数を記録するために

 合計で4枚の用紙を持ちながら保健室の中をまわらなくてはなりません。

 これは面倒だと思いませんか? 面倒でなくても事故が起こります。

 たとえば「体重を書く用紙を1枚紛失してしまった」とか。

 4枚もの紙を持ち歩くと普通に生活していても問題に遭遇しやすいのに

 プログラムとなったらさらに大変です。

 原因不明のバグが取れなくて徹夜したなどという悲劇が生まれます。



 では、どうしたら良いのでしょうか?



 その答えも身体測定にあります。

 身体測定の用紙には表のようなイメージで、身長・体重・座高などを

 記録するための「記録欄」が区切られていますよね?

 だから1枚の用紙でいろいろな数値を記録できるのです。

 プログラムの場合も同じです。ひとつの変数に「記録欄」を区切れば

 良いのです。プログラムでひとつの変数に「記録欄」を区切るためには、

 「構造体」を使います。構造体と聞くと難しそうですが、

 「健康診断の記録用紙」と想像すれば簡単だと思います。



 では player.h を見てください。実はそこにプレイヤーの記録用紙である

 構造体があります。

  ------------------------------------------------------------------
  player.h
  ------------------------------------------------------------------
    typedef struct {
      int           life;
      int           x;
      int           y;
      int           width;
      int           height;
      Study::Bitmap graphic;
    } Player, *lpPlayer;
  ------------------------------------------------------------------

 これが構造体です。見方を説明します。

  ------------------------------------------------------------------
  player.h
  ------------------------------------------------------------------
    typedef struct {
      int           life;    ← life の記録欄
      int           x;       ← x の記録欄
      int           y;       ← y の記録欄
      int           width;   ← width の記録欄
      int           height;  ← height の記録欄
      Study::Bitmap graphic; ← graphic の記録欄
    } Player, *lpPlayer;
      ~~~~~~  ~~~~~~~~~ ←この記録用紙の名前
  ------------------------------------------------------------------

 なるほど、 Player という名前の記録用紙を作っていたのですね。

 プレイヤーを動かすための記録用紙なのですから Player 。

 わかりやすくて良いですね。その中には life, x, y, width, height,

 graphic と6つの記録欄があることがわかります。

 typedef struct というのは構造体を作るための決まり文句です。

 深く考えずに覚えてしまいましょう。

 しかし、これは「記録用紙の形式」を決めているだけです。

 実際に「記録用紙を使っている」のが player.cpp になります。

  ------------------------------------------------------------------
  player.cpp (抜粋)
  ------------------------------------------------------------------
    static Player player;
    ~~~~~~~~~~~~~~~~~~~~~ ←記録用紙を作っている

    void InitializePlayer(HWND hWindow, HDC hBackBuffer)
    {
      player.graphic.load(hBackBuffer, TEXT("player.bmp"), RGB(255, 0, 255));
      player.life   = 100;
      player.width  = PLAYER_CHIP_WIDTH;
      player.height = PLAYER_CHIP_HEIGHT;
      player.x      = (PLAYER_SCREEN_WIDTH - player.width) / 2;
      player.y      = PLAYER_SCREEN_HEIGHT - player.height;
      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      ↑記録用紙に記入している(代入してデータを保存している)
    }

    (↓後ろは省略します)
  ------------------------------------------------------------------

 さきほど作った Player という用紙を player という名前で作っていて、

 その player の記入欄にデータを保存しているところです。

 「 Player と player って同じ名前じゃないか!」と思われるかも

 しれませんが、先頭が大文字と小文字の違いがあります。

 Player は「記入用紙の形式」のことで、

 player は「記入用紙」を表しています。

 わかりづらいかもしれませんが、このあたりは経験を積むことで

 慣れていきますので安心してください。



 さぁ、基礎的な話が終わりましたので、早速プレイヤーを動かす処理を

 見ていきましょう。プレイヤーを動かしているのは player.cpp の

 UpdatePlayer() という関数です。

  ------------------------------------------------------------------
  player.cpp
  ------------------------------------------------------------------
    void UpdatePlayer(HWND hWindow, HDC hBackBuffer)
    {
      if (GetAsyncKeyState(VK_LEFT) & 0x8000) {
        player.x -= PLAYER_MOVE_SPEED;
      } else if (GetAsyncKeyState(VK_RIGHT) & 0x8000) {
        player.x += PLAYER_MOVE_SPEED;
      }
    
      if (player.x < PLAYER_SCREEN_LEFT) {
        player.x = PLAYER_SCREEN_LEFT;
      }
      if ((PLAYER_SCREEN_WIDTH - PLAYER_CHIP_WIDTH) < player.x) {
        player.x = PLAYER_SCREEN_WIDTH - PLAYER_CHIP_WIDTH;
      }
    }
  ------------------------------------------------------------------

 重要なのはこの部分です。

  ------------------------------------------------------------------
      if (GetAsyncKeyState(VK_LEFT) & 0x8000) {
        player.x -= PLAYER_MOVE_SPEED;
      } else if (GetAsyncKeyState(VK_RIGHT) & 0x8000) {
        player.x += PLAYER_MOVE_SPEED;
      }
  ------------------------------------------------------------------

 ここでは GetAsyncKeyState() 関数を使って、

 「今、どのキーが押されているか?」を判定し、

 キーが押されている方向にプレイヤーを動かしています。

 GetAsyncKeyState() 関数については当ブログの記事を参照ください。

    http://www.game-create.com/archives/307

 つまり、こういうことです。

  ------------------------------------------------------------------
      if (【左キーが押されていたら↓】) {
        player.x -= PLAYER_MOVE_SPEED;
      } else if (【そうじゃなくて、右キーが押されていたら↓】) {
        player.x += PLAYER_MOVE_SPEED;
      }
  ------------------------------------------------------------------

 カーソルキーの左が押されていたら player.x から PLAYER_MOVE_SPEED を

 引いて、右が押されていたら player.y に PLAYER_MOVE_SPEED を足します。

 PLAYER_MOVE_SPEED ってなんだよ?と思われますよね。

 PLAYER_MOVE_SPEED はプレイヤーが動く速度のことで、

 player.h にその正体が隠されています。

  ------------------------------------------------------------------
  player.h
  ------------------------------------------------------------------
    #define PLAYER_SCREEN_LEFT   0
    #define PLAYER_SCREEN_TOP    0
    #define PLAYER_SCREEN_WIDTH  640
    #define PLAYER_SCREEN_HEIGHT 480
    #define PLAYER_CHIP_WIDTH    48
    #define PLAYER_CHIP_HEIGHT   64
    #define PLAYER_MOVE_SPEED    4     ←正体は4という数値
  ------------------------------------------------------------------

 つまりこういうことです。

  ------------------------------------------------------------------
      if (【左キーが押されていたら↓】) {
        player.x -= 4;
      } else if (【そうじゃなくて、右キーが押されていたら↓】) {
        player.x += 4;
      }
  ------------------------------------------------------------------

 つまり player.x の数値を、カーソルキーが押された方向に 4 ドットずつ

 動かしていたというわけです。「 player.x の値を増減するだけで

 プレイヤーが動かせるのか!」と驚かれた方は次をご覧ください。

  ------------------------------------------------------------------
  player.cpp
  ------------------------------------------------------------------
    void DrawPlayer(HWND hWindow, HDC hBackBuffer)
    {
      BitBlt(hBackBuffer, player.x, player.y, player.width, player.height,
                          ~~~~~~~~  ← 注目
             player.graphic.getMask(), 0, 0, SRCAND);
      BitBlt(hBackBuffer, player.x, player.y, player.width, player.height,
                          ~~~~~~~~  ← 注目
             player.graphic.getBitmap(), 0, 0, SRCPAINT);
    }
  ------------------------------------------------------------------

 この DrawPlayer() 関数はプレイヤーを描画する処理です。

 つまり、 player という記録用紙の x という記録欄にある数値を見て

 その数値が示す画面のX座標にグラフィックを表示しているというわけです。

 結局、値を増減するだけではキャラクターは動きません。

 その値を参考にして自分でキャラクターを動かすのです。

 プログラミングするとはこういうことです。



 さて、これで見事プレイヤーを動かすことができるようになりました。

 今月は基礎的な話になってしまいましたが、来週からはいよいよ

 ゲーム制作のキモの部分に入っていきたいと思います。

 まずは「プレイヤーが弾を撃てる」ようにしてみましょう。



 今回も最後まで読んでいただきましてありがとうございます!

 それでは!

                                                            Byerkut.

┌┬───────────────────────────────┬┐
││ 重要記事のダイジェスト                                       ││
└┴───────────────────────────────┴┘

  ■C++ は計算と記憶しかできない
  ■外部の機能(関数)を借り受けるには #include を使う
  ■#include で借り受けた機能を使うには関数を呼び出す
    http://archive.mag2.com/0000240151/20080203171350000.html

  ■Windows プログラムには必ず WinMain() 関数から開始する
    http://archive.mag2.com/0000240151/20080209215231000.html

  ■プログラムは関数の集まり
  ■プログラムは関数を増やしてソフトウェアを作る
  ■関数には次の要素がある(名前・機能・引数・戻り値)
    http://archive.mag2.com/0000240151/20080216090000000.html
  ■関数を作には次の要素を決める(名前・機能・引数・戻り値)
    http://archive.mag2.com/0000240151/20080608200909000.html

  ■プログラムはソースコードを分散させて大きなソフトを作る
    http://archive.mag2.com/0000240151/20080525121425000.html
    http://archive.mag2.com/0000240151/20080531212858000.html

  ■ゲームを作るためには「入力」「出力」「条件分岐」が必要
    http://archive.mag2.com/0000240151/20080301221623000.html

  ■画像ファイルの絵を画面に表示する際にはメモリに読み込む
   http://archive.mag2.com/0000240151/20080406202024000.html

  ■LoadImage() 関数はコピペで使い回せる
  ■LoadImage() 関数の第2引数は
    メモリに読み込みたい画像ファイルの名前を渡す
  ■LoadImage() 関数で読み込むファイルは
    プロジェクトディレクトリにおいてある必要がある
    http://archive.mag2.com/0000240151/20080413174135000.html

┌┬─────┬─────────────────────────┬┐
││ あとがき │  発行者のつぶやきです                            ││
└┴─────┴─────────────────────────┴┘

 先日、私が執筆した本が発売されて、有志のコミュニティに

 参加してきたのですが、結構「本買いましたよ!」と言ってくださる方が

 いてうれしく思いました。次回作はゲームでがんばりたいです。

┌┬───────────────────────────────┬┐
├┘                                                              └┤
│  購読の解除はこちら↓                                            │
│  http://www.game-create.com/contents/gp_beginners_ml             │
├┐                                                              ┌┤
└┴───────────────────────────────┴┘
                            - Ads space -
┌┬───────────────────────────────┬┐
├┘                                                              └┤
│ 「挫折不可能!初級ゲームプログラミング完全マニュアル」は、       │
│ 「いちばんやさしいゲームの作り方」が運営しています。             │
│                                                                  │
│  サイト     : http://www.game-create.com/                        │
│  発行元     : http://www.game-create.com/menu/about              │
│  発行者     : http://www.game-create.com/menu/profile            │
│  問い合わせ : http://www.game-create.com/menu/contact            │
│  利用規約   : http://www.game-create.com/informations/agreement  │
├┐                                                              ┌┤
└┴───────────────────────────────┴┘
                 POWERED BY LIBERTIASTER GAME STYLE.
最新号をメルマガでお届け
登録 解除

規約に同意して

登録した方には、まぐまぐの公式メルマガ(無料)をお届けします。

最近の記事

上へ戻る