これから勉強をかねて、2048というゲームのクローンをWinFormで作ってみようと思います。
2048って何?
一時期ブームになったスマホのゲームアプリで、パネルをスライドさせながら大きな数字を作っていくゲームです。ルールは説明するより、動画を見てもらったほうが早いです。
個人的にはこのゲーム、結構プレイしていて最高で8192まで行った事があります。

作成ルール
本当は一気に作ってしまいのですが、時間が無いので下記のルールで少しづつ進めていきます。毎週何か作る。本当な毎日少しづつ進めたいけど仕事があるので、週に3回以上は最低目標とする。
作成中のプログラムをBlogにさらす。本当ならいったん全部作ってしまってから、キレイに順序だてて説明すべきなのだけど、それだとモチベーションが続かなさそう。なので、試作目的で後で消す予定のコードだとしても一旦アップしてしまう。
ネットで2048cloneの作り方は検索できるけど、勉強の為にあえて見ずに作ってみる。
今日のコード
と、言うわけでさっそく今日の成果です。とりあえず今回はイメージをつかむために、下記の試作をして見ました。
・最初の盤面は決まっている。
・カーソルキーの上を押したら、上方向にスライドさせる。
・スライドさせても新しいパネルは出現しない。
・画面表示はまだ作らない。(TextBoxに盤面データをダンプするだけ)
なので、プログラムが起動したらカーソルの上キーを押すだけの動作確認状態です。
現状のロジックだと、2回上を押すと2のパネルが消えてしまうバグがあるとう中途半端な状態ですが、続きはまた次回にします。
パネルのスライド処理が地味に面倒です…
using System; using System.Collections.Generic; using System.Data; using System.Windows.Forms; namespace Mock2048 { public partial class Form1 : Form { // 盤面の情報 private int[,] board = new int[4,4]; public Form1() { InitializeComponent(); } //********************************************************************* /// <summary> 画面表示時のハンドラ /// </summary> //********************************************************************* private void Form1_Load( object sender, EventArgs e ) { // Formコントロール自身がキー入力を取得可能とする this.KeyPreview = true; //盤面の初期化 initBoard(); // 盤面を表示する displayBoard(); } //********************************************************************* /// <summary> キー入力時のハンドラ /// </summary> //********************************************************************* private void Form1_KeyDown( object sender, KeyEventArgs e ) { moveCell( e.KeyCode ); // 盤面を表示する displayBoard(); } //********************************************************************* /// <summary> 盤面の初期化(テストデータのセット) /// </summary> //********************************************************************* private void initBoard() { board[2,0] = 4; board[3,0] = 2; board[3,1] = 2; board[2,2] = 4; board[3,3] = 2; } //********************************************************************* /// <summary> 盤面を画面に表示させる /// </summary> //********************************************************************* private void displayBoard() { string boardData = ""; // すべての行のデータを出すまで繰り返し for (int y = 0; y < 4; y++) { // 1行分のデータを出力 for (int x = 0; x < 4; x++) { boardData += board[x,y]; } boardData += Environment.NewLine; } txtLog.Text = boardData; } //********************************************************************* /// <summary> 指定された方向に移動させる /// </summary> /// <param name="keyCode"></param> //********************************************************************* private void moveCell( Keys keyCode ) { // 入力されたキーを判定する switch ( keyCode ) { case Keys.Up: // 2~4列目に対して上方向のスライドを試みる for (int y = 1; y < 4; y++) { for (int x = 0; x < 4; x++) { int targetCellVal = board[x,y]; if ( targetCellVal == 0 ) { continue; // 空セルは何もしない } // 上方向に移動させる bool isMoved = false; for ( int endY = y-1; endY >= 0; endY-- ) { if ( board[x,endY] == 0 ) { continue; // 空セルなら、さらに移動先を探索 } // 空セルで無ければ、合体or衝突させる if ( targetCellVal == board[x,endY] ) { // 同じ値なら合体 board[x,endY] = targetCellVal*2; board[x,y] = 0; isMoved = true; break; } else { // 異なる値なら1つ手前のところまで移動 board[x,endY+1] = targetCellVal; board[x,y] = 0; isMoved = true; break; } } if ( isMoved == false ) { // 壁まできたら、壁まで移動 board[x,0] = targetCellVal; board[x,y] = 0; break; } } } //txtLog.Text = "[UP]"; break; case Keys.Down: //txtLog.Text = "[DOWN]"; break; case Keys.Left: //txtLog.Text = "[LEFT]"; break; case Keys.Right: //txtLog.Text = "[RIGHT]"; break; default: //txtLog.Text = ""; break; } } } } |
関連記事
コメントを残す