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);
            }
        }


    }

 

posted @ 2022-04-12 22:46  Bridgebug  阅读(337)  评论(0编辑  收藏  举报