2019年11月11日

ActiveBasicとDXライブラリでゲームプログラミング!~第13回・シューティングゲームを作ろう!その5

n88_reon.gif
玲音:こんにちは! 玲音です! ……あれ? 楓ちゃん、何か書いてるの?

n88_kaede.gif
楓:な、なんでもありませんよ! 見ないでくださいっ。

n88_reon.gif
なになに……。「きょうもかえでは、せんぱいにこうざにひきずりこまれました」
もう、楓ちゃんったら~。

n88_kaede.gif
えへへ……。それで先輩。確か今回は、当たり判定をするんでしたよね?

n88_reon.gif
うん、そうだよ。今回は、自機の弾と敵、自機と敵、自機と敵の弾の当たり判定を作って、当たった時に敵が消えたり、ゲームオーバーになったりする処理をやっていくよ。それじゃ、さっそく初めてみよう!

~関数を作ろう!

n88_reon.gif
それじゃ、まずはモノとモノとの当たり判定を行う関数を作っていこう!

n88_kaede.gif
関数、ですか?

n88_reon.gif
うん。そしてこの関数を、それぞれ(自機の弾と敵の時、自機と敵の時、自機と敵の弾の時)で使いまわすようにしていくんだ。そうすれば、処理がシンプルになるでしょ?

abdx1911-g01a.jpg

abdx1911-g01b.jpg

n88_kaede.gif
なるほどっ。さすが、私のこの講座に引きずり込んだ先輩ですっ。

n88_reon.gif
だから、引きずり込んだんじゃないってばぁ……。こほん、それじゃ続いて、当たり判定の考え方ね。
まずはこの図をみて。

abdx1911-g02.jpg

n88_reon.gif
これが当たっている状態ね。これを見て、何か気づかないかな?

n88_kaede.gif
あっ! 当たっている状態というのは、中心同士の距離が、二つのものの幅の半分の合計より小さい状態なんですね!

n88_reon.gif
そういうこと。こうなっているかどうか判定して、条件が成立したら、当たっているという判定を返せばいいんだよ。というわけで、それを関数にしたものがこちらです!

abdx1911-l01.jpg

n88_reon.gif
まず、p〇1とついているのは物体(自機や弾、敵など)1の位置や大きさの情報。p〇2とついてるのは物体2の情報だよ。
そして、まず12行目から16行目まで(赤枠の部分)では、各物体の中心の位置を計算しているよ。
そして18行目からがいよいよ本番。中心の間の距離と、幅(高さ)の半分の合計を計算し(青枠の部分)、そしてこれを比べて、当たっていれば、1を返し、そうでなければ0を返すようにしてるんだ(緑枠の部分)。

n88_kaede.gif
なるほどー。あ、先輩、このAbsっていうのはなんなんですか?

n88_reon.gif
うん。それは、引数の絶対値を返す関数だよ。簡単に言うと、値のマイナスを取って返してくれるもの。

n88_reon.gif
これを使わないと、比較するために、値が正の数かどうかチェックして、負の数だったら正の数に直す手間がかかるからね。

n88_kaede.gif
なるほどー。

n88_reon.gif
さて、それじゃ、次はこの関数を使って行こう!

~関数を使おう!

n88_reon.gif
まずは、自機の弾と敵との当たり判定ね。考え方は簡単。全ての自機弾と敵のデータをチェックして、双方ともある組み合わせの時のみ、判定の関数を呼び出して判定する、という形。というわけで、そのためのサブプロシージャがこちら!

abdx1911-l02.JPG

n88_reon.gif
続いて、自機と敵、自機と敵の弾の当たり判定だよ。こちらも考え方は、さっきと同じ。ただ、自機は一機しかいないし、自機に当たったらゲームオーバー画面に行くので、自機があるかどうかの判定はしてないところが違うの。

abdx1911-l03.JPG

abdx1911-l04.JPG

n88_reon.gif
これができたところで、これらの関数をGameMainサブプロシージャに組み込もうか。次のコードをGameMainサブプロシージャに付け加えてね。

abdx1911-l05.JPG

abdx1911-l06.jpg
↑書き直した後のGameMainがこちら。(赤枠が追加した部分です)

n88_reon.gif
なお今回は、ゲームオーバーの処理は作ってないから、敵や弾に当たったら画面が黒くなるだけになってる。そこらへんは次回にやっていくよ。では実行してみよう!




n88_kaede.gif
おー! こちらの弾で敵を倒せたり、弾や敵に当たったら画面が黒くなるようになりましたよ!

n88_reon.gif
それでは今回はここまで。次回はいよいよラスト。スコアをいれたり、タイトルやゲームオーバー画面を入れたり、BGMを入れたりしていくよ。よろしくね!

==========

※次の更新は、『師匠TのチャレンジARSゲーム』の予定です。お楽しみに!

2019年10月14日

ActiveBasicとDXライブラリでゲームプログラミング!~第12回・シューティングゲームを作ろう!その4

n88_reon.gif
玲音:こんにちは! 玲音です!

n88_kaede.gif
楓:こんにちは! 気づいたら、この講座に引きずり込まれてた、玲音先輩の後輩の楓です!
今月もよろしくお願いします!

n88_reon.gif
あ、言われちゃった。しまったなぁ。だから、引きずり込んだんじゃないってばぁ……。

n88_kaede.gif
えへへ、それで先輩。今回は、弾の発射処理を作るんでしたよね?


n88_reon.gif
うん。その通り。今回は、弾の発射角度の計算から、そこから弾の移動量を計算する処理、そして実際の弾の移動をやっていくよ。張り切っていこう!

n88_kaede.gif
はーい!


~まずするべきことは?

n88_reon.gif
さてさて。弾の処理を作る前にするべきことがあります。それはなんでしょう?

n88_kaede.gif
はーい! 弾の変数を用意して初期化し、そして弾の画像を読み込んでおくことでーす!

n88_reon.gif
それでは、まずは弾の変数の定義からやっていこうー!
''メイン関数 の前あたりに、次の文を書いてね。

abdx1910c01.JPG

n88_kaede.gif
新しい配列変数、bVX()とbVY()が登場しましたね。これはどんな役割をする変数なんですか?

n88_reon.gif
うん。この二つは、弾の移動量を保存しておく変数だよ。bVX()がX(横)方向、bVY()がY(縦)方向。この分だけ、弾を動かすようにするんだ。

n88_kaede.gif
なるほどー。

n88_reon.gif
bFlag()はその弾が存在しているかどうかを表す変数、bX()、bY()が位置を表す変数だよ。

n88_kaede.gif
hnbBalletは、弾の画像のハンドルが入る変数ですよね。

n88_reon.gif
その通り。そして、BALLETSは弾の数を表す定数だよ。では続いて、弾の初期化をする関数を作っていこう!
こちらだよ。

abdx1910c02.JPG

n88_kaede.gif
そんなに難しくないですね。

n88_reon.gif
そうだね。For~Nextで回して、配列変数bFlag()に0を入れてるだけだからね。
あ、そうだ。敵キャラの情報を初期化するサブプロシージャも作らないとね。こちらだよ。

abdx1910c03.JPG

n88_reon.gif
では、これらを呼び出す命令も入れていこう。サブプロシージャStageInitの中にこれを書いてね。

abdx1910c04.JPG

abdx1910l01.JPG
↑入れた後のStageInitはこうなります。(赤枠が追加した文)

n88_reon.gif

続いて、画像を読み込む部分も書いていこうか。サブプロシージャMaterialLoadにこれを追加して。


abdx1910c05.JPG

abdx1910l02.JPG
↑入れた後のMaterialLoadはこうなります。(赤枠が追加した文)

n88_reon.gif
さて、ここまでできたら準備はOK! いよいよ本番だよ!

n88_kaede.gif
はーい!


~弾を作るために必要なものは?

n88_reon.gif
さて、弾を作る処理を作る前に、一つ作らなければならない処理があります。それはなんでしょう?

n88_kaede.gif
うーん、なんでしょうか? わからないですー。

n88_reon.gif
くすくす。それは、弾を撃つ敵機と自機との角度を求めることと、その角度を元に移動量を計算することでーす。
ということで、まずは角度を計算する関数を作ろう。まずは、次のファイルをダウンロードして、解凍したAtan2.dllをプログラムのフォルダに入れてね。


n88_reon.gif
それが済んだら、次の行をプログラムの一行目に追加してください。

abdx1910c06.JPG

n88_reon.gif
それができたら、いよいよ関数を作っていきましょう! こちらです!

abdx1910c07.JPG

n88_reon.gif
まず、最初に追加したDeclareから始まる文は、ActiveBasicに、Atan2.Dllの中に入っている_Atan2という関数を使いますよ、と教えている文だよ。これを書くことによって、この関数を使えるようになるの。

n88_kaede.gif
ふむふむ。

n88_reon.gif
そして関数の中身だけど、ちょっと難しいから細かいことは省略するね。やっていることは、自機と敵機の間の角度を求めている、というもの。なお、求めているのは普通の角度ではなくてラジアンだよ。

n88_kaede.gif
ラジアン?

n88_reon.gif
ラジアンというのは、(180÷π)度を1ラジアンとする、特別な角度の単位で、コンピュータの世界ではよく使われるんだよ。さて、続いて、弾を作る処理をやっていこうか。まずは、空いている弾を探す関数ね。

abdx1910c08.JPG

n88_reon.gif
これについて難しくないよね。今までやってきたのと同じだから。

n88_kaede.gif
はいっ。

n88_reon.gif
それでは続いて、弾を作る処理です!

abdx1910c09.JPG

n88_reon.gif
ここは、基本的には、敵やショットを作るときと同じ。弾の位置を決める方法が違うのと、移動量を決めているのが違いだね。

n88_kaede.gif
弾の位置を決める時には、どうして16を足して、5を引く、というようなことをしてるんですか?

n88_reon.gif
それは、弾の初期位置が敵の中心にしているのと、そしてdxDrawGraphを使うとき、指定するのは画像の左上隅の座標だからだよ。敵の画像サイズは32×32だから、その半分の16を足して、敵の中心の位置を計算して、そこから弾のサイズの10の半分である5を引いて、弾の左上の座標を計算してるんだ。
Angle関数の中で、敵の位置に16を足しているのも同じ理由だし、自機の位置に数値を足してるのも同じ。

n88_kaede.gif
なるほどー。

n88_reon.gif
さて、そしたら後は弾の処理だね。まずは弾の移動!

abdx1910c10.JPG

n88_reon.gif
弾は、いろんな方向に飛ぶから、ここでは上下左右について、画面外に出たかどうかをチェックしているよ。そして出たら弾を消している、と。では続いて、弾の描画処理です!

abdx1910c11.JPG

n88_reon.gif
そして、これらの処理を呼び出すBalletMainサブプロシージャです!

abdx1910c12.JPG

n88_reon.gif
そして、弾を発射するコードを、MoveEnemyサブプロシージャ内に書きましょう!
配列関数eTimeCnt()を1ずつ増やしていき、eFireTime()と同じ値になったら、BalletCreateサブプロシージャを呼び出して、eTimeCnt()を0にする、ということをしているよ。

abdx1910c13.JPG
↑処理を追加した後のMoveEnemyはこうなります。(赤枠が追加した部分)

n88_reon.gif
そして、後は、GameMainサブプロシージャに次の一行を書き加えればOKだよ。できたら実行してみてね。

abdx1910c14.JPG

abdx1910l03.JPG
↑入れた後のGameMainはこうなります。(赤枠が追加した文)

n88_kaede.gif
おー! 敵が弾を撃ってくるようになりましたよ!




n88_reon.gif
それでは、今回はここまで。次回は自機と敵、自機と敵弾、敵とショットの当たり判定を作っていくよ! また次回!

n88_reon.gif
そうそう、今回から、その回までのソースファイルを公開することにしたよ。こちらからダウンロードしてね!


==========

※次の更新は、『師匠TのチャレンジARSゲーム!』の予定です。お楽しみに!

2019年09月09日

ActiveBasicとDXライブラリでゲームプログラミング!~第11回・シューティングゲームを作ろう!その3

n88_reon.gif
玲音:どうも玲音です! さてさて、楓ちゃんに変なこと言われる前に、講座を始めていきましょう!
今回は、敵の表示と移動について説明していきますよ!

n88_kaede.gif
楓:先手打たれちゃったー。どうも、楓です。今日もよろしくお願いしますっ。

n88_reon.gif
ふふん、私だって、いつもやられてばかりじゃないよー。それじゃ初めていきましょう!


~敵に必要な変数は?~

n88_reon.gif
さて、まずは敵の移動や表示に関係する変数の定義から始めていこうか。
''メイン関数 の前のあたりに、次のコードを書いてね。

abdx1909-c01.JPG

n88_kaede.gif
あの、先輩。このeFlagって配列変数はなんですか?

n88_reon.gif
うん。それは、その番号の敵が出現しているかどうかを表すフラグだよ。これが1になってる敵だけを表示、移動させるようにするんだ。

n88_kaede.gif
なるほどー。

n88_reon.gif
それと、eFireTimeは、出現してから弾を発射するまでの時間。eTimeCntは出現してから経過した時間だよ。
eTimeCntがeFireTimeと同じになったら、弾を発射するようにする予定。

~敵を作ろう!~

n88_reon.gif
さて。それでは、まずは敵を出現させる処理から作っていこうか。でもその前に一つやっておかなくちゃならないことがあるの。わかる?

n88_kaede.gif
しなくちゃならないこと? うーん……。

n88_reon.gif
それは、まだ使われていない番号を探すこと。使われている番号を使ってしまうと、移動中の敵が、突然別のところに出現した!ってことになっちゃうでしょ?

n88_kaede.gif
あぁ、なるほどっ。

n88_reon.gif
ということでさっそく、使われていない敵の番号を探す関数、FindEmptyEnemyを作りましょう。これですっ!

abdx1909-c02.JPG

n88_reon.gif
といっても、やってることは前回作ったGetShotIDと同じだけどね。

n88_kaede.gif
ふむふむ。これを使って、見つけた番号に敵を作っていくわけですね!

n88_reon.gif
うん、その通り。それでは改めて、敵を作るサブプロシージャ『CreateEnemy』を作っていきましょう! とはいっても、やってることはCreateShotとほぼ同じだけどね。

abdx1909-c03.JPG

n88_reon.gif
出現するX座標と弾を発射するまでの間隔は、乱数(でたらめな数)で決めてるよ。dxGetRand関数は、0から()の中までの乱数を返すものだってことは、前の講座で話したよね。

n88_kaede.gif
はいっ。

n88_reon.gif
13行目の

eFireTime(id) = 40 + dxGetRand(20)

にも注目。
このような書き方をすることで、例えばこの例だと40から60までの乱数を取り出すことができるよ。

n88_kaede.gif
なるほどー。

n88_reon.gif
さて、次は移動と表示の処理も作っていこうか。と言っても、することは難しくないよ。For~Nextのループで敵の番号を回して、eFlagが1のものだけを移動、そして表示させてるだけ。そして移動の結果、敵が画面外に出たら、eFlagを0に戻してる、と。

n88_kaede.gif
ふむふむ。

n88_reon.gif
では、まずは画像の読み込みからやっていこうか。
サブプロシージャMaterialLoadに、次のコードを書いてね。

abdx1909-c04.JPG

abdx1909-r01.JPG
↑追加後のMaterialLoadはこうなります。(赤枠で囲まれたのが追加したところ)

n88_reon.gif
続いて、敵の移動を処理するサブプロシージャMoveEnemyだよ。

abdx1909-c05.JPG

n88_reon.gif
そして、こちらが敵の描画を処理するサブプロシージャDrawEnemy。やっているのが移動か描画の違いだけで、ほとんど、MoveEnemyと同じだけどね。

abdx1909-c06.JPG
n88_reon.gif
そして、この二つのサブプロシージャを実行し、さらに敵の出現の制御を行う、いわば上記二つのサブプロシージャの親玉というべきサブプロシージャ、EnemyMainだよ。

abdx1909-c07.JPG
n88_reon.gif
ここでは、MoveEnemyとDrawEnemyを呼び出す他にも、totalTimeをカウントアップして、30の倍数になるごとに、CreateEnemyを呼び出して敵を作ることもやっているよ。Mod演算子は、割った余りを計算する演算子なんだけど、このように使えば、一定の値ごとに処理を呼び出す処理を作ることができるんだ。

n88_kaede.gif
なるほどー。

n88_reon.gif
さて、ではこのEnemyMainサブプロシージャを、GameMainの中に組み込もう! GameMainの中に、次のコードを付け加えてね。

abdx1909-c08.JPG

abdx1909-r02.JPG
↑付け加えた後のGameMain。(赤枠内が追加されたコード)

n88_reon.gif
できたら実行してみて。

n88_kaede.gif
はーい。おおっ! 画面の上から敵キャラが下に移動していきますっ!

n88_reon.gif
では今回はここまで。次回は、弾を撃つ処理をやっていくよ。よろしくね!

==========

※次の更新は、『師匠TのチャレンジARSゲーム!』の予定です。お楽しみに!

2019年08月12日

ActiveBasicとDXライブラリでゲームプログラミング!~第10回・シューティングゲームを作ろう!その2

n88_reon.gif
玲音:どうもこんにちは! B-Maga編集部の紅一点・玲音です!

n88_kaede.gif
楓:こんにちは! その玲音先輩に講座に引きずり込まれた、後輩の楓です!

n88_reon.gif
だから、引きずり込んだんじゃないってばぁ……。
さてさて、シューティング編第2回は、自機の移動と、弾の発射をやっていきますよー。

n88_kaede.gif
はーいっ。

~その前に……

n88_reon.gif
その前に……ごめんなさいっ。
前回説明した準備と、プログラムについて、いくつか間違いがありましたので、訂正させていただきますっ。

n88_kaede.gif
まず準備についてですが、画像を入れる他に、することがあったのでした。下のファイルをダウンロードして、解凍してできた二つのファイルを、プロジェクトのフォルダにコピーしてください。


n88_kaede.gif
なお、このファイルは、配布元のサイト様が閉鎖されてしまったので、やむを得ずこちらで代理公開させていただいてます。ご了承ください。

n88_reon.gif
さて、それができたら、元型のプログラムの一行目を次のように直してくださいね。

(旧)
#include "../DxLib.sbp"

(新)
#include "./DxLib.sbp"

n88_reon.gif
これができればOKですよ。この説明が抜けていたこと、改めて謝罪させていただきます。申し訳ありませんっ。

n88_kaede.gif
さて、それでは本題にいきましょうー。

~キャラを表示させてみよう

n88_reon.gif
さて。それでは、まずは自機のキャラを表示させてみようか。
まずは……

''※このほかにも必要な変数があればこの下に追加してください

n88_reon.gif
この行の下に、次の一行を追加してね。

abdx1908-l01.JPG

n88_kaede.gif
自機キャラのグラフィックのハンドルを入れる変数を用意してるんですよねっ。

n88_reon.gif
その通り。その下のpX、pYは自機の座標を入れる変数だよ。
では、そのグラフィックを読み込む処理を書いていこうっ。サブプロシージャMaterialLoadに、次の一行を書いてね。

abdx1908-l02.JPG

n88_reon.gif
そしてそれが済んだら、新しい関数、JikiDraw()を作りましょう。内容はこの通りだよ。

abdx1908-l03.JPG

n88_kaede.gif
(変数pX, 変数pY)の位置に、自機を表示させてるんですね。あっ、先輩、でもまだpXとpYの値を決めてませんよ?

n88_reon.gif
あっ、そうだったね。それじゃ、サブプロシージャPlayInitに次の行を書き加えよう。

abdx1908-l04.JPG

n88_reon.gif
さて、ここで元型にもともと備わってる定数について説明するね。
SCREEN_XとSCREEN_Yは、ゲーム画面の右上の座標だよ。

n88_kaede.gif
どうして、(0, 0)に固定しないんですか?

n88_reon.gif
それは、ゲームによっては画面を全部使わずに、画面の中央あたりにゲームの画面を置いて、その外にスコアなどの情報を置く場合があるからだよ。そういう画面構成にすることも考えて、画面左上の位置も変えられるようにしてあるんだよ。

n88_kaede.gif
なるほどー。

n88_reon.gif
それと、SCREEN_WとSCREEN_Hは、ゲーム画面の幅と高さを表す定数だよ。

n88_kaede.gif
なるほどっ。

n88_reon.gif
それじゃ後は、サブプロシージャGameMainに、さっき作ったJikiDrawを呼び出すコードを書きましょう。このコードを書いてね。

abdx1908-l05.JPG

n88_kaede.gif
できましたーっ。……あれ? 先輩。実行しても、何も起こりませんよ?

n88_reon.gif
え? あっ……! ごめんごめん。臨時的に、Title()と書かれた行の下に、次の命令を書いてくれるかな?

abdx1908-l06.JPG

n88_reon.gif
元型では、タイトル画面でスペースキーを押してゲームスタートする前提になっているので、この行が抜けていたの。もちろん今回も、タイトル画面の処理をいれたら、この行は消すからね。

n88_kaede.gif
はーい。

n88_reon.gif
それじゃ続いて、このキャラクターを移動させよう!

~自機を動かそう!

n88_reon.gif
ではまず、自機を動かすためのサブプロシージャを作ろう。名前はJikiMoveにしておこう。

abdx1908-l07a.JPG
abdx1908-l07b.JPG

n88_reon.gif
それができたら、サブプロシージャGameMainに、JikiMoveを呼び出すコードを書き加えましょう。JikiDraw()の前に、次の行を書き加えるんだよ。

abdx1908-l08.JPG

n88_reon.gif
ここまでできたら、実行してみてね。

n88_kaede.gif
おぉっ! 自機がカーソルキーで動かせますよ!

n88_reon.gif
このサブプロシージャの前半部分(赤枠の部分)は説明しなくてもいいよね。押されたカーソルキーによって、位置を表す変数の値を変えているだけ。ここのコツは後半部分(青枠の部分)だよ。

n88_kaede.gif
前半部と同じく、IF文がたくさん並んでますね。ここでは何をしてるんですか?

n88_reon.gif
ここでは、キャラクターがゲーム画面をはみ出ていないかをチェックして、もしはみ出ていたらはみ出ないように位置を修正しているんだよ。具体的には、X位置が画面の幅の範囲を超えていないか、Y位置が画面の高さの範囲を超えていないかをチェックしてるの。

abdx1908-z01.jpg

n88_kaede.gif
なるほどー。

n88_reon.gif
さて、次は弾を発射させるよ!

~弾を発射しよう!

n88_reon.gif
さて、次は弾を発射するわけだけど、弾には位置だけでなく、存在しているかどうかのフラグが必要になるよね。

n88_kaede.gif
あ、そうですね。

n88_reon.gif
その考えをさらに進めて、存在しているフラグの立っている弾だけ移動させて、表示させるようにしようと思います。そして、発射ボタンを押した時に、フラグが立っていない弾のフラグを立てて、弾が画面外に出たか敵に当たった時にフラグを倒す、と。

n88_kaede.gif
なるほどー。

n88_reon.gif
それでは、まずは弾の情報からだね。

''※このほかにも必要な変数があればこの下に追加してください

n88_reon.gif
この行の下あたりに、次の行を追加してね。

abdx1908-l09.JPG

abdx1908-r01.JPG
▲ 入れた後はこうなります(青枠が追加した部分です)

n88_kaede.gif
hndShotは、弾の画像のハンドルが入る変数ですよね。

n88_reon.gif
うん、そうだよ。そして、ShotFlag、ShotX、ShotYはそれぞれ、フラグ、X座標、Y座標を入れる配列変数ね。ではまずは、画像をロードする処理を書こうか。このコードを、サブプロシージャMaterialLoadに書いてね。

abdx1908-l10.JPG

abdx1908-r02.JPG
▲ 入れた後のMaterialLoad(枠が追加した部分です)

n88_reon.gif
ここは難しいところはないよね。それじゃ続いて、フラグを全部0にするサブプロシージャも作っておくよ。
こちらです!

abdx1908-l11.JPG

n88_reon.gif
できたら続いて、サブプロシージャStageInitに、今のサブプロシージャを呼び出すコードを書いてね。

abdx1908-l12.JPG

n88_kaede.gif
あの、先輩。どうしてこんなことをするんですか?

n88_reon.gif
やられたりした後、ゲームをやり直す時のことを考えてみて。弾を消さないでおくと、再会した時に、前のプレイの時の弾が残っちゃうでしょ?

n88_kaede.gif
あぁ、なるほどー。

n88_reon.gif
さて、次に、弾を移動させ、表示するサブプロシージャを作りましょう。こちらです!

abdx1908-l13.JPG

n88_reon.gif
やっていることは難しくないよ。まず、4行目と17行目のForとNextで、弾の数だけ繰り返し、もしチェックする弾のフラグが1だったら、7行目でその弾を上に移動。9~11行目では、もし弾が画面の上端を超えたら、フラグを0に戻してます。そしてその後再び、フラグが1だったら、弾を表示する、ということを13~15行目でやっています。

n88_kaede.gif
なるほどっ。

n88_reon.gif
では、このサブプロシージャを呼び出すコードを、GameMainに書き加えましょう。

abdx1908-l14.JPG

abdx1908-r03.JPG
▲ 入れた後のGameMain(枠が追加した部分です)

n88_reon.gif
最後は、弾を発射する処理だね。まずは、存在していない弾の番号を取得する関数を作りましょう。こちらです!

abdx1908-l15.JPG

n88_reon.gif
やってることは難しくないよ。ただ、フラグが0になっている(つまり存在していない)弾の番号を変数に入れて、その変数の値を返しているだけ。全部埋まっているときは-1を返しているよ。

n88_kaede.gif
ふむふむ。

n88_reon.gif
では続いて、弾を作る処理も作っちゃいましょう。これもやっていることは難しくないよ。さっきの関数から番号を受け取り、その番号のフラグを1にして、位置をセットしているだけ。位置は、ちょうど横位置が自機の中間地点、そして縦位置がちょうど自機の真上になるようにしているよ。

abdx1908-l16.JPG

n88_reon.gif
さて。最後に、ボタンを押したらショットを発射する処理だけど、ここはちょっと面倒。まずは、

''※このほかにも必要な変数があればこの下に追加してください

n88_reon.gif
の行の下のところに、次の文を書いてね。

abdx1908-l17.JPG

abdx1908-r04.JPG
▲ 入れた後はこうなります。(青枠の部分が追加したところです)

n88_reon.gif
そして次に、サブプロシージャJikiMoveの一番後ろあたりに、このコードをいれます。

abdx1908-l18.JPG

abdx1908-r05a.JPG
abdx1908-r05b.JPG
▲ 入れた後のJikiMoveはこうなります。(枠の部分が追加したところです)


n88_reon.gif
ここでは、発射ボタンを押してる間、カウンタの変数を加算していって、その値が、定数RAPIDの数ごとに、CreateShot()を呼び出して、弾を発射してるんだよ。

n88_kaede.gif
先輩。どうしてそんなことを?

n88_reon.gif
このようにしないと、押している間、弾が途切れなく発射されて、一本の線みたいになっちゃうんだ。だから、一定間隔ごとに発射するようにしているんだよ。

n88_kaede.gif
なるほどー。

n88_reon.gif
ここでのポイントは、2行目と4行目だよ。まず2行目は、このようにmod演算子(余りを計算する演算子)を使うことで、0~ある数を繰り返すようになるんだよ。

n88_kaede.gif
ふむふむ。

n88_reon.gif
そして4行目。このようにすることで、一定数ごとに処理をすることができるんだよ。例えば今回の例だと、RAPIDの値、つまり10の倍数になるごとにCreateShotを呼び出すことになってるんだね。

n88_kaede.gif
なるほどー。とてもためになるテクニックです!


n88_reon.gif
さて。長くなったけど、今回はここまでっ。次回は、敵の移動の処理を作っちゃいますよ! それでは……。

n88_kaede.gif
また次回~!

==========

※次の更新は、『師匠TのチャレンジARSゲーム!』の予定です。お楽しみに!

2019年07月08日

ActiveBasicとDXライブラリでゲームプログラミング!~第9回・シューティングゲームを作ろう!その1

n88_reon.gif
玲音:どうもこんにちは、玲音です!

n88_kaede.gif
楓:どうもこんにちは! 玲音先輩に勧誘されて、この講座を一緒に担当している楓です!

n88_reon.gif
今度は『勧誘』ときたかー。さてさて、今回からは、いよいよシューティングゲームを作っていきますよ! ショットの発射はもちろん、当たり判定もやっていきますので、お楽しみに!

n88_kaede.gif
はーい。さっそく、はじめていきましょー!



~新しい元型と準備です!

n88_reon.gif
さてさて、ここで一つ重要なことがあります。ActiveBasicとDXライブラリの組み合わせでは、なぜか大がかりなプログラムになると、前の元型では正しくコンパイルできなかったり、動かなかったりすることがあるの。だから……。

n88_kaede.gif
前の元型とは違う元型を使う必要があるってことですねっ。

n88_reon.gif
そういうことです。ということで、新しい元型がこちら!

list1907-01.JPG
list1907-02.JPG
list1907-03.JPG
list1907-04.JPG
list1907-05.JPG
list1907-06.JPG

n88_reon.gif
今回は、この元型に色々肉付けしていくことで、ゲームを作っていくよ。よろしくね!

n88_kaede.gif
はーい!

n88_reon.gif
ではまず、準備から始めていこうね。まず、フォルダを作って、その中に、次の素材をダウンロードして入れましょう!

title.jpg
▲ タイトルの画像

gameover.jpg
▲ ゲームオーバー画面の画像

jiki.bmp
▲ 自機の画像

shot.bmp
▲ ショットの画像

enemy.bmp
▲ 敵機の画像

tekitama.bmp
▲ 敵弾の画像

n88_reon.gif
そしたら続いて、ActiveBasicを起動し、先ほどの元型のプログラムリストを打ち込みます。出来上がったら、同じフォルダに、適当な名前をつけて保存してね。それで準備完了だよ!

n88_kaede.gif
おーー!!

~新元型の解説だよ!

n88_reon.gif
さてここで、この元型の説明をするね。まずは、関数Main。これはその名前の通り、主な処理を行う関数だよ。ここは基本的には、特にいじることはありません。

n88_kaede.gif
ふむふむ。

n88_reon.gif
DxInit関数とDxEnd関数も、特にいじることはないよ。私たちが処理を書いていくのは、そのほかの、AppInit、MaterialLoad、Title、PlayInit、StageInit、GameMain、GameClear、Miss、GameOverの9つの関数。まずは、AppInit関数から説明していくね。

n88_kaede.gif
はーいっ。

n88_reon.gif
これは、ゲームを起動したときに行う処理をする関数。例えば、ハイスコアを初期化したりとかね。

n88_kaede.gif
ふむふむ。

n88_reon.gif
次はMaterialLoad関数。これは、その名前の通り、画像やBGM、効果音などの素材を読み込む処理を書く関数だよ。

n88_kaede.gif
次のTitle関数は、タイトル画面を出したり、キーを押したらゲームをスタートしたりなどの、タイトル画面についての処理を書くところですよね。

n88_reon.gif
うん、そのとおり。その後のPlayInitは、ゲームスタート時の初期処理、StageInitは各ステージ開始時の処理を書く関数だよ。

n88_kaede.gif
その後のGameClear、Miss、GameOverはそれぞれ、ゲームやステージをクリアした時、ミスした時、ゲームオーバーになった時の処理を書く関数ですねっ。

n88_reon.gif
うん、正解っ。その通りっ。さて、次回からはいよいよプログラムを書いていくよ。まず次回は、自機の移動やショットの発射処理を書いていきます。お楽しみにねっ。

n88_kaede.gif
また次回~。



※次の更新は、『師匠TのチャレンジARSゲーム』の予定です。お楽しみに!