ゲーム・スクランブルでは地上にミサイルが設置されていて戦闘機にむけて発射されます。
Mと書かれている部分がミサイル設置地点です。
Missileクラスの作成
まずミサイルのクラスを作成します。
メソッド
void Fly()
上へむけて移動させる
void Draw(Graphics g)
パネル上に描画する
プロパティ
int initX, initY
最初に設置されている座標
int moveY
どれだけ上へ移動したか?
bool IsDead
破壊されているかどうか?
(破壊されていなくても、描画の必要がない場合はIsDead == true とする)
bool IsFlying
飛行中かどうか
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
public class Missile { public Missile(Form1 form1, int x, int y) { initX = x; initY = y; MainForm = form1; } Form1 MainForm { get; set; } = null; public int initX { get; protected set; }= 0; public int initY { get; protected set; } = 0; public int moveY { get; protected set; } = 0; public void Fly() { if(!IsDead && IsFlying) moveY += 5; } public bool IsFlying { get; set; } } |
画面がスクロールされたり上へ移動した結果、表示する必要がなくなったら、IsDead = trueにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
public class Missile { bool isDead = false; public bool IsDead { get { if(isDead) return true; int displacement = MainForm.Jiki.Displacement; // 画面が左にスクロールされて左から画面外へ。表示の必要なし。 if((initX - displacement < -10)) isDead = true; // 上昇して上から画面外へ。表示の必要なし。 if(initY - moveY < -10) isDead = true; return isDead; } set { // 破壊されたら isDead = trueにする isDead = value; } } } |
以下はミサイルを描画するためのメソッドです。IsDead == trueなら表示の必要はありません。まだ発射されていないのであれば発射すべきかどうかも、ここで判定します。自機とミサイルの位置関係で判定していますが、すべてのミサイルが同じタイミングで発射されないように乱数を使っています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
public class Missile { Bitmap Bitmap = Properties.Resources.missile; static Random r = new Random(); public void Draw(Graphics g) { // IsDead == trueなら表示の必要なし if(!IsDead) { int displacement = MainForm.Jiki.Displacement; g.DrawImage(Bitmap, new Point(initX - displacement, initY - moveY)); // ミサイルは飛ばすべきか? // 発射するかどうか? int rand2 = r.Next(20); if(rand2 != 0) return; // 自機とミサイルの位置関係から発射するかどうか決める Point point = GetJikiPosition(); if(initX - point.X - 100 < initY - point.Y) IsFlying = true; } } public Point GetJikiPosition() { return new Point(MainForm.Jiki.Displacement + MainForm.Jiki.X, MainForm.Jiki.Y); } } |
Topographyクラスの変更
ミサイルの設置位置は地形クラスで管理します。Mがミサイルの設置場所です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
public class Topography { string topography0 = "□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□"; string topography1 = "□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□"; string topography2 = "□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□"; string topography3 = "□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□"; string topography4 = "□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□"; string topography5 = "□□□□□□□□□□▲△□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□"; string topography6 = "□□□□□□□□□▲■■△□□□□□□□□□□□□□□□□▲△□□□□□□□□□□□□□□"; string topography7 = "□□□□□□□□▲■■■■△□□□□□□□□□□□□□□▲■■△□□□□□□□□□□□□□"; string topography8 = "□□□□□□□▲■■■■■■△□M□MMMM□MMM□▲■■■■△□□□□□□□□□□□□"; string topography9 = "□□□□□□▲■■■■■■■■■■■■■■■■■■■■■■■■■■△□□□□□□□□□□□"; string topography10 = "■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■△□□□□□□□□□□"; string topography11 = "■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■△□MMMMMMMM"; string topography12 = "■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■"; string topography13 = "■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■"; string topography14 = "■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■"; } |
GetInitMissilePosition()メソッドは、ミサイルの設置座標を取得するためのメソッドです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
public class Topography { public List<Point> GetInitMissilePosition() { List<string> listTopography = GetListTopography(); List<Point> MissilePositions = new List<Point>(); // blockSizeとミサイルのサイズが違うので補正 Bitmap MissileBitmap = Properties.Resources.missile; int correction = MissileBitmap.Height - blockSize.Height; int y = 0; foreach(string str in listTopography) { Char[] vs = str.ToArray(); int x = 0; foreach(Char c in vs) { if(c == 'M') { Point pt = new Point(x * blockSize.Width, y * blockSize.Height - correction); MissilePositions.Add(pt); } x++; } y++; } return MissilePositions; } } |
その他のメソッド、プロパティ、フィールド変数は前回と同じです。
Form1クラスの変更
ゲームが開始されたらミサイルの設置位置を調べてミサイルの初期化をします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
public partial class Form1 : Form { List<Missile> Missiles = new List<Missile>(); // ミサイルの設置位置を調べてリストに格納する void InitMissiles() { List<Point> missilePositions = Topography.GetInitMissilePosition(); Missiles = new List<Missile>(); foreach(Point pt in missilePositions) { Missiles.Add(new Missile(this, pt.X, pt.Y)); } } private void GameStartMenuItem_Click(object sender, EventArgs e) { Jiki.DoesShow = true; InitMissiles(); Timer.Start(); } } |
Tickイベントが発生したらすでに発射されているミサイルのY座標を上へ移動させます。panelEx1.Invalidate()が実行されたらイベントハンドラPanelEx1_Paintによって自機と地形、ミサイルが描画されます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
public partial class Form1 : Form { private void Timer_Tick(object sender, EventArgs e) { TimerTick_JikiMove(); CheckIsDead(); foreach(Missile missile in Missiles) { // ここでミサイルの飛行中のY座標が変化する missile.Fly(); } panelEx1.Invalidate(); } private void PanelEx1_Paint(object sender, PaintEventArgs e) { Jiki.Show(e.Graphics); Topography.Show(e.Graphics); foreach(Missile missile in Missiles) { missile.Draw(e.Graphics); } } } |