本節は読者用の課題である。
本節の課題はオブジェクトから弾を発射するプログラムの作成である。
オブジェクトから弾を発射するプログラムについては本章の2-11節から2-17節にかけて扱ったが、そこで使われた弾は図1に示される Shell というオブジェクトであり、Shellの形状は円盤(実際には正8角形)なのでShellをどの方向に発射してもShellの向きを変える必要はなかった (図2 ; Shellはその移動中 位置だけが変化し、向きは初期状態から変わらない)。
図1 Shell 初期状態 (正8角形)
図2 Shellの発射 (どの方向に発射しても向きは初期状態のまま) しかし、今回使用するShellは下図3に示される縦に細長い形状のもので、このShellには向きがあり初期状態においては y軸プラス方向を向いている。今回のShellには向きがあるので上記の円盤型のShellと異なり、発射する際には適切な向きに回転した状態で発射しなければならない。
例えば下図4に示されるオブジェクト Plane からこのShellを発射するとしよう。図4はPlaneの初期状態であり、初期状態ではPlaneは y軸プラス方向を向いており、初期状態においてはPlaneとShellの向きは同じである。
図3 Shell 初期状態
図4 Plane 初期状態 下図5はPlaneに何も回転を行っていない状態でこの細長いShellを発射しているときの様子である。Planeには回転が行われていないのでその向きは y軸プラス方向であり、Shellの発射方向も同じく y軸プラス方向である。図5のShellにも回転は行われておらず、毎フレーム y軸プラス方向に進んでいるだけである。図に示されるように、この場合にはShellに何も回転を行わなくても特に不自然ではない。
図6はPlaneに $-45^\circ$ の回転を行った状態でShellを発射しているときの様子であるが、ここで発射されるShellに対しても何も回転は行われていないのでShellの向きは初期状態の向きである y軸プラス方向のまま飛んでいくことになる。図に示されるように、この場合においては明らかにShellの向きは不自然である。
図5 回転の行われていないPlaneからShellを発射
図6 -45°の回転の行われたPlaneからShellを発射 Planeが $-45^\circ$ 回転した状態でShellを発射する際には、(y軸から) $-45^\circ$ の方向にShellが進んでいくことになるが(図7)、その場合にはShellも $-45^\circ$ 回転した状態で進んで行かなければならない (図8、図9)。
同様にPlaneが $60^\circ$ 回転した状態でShellを発射する際には、(y軸から) $60^\circ$ の方向にShellが進んでいくことになるが(図10)、その場合にはShellも $60^\circ$ 回転した状態で進んで行かなければならない (図11、図12)。
# Code1
ここでの課題は上図3の細長い形のShellをオブジェクトから連射するプログラムの作成である。
プログラムで使用するオブジェクトは下図13の Jet である。Jetは初期状態では上記のPlaneと同じく y軸プラス方向を向いている。今までの連射プログラムと今回のプログラムの主な違いは上で述べたShellの形状の他にもう1つあり、それは今回使用するJetにはShellの発射口が2箇所あることである。
図13 Jet 初期状態
図14 発射口が2つある 図14は初期状態におけるJetの発射開始位置と発射方向であるが、発射口が2箇所あるため図に示されるように発射開始位置が2つになっている (初期状態における発射方向はいずれも y軸プラス方向)。
したがって今回はJetからShellを発射する際にはこの
2箇所の発射口から同時に 2つのShellが発射されるようにしなければならない。具体的には以下のような実行結果になればよい。
図15 そして今回の課題では
使用するインスタンス変数や定数については読者の側で用意するものとする 。
2-11節~2-17節で使用したオブジェクトは
THAlphaObject2D クラスのオブジェクトであり、Shellは
THShell2D クラスのオブジェクトであったが、これらのクラスにはあらかじめ連射に必要なプロパティ(
lastShootFrame 、
shootInterval 、
initShootPosition など)が用意されていた。
しかしここで使用する Jet は
CustomJet 、Shell は
CustomShell というクラスのオブジェクトであり、これらのクラスは以下に示されるようにコンストラクタ以外は何もない空のクラスである。
public class CustomJet : THObject2D
{
public CustomJet(GameObject go) : base(go) { }
}
public class CustomShell : THObject2D
{
public CustomShell(GameObject go) : base(go) { }
}
したがって、今回の連射プログラムに必要なプロパティはこれらのクラスに追加しなければならない (もちろん
CustomJet 、
CustomShell の2つのクラスに何も追加しないで、独自にインスタンス変数などを用意する形でも構わない)。
(
CustomJet 、
CustomShell はいずれも
THObject2D クラスを継承しているので今までのプログラムで使用した
SetMatrix(..) 、
GetMatrix() 、
SetPosition() 、
GetPosition() などのメソッドは使うことができる。)
また Jetを動かす際には次のキー操作によるものとする (2-14節、2-17節のものと同じである)。
H : Jetの向きを反時計周りに回転
L : Jetの向きを時計周りに回転
S : Jetの移動/停止用スイッチ
A : Shellの連射
プログラムは Code1 に作成するものとする。Code1は始めの段階では初期化ブロックのみが記述されている。
[Code1]
if (!i_INITIALIZED)
{
i_INITIALIZED = true;
}
ここで用意されている
CustomJet クラスや
CustomShell クラスは上記のように空のクラスであるが、プログラム中で使用するオブジェクト Jet や Shell はもちろん null ではない。例えば初期化ブロックで以下のように記述すると、
if (!i_INITIALIZED)
{
Jet.SetMatrix(THMatrix3x3.identity);
for(int i=0; i<Shell.Length; i++)
{
Shell[i].SetMatrix(THMatrix3x3.identity);
}
i_INITIALIZED = true;
}
JetとすべてのShellが原点に置かれた状態になる (プログラム中のShellは要素数 $60$ の配列である)。
(解答例については Sec230_Ans.txt Code1 を参照)