ゲームプログラミング解説の第二段スタート!!
ゲームプログラミングのコードを細かく解説するシリーズの第二段です。今回もヒューマンネット上本町センターの利用者さんが作った『弾幕インベーダーゲーム』を取り上げます。『弾幕インベーダーゲーム』は当事業所のホームページで公開しております。実際に遊んでみたい方は下記にリンクを貼っておきますので、そちらからアクセスしてみてください。またソースコードはGitHub上に公開しております。こちらもリンクを貼っておきますので、ソースコードが見たい方はリンクをアクセスしてください。
『弾幕インベーダー』は昔懐かしのインベーダーゲームをオマージュして作っています。”弾幕”と付いている通り、本家本元のインベーダーゲームにはない多彩な攻撃をしてきます。さらにインベーダーを倒すとアイテムが落ちてきます。インベーダーの攻撃を掻い潜り、アイテムを駆使しながらクリアを目指しましょう。
インベーダーゲームは敵をミサイルで攻撃して倒す単純なゲームですが、いざ自分で作ってみようとするとプログラミング初心者には意外と難しいと思います。インベーダーゲームのようなシューティングゲームを作ってみたいという方には参考になると思いますので、ぜひシリーズの最後までお付き合いください。
『弾幕インベーダーゲーム』で遊びたい方は以下よりアクセスしてください。
今回のコードもプロのエンジニアの方から見ればツッコミどころ満載のコードですが温かい目で見守ってください。
ソースコードはGitHub上にアップしています。
今回もまずは定義関連から見ていきたいと思います。
グローバル変数定義一覧
変数名 | 内容 | 変数名 | 内容 |
---|---|---|---|
canvas | キャンバスの取得 | ctx | コンテキストの取得 |
x | 自機のx座標 | stage | ステージ数 |
score | スコア | keyr | 右移動キー押下状態 |
keyl | 左移動キー押下状態 | shot | 自機のミサイル数 |
power | パワーアップアイテム数 | shotwait | 次のミサイル発射までの待ち時間 |
bomb | ボムアイテム数 | bombwait | ボム効果用のカウンタ |
zanki | 残機数 | clear | クリア状態 |
miss | 被弾状態 | gameover | ゲームオーバー状態 |
extend | ボーナス得点(1機アップ)のカウンタ | shield | シールド状態 |
invincible | 無敵状態 | tx | インベーダーのx座標 |
tmove | インベーダーの移動量 | tcount | インベーダーの生存数 |
tact | 障害物の上下方向の移動量 | teki | インベーダーの管理用配列 |
tama | インベーダーのミサイルの管理用配列 | jtama | 自機のミサイルの管理用配列 |
item | アイテムの管理用配列 |
関数定義一覧
関数名 | 処理概要 |
---|---|
draw() | 自機・枠表示 |
shotmove() | 自機のミサイル制御 |
nextstage() | 次のステージに進める処理 |
tamareset() | インベーダーのミサイル初期化 |
tdrow(e) | インベーダーの移動・描画処理 |
dropchance(e) | ドロップアイテム抽選処理 |
shotchance() | インベーダーのミサイル制御 |
itemmove() | アイテム制御 |
hit() | 自機の被弾処理 |
tamamovea() | インベーダーの3Way弾制御 |
tamamoveb() | インベーダーの誘導弾制御 |
tamamovec() | インベーダーのビーム制御 |
tamamoved() | インベーダーのスター弾幕制御 |
respone() | 自機のリスポーン処理 |
cleareffect() | クリア表示 |
gameovereffect() | ゲームオーバー表示 |
bombeffect() | ボム表示 |
game() | メイン制御 |
keyDownHandler() | キー押下処理 |
keyUpHandler() | キー開放処理 |
オブジェクト指向プログラミング
『弾幕インベーダーゲーム』ではインベーダーやミサイル、ドロップアイテムなど同じ特徴(性質)を持ったデータが沢山登場します。このように同じ性質を持ったデータを大量に扱う場合はオブジェクト指向プログラミングが強力です。
オブジェクト指向とは端的に言うと我々の現実世界でのモノ(オブジェクト)の扱い方をプログラミングの世界でも同じように扱えるようにした考え方(概念)のことです。オブジェクト指向言語というとオブジェクト指向を言語仕様として採用しているプログラミング言語のことをいいますが、オブジェクト指向は単に考え方のことを指していますので、C言語のような非オブジェクト指向言語でもオブジェクト指向(の考え方)を使ったコーディングは可能です。とはいえ、オブジェクト指向でプログラミングをする場合は、やはりオブジェクト指向言語を使った方が圧倒的に便利です。JavaScriptは代表的なオブジェクト指向言語の一つです。
オブジェクト指向プログラミングはカプセル化、継承、ポリモフィズムといった概念がでてくるため、プログラミング初心者にはハードルが高い内容ですが、オブジェクト指向の考え方自体は非常にシンプルです。なぜなら先ほども書いた通り、我々の現実世界のモノの概念を取り込んでいるからです。
では我々の世界のモノの概念とは具体的には何を指すのか?我々の世界はモノで溢れています。しかもほとんどのモノは誰かが作ってくれていて、我々はそれを買うだけですぐに使うことができます。もしすべてのモノを自分で一から作っていたら、とんでもなく効率が悪いですよね。さらにモノが世界にたった1つしかないとすれば、それを使いたい人は取り合いになってしまい、それも効率が悪いです。つまり我々の世界でのモノというのは大量に作られて、多くの人が同じモノを使える仕組みになっています。同じモノを大量に作るにはどうしたらいいか?それは設計図があれば問題ないですね。
オブジェクト指向で取り入れているモノの概念とは「設計図を元にして大量に生産し、消費する」ということなんです。オブジェクト指向の本質はたったこれだけです。それでも多くのプログラミング初心者がオブジェクト指向で躓くことが多いのは『継承』や『ポリモフィズム』のところだと思います。今回のプログラムでは継承やポリモフィズムは使っていませんので、気軽に参考にしてもらえればと思います。
オブジェクト指向の本質のところで述べた『設計図』に相当するのが『クラス宣言』になります。クラスはオブジェクト化(インスタンス化)され、使用されます。『クラス』が『設計図』、『オブジェクト化』が『モノの生産』、『使う』が『消費』に相当します。
クラス宣言一覧
今回のプログラムで宣言しているクラス一覧です。これらのクラスがプログラムのどこで生産され(オブジェクト化され)、どこで消費(使用)されているかを意識しながらプログラムを読み込めばオブジェクト指向がいかに便利かが多少でも感じ取れると思います。
クラス名 | 内容 |
---|---|
Jtama | 自機のミサイル |
Item | ドロップアイテム |
Enemy | インベーダー |
BombA | インベーダーの3Way弾 |
BombB | インベーダーの誘導弾 |
BombC | インベーダーのビーム |
BombD | インベーダーのスター弾幕 |
メイン処理
メインの処理は今回もgame()関数内でを行っており、10msecごとに呼び出すように設定しています。メイン処理では以下の処理を行っています。
- キャンバスのクリア
- 自機関連の制御関数の呼び出し
- インベーダー関連の制御関数の呼び出し
- ボムの爆発制御
- クリア時の表示
- ゲームオーバー時の表示
- 自機の移動
- 各制御カウンタのカウント
game()関数のコード
//メイン処理
function game() {
//キャンバスのクリア
ctx.clearRect(0, 0, canvas.width, canvas.height);
//自機関連の制御関数の呼び出し
draw();
shotmove();
//インベーダー関連の制御関数の呼び出し
tdrow();
itemmove();
tamamovea();
tamamoveb();
tamamovec();
tamamoved();
//ボム爆発表示
if (bombwait<20){
bombeffect();
}
//クリア時の表示
if (clear) {
cleareffect();
}
//ゲームオーバー表示
if (gameover) {
gameovereffect();
}
//自機の移動
if(!miss&&!clear){ //自機が被弾状態でない、かつ、クリア状態でないとき
if (keyl) { //左移動キー押下時
x = x - 2; //x座標を2pxずつ減らす
if (x < 0) { //左端に到達したとき
x = 0; //x座標に常に0をセット
}
}
if (keyr) { //右移動キー押下時
x = x + 2; //x座標を2pxずつ増やす
if (x > 760) { //右端に到達したとき
x = 760; //x座標に常に760をセット
}
}
}
//各種カウンタのカウント
shotwait++;
bombwait++;
invincible--;
//デバッグ用
debug();
}
さいごに
『避けゲー』では登場人物が少なかったので、クラスは使用していませんでしたが、『弾幕インベーダー』では複数のインベーダー、ミサイル、アイテムと沢山のオブジェクトが登場します。同じデータを何度も作って使うときはクラスにまとめてオブジェクト化して使うととても便利です。せっかくJavaScriptでプログラミングを学習しているのですから、オブジェクト指向の仕組みを使わないと勿体ないですね。いきなりオブジェクト指向を習得するのは難しいと思いますが、まずはクラスを作って、オブジェクト化してみるところから始めてみてはいかがでしょうか。今回はシリーズの第一弾ということで全体の構成を見ていきましたので、宣言したクラスがどのように使われているかは、今後のシリーズで触れていく予定です。次回以降もお楽しみに!
ちょっと息抜き
プログラミングを学習していると、脳をフル稼働させますし、じっと座ってコーディングしているときは目も身体も疲れてしまいます。そんな時は一息入れて、Yahoo!トラベルを見て現実逃避しましょう♪
Yahoo!トラベルはお得が一杯
- 取り扱い施設数が約17000施設!
- リーズナブルな価格での宿泊施設から贅沢な宿泊施設まで掲載!
- 日程や希望の条件からプランの検索・比較が簡単!
- 期間限定のクーポンがいっぱい!
- PayPayポイントが使える・貯まる!
- エリア×テーマで最も売れている宿をデイリーで更新中!
具体的に旅行を考えている方はもちろん、旅行の計画がなくてもYahoo!トラベルを見ているだけでほんのちょっと旅行に行った気分を味わえます。良い気分転嫁が出来ると思いますので興味がある方はアクセスしてみてください。