2008/08/23
初級ゲームプログラミング完全マニュアル [vol.0060 2008/08/23]
┏┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳┓
┣┛ ┗┫
┃ 挫折不可能! 初級ゲームプログラミング完全マニュアル ┃
┃ ┃
┃ 第 60 号 2008/08/23 ┃
┣┓ ┏┫
┗┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻┛
- Ads space -
┌┬───────────────────────────────┬┐
││ はじめに ││
└┴───────────────────────────────┴┘
みなさま、こんにちは!
個人ゲーム制作アドバイザーの Byerkut です!
先日まで暑い暑いと騒いでいたのに、今日はしとしと雨降りで、
肌寒ささえ感じます。耐えきれず3時頃に起きてメルマガを書いてます。
燃えたぎるゲームプログラミングの魂で体を温めようという、
熱き心のなせる技なのかもしれません(意味不明)。
さて、今日は地球防衛ゲームのゲームオーバーです。
┌┬───────────────────────────────┬┐
││本日のラインナップ ││
└┴───────────────────────────────┴┘
・今日のメインテーマ
【地球最後の日】
・あとがき
┌┬───────────────────────────────┬┐
││ みんなの備忘録 ││
└┴───────────────────────────────┴┘
■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
┏┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳┓
┃┃ ┃┃
┃┃ 今日のメインテーマ ┃┃
┃┃ ┃┃
┃┃ 【地球最後の日】 ┃┃
┃┃ ┃┃
┗┻━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┻┛
前回までのメルマガで、ゲームはたくさんの画面から成り立っており
その画面を「シーン」と呼ぶことを学びました。
今回は当初の目的であった「ゲームオーバー画面」を実装してみます。
まずは、サンプルをダウンロードして動きを確認してください。
http://www.game-create.com/archives/632
どこが変わったのかわかるようにするために、
一度わざと敵を3回攻め込ませてゲームオーバーになってください。
エフェクトの使い回しですが大爆発によって陣地が崩壊します。
(よく見ると左上に「地球防衛失敗」と書いてあったりして…)
これを作るためにはどうすればいいのかが今回のテーマです。
では、ソースファイルを見てください。
まず、前回までのサンプルと違うのは、「敵に3回攻め込まれたら
ゲームオーバーになる」という仕様が追加されたことです。
この「〜たら」と来たら if 文を想像してください。
ゲームにおいて「分岐」は重要な要素です。
では、この分岐はどこにあるのでしょうか?
答えは player.cpp の中です。
------------------------------------------------------------------
player.cpp
------------------------------------------------------------------
if (player.life <= 0) {
currentScene = GameOver;
}
------------------------------------------------------------------
ここは「プレイヤーのライフが0以下になったら currentScene を
GameOver にする」というわけです。プレイヤーのライフは
わかりますよね?問題は currentScene と GameOver です。
実は currentScene は今回の更新で追加された、
「現在のはどのシーンか?」を保持する変数なのです。
宣言は scene.cpp にありますのでご確認ください。
------------------------------------------------------------------
scene.cpp
------------------------------------------------------------------
#include "scene.h"
bool wantInitialize = false;
Scene currentScene = Main; // ←ここ
------------------------------------------------------------------
(おや?初期値は Main のようですね)
そして GameOver というのは currentScene の取りうる値です。
scene.h に定義してあります。
------------------------------------------------------------------
scene.h
------------------------------------------------------------------
typedef enum enumTagSchene {
Opening, // ←オープニング画面
Main, // ←ゲーム画面
GameOver, // ←ゲームオーバー画面
Ending, // ←エンディング画面
} Scene;
------------------------------------------------------------------
どうやらそろそろカラクリがわかってきました。
そうなのです currentScene 変数の中身を変えるとシーンが変わるのです。
今回は currentScene が Main の場合はゲーム画面。
GameOver の場合はゲームオーバー画面になりますので、
currentScene の中身が Main の時に GameOver に変更すれば、
「敵にやられたときにゲームオーバーにする」という動作を
実現することができるのです。
すべてを解き明かしているのが template.cpp です。
開いてみましょう。
------------------------------------------------------------------
template.cpp
------------------------------------------------------------------
void UpdateGame(HWND hWindow, HDC hBackBuffer)
{
if (wantInitialize) {
FinalizeGame(hWindow, hBackBuffer);
InitializeGame(hWindow, hBackBuffer);
}
if (currentScene == Opening) {
// オープニング
} else if (currentScene == Main) {
// ゲームのメイン
UpdateBackground(hWindow, hBackBuffer);
UpdatePlayer(hWindow, hBackBuffer);
UpdatePlayerBullets(hWindow, hBackBuffer);
UpdateEnemiesController(hWindow, hBackBuffer);
UpdateEffectsController(hWindow, hBackBuffer);
CheckCollisionPlayerBulletsAndEnemies(GetPlayerBullets(), GetEnemies());
} else if (currentScene == GameOver) {
// ゲームオーバー
UpdateBackground(hWindow, hBackBuffer);
UpdateEffectsController(hWindow, hBackBuffer);
UpdateGameOver(hWindow, hBackBuffer);
} else if (currentScene == Ending) {
// エンディング
}
}
------------------------------------------------------------------
「あ、これどこかで見たことがある」と思われた方、正解です。
これは先週のメルマガの具体的な実装例です。
currentScene 変数の中身を判断して適切に関数を呼び分けています。
これで currentScene の内容を変えるとゲーム画面が変わる理由が
ご理解いただけたかと思います。他でもないメインのプログラムである
template.cpp が、画面ごとに呼び出す処理を適切に振り分けていた
というわけです。
さて、これでゲーム画面を増やすことができるようになりました。
しかし、今回は初めて出てくる考え方がありますので、ご照会します。
まず、考えていただきたいのは、今回の currentScene 変数が、
player.cpp の中や template.cpp の中から参照されているということです。
currentScene という変数は scene.cpp で宣言されているのですが、
変数は一カ所で宣言すればどのファイルからでも使えるのでしょうか?
答えは No です。
scene.cpp で宣言した変数は scene.cpp の中でしか使えません。
では、なぜ今回 player.cpp や template.cpp の中から
currentScene 変数を使うことができるのでしょうか?
その答えを知るために player.cpp の冒頭を見てください。
------------------------------------------------------------------
player.cpp
------------------------------------------------------------------
extern Scene currentScene;
~~~~~~
------------------------------------------------------------------
extern ??? 何ですか、このいかにもな英単語は?
( external = 外部の〜)
そうです、実は extern とつけて変数を宣言することで、
他人のファイルの変数を見ることができるのです。
(ただし、他人のファイルの関数の中の変数は見れません)
これは C/C++ の言語仕様ですので覚えておきましょう。
関連する解説が当サイトのブログにありますので参照ください。
http://www.game-create.com/archives/60
さて、シューティングゲームサンプルの頃には解説できなかった部分も
解説ができるようになりました。これもメルマガ 60 回目のなせる技、
そして、みなさまのレベルアップのたまものと言えるでしょう。
来週はいよいよ大詰めの地球防衛ゲーム…
ボスキャラの登場ですッッッッッ!!!
期待してお待ちください。
今回も最後まで読んでいただきましてありがとうございます!
それでは!
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
┌┬─────┬─────────────────────────┬┐
││ あとがき │ 発行者のつぶやきです ││
└┴─────┴─────────────────────────┴┘
最近、オープンソースのライブラリが熱いです。
SQLite, POSH, Boost, Lua, OGRE 3D などなど…
大きなゲームを作るハードルはどんどん低くなっています。
昔は、ゲームのライブラリは自作するものでしたが、
最近では必ずしもそうとは限らないのかもしれません。
次はマルチメディア系のライブラリで何か良いものを探してみます。
┌┬───────────────────────────────┬┐
├┘ └┤
│ 購読の解除はこちら↓ │
│ 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.


