c#俄羅斯方塊遊戲

來源:互聯網
上載者:User

一、設計思路

一個背景數組,一個方塊數組。將方塊數組放入背景數組時,需要一個座標進行定位,即在兩個座標系之間存在一個映射關係。

二、form內代碼

ErLuoSiClass elsClass = new ErLuoSiClass();        /*遊戲開始 按鈕事件*/        private void button1_Click(object sender, EventArgs e)        {            elsClass.CellWidthCount = 12;            elsClass.CellHeightCount = 16;            elsClass.InitErLuoSi();            elsClass.winHandle = elsPanel.Handle;            elsPanel.Width = elsClass.Width;            elsPanel.Height = elsClass.Height;            elsClass.ErLuoSiDraw();            button1.Enabled = false;            //隨機產生當前 block            elsClass.GetInitBlockData();            //定時器開始            timer1.Enabled = true;        }        /*俄羅斯方塊重繪事件*/        private void elsPanel_Paint(object sender, PaintEventArgs e)        {            if (elsClass.elsStartFlag)                elsClass.ErLuoSiDraw();        }        /*鍵盤操作*/        private void Form1_KeyDown(object sender, KeyEventArgs e)        {            if (e.KeyCode == Keys.Down)            {                //先判斷是否可以下移                if(elsClass.CanDown())                    elsClass.currentX++;//下移            }            else if (e.KeyCode == Keys.Left)            {                //先判斷是否可以左移                if (elsClass.CanLeft())                    elsClass.currentY--;//左移            }            else if (e.KeyCode == Keys.Right)            {                //先判斷是否可以右移                if (elsClass.CanRight())                    elsClass.currentY++;//右移            }            else if (e.KeyCode == Keys.Up)            {                //先判斷是否可以變換                if(elsClass.CanChange())                    elsClass.ChangeBlock();//變換            }            else if (e.KeyCode == Keys.Space)            {                //空格鍵暫停、開始                if (timer1.Enabled)                    timer1.Enabled = false;                else                    timer1.Enabled = true;            }            //重繪 此處也重繪 在介面上反映快點            elsClass.ErLuoSiDraw();            elsPanel.Focus();        }        /*定時器事件*/        private void timer1_Tick(object sender, EventArgs e)        {            if (elsClass.CanDown())            {                elsClass.currentX++;            }            else  //假如不能再移動了            {                //將block中的值放入背景數組中                elsClass.SetData();                //檢查並刪除行                elsClass.CheckAndDeleteLines();                //檢查是否到頂                if (elsClass.CheckToTop())                {                    timer1.Enabled = false;                    MessageBox.Show("到頂了!");                }                //重新設定起始狀態                elsClass.currentX = -4;                elsClass.currentY = 5;                //隨機產生新的block                elsClass.GetInitBlockData();            }            //重繪圖            elsClass.ErLuoSiDraw();        }

三、核心控制類

public class ErLuoSiClass    {        #region 參數        public System.IntPtr winHandle;        //遊戲開關標誌        public bool elsStartFlag = false;        //遊戲畫板對應數組 預設全是0        public int[,] RushData;        #region 小圖案的狀態,暫且7種,每種都用四個變化 (7*4)*4*4        public int[, ,] Blocks =         {            //逆時針旋轉            #region 橫杆的4種狀態            {                {1,0,0,0},                {1,0,0,0},                {1,0,0,0},                {1,0,0,0}            },            {                {1,1,1,1},                {0,0,0,0},                {0,0,0,0},                {0,0,0,0}            },            {                {1,0,0,0},                {1,0,0,0},                {1,0,0,0},                {1,0,0,0}            },            {                {1,1,1,1},                {0,0,0,0},                {0,0,0,0},                {0,0,0,0}            },            #endregion                        #region 方框的4種狀態            {                {1,1,0,0},                {1,1,0,0},                {0,0,0,0},                {0,0,0,0}            },            {                {1,1,0,0},                {1,1,0,0},                {0,0,0,0},                {0,0,0,0}            },            {                {1,1,0,0},                {1,1,0,0},                {0,0,0,0},                {0,0,0,0}            },            {                {1,1,0,0},                {1,1,0,0},                {0,0,0,0},                {0,0,0,0}            },            #endregion            #region T字的4種狀態            {                {1,1,1,0},                {0,1,0,0},                {0,0,0,0},                {0,0,0,0}            },            {                {1,0,0,0},                {1,1,0,0},                {1,0,0,0},                {0,0,0,0}            },            {                {0,1,0,0},                {1,1,1,0},                {0,0,0,0},                {0,0,0,0}            },            {                {0,1,0,0},                {1,1,0,0},                {0,1,0,0},                {0,0,0,0}            },            #endregion            #region 7字的4種狀態            {                {1,1,0,0},                {0,1,0,0},                {0,1,0,0},                {0,0,0,0}            },            {                {1,1,1,0},                {1,0,0,0},                {0,0,0,0},                {0,0,0,0}            },            {                {1,0,0,0},                {1,0,0,0},                {1,1,0,0},                {0,0,0,0}            },            {                {0,0,1,0},                {1,1,1,0},                {0,0,0,0},                {0,0,0,0}            },            #endregion                        #region 反7字的4種狀態            {                {1,1,0,0},                {1,0,0,0},                {1,0,0,0},                {0,0,0,0}            },            {                {1,0,0,0},                {1,1,1,0},                {0,0,0,0},                {0,0,0,0}            },            {                {0,1,0,0},                {0,1,0,0},                {1,1,0,0},                {0,0,0,0}            },            {                {1,1,1,0},                {0,0,1,0},                {0,0,0,0},                {0,0,0,0}            },            #endregion                        #region Z字的4種狀態            {                {1,1,0,0},                {0,1,1,0},                {0,0,0,0},                {0,0,0,0}            },            {                {0,1,0,0},                {1,1,0,0},                {1,0,0,0},                {0,0,0,0}            },            {                {1,1,0,0},                {0,1,1,0},                {0,0,0,0},                {0,0,0,0}            },            {                {0,1,0,0},                {1,1,0,0},                {1,0,0,0},                {0,0,0,0}            },            #endregion            #region 反Z字的4種狀態            {                {0,1,1,0},                {1,1,0,0},                {0,0,0,0},                {0,0,0,0}            },            {                {1,0,0,0},                {1,1,0,0},                {0,1,0,0},                {0,0,0,0}            },            {                {0,1,1,0},                {1,1,0,0},                {0,0,0,0},                {0,0,0,0}            },            {                {1,0,0,0},                {1,1,0,0},                {0,1,0,0},                {0,0,0,0}            },            #endregion        };        #endregion        /*當前操作的block塊的內部組成*/        public int[,] CurrentBlock = new int[4, 4];        //當前操作的block起點在整個數組中的位置,起點在左上方        public int currentX = -4;        public int currentY = 5;        //當前方格數、方格狀態數        public int CellNum = 0;        public int CellState = 0;        //一個格子的大小        public int CellSize = 15;        //在寬度、高度方向上格子數目        public int CellWidthCount;        public int CellHeightCount;        //地區寬度、高度        public int Width;        public int Height;        #endregion        /*初始化*/        public void InitErLuoSi()        {            RushData = new int[CellHeightCount, CellWidthCount];            Width = CellWidthCount * (CellSize + 1) + 1;            Height = CellHeightCount * (CellSize + 1) + 1;            elsStartFlag = true;    //遊戲狀態設定為開始        }        /*畫遊戲圖*/        public void ErLuoSiDraw()        {            Image myImage = new Bitmap(Width, Height);            Graphics g = Graphics.FromImage(myImage);            g.FillRectangle(new SolidBrush(Color.Gray), 0, 0, Width, Height);                        //寬度方向上走,畫豎線            for (int i = 0; i <= CellWidthCount; i++)            {                g.DrawLine(new Pen(Color.Black), (CellSize+1) * i, 0, (CellSize+1) * i, Height);            }            //高度方向上走,畫橫線            for (int i = 0; i <= CellHeightCount; i++)            {                g.DrawLine(new Pen(Color.Black), 0, (CellSize + 1) * i, Width, (CellSize + 1) * i);            }            SolidBrush brush = new SolidBrush(Color.Gray);  //預設灰色背景畫刷            FontFamily fontFamily = new FontFamily("Arial");            Font font = new Font(fontFamily, 12, FontStyle.Regular, GraphicsUnit.Pixel);            string strTemp = "";  //預設需要寫的字            int fontLeft = CellSize/5;            //畫所有方格            for (int i = 0; i < CellHeightCount; i++)            {                for (int j = 0; j < CellWidthCount; j++)                {                    brush = new SolidBrush(Color.Gray);  //灰色背景畫刷                    if (RushData[i, j]  == 1)                        brush = new SolidBrush(Color.Gold);  //金色背景畫刷                    strTemp = RushData[i, j].ToString();                    g.FillRectangle(brush, (CellSize + 1) * j + 1,                        (CellSize + 1) * i + 1, CellSize, CellSize);                    g.DrawString(strTemp, font, new SolidBrush(Color.Black),                        (CellSize + 1) * j + fontLeft, (CellSize + 1) * i + fontLeft);                }            }            //畫當前移動的方格            for (int i = 0; i < 4; i++)            {                for (int j = 0; j < 4; j++)                {                    if (currentX + i < 0)                        continue;                    brush = new SolidBrush(Color.Gray);  //預設灰色背景畫刷                    strTemp = CurrentBlock[i, j].ToString();                    if (CurrentBlock[i, j] == 1)                    {                        brush = new SolidBrush(Color.Gold);  //金色背景畫刷                    }                    if (currentX + i >= 0 && currentX + i <= CellHeightCount - 1                        && currentY+j >= 0 && currentY + j <= CellWidthCount - 1                        && RushData[currentX+i,currentY+j]==1)                    {                        brush = new SolidBrush(Color.Gold);  //金色背景畫刷                        strTemp = "1";                    }                                       g.FillRectangle(brush, (CellSize + 1) * (currentY + j) + 1,                        (CellSize + 1) * (currentX + i) + 1, CellSize, CellSize);                    g.DrawString(strTemp, font, new SolidBrush(Color.Black),                        (CellSize + 1) * (currentY + j) + fontLeft, (CellSize + 1) * (currentX + i) + fontLeft);                }            }            Graphics gg = Graphics.FromHwnd(winHandle);            gg.DrawImage(myImage, 0, 0);          }                /*隨機產生當前的block*/        public void GetInitBlockData()        {            Random ran = new Random();            CellNum = ran.Next(0, 6);            CellState = ran.Next(0, 4);            for (int i = 0; i < 4; i++)            {                for (int j = 0; j < 4; j++)                {                    CurrentBlock[i, j] = Blocks[CellNum * 4 + CellState, i, j];                }            }        }        /*是否可以向下移動*/        public bool CanDown()        {            for(int i=3; i>=0; i--)            {                for (int j = 0; j <4 ; j++)                {                    //小方格內為1 則需要判斷是否可以向下                    if (CurrentBlock[i, j] == 1)                    {                        if (currentX + i + 1 >= CellHeightCount)                        {                            return false;  //不能向下移動了                        }                        else if (currentX + i + 1 >= 0 && currentX + i + 1 < CellHeightCount                            && currentY + j >= 0 && currentY + j < CellWidthCount                            && RushData[currentX + i + 1, currentY + j] == 1)                        {                            return false;  //不能向下移動了                        }                    }                }            }            return true;        }        /*是否可以向左移動*/        public bool CanLeft()        {            for (int i = 0; i <4 ; i++)            {                for (int j = 0; j < 4; j++)                {                    if (CurrentBlock[ i,  j] == 1)                    {                        if( currentY + j - 1 < 0)                        {                            return false;  //不能向下移動了                        }                        else if (currentX + i >= 0 && currentX + i < CellHeightCount                            && currentY + j - 1 >= 0 && currentY + j - 1 < CellWidthCount                            && RushData[currentX + i , currentY + j- 1] == 1)                        {                            return false;  //不能向下移動了                        }                    }                }            }            return true;        }        /*是否可以向右移動*/        public bool CanRight()        {            for (int i = 0; i < 4; i++)            {                for (int j = 0; j < 4; j++)                {                    if (CurrentBlock[i, j] == 1)                    {                        if (currentY + j + 1 >= CellWidthCount)                        {                            return false;  //不能向下移動了                        }                        else if (currentX + i >= 0 && currentX + i < CellHeightCount                            && currentY + j + 1 >= 0 && currentY + j + 1 < CellWidthCount                            && RushData[currentX + i , currentY + j + 1] == 1)                        {                            return false;  //不能向下移動了                        }                    }                }            }            return true;        }        /*是否可以旋轉*/        public bool CanChange()        {            CellState = (CellState + 1) % 4;            for (int i = 0; i < 4; i++)            {                for (int j = 0; j < 4; j++)                {                    //主要看為1的方格旋轉後的位置是否衝突                    if (Blocks[CellNum * 4 + CellState, i, j] == 1)                    {                        //如果在範圍內                        if (currentX + i >= 0 && currentX + i < CellWidthCount                            && currentY + j >= 0 && currentY + j < CellHeightCount)                        {                            if (RushData[i, j] == 1)                                return false;                        }                        //如果不在範圍內                        else                        {                            return false;                            }                    }                }            }                                return true;        }        /*旋轉當前的方格*/        public void ChangeBlock()        {            for (int i = 0; i < 4; i++)            {                for (int j = 0; j < 4; j++)                {                    CurrentBlock[i, j] = Blocks[CellNum * 4 + CellState, i, j];                }            }        }        /*置數組:將已經不能再移動的block中的值放入背景數組中 */        public void SetData()        {            for (int i = 0; i < 4; i++)            {                for (int j = 0; j < 4; j++)                {                    if (CurrentBlock[i, j] == 1)                    {                        if (currentX + i >= 0 && currentX + i < CellHeightCount                            && currentY + j >= 0 && currentY + j < CellWidthCount )                            RushData[currentX + i,currentY + j] = 1;                    }                }            }        }                /*檢查行滿,並銷毀行、計分*/        public void CheckAndDeleteLines()        {            int lines = 0;  //行數 用於計分            int[] linesFlag = new int[CellHeightCount]; //記錄每行是否填滿            //尋找滿的行            for (int i = CellHeightCount-1; i >=0 ; i--)            {                int count = 0;  //本行滿的數目                for (int j = CellWidthCount-1; j >=0 ; j--)                {                    if (RushData[i, j] == 1)                    {                        count++;                    }                }                if (count == CellWidthCount)                {                    linesFlag[i] = 1;                    lines++;                }            }            //移動行            for (int i = 0; i < CellHeightCount; i++)            {                //如果本行滿                if (linesFlag[i] == 1)                {                    //從最大序號的行開始移動                    for (int j = i; j >0 ; j--)                    {                        for (int k = 0; k < CellWidthCount; k++)                        {                            RushData[j, k] = RushData[j - 1, k];                         }                    }                    for (int k = 0; k < CellWidthCount; k++)                    {                        RushData[0, k] = 0;                    }                }            }        }        //檢查是否到頂        public bool CheckToTop()        {            //列迴圈            for (int j = 0; j < CellWidthCount; j++)            {                if (RushData[0, j] == 1 && currentX < 0)                    return true;  //到頂               }            return false;        }    }

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.