プチコン3号経験者によるプチコン4まとめ (6) スプライト機能を生かしたシューティングゲーム【オマケ編】

[前編](https://qiita.com/yamachan360/items/77dd7bcf851a8f5f6b12)、[後編](https://qiita.com/yamachan360/items/21165c467bd1c0f9c4f7) と続けて、スプライト機能を生かしたシューティングゲームのサンプルを作成してきました。わりとシンプルな一画面プログラムなので、自由に改変して遊んでいただけたら嬉しいです。

というわけで、今回はオマケ編として、私自身がサンプルを改変して遊んでみたいと思います。一画面におさめるため機能を削ったとこを拡張したり、うっかり忘れていたコードを追加したり、あとゲームとしてもう少し複雑になるよう改善してみたり。今回はより自由にコードを書いてみたいな、と思います。

今回のコード、ほんと参考程度に、こんな書き方もあるんだなぁ程度で、生温く眺めていただけると嬉しいです。

# 今回のサンプル動画

![qiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/2c69ba19-9905-e08f-c989-3d5732f7aa00.gif)

# まずは一画面のまま改善

ざっとサンプルを眺めてみて、いくつか改善してみましたので、最初にご紹介しておきます。コードはこちら。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/3d5991a4-107c-1306-fdd9-b88eaa036617.png)
(1) は敵機が破壊された時に音が設定していなかったので、爆発音を設定しています。同様に (2) では自機がやられた時により派手目な爆発音を設定してみました。これら音の追加で、よりシューティングゲームらしさが出てきた気がします。

(3) については、ちょっと説明が必要です。もともとプチコン4で用意されている爆発パターンは4種類の画像によるアニメーションなのですが、これまでのサンプルではそのうち3つしか利用していませんでした。利用しなかった理由は、以下を見ていただければわかると思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/1689d621-7ac7-c3c7-94cf-74721bd3a055.png)
赤枠が最初から用意されている爆発のパターンなのですが、いちばん右にある4つ目のパターンだけ、画像サイズが異なることがわかります。しかも上の部分に違うパターンが格納されています。4つを同じ設定でアニメーション表示させると、この違うパターンまで表示されてしまいます。

対応方法は幾つかあるのですが、ちょっと面倒だし、コードが長くなるのでパターン3つ目までで我慢していた、という状況でした。

今回、ここをちゃんと対応しています。つまり、(3) の爆発用アニメーション定義において、4つ目のパターンも追記したのです。

そして余計なパターンを表示させないため、6行目に (4) のコードを追加しています。スプライトの機能って、結局は「グラフィック画面にある任意の小さな領域を、好きな位置に表示する」という機能ですから、元になるグラフィック画面を書き換えちゃえばいいよね、という発想です。具体的には、表示したくない余計なパターン部分を黒で塗りつぶしています。

以上4ヶ所の修正で、敵機や自機の爆発に音がつき、またその爆発パターンも本来の4種類の画像切り替えによる表現にすることができました。

さて、サンプルとしてはこれで完成、あとは私の好みで拡張していきます。

# 敵の種類を増やしてみる

私はわりと突進系の敵が好きなので、追加してみましょう。ちょっと小さくて、脆いけれど、スピードが速いので、撃つか避けるか判断を要求するような敵です。弾は撃ちません。こんな感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/9ba665b0-42c9-0354-4f98-863aae341ada.png)
コードのメイン部分では、以下のように、敵を生成している部分を拡張してみました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/b713a7f3-667b-470b-5752-7567e15ede18.png)
まず (1) の部分ですが、`ET` という変数を追加し、これがどんな敵を生成するかを示しています。その次で場合分けをしていますが `WHEN 1:` の部分は以前からいる敵機の生成なので、中身はほぼ同じです。

それに対して `OTHERWISE:` の部分が、新しい敵機を生成している部分になります。元からある敵機と比べると、違いが判り易いでしょう。まずスプライトのサイズを 16x16 と小さく指定し、アニメーションを同時に2つ定義し、また衝突判定のマップに 10 という値を指定しているのがわかります。

今回の敵機は回転しながら飛行するよう、(2) のように2つのアニメーションを定義し、同時に指定してあります。10行目は移動のためのアニメーション、11行目は回転(キャラの画像切り替え)のためのアニメーションの定義です。

衝突判定に関しては、ちょっと複雑になってきたので表にしてみました。縦に見て、同じ列に X があれば、その対象同士には衝突判定があります。今回、敵同士の衝突を避けるため、8 という新しいマスク値を導入しています。

| | 1 | 2 | 4 | 8 |
| :--: | :--: | :--: | :--: | :--: |
| 自機 | X | X | | X |
| 自弾 | | X | X | X |
| 敵弾 | | X | | |
| 敵機1 | X | | X | |
| 敵機2 | | X | | X |

この表を見ながら、(3)～(4) のマスク値が変更されていることを確認してみてください。

※ (4) は `SPCOL 0,,11` が正しいですね

また、敵機の種類が増えたので、`SPFUNC` に格納する値を増やしてあります。これまでは耐久度を示す `"HP"` だけ定義していましたが、スコア値を示す `"S"` と、敵機の種類を示す `"T"` を追加しました。

さて、後半の `SPFUNC` 用のロジック定義は、以下のように修正しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/bcddd299-aa9e-e037-ee73-73a9e1da52cb.png)

まず (1) では、敵機の種類を示すスプライト内の `"T"` の値を `ET` という変数に格納し、この後の処理で敵機の種類による場合分けをしています。

敵機2 は弾を撃たないので、(2) のように敵機1の場合だけ弾を撃つよう条件を追加しています。

また敵機2は他より小さく、爆発のパターンも小さくしないと不自然に見えますので、(3) の部分で爆発用スプライトのサイズ調整をしています。
![2019072818313600-B4374FDA41BFF09D976C1FEA83EFB230.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/43cd344a-ae32-760c-ce10-3f62f32bf098.jpeg)
とまあ、こんな感じで敵機の種類を増やしてみました。

# 更に敵の種類を増やしてみる

骨組みができたので、敵機の種類を増やしていくのは容易です。でもキリがないので、もう1種類だけ増やしてみましょう。未使用の赤い機体の画像を使ってみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/3f04aabc-083f-1beb-e6ee-f81e4305e7da.png)
赤だとやはりエース機のイメージでしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/17bdb752-4c84-91f7-d2ae-7b0b4f3e84c3.png)
※ 4行目の最後は `SPCOL 0,,11` が正しいですね

(1) の `WHEN 2:` の部分が、今回追加した赤い敵機の生成部分です。今回のちょっとした試みとしては、(2) のように移動のアニメーションを2種類用意し、そのどちらかをランダムにセットしていることです。

後半の `SPFUNC` 用のロジック定義は、以下のように修正しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/f59f470f-0355-1831-5c56-e2b47dbbcc86.png)

これらの修正は赤い敵機の追加とは直接の関係はなく、全体的な調整です。まず (1) は敵機どうしの接触による破壊に対応するものです。敵機の動きが複雑になってくると、接触も増えます。マスクだけだと敵機同士の当たり判定が発生し、勝手にダメージを与えあってしまうので、接触先をみてダメージを与えるように修正しました。

同様に (2)～(3) では、自機の弾に目印を付けておき、敵弾との相殺の際にその目印をチェックするよう修正しました。これにより敵弾同士の接触による消滅がなくなりました。

さて、実際にプレイしてみましょう。
![2019072821535701-B4374FDA41BFF09D976C1FEA83EFB230.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/a9a76b6d-8ed1-8cac-43fb-403611c52cf9.jpeg)
うん、だいぶゲーム性が増し、良い感じになってきました。

# 簡単なタイトルを追加しておく

最後は簡単なタイトルを追加して終わりにしましょう。
![2019072822433300-B4374FDA41BFF09D976C1FEA83EFB230.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/10b76671-c8ba-d0cf-7b9c-da96127aa819.jpeg)
全体のソースファイルをもういちど掲載しておきますね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/fb0185ad-a447-767c-fcbd-ba8cb0825907.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193519/540bf51a-36db-1dab-00d9-5d2b566395f6.png)

# というわけで！

[前回](https://qiita.com/yamachan360/items/21165c467bd1c0f9c4f7) で終わりのつもりが、ちょっと物足りなくて続けてしまいました。とりあえずゲームとして遊べる感じになったので、いったんここで終わりにします。

皆さんも自分の好きなように改造して、遊んでみてください。

それではまた！