前回は自作したテトリスを改良しましたが、
まだまだ不満な点はあります。点数表示がありません。
テトリスの点数はどのように決められているのでしょうか?
http://setsumei.html.xdomain.jp/famicom/tetris/tetris.html
これはファミコン編の説明ですが、ラインがそろったときだけでなくドロップ得点もあることがわかります。またブロックライン得点は1列消しただけなら40点、2列なら100点、4列同時に消すことができると1200点と単純に消した列の数に比例するのではないことがわかります。
ということで、得点もこれで計算することにします。
まず簡単そうなブロックライン得点から。
まずは得点を管理するためのフィールド変数を用意します。さらに得点を追加するためのメソッドも作成します。
1 2 3 4 5 6 7 8 9 10 |
public partial class Form1 : Form { int myPoint = 0; void AddPoints(int addPoints) { myPoint += addPoints; // さらに点数を表示する処理も必要。後述 } } |
次にテトリミノが着地したときに消せるラインがあるかどうか判定する必要がありますが、これは自作メソッドのGetDeleteLineを使えばわかります。
消せるラインがあればラインを消す自作メソッド DeleteLineIfNeedの中で得点に関する処理をおこなます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public partial class Form1 : Form { void DeleteLineIfNeed() { List<int> lines = GetDeleteLine().OrderBy(x=>x).ToList(); if(lines.Count == 0) return; foreach(int i in lines) { // ラインを消す処理(省略) } int linesCount = lines.Count; if(linesCount == 1) AddPoints(40); if(linesCount == 2) AddPoints(100); if(linesCount == 3) AddPoints(300); if(linesCount == 4) AddPoints(1200); } } |
スコアを表示させるために
1 2 3 4 5 6 7 8 9 10 11 |
public partial class Form1 : Form { void AddPoints(int addPoints) { myPoint += addPoints; // 得点を表示する処理 labelScore.ForeColor = Color.White; labelScore.Text = String.Format("Score {0}", myPoint); } } |
つぎにドロップ得点ですが、↓キーが押されたときに処理をすることになりますが、・・・
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public partial class Form1 : Form { private void Form1_KeyDown(object sender, KeyEventArgs e) { if(e.KeyCode == Keys.Left) MoveLeftTetoro(); if(e.KeyCode == Keys.Right) MoveRightTetoro(); if(e.KeyCode == Keys.Space) RotateTetoro(); if(e.KeyCode == Keys.Down) Drop(); } } |
新しくDropメソッドを作成してそのなかでおこないます(ややこしくなりそうなので)。
1 2 3 4 5 6 7 8 9 |
public partial class Form1 : Form { void Drop() { Timer.Interval = 40; // 急速で落下させる // さあ、どうする? } } |
事前にどれだけ落下するのか計算してもいいのですが、ここではとりあえず急速落下させてみて、どれだけ落下するのかカウントすることにします。
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 |
public partial class Form1 : Form { int dropPoint = 0; bool isDroping = false; void Drop() { Timer.Interval = 40; dropPoint = 0; isDroping = true; } void MoveDownTetoro() { // ひとつ下に落下させる処理(省略) // 急速落下中であればカウントを増やす if(isDroping) dropPoint++; } void TetoroDowned() { Timer.Interval = 1000; // 急速落下していたのであればカウント数を調べてドロップ得点を加算する if(isDroping) { isDroping = false; // フラグをクリア AddPoints(dropPoint); dropPoint = 0; // カウントをリセット } FixedTetoro.AddRange(MovingTetoros); DeleteLineIfNeed(); ShowNewTetoro(); } } |
またゲーム開始時は得点をリセットする必要があります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
public partial class Form1 : Form { void ResetScore() { myPoint = 0; // 得点0を表示する処理 labelScore.ForeColor = Color.White; labelScore.Text = String.Format("Score {0}", myPoint); } void GameStart() { ResetScore(); // これを追加 labelGameOver.Visible = false; ClearField(); ShowNewTetoro(); Timer.Interval = 1000; Timer.Start(); } } |