本物のRally-Xには燃料計があります。現在作成中のRally-Xもどきにも燃料計を表示させます。
ラリーX – Wikipediaによると、
マイカーには燃料計があり時間経過とともに減少する。煙幕を発生させるとその分だけさらに減少する。燃料切れになってもミスにはならないが、スピードが劇的に落ちるので、レッドカーに追いつかれることが必至の状況に陥る。ラリーXでは自車がかなり高燃費であり、特にチャレンジングステージでは最速ルートでフラッグを取らないと途中で燃料が切れる可能性が極めて高い。
Rally-Xらしくするために燃料計をつくります。
燃料はステージクリア時の得点にも影響します。そこで燃料はどれくらい存在するのか? どのようなペースで減っていくのかを決めます。
道路はブロックが連続して繋がることで構成されています。だったらブロックの総数をもとに決めればいいのではないのでしょうか? ブロックの総数の0.7倍くらいにして(すべてのチェックポイントを通過するためにすべての道路を通過する必要はないので0.7倍が適切だと思う)ブロックを通過するたびに1単位ずつ減っていくという仕様にします。
燃料計を追加したのでレイアウトがちょっと変更になりました。ラベルの背景をGLControlの背景色に合わせています。またスコアは太字で表示しています。
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 |
public partial class Form1 : Form { public Form1() { InitializeComponent(); glControl1.Load += GlControlEx1_Load; glControl1.Paint += GlControlEx1_Paint; glControl1.Resize += GlControl1_Resize; timer.Tick += Timer_Tick; panelRadar.Paint += PanelRadar_Paint; InitSideBar(); this.Size = new Size(643, 511); } // サイドバーの見た目を整える void InitSideBar() { Font font = new Font("MS UI Gothic", 14, FontStyle.Bold); label1.BackColor = Color.Black; label1.ForeColor = Color.White; label1.Font = font; label2.BackColor = Color.Black; label2.ForeColor = Color.White; label2.Font = font; labelScore.BackColor = Color.Black; labelScore.ForeColor = Color.LightGreen; labelScore.Font = font; labelScore.TextAlign = ContentAlignment.MiddleRight; labelRest.BackColor = Color.Black; labelRest.ForeColor = Color.White; labelRest.Font = font; Rest = 0; } // Restをフィールド変数からプロパティに変更した。 int _rest = 0; int Rest { get {return _rest; } set { _rest = value; labelRest.Text = _rest.ToString(); } } void GameStart() { isGameOver = false; Rest = MaxRest; Score = 0; TimerReset(); ResetMyCar(); ResetRedCars(); ResetCheckPoints(); // 燃料をリセット InitFuel(); // スモークスクリーンもリセット Smokes.Count(); timer.Start(); } } |
InitFuel()メソッドは消費された燃料をリセットして満タンの状態にするためのメソッドです。最大燃料の計算方法はコメントのとおりです。
1 2 3 4 5 6 7 8 9 10 11 12 |
public partial class Form1 : Form { void InitFuel() { // 燃料はRoadBlocks.Countと同じ // ただしTimer.Tickイベント5回で1ブロック分移動するのでTimer.Tickイベント1回の燃料消費量を1とするなら // 燃料の最大値はRoadBlocks.Count * 0.7 * 5となる progressBar1.Maximum = (int)(RoadBlocks.Count * 0.7 * 5); progressBar1.Minimum = 0; progressBar1.Value = progressBar1.Maximum; } } |
マイカーが移動すると燃料が消費されます。燃料が切れかけたら(20%以下になったら)移動速度を半分にして燃料が切れたら4分の1にします(燃料がきれたら普通は動けなくなるものなのだが・・・)。
スモークスクリーンは通常の走行に対して燃料を消費量が多いです。燃料がきれたらスモークスクリーンは使えなくなります。
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 49 50 51 52 |
public partial class Form1 : Form { void MoveMyCar() { if(progressBar1.Value > 0) progressBar1.Value--; // speedはその整数倍が1.0になるようにすること。 double speed = 0.20; // 燃料が切れたら極端に移動速度を遅くする // 燃料が切れかけたら移動速度を半分にする if(progressBar1.Value == 0) speed = 0.05; else if(progressBar1.Value < progressBar1.Maximum / 20) speed = 0.1; if((CurDirect == Direct.North || NextDirect == Direct.North) && CanNorth(EyeX, EyeY)) { CurDirect = Direct.North; EyeY += speed; } if((CurDirect == Direct.East || NextDirect == Direct.East) && CanEast(EyeX, EyeY)) { CurDirect = Direct.East; EyeX += speed; } if((CurDirect == Direct.South || NextDirect == Direct.South) && CanSouth(EyeX, EyeY)) { CurDirect = Direct.South; EyeY -= speed; } if((CurDirect == Direct.West || NextDirect == Direct.West) && CanWest(EyeX, EyeY)) { CurDirect = Direct.West; EyeX -= speed; } } void SetSmoke() { // 燃料ゼロのときはスモークスクリーンは使用不可 if(progressBar1.Value < 0) return; // スモークスクリーンを使用すると燃料を消費する if(progressBar1.Value > 0) progressBar1.Value -= 5; Smokes.Add(new Smoke(EyeX, EyeY, CurDirect)); } } |
ミスをしたら燃料が満タン状態の新しいマイカーが現れ、ゲームを再開します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public partial class Form1 : Form { // ミスから3秒後に呼び出されるイベントハンドラ private void Timer2_Tick(object sender, EventArgs e) { Timer t = (Timer)sender; t.Stop(); t.Dispose(); GetCount = 0; ResetMyCar(); ResetRedCars(); // ミス時は燃料をリセット(満タン)にして再スタート InitFuel(); timer.Start(); } } |
ステージクリア時には残りの燃料がボーナスポイントになります。点数も一気に増えるのではなく、カウンターの値が上昇していくように小刻みで増えていきます。
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 |
public partial class Form1 : Form { void StageClear() { if(!isGameOver) { timer.Stop(); // ステージクリア時には残りの燃料をボーナスとして加算する Timer timer3 = new Timer(); timer3.Interval = 50; timer3.Tick += Timer3_Tick; timer3.Start(); // ステージクリア時もGetCountをリセット GetCount = 0; } } // ステージクリア時の残りの燃料をボーナスとして加算する処理 private void Timer3_Tick(object sender, EventArgs e) { // 燃料1に対して10点だが、10点ずつ加算していては時間がかかるので8単位まとめて加算する // 8未満は最後に加算する if(progressBar1.Value > 8) { progressBar1.Value -= 8; Score += 80; } else if(progressBar1.Value > 0) { Score += 10 * progressBar1.Value; progressBar1.Value = 0; } else { Timer t = (Timer)sender; t.Stop(); t.Dispose(); MessageBox.Show("クリア"); Smokes.Clear(); } } } |