JAVA で作る弾幕系シューティングゲーム Barrage

JAVA で作る弾幕系シューティングゲーム
Barrage-based Shooting Game
01 月 17 日
経営情報学部経営情報学科
5110158 西岡和樹
5110201 藤本健人
1
目次
第1章 初めに………………………………………………………………p.3
第2章 関連研究……………………………………………………………p.4
第 1 節 JAVA について……………………………………………p.4
第 2 節シューティングゲームの歴史と課題について…………p.5
第 3 節 3D シューティングゲームについて……………………p.6
第3章 作成物の紹介………………………………………………………p.9
第 1 節シューティングゲームの作成……………………………p.9
第 2 節プログラムの概要…………………………………………p.10
第 3 節クラスの詳細………………………………………………p.11
第 4 節ゲームの詳細………………………………………………p.12
第4章 作成物のオリジナル機能の追加…………………………………p.15
第 1 節追加機能の概要……………………………………………p.15
第 2 節ステージの追加について…………………………………p.15
第 3 節自機の追加について………………………………………p.17
第 4 節自機のライフの追加について……………………………p.19
第5章 まとめ………………………………………………………………p.21
参考文献……………………………………………………………p.22
謝辞…………………………………………………………………p.22
2
第1章
はじめに
近年は、技術の進歩により様々なゲームが生まれてきた。昔は、テレビにつないで遊
ぶプレーステーション®(http://www.jp.playstation.com/)やゲームキューブ
®(http://www.nintendo.co.jp/ngc/)などといったゲームが一般的だった。故に、パソコン
をインターネットに介してゲームをする機会はあまりなかった。しかし近年は、3D 画面
を用いた 3DS®(http://www.nintendo.co.jp/3ds/)などの様々なゲーム機器に加えて、イン
ターネットが普及し一家に一台はパソコンがある。よってパソコンを使ったネットゲー
ムやオンラインゲームが非常に人気を博しており、ほとんどの人が一度はパソコンを使
ってゲームを遊んだことがある時代になった。一方で昔から遊んでいたゲームは見かけ
ることが少なくなってきたのも事実であり、シューティングゲームもその一つといえる。
1978 年に発売されたスペースインベーダー®(http://spaceinvaders.jp/)などにも代表さ
れるように約 30 年前は、シューティングゲームはアクションゲームと並ぶ主流ゲームの
一つでありゲームセンターなどでよく見かけた。しかしシューティングゲームは、ルー
ルが簡単なのですぐに飽きてしまう。そのマンネリ化を防ぐために難易度を上げるが、
今度は初心者にとって非常に難しいゲームになってしまった。
今回私たちは、JAVA を使ってシューティングゲームの作成をした。シューティングゲ
ームを市販の参考書を参考にしながら新しいシューティングゲームを作成した。様々な
プログラミング言語の中から JAVA を選んだのかを述べると、JAVA の汎用性に注目した
からである。つまり JAVA はパソコンだけでなくスマートフォンなどの様々な環境で用
いることができ、他の言語と比較しても有用性と活動実績にすぐれているからである。
他言語では、標準機能として持っていないものも大幅に追加されているので高い汎用性
を実現している。また JAVA を使った作品は数多くあり、サンプルも多く実績が高いと
評価されているからである。そして近年では、スマートフォン用のアプリに JAVA が使
用されたことで JAVA の社会的位置付けが向上してきている。このようにゲームやアプ
リなどに使われることが多くなったことによる世の中の JAVA の社会的重要性と高い汎
用性に注目し、JAVA を選ぶことにした。
今回作成したシューティングゲームの概要は、キーボードによる操作で自機を操作し
敵キャラを倒していくというものである。敵キャラには、ライフメーターがあり、それ
が無くなればステージクリアになる。また敵キャラの攻撃も自機を自動で追いかけてく
る追跡弾や斜めに出てくるものなど様々あり、攻撃に一度当たるとゲームオーバーにな
るというゲームである。ステージは 2 ステージまであり、2 ステージ目には敵キャラが二
体出てくるという仕様になっている。これらを発展させて、新しいゲームを作成した。
以降、第 2 章では JAVA やシューティングゲームに関する関連研究について述べ、第 3
章では作成物について紹介し第 4 章では私たちが付け加えたアイデアについて説明し、
第 5 章で、課題やまとめについて述べる。
3
第2章
第1節
関連研究
JAVA について
図 1 仮想マシン実行方式
出典
http://techfun.tv/contents/kouza/javatx1.html
JAVA とは、1990 年代前半にサンマイクロシステムズ社によって開発されたプログラ
ミング言語である。JAVA の特徴は、プログラムがさまざまな環境上で JAVA 仮想マシ
ンを使うことにより高速に実行できるという点である。つまり仮想マシンを使えばコン
パイルの必要がなく、どの OS でも実行可能になる。逆に弱点としては、C 言語などと
比べて実行速度が 10 分の 1 程度になってしまい他の言語に比べて実行速度が遅いとい
うのが弱点になっている。JAVA が登場したころはプログラムを書いてからそれを配布
実行するまでの方式は以下の二つしかなかった。
① マシン語にコンパイルする方式
プログラムをコンパイラというプログラムを使って配布する方式である。CPU が直接
理解できるマシン語なので性能を 100%引き出すことができる。有名なものには C 言語
や C++がある。
② インタプリンタ方式
ソースコードのままプログラムを配布して、実行するときはインタプリンタと呼ばれ
るプログラムが解読していく方式である。上記の方法より簡単に覚えることができる。
有名なものには JavaScript がある。
ここで重要なのが仮想マシン実行方式である。この仮想実行マシンとは、図 1 にもあ
るようにプログラムそれぞれのバイトコードの違いを吸収してくれるものである。例え
ば、JAVA で作ったプログラムをそのまま Mac などで動かそうとしてもそれぞれバイト
コードが違うので実行することはできない。仮想マシンは、その OS 固有のネイティブ
コードに変換して実行する。この仕組みを導入していることにより JAVA は様々な環境
で高速に動くことができる。また仮想マシンは、危険な処理を監視する機能も備わって
4
いる為、①や②の方式よりも致命的なエラーが起きにくくなっている。その為、現在主
流のプログラミングの手法を学ぶには最適な言語であると言える。
第2節
シューティングゲームの歴史と課題について
年代
出来事
この年代は、1978 年に発売されたスペースインベーダーを筆頭に
1970~1980
年代
様々なシューティングゲームが発売され、ゲーム人気に火が付き始めた
年代である。アクションゲームとともに人気ジャンルになった。
図 2 スペースインベーダー
出典:http://blog.livedoor.jp/natsukashi_games/archives/50309857.html
1980 年代に入ると、ますますシューティングゲーム人気は高くなっ
1980~1990
年代
た。ゲームグラフィックなどの技術が大きく進歩し、ゲームセンターな
どに留まらずテレビゲームの中心ジャンルとして活躍していた。
1990 年代に入ると、シューティングゲーム人気にも陰りが見えてくる。
1990~2000
年代
主な原因としては、アイデアが出尽くしたことなどが挙げられる。また、
ロールプレイングゲームや対戦型アクションゲームなどの台頭により、シ
ューティングゲームにとって厳しい年代である。
2000 年代に入っても、復調の兆しは見られない。しかし同人ゲーム
2000 年~現在
などのゲームとしての開発は、活発に行われている。また、PC の互換
性が高くなったことなどによりテレビゲームなどでも遊べるようにな
るなど少しずつ復活の兆しを見せている。
図 3 シューティングゲームの年表
まず、シューティングゲームの歴史について図 3 を使って簡単に説明する。1978 年
に開発されたスペースインベーダー(図 2 参照)というシューティングゲームは、当時社
会現象を巻き起こすほどの爆発的な人気を誇り、日本で初めて社会現象を巻き起こした
テレビゲームと言われている。その後もギャラクシアン
®(http://www.hakoniwa.net/games/galaxians/)などが人気を博し、1970 年~1990 年に
は高い人気を誇った。一方で 1990 年代に入ると徐々に人気が衰えてきており、現在で
も主要ジャンルのゲームとは呼べないだろう。シューティングゲームの特徴としては、
ゲームのルールが簡単という点である。このことにより初心者でも、気軽に始めること
5
のできるゲームと言える。また一方で、前章でも述べたようにルールが簡単というのは
逆に弱点でもあり、最も初心者離れを起こしてしまったゲームとも言われている。
こういった課題を解決するために様々な工夫が施されている。まず一つは、最近のシ
ューティングゲームはゲーム性に冒険しながらレベルアップしたりやアイテムを買っ
て強化しながらゲームを進めることができる。こういったロールプレイングゲーム
(RPG)のゲーム性を追加することにより、飽きることなくゲームを楽しむことができ
る。二つ目は、同人ゲームのアーケードゲームへの移植である。図 3 にもあるように、
近年は PC の互換性が高くなったことや、この移植によって家庭用ゲーム機などで遊べ
るゲームも多く開発されている。こういった様々な工夫により少しずつ人気を取り戻し
つつある。
第3節
3D シューティングゲームについて
シューティングゲームの種類については、大きく分けて昔からある 2D シューティン
グゲームと 3D シューティングゲームの二つがある。ここでは、その中でも近年人気が
高くなってきている 3D シューティングゲームについて説明する。3D シューティングゲ
ームの主な種類としては以下のものがあげられる。
(1)FPS (First Person shooter)
(2)TPS (Third Person shooter)
(3)フライトシューティングゲーム
(4)スペースコンバットシューティングゲーム
以下、一つずつ説明していく。
(1) FPS (First Person shooter)
FPS は、ファーストパーソン・シューティングゲームの略である(図 4 参照)
。FPS
というゲーム自体は、以前から開発されており DOOM 系ゲームなどと呼ばれていたこ
ともあり歴史は古い。現在では、CALL OF
DUTY®(http://www.callofduty.com/)や
バトルフィールドシリーズ®(http://www.battlefield.com/jp)が人気である。これらのゲ
ームの大きな特徴としては、一つは視点が自分たちから本当に見えているかのような 1
人称視点と呼ばれる視点になっていることである(図 5 参照)。これにより自分たちが、
本当に戦っているかのように錯覚する。また臨場感や緊張感などを感じながら遊ぶこ
とができ、非常に人気の高いジャンルである。もう一つの特徴としては、一回の遊ぶ
時間が 10 分程度で短いということである。このことにより時間があまりない人でも遊
ぶことができて人気が高いジャンルである。しかし難しいところもあり、敵の攻撃が
判別しにくいという欠点もある。一人称視点だとカメラ視点と違い、画面全体から攻
撃されてくるので攻撃が回避しにくい。またゲームに没頭しすぎてしまい、現実の世
界でも同じような行動を自分でしてしまう FPS 症候群と呼ばれる人たちも出てきてい
る。
6
図4
出典
FPS(First Person shooter)
図 5 一人称視点
http://www.warrock.jp/about/fps.php
出典
http://www.onlinegamer.jp/game/331/
(2) TPS (Third Person shooter)
TPS とは、サードパーソン・シューティングゲームの略である(図 6 参照)。一人称視
点の FPS に対して TPS は画面が主人公を見下ろすようになっており、第三者から見たか
のような視点なので三人称視点のシューティングゲームと呼ばれている (図 7 参照)。TPS
の特徴は、FPS に比べて後方からの映像になるのでキャラクターの動きなどの情報が非
常に見やすくなっており操作しやすいところにある。一方で FPS に比べて第三者からの
視点になるので、ターゲットに弾をヒットさせるのが難しいゲームである。どちらかと
いえば演出要素の強いゲームで用いられることが多い。最近では、メタルギアソリッド
2®(http://www.konami.jp/kojima_pro/japanese/)やバイオハザード
4®(http://www.capcom.co.jp/bio_series/)などのゲームが人気を博している。
図6
出典
図7
TPS 画像
三人称視点
出典 http://nukacolafanclub.blog86.fc2.com/page-3.html
http://www.kotaku.jp/2011/09/me3_tgs2011_demo.html
(3)フライトシューティング
フライトシューティングとは、戦闘機や飛行機などを自ら操作し自由に飛び回りなが
ら敵を倒していく 3D ポリゴンという技術を用いたシューティングゲームである(図 8 参
照)。類似のソフトにフライトシミュレーターというものがあり、これは挙動などが非常
に細かく正確に再現されている(図 9 参照)。一方でフライトシューティングは、操作方法
などが非常に簡略化されているので初心者の人でも気軽に遊ぶことができる昔から人気
の高いゲームである。難しいところは、さまざまな角度から攻撃が来るので回避するの
が非常に難しいという点である。このゲームには昔から人気が高い「エースコンバット」
®(http://www.acecombat.jp/)シリーズなどがある。
7
図 9 フライトシューティング 2
図 8 フライトシューティング
出典
出典
http://www.inside-games.jp/article/2010/01/21/39977.html
http://www.macotakara.jp/blog/iphone_app_store/entry-5875.html
(4)スペースコンバットシューティング
スペースコンバットシューティングゲームとは、先ほど紹介したフライトシューティ
ングゲームの舞台が宇宙空間になっており、宇宙船を操り自由に宇宙空間を移動するこ
とができるシューティングゲームである(図 10 参照)。他のジャンルのゲームに比べても、
爽快感や臨場感が多く感じられるジャンルのゲームになっている。一方で複雑な操作や
高い戦術性が求められる。またこのジャンルのゲームには、シューティングゲームの要
素だけではなくキャラクターが自ら旅をしながら成長していくといったようなロールプ
レイングゲームの要素を取り入れたゲームも数多く存在している。
図 10 スペースコンバットシューティング
出典 http://game.ekikara7.jp/archives/22526
8
第3章
第1節
作成物の紹介
シューティングゲームの作成
私たちが作成したゲームは、第 1 節でも述べたようにステージが 2 つありそれぞれの
ボスキャラにライフメーターがある。それがなくなるとクリアというシューティングゲ
ームである。
(1)ステージとキャラクターについて
まず図 11 が最初のステージであり手前に自機、奥に敵キャラクター1 が配置されてい
る。自機はキーボードを使い上下左右に移動することができる。図 12 のステージ 2 は、
最初から敵キャラクターが 2 体出現し前後左右に移動しながら攻撃してくる。
敵キャラ 2
ライフ
敵キャラ 1
敵キャラ 3
自機
自機
図 11 ステージ 1
図 12 ステージ 2
(2)自機の攻撃について
自機の攻撃についてはキーボードで設定されたキーを押すことにより、図 13 にあるよ
うな緑色のビームを出して敵キャラクターを攻撃することができる。またこの攻撃は、
ビームの発射の間隔や連続して発射できる数などを設定することができる。同じ攻撃だ
が、
この設定を変えることにより図 14 のようまた違った攻撃に見せることが可能である。
自機の攻撃 2
自機の攻撃
図 13 自機の攻撃について
図 14 自機の攻撃について 2
9
(3)敵の攻撃について
敵の攻撃は、弾による攻撃と突進による攻撃の 2 種類がある。まず弾による攻撃だ
が複数の種類がある。まっすぐ飛んでくる弾、斜め四方向に飛んでくる弾、自機を自
動で追跡してくる弾など合計 8 種類の弾の種類がある(図 15 参照)。突進による攻撃に
ついてだが、最初は一定の位置から弾だけの攻撃をしてくる。しかしある程度の時間
がたつと左に移動して突進攻撃などを組み合わせて攻撃してくる(図 16 参照)。
敵の突進攻撃
敵の攻撃
図 16 敵の突進攻撃
図 15 敵の攻撃
第2節
プログラムの概要
このシューティングゲームのクラス図を、図 17 にて示す。Main メソッドを持つクラ
スは、First Shooting クラスであり、他にもゲームで使うキーをチェックしている
Graphics Info クラスなどがある。この中で重要なクラスとなるのが、やはり Main メソ
ッドを持っている First Shooting クラスである。このクラスでは、画像の読み込みや 1
フレーム分の秒数求める、実際に使用するキーを決定するなどゲームの中枢を担ってい
る。そしてもう一つ重要になるクラスが、GameChara クラスである。このクラスは、ボ
スや自機などすべてのキャラクターのスーパークラスになっている。画像の角度や中心
位置に加えて画像を回転させるための変形処理などキャラクターに関する多くの処理が
このクラスで行われている。
10
図 17 シューティングゲームのクラス図
第3節
クラスの詳細
ここでは、主要なクラスの詳しい紹介をする。今回は、First Shooting, GameChara
クラス、この 2 つを紹介する。
(1)First Shooting クラス
このクラスは、main メソッドを持つクラスであり、ゲームの中心となっているクラス
でもある。コンストラクタやキーアダプターなど様々な処理が行われているが、その中
でも重要な処理が速度調整のクラスである。この処理は、Timer と Timer Task というク
ラスを利用して、人間が体感している時間に合わせてプログラムを動かすリアルタイム
処理と呼ばれる処理をしている。このコードでは、まず①の行で frame time の設定の処
理を行い、時間を計測している。まず、現在の時刻を求めている time から lasttime フィ
ールドを引くことにより前回設定した時間から現在時刻の差を求めている。これが、1
ループ分の時間になる。そして②の行で、time に記録されている時刻を GraphicsInfo
クラスの currenttime フィールドに代入している。この速度処理を行う理由は、タイマ
ーが設定の時間を保てなくなることがあるからである。何らかの理由でタイマーに遅れ
が生じると、キャラクターなどの動きが突然遅くなったように感じてしまう時に役立つ
のが Frame time である。まず 1 ループ分の時間を計測できるこの処理を行う。そして
Timer から Last time を引くことにより 1 ループ分の時間を求めている。その時間を
Graphics Info クラスの Frame Time フィールドに設定し、キャラクターの移動量を設定
している。この処理をしておくことにより、例えタイマーに何か不具合を起こし遅れが
生じてもキャラクターの適切な運動量を求めることができる(図 18 参照)。
11
Long last time = System.currentTimeMillis ();
Graphics Info ginfo = new Graphics Info ();
void render(){
//時間計測
long time = System.currentTimeMillis();
// 1フレーム分の秒数を求める
this.ginfo.frametime = (time - this.lasttime) * 0.001;
this.lasttime = time;
this.ginfo.currenttime = time;
Graphics2D g = (Graphics2D) this.strategy.getDrawGraphics();
g.setBackground(Color.black);
g.clearRect(0, 0,
this.mainwindow.getWidth(), this.mainwindow.getHeight());
ginfo.g = g;
図 18
FirstShooting クラスのタイマーに合わせて速度を調節するコード
(2) GameChara クラス
図 19
GameChara の画像処理のコード
このクラスは、すべてのキャラクターのスーパークラスになっている。つまり、キャ
ラクターを画面に表示するために必要な処理を行っているクラスである。このクラスで
重要な処理が図 19 の画像の変形待避、変形復帰という処理である(図 19 参照)。このゲー
ムでは、画像を回転して描画できるようにしている。画像を回転するには変形という処
理が必要になる。この処理を行うには、最初に設定されている変形設定を待避させて描
画がおわると元に戻す必要がある。この処理がなければ設定が、他のキャラクターにも
影響してしまい上手く表示されなくなってしまう。このゲームの場合、3 の行で現在の変
形設定を getTransform メソッドを使い取得しその設定を変数 oldtr へ待避させている。
その後、4 の行で draw Image メソッドを用いて描画し、最後の行で set Transform メソ
ッドを用いて再設定している。
12
第4節
ゲームの詳細
本節では、自機の動かし方や当たり判定などのゲームの詳細に関してプログラムを用
いながら詳しく説明する。
(1)自機の動かし方
//キー入力
⑤If (ginfo.keystate[KEY_STATE.LEFT]){
this.position.x -= PlayerChara.SPEED
}
if(ginfo.keystate[KEY_STATE.RIGHT]){
this.position.x += PlayerChara.SPEED
}
if(ginfo.keystate[KEY_STATE.UP]){
this.position.y -= PlayerChara.SPEED
}
if(ginfo.keystate[KEY_STATE.DOWN]){
this.position.y += PlayerChara.SPEED
* ginfo.frametime;
* ginfo.frametime;
* ginfo.frametime;
* ginfo.frametime;
図 20 カーソルキーをチェックするコード
今回作ったゲームの自機は、PlayerChara クラスの keystate フィールドを利用して、
カーソルキーをチェックして自機を動かしている(図 20 参照)。まず 5 の行から自機が左
に動く処理をしてそれ以降右、上、下と処理をしている。そして、そこに[速度×時間]を
position フィールドに足すことにより自機を動かしている。
(2)当たり判定について
⑥
private Vector2D v = new Vector2D();
public boolean hitTest(GameChara gc) {
⑦this.v.x = this.position.x - gc.position.x;
⑦this.v.y = this.position.y - gc.position.y;
double l = this.v.lengthSquare();
double l2 = this.size * this.size + gc.size * gc.size;
if(l < l2) return true;
return false;
}
図 21 あたり判定を行うコード
このゲームの当たり判定は、様々なやり方がある中でキャラクター同士の距離を調べ
る方法を採用している。まず、すべての弾、ボスのサイズ、自機のサイズをそれぞれ設
定する。その後に、図 21 のように GameChara クラスの中に個々のあたり判定を行う
hit Test メソッドを追加する。このメソッドで行なっている処理は、まず図 21 の⑥の行
で作業用のフィールド Vector2D を用意しその後 7 の行で自機とキャラクターの位置の差
を求める。その後、length Square メソッドで長さの二乗を求め、これがキャラクターと
13
自機との距離を表している。次に、二つのキャラクターの二乗したものの和を求めそれ
が先に求めたものより小さい場合は当たっているということなので true を返し、そうで
ない場合は false を返す。
⑧If (this.getEnemy().hitTest(this.player) == true) {
}
return true;
⑨
for (int i=0; i<MAX_BULLETS_E; i++){
if(this.bullets_e.get(i).visible == true){
if(this.bullets_e.get(i).hitTest(this.player) == true ){
return true;
}
}
}
Return false;
}
図 22 あたり判定を実行するコード
そして Stage クラスに hitTestAll という抽象メソッドを追加する。その後、図 22 のよ
うにサブクラスである Stage1 クラスにボスとの判定そして敵の弾との判定を追加する。
このコードは、まず 8 の行でボスと自機との判定を行う。そして 9 の行で敵の弾と自機
の当たり判定を行っている。最後に弾に当たるとゲームオーバー画面に切り替わる処理
を追加し当たり判定となっている。
(3)自機の弾について
if(ginfo.keystate[KEY_STATE.M]){
if(this.shootcount > 6){
if(ginfo.currenttime - this.lastshooting > 500){
this.shootcount = 0;
}
} else if(ginfo.currenttime - this.lastshooting > 50) {
図 23 発射待機の処理
図 23 発射待機の処理
自機が弾を発射するには、まず自機の弾用の取得メソッドを作成する必要がある。そ
の後、弾の初期化や描画などを行い発射する処理をするのだが、ここで重要なのが図
23 の発射待機という処理である。最初の行で、キーボードの M が押されたら発射処理
が開始される。そのままだとずっと弾が発射している状態なので、ゲームに面白みがな
い。そこで次の行で連続して発射できる弾の数を 6 発までその後は 500 ミリ秒待機とい
う処理を行う。この処理を行うことにより、弾からよける、弾を打つということにメリ
ハリをつけることができ面白いゲームになる。また最後の行で、連射の間隔を 50 ミリ
秒おきにしている。その理由は、この処理を行わないと 60 分の 1 秒間隔でずっと弾を
発射し続けることになり弾に見えないからである。
14
第4章
第1節
作成物のオリジナル機能の追加
追加機能の概要
今回、シューティングゲームを作成するに当たって参考書を参考にして作成した。そ
こにオリジナル機能としてステージの追加、自機の追加、自機のライフの追加の 3 点を
追加機能として作成した。この 3 つの機能を追加する為に、図 24 中の赤丸部分のクラス
である 6 つのクラスを変更した。また青丸部分の 2 つのクラスを追加した。追加したク
ラスや変更したクラスの説明は、以下の節にて詳しく説明する。
図 24 追加したクラスと変更したクラスを示したクラス図
第2節
ステージの追加について
今までは、参考書を参考にして 2 通りのステージを作成した。そこで本プログラムで
は、オリジナル機能として新たにステージ 3 を追加した。ステージは、1 面 2 面 3 面と続
いていくものでそれらも 1 つずつのクラスとして扱った方が良い為、Stage1 クラス
Stage2 クラスそして今回ステージ 3 を作るためのクラスとして Stage3 クラスと個別に
作成した。ステージ 3 を作成するには、他のクラスを変更したりする必要はないので新
しく作成した Stage3 クラス内に処理を書いていくということになる。今までのステージ
と異なる点は、敵キャラが個別に出現しない点である。今までのステージでは、個別に
15
敵キャラが出現していたのに対して今回のステージ 3 では敵キャラが全て出現する仕様
になっている(図 25 参照)
。
これらのステージを作成するクラスは、スーパークラスの Stage クラスを元にサブク
ラスとして Stage1 クラス Stage2 クラス Stage3 クラスを作成している。このシューテ
ィングゲームでは、ImageIO クラスを利用してキャラクターの描画を行っている。この
クラスを利用することで JPEG、PNG、GIF 形式のファイルを読み込むことができる。
今回は、不透明度が設定できる PNG 形式の画像ファイルを採用している。そしてそのフ
ァイルを読み込むために read メソッドを利用して File クラスのインスタンスを受け取っ
て、BufferImage クラスのインスタンスを返している。受け取った画像を全て返すので
はなく、今回は複数のキャラクターが 1 枚の画像ファイルにまとめられている為、画像
を分割して 1 つのキャラを作成していけるように getSubimage メソッドで x の値や y の
値、h の値や w の値を指定する。そうすることで 1 つのファイルからでも自機や敵キャ
ラなどの個別のキャラクターを作成することができる。また画像データ本体は共有して
いるので、この getSubimage メソッドを何回も繰り返したとしてもそれほどメモリ容量
が増えることがない。
本プログラムで説明すると、まずそれぞれのステージを作成しているクラス内に
loadMedia メソッドというものがある(図 26 参照)。これは、画像ファイルの読み込み処
理を行うためのメソッドで 1 つ 1 つサブクラスに実装する必要がある。まず図 25 の 2 行
目の処理で img_chara という変数に chara.png という画像ファイルを読み込ませている。
そ の 後 の 3 行 目 か ら 16 行 目 の 処 理 で キ ャ ラ ク タ ー ご と の 名 前 を 付 け た 変 数 に
getSubimage メソッドを用いて必要な画像だけを抽出している。例えば player という変
数には、自機画像だけを抽出したいので chara.png の(0.0)から 48*48 ピクセル分の位置
にある図 27 の赤い丸部分の画像が抽出される。これと同じようにして位置情報を書き換
えるだけで違うキャラクターを作成することが可能になる。次に draw メソッドでそれぞ
れのキャラクターを描画する処理を行い、init メソッドで位置情報などの初期化を行う処
理を行うなどの処理を書くことでステージが完成する。そして今回は、Stage3 クラスを
作成するために loadMedia メソッド draw メソッド init メソッドの 3 つのメソッド内の
処理を変更した。loadMedia メソッドでは、図 26 の 7 から 9 行目の敵を抽出する処理を
追加した。それと同じように draw メソッドでは、loadMedia メソッド内で作成した図
28 の 5 から 7 行目の enemy、enemy1、enemy2 を描画して init メソッド内で図 29 の 4
行目から 27 行目の処理で位置情報などを初期化することで図 25 の様な全ての敵キャラ
が出現するステージを作成することができる。またこれらの処理は、ステージを作成す
るクラスごとに処理を書いている為、比較的簡単にオリジナル機能を追加することがで
きた。
16
図 27 chara.png の画像
図 25 ステージ 3 のイメージ画像
図 26
図 28
Stage3 クラスの loadMedia メソッド
Stage3 クラスの draw メソッド
図 29
第3節
Stage3 クラスの init メソッド
自機の追加について
本プログラムは、オリジナル機能として自機の追加を行うことにした。まず自機では、
シューティングゲームを行う際に自分で操作できるものでそれを用いて出現する敵キャ
ラの攻撃を避けるや攻撃して倒すことができる。そのシューティングゲームの自機に必
要な処理は、
キーを操作し移動することと弾を撃つことの 2 つの処理を行うことである。
今回は、これらの操作が可能となる自機をもう 1 つ作成し 2 人で操作できるようにする
17
というオリジナル機能の追加を行う(図 30 参照)
。自機を作成する為には、新たに自機
クラスの追加 PlayerChara2 クラスを作成し GraphicsInfo クラス KEY_STATE クラス
FirstShooting クラス及び Stage1 クラス Stage2 クラス Stage3 クラスの変更で作成する
ことができる。
自機は、キャラクターの描画や画像データ等の記録を行っているキャラクターを管理
するスーパークラス GameChara クラスを利用してサブクラスとしてステージの作成方
法と同様に自機に関しても PlayerChara クラス PlayerChara2 クラスと個別に作成する。
自機の追加をする為に、敵キャラを増やした処理と同じように loadMedia メソッド内の
処理を変更する。player2 という変数を作りそこに自機の画像の位置を指定して代入する。
そして draw メソッドや init メソッド内に player2 に関する処理を追加することで自機を
追加することができる。しかしこの状態のままであればキーの操作方法が同じ設定の為、
1 つだけ操作したいと考えていても同時に動いてしまうという問題点がある。
その問題を解決するために違うキーを使用できるようにし、そのキーを用いて操作で
きるようにする処理に変更する。まずキーボード操作で使用するキーを簡単にチェック
できる仕組み、描画する全てのクラスに Graphics2D インスタンスを渡す仕組み、タイ
マーの遅れに合わせて速度調節する仕組みを兼ね備えた GraphicsInfo クラスを変更する。
このクラスでは、キーの状態を記録する boolean 型の配列フィールド keystate を作成し
ており、コンストラクタで keystate に要素を設定している。今までの 1 人プレイでは、
図 31 の 15 行目のように必要な配列の数として 8 を設定していたが、2 人プレイではキ
ーが足りなくなるので図 32 の 15 行目の i の要素数を 20 へと変更した。そして自機を操
作するための処理として FirstShooting クラスの getKeyCode メソッドで押されているキ
ーを調べ、keystate に true か false かを設定する。更に keyPressed メソッド keyRelease
メソッドでキーコードを調べ、それを keystate フィールドに反映させるために追加され
ている setValue メソッドを呼び出す。ここでは swtich 文でキーコードに合わせた処理を
行っている。その部分に新たに設定したキーを追加してやることで他のキーでの操作も
可能になる。そして PlayerChara クラス PlayerChara2 クラスそれぞれに違うキーを設
定した。例えば PlayerChara クラスの自機では、矢印キーを用いて操作することができ
PlayeChara2 クラスでは ADWX という文字キーを用いて操作することができるように
なっている(図 33 参照)
。
このように 2 つの自機を作成し、また個別での操作が可能にすることで自機の追加と
いうオリジナル機能の作成を行った。
図 30 自機が 2 つあるイメージ画像(赤丸が自機)
18
図 32 変更後コード
図 31 変更前コード
図 33
第4節
PlayerChara クラス(左)と PlayerChara2 クラス(右)の操作するキー
自機のライフについて
本プログラムでは、今までの敵の攻撃に当たれば即時にゲームが終了していた仕様か
ら従来のシューティングゲームの様に敵の攻撃に当たってしまっても自機が復活しゲー
ムを続けることが出来る仕様に変更することでオリジナル機能の追加を行う。このシュ
ーティングゲームでは、キャラクター同士の距離を調べる方法を用いて当たり判定を作
成する。当たり判定のシビアさは、GameChara クラスの size フィールドに代入する値
で調節する。まず全ての弾のサイズを調整する為に、弾を作成するためのスーパークラ
スとして BulletChara クラスというものがある。その BulletChara で全て同じ大きさの
12 ピクセルサイズをコンストラクタで設定する。また敵キャラと自機は、それぞれのク
ラス内のコンストラクタで設定している。
次に個々の当たり判定を行う hitTest メソッドを GameChara クラスに追加する。この
クラスに追加することで、全てのサブクラスがそれを持っていることになる。この中で
行っている処理は、作業用の Vector2D 型フィールドを用意しておき、自分と引数に渡さ
れたキャラクターの位置の差を求めてベクトルにする。lengthSquare メソッドで長さの
二乗を求める。これが 2 つのキャラクターの距離を表すことになる。次に 2 つのキャラ
クターの size フィールドを二乗したものの和を求める。どちらとも長さの二乗だが、比
較するにはこのままでも問題はない。後者より前者が小さい場合には、当たっているの
で true を返し、そうでない場合には false を返す処理を行う。
そして当たり判定を実行する為に、それぞれの Stage1 クラス Stage2 クラス Stage3
19
クラスごとに hitTestAll メソッドを実装する。この中で敵キャラとの判定、敵キャラの
弾との判定を行い、
もし当たっていれば true を返す処理を行う。自機を一度の接触で true
を返させないためにこの中の処理を変更した。自機にライフを持たせ、当たり判定で true
と判定されるとそのライフを減らしていく。そして自機に設定されているライフが 1 を
下回れば初めてそこでゲームオーバーという処理に変更する。
本プログラムでは、まず PlayerChara クラス PlayerChara2 クラスそれぞれに
lifecount という変数を設定する。
次にそれぞれのステージごとに設定している hitTestAll
メソッド内の当たり判定後の処理を図 34 の変更前のソースコードの当たり判定後の処理
を敵キャラ本体、敵キャラビームの当たり判定を図 35 のソースコードに変更する。そう
することで、敵キャラの攻撃に当たったと判定されれば図 34 の 175 行目、187 行目の処
理の様に PlayerChara に設定されている lifecount の数値がデクリメントされるようにな
っている。また、攻撃に当たったと判定された際には、図 35 の 176 行目から 177 行目、
188 行目から 189 行目の様に位置情報の初期化も重ねて行われる為、より復活している
様に見える(図 36 参照)
。
このように自機にライフを付けて攻撃を受ければ初期位置に戻る、そしてライフが 1
を下回れば true が返されゲームが終了するというオリジナル機能の追加を行った。
図 35 変更後
図 34 変更前
図 36 自機が復活する場面のイメージ画像
20
第 5 章まとめ
今回私たちは、
参考書を参考にして JAVA を用いたシューティングゲームを作成した。
内容としては JAVA の API を利用してウィンドウを作成した。そこに自機の画像や敵キ
ャラクターを描画処理など行い作成した。これらのキャラクターは、1 つの画像を元に作
成されている為、重くなることもない。そしてこれらの処理を応用してステージの追加、
自機の追加、自機ライフの追加というオリジナルのシューティングゲームにするために
追加機能の実装を行った。
今後の課題として、今回作成したオリジナル機能を実装したシューティングゲームに
は自分たちで考えたオリジナル機能が少ない点にある。アイデア自体も先生に考えて頂
いたりや実装した機能も今まで作成したものを応用して作られたものばかりである。今
後は、オリジナルの弾幕を作成するなどを行いこのようなオリジナル機能を最初から自
分たちのアイデアで作成していければと考えている。作成する際にも様々な工夫も付け
加えていきたい。例えば 1 秒間弾を撃って 0.7 秒間待機などの処理は、JAVA のコードだ
けで書くと非常にややこしく且つ難しくなってしまう。そこで設定を書いたテキストフ
ァイルなどを解釈して作成する方がより簡単にできるのでそういった細かな工夫も付け
加えていければと考えている。今回は、パソコン上で動くシューティングゲームを作成
した。しかし JAVA というのは第 1 章でも説明したようにパソコン上だけでなく他のデ
バイスでも動くプログラムを作成することができる。そういった他のデバイスにも対応
したシューティングゲームを作成していきたい。パソコンと比べて機能制限が多いスマ
ートフォンだと細かなチューニングなども重要となってくるが、それだけやりがいも多
く目標にもなってくる。
このシューティングゲームを作成するのは 2 人での共同作業が予定だった。しかし 2
人で作業を分担しても、お互いの能力や知識量などの差から進捗具合が合わず、進める
ことも難しかった。自宅で作業を進めることが多く進捗状況も伝えられないこともあり、
その点にも苦労した。
また、お互いに作業を分担して予定を立てて作成したプログラムでも、実際に動かし
てみると予定外の動作やエラーが起こることも多々あった。例えばステージ 3 を作成し
た際に敵キャラクター同士の動きが重なったり、当たり判定後の処理がおかしくなり自
機の攻撃が 1 発当たっただけでボスが倒されたりと全く予想していない動作が起こった。
私たちは、このシューティングゲーム制作を通じて予定外のことが起こらずプログラ
ムを作成することは非常に難しいものであり、また何かを作成しようとする際にはコミ
ュニケーションを取ることが非常に重要であると痛感させられた。
参考文献
21
[1]15 歳からはじめる JAVA わくわくゲームプログラミング教室フルカラー最新版
著者:大槻有一郎 発行者:黒田康夫 発行所:株式会社ラトルズ
[2]weblio 辞書 http://www.weblio.jp/
[3]ニコニコ大百科 http://dic.nicovideo.jp/
[4]FPS 上達情報局:上級者になる為のコツ http://tara-fan.com/fps/
[5]TPS・FPS シューターズ http://tps.game-tansaku.net/
[6]ステンバーイ http://cod-standby.com/
謝辞
いつも机の上に寝そべって中小企業の社長の様な恰好でゼミに来ていた臼杵高太郎
氏に感謝します。3 回生の頃はまだマシだったけど 4 回生になると頻繁に遅刻を繰り返
すようになってしまったゼミ長の近藤彪氏に感謝します。天丼食べて行くからと謎の
理由で遅刻したことのある堀慶文氏に感謝します。帰りの電車が一緒になることが多
い石橋和也氏に感謝します。いつも遊びに行った帰りに王寺駅まで送ってくれる西田
翔一氏に感謝します。同ゼミの紅一点である大塚貴史氏に感謝します。会社説明会に
同行した国重和章氏に感謝します。同ゼミのメガネ男子である塩田翔平氏に感謝しま
す。いつも隣の席で励ましあってきた松村和学氏に感謝します。もう学校は辞めてし
まったけど、それまで 1 回生の頃から学籍番号が近く、一緒に勉強したこともある西
原彰人氏に感謝します。最後に、本論文の添削やアドバイスの他に、今まで就職や数
多くに関してご指導して頂いた花川典子教授に感謝します。
22