【Winform开发2048小游戏】

先来看一下界面:

【Winform开发2048小游戏】

 

 游戏帮助类

class GameCore

    {

        //游戏地图

        private int[,] map = new int[4, 4];

        //合并时用到的临时数组

        private int[] mergeArr = new int[4];

        //空位数量

        private int emptyCount = 16;

        //所有空位位置

        private Location[] emptyArr = new Location[16];

        private Random random = new Random();

        //画板

        private Graphics gp = null;

        //用位图做画板

        private Image image = null;

        // 游戏项大小

        private const int ITEMSIZE = 80;

        //游戏得分

        private int score = 0;



        public bool IsChange { get; set; }



        /// <summary>

        /// 当前得分

        /// </summary>

        public int Score

        {

            get { return score; }

        }



        /// <summary>

        /// 空位数量

        /// </summary>

        public int EmptyCount

        {

            get

            {

                return emptyCount;

            }

        }



        /// <summary>

        /// 游戏初始化

        /// </summary>

        public GameCore()

        {

            ComputeEmptyCount();

            // 初始化数组

            Location loc1;

            GenerateNum(out loc1);



            ComputeEmptyCount();

            GenerateNum(out loc1);

            //初始化画板

            image = new Bitmap(ITEMSIZE * 4 + 5 * 8,

                                              ITEMSIZE * 4 + 5 * 8);

            gp = Graphics.FromImage(image);





        }



        #region 移动并合并相邻的相同数字



        /// <summary>

        /// 移动单元格数据

        /// </summary>

        /// <param name="direction"></param>

        public void Move(string direction)

        {

            IsChange = false;

            switch (direction)

            {

                case "Up": MoveUp(); break;

                case "Down": MoveDown(); break;

                case "Left": MoveLeft(); break;

                case "Right": MoveRight(); break;

            }

        }

        /// <summary>

        /// 上移

        /// </summary>

        public void MoveUp()

        {

            //1

            for (int c = 0; c < 4; c++)//列

            {

                for (int r = 0, index = 0; r < 4; r++)//行

                {

                    if (map[r, c] != 0)//非零

                    {

                        mergeArr[index++] = map[r, c];//放入合并数组

                    }

                    //数字位置发生变化

                    if (mergeArr[r] != map[r, c])

                    {

                        IsChange = true;

                    }

                    map[r, c] = 0;//将矩阵中取走的清零



                }

                //2合并

                MergeCell();

                //3 将合并后的数据放入矩阵

                for (int i = 0, r = 0; i < 4; i++)

                {

                    if (mergeArr[i] != 0)

                    {

                        map[r++, c] = mergeArr[i];

                        mergeArr[i] = 0;

                    }

                }

            }

        }



        /// <summary>

        /// 下移

        /// </summary>

        public void MoveDown()

        {

            //1

            for (int c = 0; c < 4; c++)//列

            {

                for (int r = 3, index = 0; r >= 0; r--)//行

                {

                    if (map[r, c] != 0)//非零

                    {

                        mergeArr[index++] = map[r, c];//放入合并数组

                    }

                    if (mergeArr[3-r] != map[r, c])  

                    {

                        IsChange = true;

                    }

                    map[r, c] = 0;//将矩阵中取走的清零

                }

                //2合并

                MergeCell();

                //3 将合并后的数据放入矩阵

                for (int i = 0, r = 3; i < 4; i++)

                {

                    if (mergeArr[i] != 0)

                    {

                        map[r--, c] = mergeArr[i];

                        mergeArr[i] = 0;

                    }

                }

            }







        }



        /// <summary>

        /// 合并单元格

        /// </summary>

        private void MergeCell()

        {

            for (int i = 0; i < 3; i++)

            {

                if (mergeArr[i] != 0 && mergeArr[i] == mergeArr[i + 1] )

                {

                    mergeArr[i] += mergeArr[i + 1];

                    score += mergeArr[i];

                    IsChange = true;

                    mergeArr[i + 1] = 0;

                }

            }

        }



        /// <summary>

        /// 左移

        /// </summary>

        public void MoveLeft()

        {

            //1

            for (int r = 0; r < 4; r++)//行

            {

                for (int c = 0, index = 0; c < 4; c++)//列

                {

                    if (map[r, c] != 0)//非零

                    {

                        mergeArr[index++] = map[r, c];//放入合并数组

                    }

                    if (mergeArr[c] != map[r, c])

                    {

                        IsChange = true;

                    }

                    map[r, c] = 0;//将矩阵中取走的清零

                }

                //2合并

                MergeCell();

                //3 将合并后的数据放入矩阵

                for (int i = 0, c = 0; i < 4; i++)

                {

                    if (mergeArr[i] != 0)

                    {

                        map[r, c++] = mergeArr[i];

                        mergeArr[i] = 0;

                    }

                }

            }

        }



        /// <summary>

        /// 右移

        /// </summary>

        public void MoveRight()

        {

            //1

            for (int r = 0; r < 4; r++)//行

            {

                for (int c = 3, index = 0; c >= 0; c--)//列

                {

                    if (map[r, c] != 0)//非零

                        mergeArr[index++] = map[r, c];//放入合并数组



                    if (mergeArr[3-c] != map[r, c])

                        IsChange = true;

                

                    map[r, c] = 0;//将矩阵中取走的清零

                }

                //2合并

                MergeCell();

                //3 将合并后的数据放入矩阵

                for (int i = 0, c = 3; i < 4; i++)

                {

                    if (mergeArr[i] != 0)

                    {

                        map[r, c--] = mergeArr[i];

                        mergeArr[i] = 0;

                    }

                }

            }

        }





        #endregion



        /// <summary>

        /// 计算空位数量

        /// </summary>

        public void ComputeEmptyCount()

        {

            emptyCount = 0;

            Array.Clear(emptyArr, 0, 16);



            for (int r = 0; r < 4; r++)//行

            {

                for (int c = 0; c < 4; c++)//列

                {

                    if (map[r, c] == 0)

                    {

                        emptyArr[emptyCount++] = new Location(r, c);

                    }

                }

            }

        }



        /// <summary>

        /// 生成新数字

        /// </summary>

        public int GenerateNum(out Location location)

        {

            int index = random.Next(0, emptyCount);

             location = emptyArr[index];

             map[location.X, location.Y] = random.Next() % 10 == 0 ? 4 : 2;

             return map[location.X, location.Y];

        }



        /// <summary>

        /// 判断游戏是否结束

        /// </summary>

        /// <returns></returns>

        public bool IsGameOver()

        {

            ComputeEmptyCount();

            //如果还有空位,游戏未结束

            if (EmptyCount > 0)

                return false;

            //检查横纵相邻单元格中是否有相同的数字,

            for (int r = 0; r < 4; r++)

            {

                for (int c = 0; c < 3; c++)

                {

                    //横

                    if (map[r, c] == map[r, c + 1])

                        return false;



                    //纵

                    if (map[c, r] == map[c + 1, r])

                        return false;

                }

            }

            return true;



        }



        #region 绘制游戏画面

        /// <summary>

        /// 绘制游戏画面

        /// </summary>

        /// <returns></returns>

        public Image DrawMap()

        {

            //清空画板原有内容

            gp.Clear(Color.DarkGray);

            for (int r = 0; r < map.GetLength(0); r++)

            {

                for (int c = 0; c < map.GetLength(1); c++)

                {

                    DrawItem(r, c, GetColor(map[r, c]));

                }

            }

            return image;

        }





        /// <summary>

        /// 通过数字从程序集资源中找图片

        /// </summary>

        /// <param name="num"></param>

        /// <returns></returns>

        public Image GetColor(int num)

        {

            return Properties.Resources.

                      ResourceManager.

                      GetObject("_" + num.ToString()) as Image;

        }



        /// <summary>

        /// 绘制一个数字块

        /// </summary>

        /// <param name="rowindex">行索引</param>

        /// <param name="columnIndex">列索引</param>

        /// <param name="img">要绘制的图片</param>

        private void DrawItem(int rowindex, int columnIndex, Image img)

        {

            //画在哪 rowindex columnindex

            int x = (columnIndex + 1) * 8 + columnIndex * ITEMSIZE;



            int y = (rowindex + 1) * 8 + rowindex * ITEMSIZE;



            //绘制内容img                       画多大 itemSize

            gp.DrawImage(img, x, y, ITEMSIZE, ITEMSIZE);

        }



        #endregion



    }

 定义一个结构:

 struct Location

    {

        private int x;

        private int y;



        public Location(int x, int y)

        {

            this.x = x;

            this.y = y;

        }

     



        public int X

        {

            get { return x; }

        }

        public int Y

        {

            get { return y; }

        }

    }

 窗体代码:

  public partial class FrmMain : Form

    {

        private GameCore gameCore = null;



        public FrmMain()

        {

            InitializeComponent();

        }



        public void DrawGameMap()

        {

            this.picMap.Image = gameCore.DrawMap();

        }



        //开始游戏

        private void FrmMain_Load(object sender, EventArgs e)

        {

            StartGame();

        }



        private void StartGame()

        {

            //得分清零

            lblScore.Text = "0";

            gameCore = new GameCore();

            DrawGameMap();

        }



        private void btnStart_Click(object sender, EventArgs e)

        {

            StartGame();

        }



        //用键盘控制游戏动作

        private void FrmMain_KeyDown(object sender, KeyEventArgs e)

        {

            string keyString =   e.KeyData.ToString();

            switch (keyString)

            {

                case "Up":

                case "Down":

                case "Left":

                case "Right":

                    gameCore.Move(keyString);

                    //更新游戏地图

                    UpdateGameMap();

                    break;

            }

        }



        public void UpdateGameMap()

        {

            //游戏流程?

            //地图发生过变化

            if (gameCore.IsChange)

            {

                //绘制游戏地图

                DrawGameMap();

                //刷新得分

                this.lblScore.Text = gameCore.Score.ToString();

                //重新计算空位

                gameCore.ComputeEmptyCount();

                //如果空位数大于0

                if (gameCore.EmptyCount > 0)

                {

                    //产生新数

                    Location loc;

                     int num = gameCore.GenerateNum(out loc);

                    //开启绘制新数的动画 异步调用

                    Action<int,int,int> handler = DrawNewNumber;

                    handler.BeginInvoke(loc.X, loc.Y, num,

                                                        null, null);

                    

                }



                //判断游戏是否继续

                if (gameCore.IsGameOver())

                {

                    MessageBox.Show("GAME OVER");

                }

            }

            

        }





        public void DrawNewNumber(int r,int c,int num)

        {

            int xOfMap = (c + 1) * 8 + c * 80;

            int yOfMap = (r + 1) * 8 + r * 80;

            Graphics gp = this.picMap.CreateGraphics();



            Image img = gameCore.GetColor(num);

            //数字出现由小及大,最小宽为10  最大为80

            int w = 10;



            while (w <= 80)

            {

                int x =xOfMap+ 80 / 2 - w / 2;

                int y =yOfMap+ 80 / 2 - w / 2;

                gp.DrawImage(img, x, y, w, w);

                w += 5;

                System.Threading.Thread.Sleep(10);

            }

        }

    }

 OK ,完成了。

 

你可能感兴趣的:(WinForm)