プログラミングで簡単なジャンプアクションゲームの作り方
こんにちは。継続の錬金術士なおキーヌです。
ブログ毎日更新は92日目になります。
文章だけで解説するゲームの作り方第三弾です。
- 第一回:プログラミングが難しいと感じる初心者はゲームを作ってみよう
- 第二回:プログラミングでブロック崩しを作るイメトレ
- 第三回:プログラミングで簡単なジャンプアクションゲームの作り方 ← イマココ
番外編としては以下の記事を見てください。
ジャンプアクションゲームは、アタリ判定さえしっかりしていれば案外簡単に作れてしまいます。
マリオのようにジャンプだけのアクションにするか、
ロックマンのようにショットを打てるタイプのシューティング要素があるアクションにするかで難易度が変わります。
ジャンプアクションゲーム
特に攻撃アクションがなく、ジャンプボタンと移動ボタンだけで操作できるゲームです。
スクロール実装は結構難易度が高いので、1画面でのジャンプアクションにしてみましょう。
ということで超絶シンプルなジャンプアクションゲームの作り方は下記になります。
- プレイヤーを用意する
- ステージを用意する
- プレイヤーの移動処理を作る
- プレイヤーのジャンプ処理を作る
- 針や動く敵などを障害物を用意する
- クリアフラグを準備する
プレイヤーを用意する
プレイヤーが居ないとゲームが始まりませんね。
基本的に2DゲームではプレイヤーやNPC等の動くモノはすべてスプライトという表現を行います。
ゲーム系のライブラリだけではなく、基本的にスプライト(Sprite)と呼ばれています。
今後のゲーム解説記事でもスプライトと表現するので覚えておいてください。
スプライトはゲームライブラリで用意されていることが多く、
様々な情報を持つことが出来るように作られています。
今回プレイヤーを用意するのに使う要素は大きく絞って下記の3種になります。
- 座標
- テクスチャ(必要であればアニメーション実装)
- 判定するための矩形
座標はプレイヤーの位置ですね。
テクスチャはプレイヤーの見た目なのでドット絵をテクスチャにしたり、土っとアニメーションを実装したりですが
ドット絵を用意していては時間がかかってしまうのであとから差し替えられるようにしておいて、
開発中は矩形塗りつぶしで対応することも多いです。
判定するための矩形とは、PONG GAMEやブロック崩しでも使いました。
基本的にプレイヤーのスプライトとまったく同じ大きさの透明の矩形を、
プレイヤーとまったく同じ座標においておくことで判定に使用できます。
余談として、全く同じ大きさの場合アタリ判定が多すぎてドット絵に当たっていないのに
当たっていると判定されてしまうので基本的には小さく設定されることが多いですね。
代表例としてはシューティングゲームではないでしょうか?
あれは自機の中心に円系のアタリ判定を実装していることが基本になっているのではないでしょうか。
東方等の弾幕シューティングゲームの場合、キャラと同じ大きさの判定を持っていては
あの小さい隙間を通ることは不可能なので、基本的には小さく設定します。
開発中は別に同じ大きさでも問題ないかと思います。
プレイしてみて簡単すぎたりシビアすぎたりしたら判定のサイズを変更すれば調整可能になります。
ステージを用意する
プレイヤーだけを作っても何もできないので、動き回るためのステージを作りましょう。
何をするかというと、プレイヤーのようにスプライトを使って壁やブロックなどを作ります。
スプライトを使うことで動く床や某即死ゲーみたいに動く針とかも作れます。
しかしすべてスプライトにしてしまうと処理負荷がかかってしまうので、
まったく動かないであろうものは画面全体の背景として1つの背景にしてしまうと軽くなります。
ネタバレしておくと、結局それもテクスチャを貼ったりする大きいサイズのスプライトになっちゃうんですが、
ステージは基本的に固定なので動かすこともテクスチャを更新することもほとんどないので処理負荷を抑えられます。
ですがそのまま背景に当たり判定をつけてしまうとプレイヤーがまったく動けなくなる(常にぶつかってるという判定になるため)
ステージそのものには基本的に当たり判定をつけません。
しかし判定がないと地面が見えているのにプレイヤーは当たり判定にぶつからないので
重力があった場合落下していきますね。
それじゃあどうするかというと、見えない矩形を使い、背景の地面や建物に沿って当たり判定を作成することによって
プレイヤーをステージ上の道路を歩かせたりするのです。
そして、見えているものすべてに当たり判定をつける必要はありません。
例えば、街ステージを作ったとします。
2つのビルが建っていて、屋上に連絡通路みたいなものがあればそこを歩けるように当たり判定をつけますよね。
普通のプレイではその連絡通路の下には行くことは不可能にしている場合、
ビジュアル的に連絡通路の下に他の連絡通路があった場合、そこには当たり判定をつけなくても構いません。
別につけても構いませんが、プレイヤーが触れることのない当たり判定をつけても処理負荷が増えるだけなので、
必要な部分だけ当たり判定をつけていくのが基本の作り方になります。
この辺りは文字だけでは分かりづらい部分があると思うので、そのうち絵でも差し込んでおきます。
3Dゲームであればオブジェクトに対してアタリ判定と物理判定を付けられるので
楽なのですがその分処理も重たくなりますが3Dの場合はそうしないと作業量がすさまじくなるので仕方ないですね。
2Dゲームの場合は出来る限り処理を軽くするために必要最低限の当たり判定を作ることが多いです。
もう一ついうと、マリオのTAS動画とかを見たことがある人ならすぐに理解してもらえるのですが
本来は入れないであろう地面の中をマリオがマントで飛んでたりしますよね
ああいう感じで実際にプレイヤーがいけいない場所には当たり判定は基本つけていません。
そして、当たり判定は矩形だけではなく、線状でも作ることは可能です。
まさに地面の当たり判定にうってつけですね。
ただ、この線状の当たり判定には欠点があって、何かしらのめり込みを利用しされると
線の判定を抜けてしまって地面にめり込んでそのまま落ちてしまいます。
なので、地面は矩形で判定を作っておくと安心です。
……判定の説明をするとそれだけで1記事以上のボリュームになってしまうのでここで止めておきます。
プレイヤーの移動処理を作る
次に、プレイヤーを画面上で動かすためにキー入力処理を作ります。
使用する言語によって作り方は結構変わってくるのですが
ライブラリを使えばキー入力処理を用意してくれていたりするので、最初のうちはそっちを利用しましょう。
特にキャラクターが混乱とかなっていなければ右キーを押せばプレイヤーは右に進みますよね。
左に押せば左に進みます。当たり前ですね。
基本的にプログラムの世界では左上が始点になります。
見た目的に数学の勉強みたいになってしまうのですが、2Dの画面はXとYで表すことが多いです。
左上が0だとすると、一番左上は(x,y) = (0,0)と表現できますね。
右に10進むと(10,0)になって、そこから下に50進むと(10,50)となりますね。
なので右に進むときはx方向に加算と表現します。
左に進むときはもうおわかりですね。x方向に減算と表現します。
上下の時はxをyに変更するだけです。
しかしそれだけでは不十分で、コントローラーであれば大丈夫だと思いますが、
キーボードだと左と右を同時押しにすることもできますよね。
なので、条件分岐でどちらかを押されていればどちらかは動かさないという条件を作らないといけません。
プレイヤーのジャンプ処理を作る
次に今回のジャンプアクションゲームの要になります。
ジャンプ処理は様々な実装方法があるので一概にコレ!とは言えませんが
理想的なジャンプアクションと言えばやはりマリオやロックマンでしょうか?
マリオのジャンプは、グラフで書くと山型になりますね。
どういうことかというと、ジャンプボタンを押すとY座標を1ループごとに減算していき
限界点に達したらY座標を加算していくという感じにすればジャンプっぽくなります。
この時にYを減算する値は+1,+3+,+5,+7みたいに徐々に増やしていけば滑らかなジャンプになります。
落下する時も同じ感じですね。
テクニックとしてはこの減算する値は配列に仕込んでおいて
ゲームが1ループする度に次の配列を使うという風にやればスマートにコードが書けます。
配列を使いたくないという時は、forのループが回るたびに減算する値が増えていくという書き方にしてもいけますね。
後々ジャンプ力を変更したり、小ジャンプを実装したいときとかを考えると
配列にしておいた方が色々と楽になります。
針や動く敵などを障害物を用意する
ステージを作るときに少し説明しましたが、これもプレイヤーと同じでスプライトを使います。
「I wanna be the guy」でおなじみの背景のふりをした高速に移動してくる針を実装したりとか、
ロックマンの時間で出たり消えたりする床を作ったりするのにも使えますね。
あたりまえですが、他にも生き生きとした敵を実装するのにも使えます。
それぞれを動かすためにはスクリプトを組むのが楽なのですが
最初のうちは難しいと思うので、敵は無しでもいいかもしれませんね。
それ以外が完成したら実装していくという形にした方が挫折しにくくていいと思います。
クリアフラグを準備する
ゲームにはクリアが必要になります。
今回作るのはスクロールしない1画面で収まるタイプの簡単なジャンプアクションゲームなので
スタート地点とゴール地点を決めておけば大丈夫です。
ゴール地点にプレイヤが到達(座標をチェックして判定する)したり、ゴールフラッグに触れたらゴールとかでもいいですね。
当たり判定と条件式の仕組みを知っていれば簡単に実装出来ます。
──以上が簡単なジャンプアクションゲームの作り方になります。
これでもだいぶ端折っているのでもう少し詳しい解説が必要ですね……
これ以上のゲームの作り方を解説するとなると絵無しではそろそろ厳しそうな感じです。
ちょっと対策を考えようと思います。