2048
一、效果Gif
二、Mark块
public partial class Block : UserControl
{
public Block()
{
this.Size = new Size(60, 60);
MinFontSize = 4;
MaxFontSize = 40;
}
/// <summary>
/// 块的行号
/// </summary>
public int Row { get; set; }
/// <summary>
/// 块的列号
/// </summary>
public int Col { get; set; }
/// <summary>
/// 块的mark值
/// </summary>
public int Mark { get; private set; }
public void Fill(int mark, Color backColor)
{
Mark = mark;
drawMark(mark, backColor);
}
public float MaxFontSize { get; set; }
public float MinFontSize { get; set; }
/// <summary>
/// 自动计算各mark值下的字体,以达到能完成显示mark值
/// </summary>
/// <param name="mark"></param>
/// <param name="backColor"></param>
void drawMark(int mark, Color backColor)
{
Graphics g = this.CreateGraphics();
g.FillRectangle(new SolidBrush(backColor), this.ClientRectangle);
string t = mark == 0 ? "" : mark.ToString();
if (!string.IsNullOrWhiteSpace(t))
{
float fontSize = MaxFontSize;
for (float i = MinFontSize; i <= MaxFontSize; i++)
{
SizeF size = g.MeasureString(t, getFont(i));
if (size.Width > this.Width)
{
fontSize = i - 1;
break;
}
}
SizeF sizeF = g.MeasureString(t, getFont(fontSize));
g.DrawString(t, getFont(fontSize), new SolidBrush(this.ForeColor), new PointF((this.Width - sizeF.Width) / 2, (this.Height - sizeF.Height) / 2));
}
}
Font getFont(float fontSize)
{
return new Font("黑体", fontSize, FontStyle.Regular, GraphicsUnit.Point, 134);
}
}
三、游戏窗体
public partial class Form1 : Form
{
/// <summary>
/// 重写键盘键功能,让方向键起作用
/// </summary>
/// <param name="keyData"></param>
/// <returns></returns>
protected override bool ProcessDialogKey(Keys keyData)
{
if (keyData == Keys.Up || keyData == Keys.Down ||
keyData == Keys.Left || keyData == Keys.Right)
{
return false;
}
else
{
return base.ProcessDialogKey(keyData);
}
}
public Form1()
{
InitializeComponent();
this.KeyPreview = true;
this.Load += new EventHandler(this.Form1_Load);
this.KeyDown += new KeyEventHandler(this.Form1_KeyDown);
_dictBlockColor[0] = this.BackColor;
const int blockPadd = 3;
const int blockWidth = 60;
const int blockHeight = 60;
this.Width = ColCount * (blockWidth + blockPadd) + blockPadd + 16;
this.Height = RowCount * (blockHeight + blockPadd) + blockPadd + 38;
for (int c = 0; c < ColCount; c++)
{
for (int r = 0; r < RowCount; r++)
{
Block block = new Block();
block.Col = c;
block.Row = r;
block.ForeColor = Color.White;
block.Size = new Size(blockWidth, blockHeight);
block.Location = new Point(blockPadd + c * (blockWidth + blockPadd), blockPadd + r * (blockHeight + blockPadd));
this.Controls.Add(block);
_listBlocks.Add(block);
}
}
}
/// <summary>
/// 各mark值对应的背景色
/// </summary>
Dictionary<int, Color> _dictBlockColor = new Dictionary<int, Color>()
{
{2,Color.Pink},
{4,Color.Plum},
{8,Color.PaleVioletRed},
{16,Color.HotPink},
{32, Color.DarkOrange},
{64, Color.Gold},
{128,Color.OrangeRed},
{256,Color.DeepPink},
{512,Color.Magenta},
{1024,Color.BlueViolet},
{2048,Color.Red},
{4096,Color.DarkRed},
{8192,Color.DarkMagenta},
};
int _grade = 0;
List<Block> _listBlocks = new List<Block>();
const int ColCount = 5;
const int RowCount = 5;
private void Form1_Load(object sender, EventArgs e)
{
start();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
var lastMarks = _listBlocks.Select(b => b.Mark).ToList();
switch (e.KeyCode)
{
case Keys.F5:
start();
break;
case Keys.Up:
up();
break;
case Keys.Down:
down();
break;
case Keys.Left:
left();
break;
case Keys.Right:
right();
break;
}
var nowMarks = _listBlocks.Select(b => b.Mark).ToList();
if (!lastMarks.SequenceEqual(nowMarks)) //判断按下方向键后是否发生了变化,有变化就创建一个新的mark
{
var blocks = _listBlocks.Where(b => b.Mark == 0).ToList();
if (blocks.Count > 0)
{
int index = Enumerable.Range(0, blocks.Count).OrderBy(a => Guid.NewGuid()).First();
setColor(blocks[index], 2);
}
}
_grade = _listBlocks.Sum(b => b.Mark);
this.Text = string.Format("{0}", _grade);
}
/// <summary>
/// 开始游戏
/// </summary>
void start()
{
int count = _listBlocks.Count();
var listNum = Enumerable.Range(0, count).OrderBy(a => Guid.NewGuid()).Take(new Random().Next(2, 4)).ToList();
for (int i = 0; i < _listBlocks.Count; i++)
{
setColor(_listBlocks[i], listNum.Contains(i) ? 2 : 0);
}
}
/// <summary>
/// 给块设置背景色和mark值
/// </summary>
/// <param name="block"></param>
/// <param name="mark"></param>
void setColor(Block block, int mark)
{
Color color = Color.DarkMagenta;
if (_dictBlockColor.ContainsKey(mark))
{
color = _dictBlockColor[mark];
}
block.Fill(mark, color);
}
/// <summary>
/// 交换mark和累加mark
/// </summary>
/// <param name="listBlocks"></param>
void exchangeMark(List<Block> listBlocks)
{
var listMarks = listBlocks.Where(b => b.Mark != 0).Select(b => b.Mark).ToList();
for (int i = 0; i < listMarks.Count - 1; i++)
{
if (listMarks[i] == listMarks[i + 1])
{
listMarks[i] += listMarks[i + 1];
listMarks.RemoveAt(i + 1);
i--;
}
}
for (int i = 0; i < listBlocks.Count; i++)
{
setColor(listBlocks[i], listMarks.Count > i ? listMarks[i] : 0);
}
}
void up()
{
for (int c = 0; c < ColCount; c++)
{
List<Block> listBlocks = _listBlocks.Where(b => b.Col == c).OrderBy(b => b.Row).ToList();
exchangeMark(listBlocks);
}
}
void down()
{
for (int c = 0; c < ColCount; c++)
{
List<Block> listBlocks = _listBlocks.Where(b => b.Col == c).OrderByDescending(b => b.Row).ToList();
exchangeMark(listBlocks);
}
}
void left()
{
for (int r = 0; r < RowCount; r++)
{
List<Block> listBlocks = _listBlocks.Where(b => b.Row == r).OrderBy(b => b.Col).ToList();
exchangeMark(listBlocks);
}
}
void right()
{
for (int r = 0; r < RowCount; r++)
{
List<Block> listBlocks = _listBlocks.Where(b => b.Row == r).OrderByDescending(b => b.Col).ToList();
exchangeMark(listBlocks);
}
}
}