c# - 期末大作业:俄罗斯方块

总体视图 & 废话集结区

具体介绍传送门,请点!!!!!

然后放图
1111
这个大作业真的是写吐了当时。。。。

实现功能有:
随机生成砖块并显示
实现砖块的旋转和自动下落
有背景音乐,砖块消除和游戏失败的音效
玩家可以选择停止播放背景音乐

先是那啥消除整行那里判断不对。。。。强行改了两个下午勉强能看,多行消除还有bug。。。。想创新点想很久,最后弄了个背景音乐的开关 && 两个样品的叠加播放,当时查了和流是有关系的,百度了很多东西也搞不明白到底是怎么操作的就很糟心了;;;;好在后面解决了

终于,全部搞完,调试完准备录视频的时候,不对,全部录完视频&&加完那啥,,,文字解释之后意识到,。。,老师要求的作业是口头演示(然而我之前找到满绩学长的视频是没有讲话的///难道是我记错了。应该不会。所以上课的时候重新录了一个,极其嘈杂///掩面哭泣,这可能就是我成绩不好的原因吧 555555

资源下载

c# - 期末大作业:俄罗斯方块,点击下载
俄罗斯方块

代码(全)

FormMain.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Media;
using System.Threading;
using System.Runtime.InteropServices; 

namespace OhMyTetris
{
    public partial class FormMain : Form
    {
        #region 私有属性

        //画布模型
        private Canvas m_canvas;   
 
        //画布
        private Graphics m_picture;  

        //用于显示下一个砖块的画布
        private Graphics m_nextpic;

        //装载声音文件
        private SoundPlayer m_bgm = new SoundPlayer("bgm.wav");
        private SoundPlayer m_gameover = new SoundPlayer("gameover.wav");
        private SoundPlayer m_disappear = new SoundPlayer("disappear.wav");

        private float m_x;
        private float m_y;
        private bool m_isrun;

        #endregion

        #region 停止背景音乐的播放

        [DllImport("winmm.DLL",EntryPoint = "PlaySound",
            SetLastError = true,CharSet = CharSet.Unicode,ThrowOnUnmappableChar = true)]
        private static extern bool PlaySound(string szSound, System.IntPtr hMod,PlaySoundFlags flags);
        [System.Flags]
        public enum PlaySoundFlags : int
        {
            SND_SYNC = 0x0000, //同步播放声音,在播放完后PlaySound函数才返回
            SND_ASYNC = 0x0001, //用异步方式播放声音,PlaySound函数在开始播放后立即返回
            SND_NODEFAULT = 0x0002, //不播放缺省声音,若无此标志,则PlaySound在没找到声音时会播放缺省声音
            SND_LOOP = 0x0008, //重复播放声音,必须与SND_ASYNC标志一块使用
            SND_NOSTOP = 0x0010, //PlaySound不打断原来的声音播出并立即返回FALSE
            SND_NOWAIT = 0x00002000, //如果驱动程序正忙则函数就不播放声音并立即返回
            SND_FILENAME = 0x00020000, //pszSound参数指定了WAVE文件名
            SND_RESOURCE = 0x00040004 //pszSound参数是WAVE资源的标识符,这时要用到hmod参数
        }

        public void runSound()
        {
            PlaySound("bgm.wav", IntPtr.Zero,PlaySoundFlags.SND_ASYNC | PlaySoundFlags.SND_FILENAME | PlaySoundFlags.SND_LOOP);
        }
        #endregion

        //开启或禁止背景音乐事件:
        private void buttonPlayMusic_Click(object sender, EventArgs e)
        {
            //如果是音符,就停止播放背景乐
            if (buttonPlayMusic.Text == "🈲")
            {
                PlaySound(null, IntPtr.Zero, PlaySoundFlags.SND_ASYNC);
                buttonPlayMusic.Text = "🎵";
            }
            //如果显示是音乐,就重新播放背景乐
            else
            {
                m_bgm.PlayLooping();
                buttonPlayMusic.Text = "🈲";
            }
        }

        public FormMain()
        {
            InitializeComponent();

            //设置label和picture的Parent属性为pictureHole,显示更自然
            labelIntroduction.Parent = pictureBoxHole;
            labelScore.Parent = pictureBoxHole;
            labelGameover.Parent = pictureBox1;
            pictureBox2.Parent = pictureBoxHole;
            pictureBox1.Parent = pictureBoxHole;
            buttonPlayMusic.Parent = pictureBoxHole;

            pictureBox1.Focus();

            m_canvas = new Canvas();

            m_picture = pictureBox1.CreateGraphics();
            m_nextpic = pictureBox2.CreateGraphics();

            m_x = pictureBox1.Width / m_canvas.m_Columns;
            m_y = pictureBox1.Height / m_canvas.m_Rows;

            timer1.Enabled = false;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            //如果有些还没结束
            //错误:无法将方法组“Run”转换为非委托类型“bool”。
            //改正:在后面加个括号就好了
            if (m_canvas.Run() == true)
            {
                Draw();
                DrawNext();
                DrawScore();
            }
            else
            {
                timer1.Enabled = false;
                if (m_canvas.m_Score >= 100)
                {
                    //MessageBox.Show("游戏结束!胜利!");
                }
                else
                {
                    Graphics g = CreateGraphics();
                    labelGameover.Visible = true;
                    m_gameover.Play();
                    buttonStop.Enabled = false;
                }
            }
        }

        //自定义方法:创建画布
        private void Draw()
        {
            Bitmap canvas = new Bitmap(pictureBox1.Width, pictureBox1.Height);
            
            //从canvas创建新的graphics
            Graphics g = Graphics.FromImage(canvas);

            for (int i = 0; i < m_canvas.m_Rows; i++)
            {
                for (int j = 0; j < m_canvas.m_Columns; j++)
                {
                    if (m_canvas.m_Arr[i, j] == 0)
                    {
                        continue;
                    }
                    else
                    {
                        DrawItem(g, i, j);
                    }
                }
            }
            pictureBox1.BackgroundImage = canvas;
            pictureBox1.Refresh();
        }

        //自定义方法:显示游戏窗口
        private void DrawItem(Graphics g, int row, int column)
        {
            float xpos = column * m_x - 1;
            float ypos = row * m_y - 1;
            g.FillRectangle(Brushes.Orange, xpos, ypos, m_x - 2, m_y - 2);
        }

        //自定义方法:显示下一个砖块
        private void DrawNext()
        {
            pictureBox2.Refresh();
            m_canvas.DrawNewxBrick(m_nextpic, m_x, m_y);
        }

        //自定义方法:显示当前得分
        private void DrawScore()
        {
            string temp = "当前得分:" + (m_canvas.m_Score*10).ToString() + "分";
            labelScore.Text = temp;
        }

        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (keyData == Keys.Up || keyData == Keys.Down || keyData == Keys.Left || keyData == Keys.Right)
            {
                return false;
            }
            return base.ProcessDialogKey(keyData);
        }

        //键盘响应事件:
        private void FormMain_KeyDown(object sender, KeyEventArgs e)
        {
            Keys key = e.KeyCode;
            if (m_isrun == true)
            {
                if (key == Keys.Up)
                {
                    pictureBox1.Refresh();
                    m_canvas.BrickUp();
                    Draw();
                }
                if (key == Keys.Left)
                {
                    pictureBox1.Refresh();
                    m_canvas.BrickLeft();
                    Draw();
                }
                if (key == Keys.Right)
                {
                    pictureBox1.Refresh();
                    m_canvas.BrickRight();
                    Draw();
                }
                if (key == Keys.Down)
                {
                    pictureBox1.Refresh();
                    m_canvas.BrickDown();
                    Draw();
                }
            }
        }

        //开始事件:
        private void buttonBegin_Click(object sender, EventArgs e)
        {
            if (buttonBegin.Text == "开   始")
            {
                buttonBegin.Text = "重新开始";
            }
            else 
            {
                m_isrun = false;
                timer1.Enabled = false;
            }
            m_canvas = new Canvas();
            buttonStop.Enabled = true;
            labelGameover.Visible = false;
            m_bgm.PlayLooping();
            m_isrun = true;
            timer1.Enabled = true;
        }

        //暂停继续事件:
        private void buttonStop_Click(object sender, EventArgs e)
        {
            if (buttonStop.Text == "暂   停")
            {
                m_isrun = false;
                timer1.Enabled = false;
                PlaySound(null, IntPtr.Zero, PlaySoundFlags.SND_ASYNC);
                buttonStop.Text = "继   续";
            }
            else
            {
                m_isrun = true;
                timer1.Enabled = true;
                m_bgm.PlayLooping();
                buttonStop.Text = "暂   停";
            }
        }

        //退出事件:
        private void buttonExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

    }
}

Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;

namespace OhMyTetris
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new FormMain());
        }
    }
}

Brick.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace OhMyTetris
{
    public abstract class Brick
    {
        #region 私有属性
        //当前变形次序
        private int m_curTransforIndex;

        //必要的行数、列数
        private int m_needfulRows;
        private int m_needfulColumns;
        
        //变形范围
        private int[,] m_range;

        //中心点
        private Point m_center;

        //中心点的位置
        private Point m_pos;

        #endregion
        
        #region 公有属性

        public int m_CurTransforIndex
        {
            get { return m_curTransforIndex; }
            set { m_curTransforIndex = value; }
        }

        public int m_NeedfulRows
        {
            get { return m_needfulRows; }
            set { m_needfulRows = value; }
        }
        public int m_NeedfulColumns
        {
            get { return m_needfulColumns; }
            set { m_needfulColumns = value; }
        }

        public int[,] m_Range
        {
            get { return m_range; }
            set { m_range = value; }
        }

        public Point m_Center
        {
            get { return m_center; }
            set { m_center = value; }
        }
        public Point m_Pos
        {
            get { return m_pos; }
            set { m_pos = value; }
        }
        #endregion

        //自定义方法:判断能否变形
        public abstract bool CanTransform(int[,] arr, int rows, int columns);

        //自定义方法:变形
        public abstract void Transform();

        //自定义方法:判断能否左移
        public abstract bool CanLeftMove(int[,] arr, int rows, int columns);

        //自定义方法:左移
        public void LeftMove()
        {
            m_pos.Y -= 1;
        }

        //自定义方法:判断能否右移
        public abstract bool CanRightMove(int[,] arr, int rows, int columns);

        //自定义方法:右移
        public void RightMove()
        {
            m_pos.Y += 1;
        }

        //自定义方法:判断能否下移
        public abstract bool CanDropMove(int[,] arr, int rows, int columns);

        //自定义方法:下移
        public void DropMove()
        {
            m_pos.X += 1;
        }

        //自定义方法:随机生成形状
        public void RandomShape()
        {
            Random random = new Random();
            this.m_curTransforIndex = random.Next(4);
            this.Transform();
        }

        //自定义方法:设置中心点在画布的位置
        public void SetCenterPos(int x, int y)
        {
            this.m_pos = new Point(x, y);
        }

        //自定义方法:获取砖块出现时y的坐标
        public abstract int Appear();
    }
}

Brick1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace OhMyTetris
{
    //田字砖
    class Brick1:Brick
    {
        //定义新砖块的各个值
        public Brick1() 
        {
            this.m_CurTransforIndex = 0;
            this.m_NeedfulRows = 2;
            this.m_NeedfulColumns = 2;
            m_Range = new int[2, 2]{{1,1},
                                    {1,1}};
            this.m_Center = new Point(0, 0);
            this.m_Pos = new Point();
        }

        //重写判断能否变形的方法
        public override bool CanTransform(int[,] arr, int rows, int columns)
        {
            return false;
        }

        //重写变形的方法
        public override void Transform()
        {
            return;
        }

        //重写判断是否可以左移的方法
        public override bool CanLeftMove(int[,] arr, int rows, int columns)
        {
            if (m_Pos.X < 0)
            {
                if (m_Pos.Y == 0 || arr[m_Pos.X + 1, m_Pos.Y - 1] == 1)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            if (m_Pos.Y == 0 || arr[m_Pos.X, m_Pos.Y - 1] == 1 || arr[m_Pos.X + 1, m_Pos.Y - 1] == 1)
                return false;
            else
                return true;
        }

        //重写判断是否可以右移的方法
        public override bool CanRightMove(int[,] arr, int rows, int columns)
        {
            if (m_Pos.X < 0)
            {
                if (m_Pos.Y == columns - 2 || arr[m_Pos.X + 1, m_Pos.Y + 2] == 1)
                {
                    return false;
                }
                else
                {
                    return true;
                }
            }
            if (m_Pos.Y == columns - 2 || arr[m_Pos.X, m_Pos.Y + 2] == 1 || arr[m_Pos.X + 1, m_Pos.Y + 2] == 1)
                return false;
            else
                return true;
        }

        //重写判断是否可以下移的方法
        public override bool CanDropMove(int[,] arr, int rows, int columns)
        {
            if (m_Pos.X < rows - 2 && arr[m_Pos.X + 2, m_Pos.Y] == 0 && arr[m_Pos.X + 2, m_Pos.Y + 1] == 0)
                return true;
            return false;
        }

        //重写获取砖块出现时y的坐标方法
        public override int Appear()
        {
            return -1;
        }
    }
}

Brick2.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace OhMyTetris
{
    class Brick2:Brick
    {
        //定义新砖块的各个值
        public Brick2() 
        {
            this.m_CurTransforIndex = 0;
            this.m_NeedfulColumns = 5;
            this.m_NeedfulRows = 5;
            m_Range = new int[5, 5] { { 0, 0, 0, 0, 0 },
                                      { 0, 0, 0, 0, 0 },
                                      { 0, 1, 1, 1, 1 },
                                      { 0, 0, 0, 0, 0 },
                                      { 0, 0, 0, 0, 0 }};
            this.m_Center = new Point(2, 2);
            this.m_Pos = new Point();
        }

        //重写判断能否变形的方法
        public override bool CanTransform(int[,] arr, int rows, int columns)
        {
            bool result = false;
            if (m_Pos.X - 2 >= 0 && m_Pos.X + 2 <= rows - 1 && m_Pos.Y - 2 >= 0 && m_Pos.Y + 2 <= columns - 1)
            {
                switch (m_CurTransforIndex)
                {
                    case 0:
                        arr[m_Pos.X, m_Pos.Y - 1] = 0;
                        arr[m_Pos.X, m_Pos.Y] = 0;
                        arr[m_Pos.X, m_Pos.Y + 1] = 0;
                        arr[m_Pos.X, m_Pos.Y + 2] = 0;
                        break;
                    case 1:
                        arr[m_Pos.X - 1, m_Pos.Y] = 0;
                        arr[m_Pos.X, m_Pos.Y] = 0;
                        arr[m_Pos.X + 1, m_Pos.Y] = 0;
                        arr[m_Pos.X + 2, m_Pos.Y] = 0;
                        break;
                    case 2:
                        arr[m_Pos.X, m_Pos.Y - 2] = 0;
                        arr[m_Pos.X, m_Pos.Y - 1] = 0;
                        arr[m_Pos.X, m_Pos.Y] = 0;
                        arr[m_Pos.X, m_Pos.Y + 1] = 0;
                        break;
                    case 3:
                        arr[m_Pos.X - 2, m_Pos.Y] = 0;
                        arr[m_Pos.X - 1, m_Pos.Y] = 0;
                        arr[m_Pos.X, m_Pos.Y] = 0;
                        arr[m_Pos.X + 1, m_Pos.Y] = 0;
                        break;
                    default:
                        break;
                }
                bool temp = true;
                for (int i = -2; i < 3; i++)
                {
                    for (int j = -2; j < 3; j++)
                    {
                        if (arr[m_Pos.X + i, m_Pos.Y + j] == 1)
                        {
                            temp = false;
                            goto break2;
                        }
                    }
                }
            break2:
                result = temp;
                switch (m_CurTransforIndex)
                {
                    case 0:
                        arr[m_Pos.X, m_Pos.Y - 1] = 1;
                        arr[m_Pos.X, m_Pos.Y] = 1;
                        arr[m_Pos.X, m_Pos.Y + 1] = 1;
                        arr[m_Pos.X, m_Pos.Y + 2] = 1;
                        break;
                    case 1:
                        arr[m_Pos.X - 1, m_Pos.Y] = 1;
                        arr[m_Pos.X, m_Pos.Y] = 1;
                        arr[m_Pos.X + 1, m_Pos.Y] = 1;
                        arr[m_Pos.X + 2, m_Pos.Y] = 1;
                        break;
                    case 2:
                        arr[m_Pos.X, m_Pos.Y - 2] = 1;
                        arr[m_Pos.X, m_Pos.Y - 1] = 1;
                        arr[m_Pos.X, m_Pos.Y] = 1;
                        arr[m_Pos.X, m_Pos.Y + 1] = 1;
                        break;
                    case 3:
                        arr[m_Pos.X - 2, m_Pos.Y] = 1;
                        arr[m_Pos.X - 1, m_Pos.Y] = 1;
                        arr[m_Pos.X, m_Pos.Y] = 1;
                        arr[m_Pos.X + 1, m_Pos.Y] = 1;
                        break;
                    default:
                        break;
                }
            }
            return result;
        }

        //重写变形的方法
        public override void Transform()
        {
            switch (m_CurTransforIndex)
            {
                case 0:
                    m_Range = new int[5, 5]{{0,0,0,0,0},
                                            {0,0,1,0,0},
                                            {0,0,1,0,0},
                                            {0,0,1,0,0},
                                            {0,0,1,0,0}};
                    m_CurTransforIndex = 1;
                    break;
                case 1:
                    m_Range = new int[5, 5]{{0,0,0,0,0},
                                            {0,0,0,0,0},
                                            {1,1,1,1,0},
                                            {0,0,0,0,0},
                                            {0,0,0,0,0}};
                    m_CurTransforIndex = 2;
                    break;
                case 2:
                    m_Range = new int[5, 5]{{0,0,1,0,0},
                                            {0,0,1,0,0},
                                            {0,0,1,0,0},
                                            {0,0,1,0,0},
                                            {0,0,0,0,0}};
                    m_CurTransforIndex = 3;
                    break;
                case 3:
                    m_Range = new int[5, 5]{{0,0,0,0,0},
                                            {0,0,0,0,0},
                                            {0,1,1,1,1},
                                            {0,0,0,0,0},
                                            {0,0,0,0,0}};
                    m_CurTransforIndex = 0;
                    break;
                default:
                    break;
            }
        }

        //重写判断是否可以左移的方法
        public override bool CanLeftMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.Y > 1)
                    {
                        if (arr[m_Pos.X, m_Pos.Y - 2] == 0)
                        {
                            result = true;
                        }
                        else
                        {
                            result = false;
                        }
                    }
                    break;
                case 1:
                    if (m_Pos.Y > 0)
                    {
                        bool temp = true;
                        for (int i = -1; i < 3; i++)
                        {
                            if (m_Pos.X + i < 0)
                            {
                                continue;
                            }
                            else
                            {
                                if (arr[m_Pos.X + i, m_Pos.Y - 1] == 1)
                                {
                                    temp = false;
                                    break;
                                }
                            }
                        }
                        result = temp;
                    }
                    break;
                case 2:
                    if (m_Pos.Y > 2)
                    {
                        if (arr[m_Pos.X, m_Pos.Y - 3] == 0)
                        {
                            result = true;
                        }
                        else
                        {
                            result = false;
                        }
                    }
                    break;
                case 3:
                    if (m_Pos.Y > 0)
                    {
                        bool temp = true;
                        for (int i = -2; i < 2; i++)
                        {
                            if (m_Pos.X + i < 0)
                            {
                                continue;
                            }
                            else
                            {
                                if (arr[m_Pos.X + i, m_Pos.Y - 1] == 1)
                                {
                                    temp = false;
                                    break;
                                }
                            }
                        }
                        result = temp;
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写判断是否可以右移的方法
        public override bool CanRightMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.Y < columns - 3)
                    {
                        if (arr[m_Pos.X, m_Pos.Y + 3] == 0)
                        {
                            result = true;
                        }
                        else
                        {
                            result = false;
                        }
                    }
                    break;
                case 1:
                    if (m_Pos.Y < columns - 1)
                    {
                        bool temp = true;
                        for (int i = -1; i < 3; i++)
                        {
                            if (m_Pos.X + i < 0)
                            {
                                continue;
                            }
                            else
                            {
                                if (arr[m_Pos.X + i, m_Pos.Y + 1] == 1)
                                {
                                    temp = false;
                                    break;
                                }
                            }
                        }
                        result = temp;
                    }
                    break;
                case 2:
                    if (m_Pos.Y < columns - 2)
                    {
                        if (arr[m_Pos.X, m_Pos.Y + 2] == 0)
                        {
                            result = true;
                        }
                        else
                        {
                            result = false;
                        }
                    }
                    break;
                case 3:
                    if (m_Pos.Y < columns - 1)
                    {
                        bool temp = true;
                        for (int i = -2; i < 2; i++)
                        {
                            if (m_Pos.X + i < 0)
                            {
                                continue;
                            }
                            else
                            {
                                if (arr[m_Pos.X + i, m_Pos.Y + 1] == 1)
                                {
                                    temp = false;
                                    break;
                                }
                            }
                        }
                        result = temp;
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写判断是否可以下移的方法
        public override bool CanDropMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.X != rows - 1)
                    {
                        if (arr[m_Pos.X + 1, m_Pos.Y] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                        {
                            result = true;
                        }
                        else
                        {
                            result = false;
                        }
                    }
                    break;
                case 1:
                    if (m_Pos.X != rows - 3)
                    {
                        if (arr[m_Pos.X + 3, m_Pos.Y] == 0)
                        {
                            result = true;
                        }
                        else
                        {
                            result = false;
                        }
                    }
                    break;
                case 2:
                    if (m_Pos.X != rows - 1)
                    {
                        if (arr[m_Pos.X + 1, m_Pos.Y - 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                        {
                            result = true;
                        }
                        else
                        {
                            result = false;
                        }
                    }
                    break;
                case 3:
                    if (m_Pos.X != rows - 2)
                    {
                        if (arr[m_Pos.X + 2, m_Pos.Y] == 0)
                        {
                            result = true;
                        }
                        else
                        {
                            result = false;
                        }
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写获取砖块出现时y的坐标方法
        public override int Appear()
        {
            int result = 0;
            switch (m_CurTransforIndex)
            {
                case 0:
                    result = 0;
                    break;
                case 1:
                    result = -2;
                    break;
                case 2:
                    result = 0;
                    break;
                case 3:
                    result = -1;
                    break;
                default:
                    break;
            }
            return result;
        }
    }
}

Brick3.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace OhMyTetris
{
    class Brick3:Brick
    {
        //定义新砖块的各个值
        public Brick3() 
        {
            this.m_CurTransforIndex = 0;
            this.m_NeedfulColumns = 3;
            this.m_NeedfulRows = 3;
            m_Range = new int[3, 3] { { 0, 1, 0 },
                                      { 1, 1, 1 },
                                      { 0, 0, 0 }};
            this.m_Center = new Point(1, 1);
            this.m_Pos = new Point();
        }

        //重写判断能否变形的方法
        public override bool CanTransform(int[,] arr, int rows, int columns)
        {
            bool result = true;
            if (m_Pos.X - 1 >= 0 && m_Pos.X + 1 <= rows - 1 && m_Pos.Y - 1 >= 0 && m_Pos.Y + 1 <= columns - 1)
            {
                for (int i = -1; i < 2; i++)
                {
                    for (int j = -1; j < 2; j++)
                    {
                        switch (m_CurTransforIndex)
                        {
                            case 0:
                                if (i == -1 && j == 0 || i == 0 && j == -1 || i == 0 && j == 0 || i == 0 && j == 1)
                                {
                                    continue;
                                }
                                break;
                            case 1:
                                if (i == -1 && j == 0 || i == 0 && j == 0 || i == 0 && j == 1 || i == 1 && j == 0)
                                {
                                    continue;
                                }
                                break;
                            case 2:
                                if (i == 0 && j == -1 || i == 0 && j == 0 || i == 0 && j == 1 || i == 1 && j == 0)
                                {
                                    continue;
                                }
                                break;
                            case 3:
                                if (i == -1 && j == 0 || i == 0 && j == -1 || i == 0 && j == 0 || i == 1 && j == 0)
                                {
                                    continue;
                                }
                                break;
                            default:
                                break;
                        }
                        if (arr[m_Pos.X + i, m_Pos.Y + j] == 1)
                        {
                            result = false;
                        }
                    }
                }
            }
            return result;
        }

        //重写变形的方法
        public override void Transform()
        {
            switch (m_CurTransforIndex)
            {
                case 0:
                    m_Range = new int[3, 3]{{0,1,0},
                                            {0,1,1},
                                            {0,1,0}};
                    m_CurTransforIndex = 1;
                    break;
                case 1:
                    m_Range = new int[3, 3]{{0,0,0},
                                            {1,1,1},
                                            {0,1,0}};
                    m_CurTransforIndex = 2;
                    break;
                case 2:
                    m_Range = new int[3, 3]{{0,1,0},
                                           {1,1,0},
                                           {0,1,0}};
                    m_CurTransforIndex = 3;
                    break;
                case 3:
                    m_Range = new int[3, 3]{{0,1,0},
                                            {1,1,1},
                                            {0,0,0}};
                    m_CurTransforIndex = 0;
                    break;
                default:
                    break;
            }
        }

        //重写判断是否可以左移的方法
        public override bool CanLeftMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.Y - 1 != 0)
                    {
                        if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 2] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X - 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X, m_Pos.Y - 2] == 0)
                                result = true;
                        }
                    }
                    break;
                case 1:
                    if (m_Pos.Y != 0)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X - 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 2:
                    if (m_Pos.Y - 1 != 0)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 3:
                    if (m_Pos.Y - 1 != 0)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X - 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X, m_Pos.Y - 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写判断是否可以右移的方法
        public override bool CanRightMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.Y + 1 < columns - 1)
                    {
                        if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 2] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X - 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X, m_Pos.Y + 2] == 0)
                                result = true;
                        }
                    }
                    break;
                case 1:
                    if (m_Pos.Y + 1 < columns - 1)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X - 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X, m_Pos.Y + 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 2:
                    if (m_Pos.Y + 1 < columns - 1)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 3:
                    if (m_Pos.Y < columns - 1)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X - 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X, m_Pos.Y + 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写判断是否可以下移的方法
        public override bool CanDropMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.X != rows - 1)
                    {
                        if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                            result = true;
                    }
                    break;
                case 1:
                    if (m_Pos.X + 1 != rows - 1)
                    {
                        if (arr[m_Pos.X + 2, m_Pos.Y] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                            result = true;
                    }
                    break;
                case 2:
                    if (m_Pos.X + 1 != rows - 1)
                    {
                        if (arr[m_Pos.X + 2, m_Pos.Y] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                            result = true;
                    }
                    break;
                case 3:
                    if (m_Pos.X + 1 != rows - 1)
                    {
                        if (arr[m_Pos.X + 2, m_Pos.Y] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                            result = true;
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写获取砖块出现时y的坐标方法
        public override int Appear()
        {
            int result = 0;
            switch (m_CurTransforIndex)
            {
                case 0:
                    result = 0;
                    break;
                case 1:
                    result = -1;
                    break;
                case 2:
                    result = -1;
                    break;
                case 3:
                    result = -1;
                    break;
                default:
                    break;
            }
            return result;
        }
    }
}

Brick4.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace OhMyTetris
{
    class Brick4:Brick
    {
        //定义新砖块的各个值
        public Brick4() 
        {
            this.m_CurTransforIndex = 0;
            this.m_NeedfulColumns = 3;
            this.m_NeedfulRows = 3;
            m_Range = new int[3, 3] { { 0, 0, 0 },
                                      { 1, 1, 0 },
                                      { 0, 1, 1 }};
            this.m_Center = new Point(1, 1);
            this.m_Pos = new Point();
        }

        //重写判断能否变形的方法
        public override bool CanTransform(int[,] arr, int rows, int columns)
        {
            bool result = true;
            if (m_Pos.X - 1 >= 0 && m_Pos.X + 1 <= rows - 1 && m_Pos.Y - 1 >= 0 && m_Pos.Y + 1 <= columns - 1)
            {
                for (int i = -1; i < 2; i++)
                {
                    for (int j = -1; j < 2; j++)
                    {
                        switch (m_CurTransforIndex)
                        {
                            case 0:
                                if (i == 0 && j == -1 || i == 0 && j == 0 || i == 1 && j == 0 || i == 1 && j == 1)
                                    continue;
                                break;
                            case 1:
                                if (i == -1 && j == 0 || i == 0 && j == 0 || i == 0 && j == -1 || i == 1 && j == -1)
                                    continue;
                                break;
                            case 2:
                                if (i == -1 && j == -1 || i == -1 && j == 0 || i == 0 && j == 0 || i == 0 && j == 1)
                                    continue;
                                break;
                            case 3:
                                if (i == -1 && j == 1 || i == 0 && j == 0 || i == 0 && j == 1 || i == 1 && j == 0)
                                    continue;
                                break;
                            default:
                                break;
                        }
                        if (arr[m_Pos.X + i, m_Pos.Y + j] == 1)
                        {
                            result = false;
                            goto break1;
                        }
                    }
                }
            }
            break1: return result;
        }

        //重写变形的方法
        public override void Transform()
        {
            switch (m_CurTransforIndex)
            {
                case 0:
                    m_Range = new int[3, 3]{{0,1,0},
                                            {1,1,0},
                                            {1,0,0}};
                    m_CurTransforIndex = 1;
                    break;
                case 1:
                    m_Range = new int[3, 3]{{1,1,0},
                                            {0,1,1},
                                            {0,0,0}};
                    m_CurTransforIndex = 2;
                    break;
                case 2:
                    m_Range = new int[3, 3]{{0,0,1},
                                            {0,1,1},
                                            {0,1,0}};
                    m_CurTransforIndex = 3;
                    break;
                case 3:
                    m_Range = new int[3, 3]{{0,0,0},
                                           {1,1,0},
                                           {0,1,1}};
                    m_CurTransforIndex = 0;
                    break;
                default:
                    break;
            }
        }

        //重写判断是否可以左移的方法
        public override bool CanLeftMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.Y - 1 > 0)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 1:
                    if (m_Pos.Y - 1 > 0)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 2] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 2] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 2] == 0 && arr[m_Pos.X - 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 2:
                    if (m_Pos.Y - 1 > 0)
                    {
                        if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 1] == 0 && arr[m_Pos.X - 1, m_Pos.Y - 2] == 0)
                                result = true;
                        }
                    }
                    break;
                case 3:
                    if (m_Pos.Y > 0)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X - 1, m_Pos.Y] == 0)
                                result = true;
                        }
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写判断是否可以右移的方法
        public override bool CanRightMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.Y + 1 < columns - 1)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 2] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 2] == 0)
                                result = true;
                        }
                    }
                    break;
                case 1:
                    if (m_Pos.Y < columns - 1)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y] == 0 && arr[m_Pos.X, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y] == 0 && arr[m_Pos.X, m_Pos.Y + 1] == 0 && arr[m_Pos.X - 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 2:
                    if (m_Pos.Y + 1 < columns - 1)
                    {
                        if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 2] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 2] == 0 && arr[m_Pos.X - 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 3:
                    if (m_Pos.Y + 1 < columns - 1)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X, m_Pos.Y + 2] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X, m_Pos.Y + 2] == 0 && arr[m_Pos.X - 1, m_Pos.Y + 2] == 0)
                                result = true;
                        }
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写判断是否可以下移的方法
        public override bool CanDropMove(int[,] arr, int rows, int columns)
        {
            bool result = false;

            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.X + 1 < rows - 1)
                    {
                        if (arr[m_Pos.X + 2, m_Pos.Y] == 0 && arr[m_Pos.X + 2, m_Pos.Y + 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                            result = true;
                    }
                    break;
                case 1:
                    if (m_Pos.X + 1 < rows - 1)
                    {
                        if (arr[m_Pos.X + 2, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y] == 0)
                            result = true;
                    }
                    break;
                case 2:
                    if (m_Pos.X < rows - 1)
                    {
                        if (arr[m_Pos.X + 1, m_Pos.Y] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X, m_Pos.Y - 1] == 0)
                            result = true;
                    }
                    break;
                case 3:
                    if (m_Pos.X + 1 < rows - 1)
                    {
                        if (arr[m_Pos.X + 2, m_Pos.Y] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                            result = true;
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写获取砖块出现时y的坐标方法
        public override int Appear()
        {
            int result = 0;
            switch (m_CurTransforIndex)
            {
                case 0:
                    result = -1;
                    break;
                case 1:
                    result = -1;
                    break;
                case 2:
                    result = 0;
                    break;
                case 3:
                    result = -1;
                    break;
                default:
                    break;
            }
            return result;
        }
    }
}

Brick5.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace OhMyTetris
{
    class Brick5:Brick
    {
        //定义新砖块的各个值
        public Brick5() 
        {
            this.m_CurTransforIndex = 0;
            this.m_NeedfulColumns = 3;
            this.m_NeedfulRows = 3;
            m_Range = new int[3, 3] { { 0, 0, 0 },
                                      { 1, 1, 0 },
                                      { 0, 1, 1 }};
            this.m_Center = new Point(1, 1);
            this.m_Pos = new Point();
        }

        //重写判断能否变形的方法
        public override bool CanTransform(int[,] arr, int rows, int columns)
        {
            bool result = true;
            if (m_Pos.X - 1 >= 0 && m_Pos.X + 1 <= rows - 1 && m_Pos.Y - 1 >= 0 && m_Pos.Y + 1 <= columns - 1)
            {
                for (int i = -1; i < 2; i++)
                {
                    for (int j = -1; j < 2; j++)
                    {
                        switch (m_CurTransforIndex)
                        {
                            case 0:
                                if (i == 0 && j == 0 || i == 0 && j == 1 || i == 1 && j == -1 || i == 1 && j == 0)
                                    continue;
                                break;
                            case 1:
                                if (i == -1 && j == -1 || i == 0 && j == -1 || i == 0 && j == 0 || i == 1 && j == 0)
                                    continue;
                                break;
                            case 2:
                                if (i == -1 && j == 0 || i == -1 && j == 1 || i == 0 && j == -1 || i == 0 && j == 0)
                                    continue;
                                break;
                            case 3:
                                if (i == -1 && j == 0 || i == 0 && j == 0 || i == 0 && j == 1 || i == 1 && j == 1)
                                    continue;
                                break;
                            default:
                                break;
                        }
                        if (arr[m_Pos.X + i, m_Pos.Y + j] == 1)
                        {
                            result = false;
                            goto break1;
                        }
                    }
                }
            }
            break1: return result;
        }

        //重写变形的方法
        public override void Transform()
        {
            switch (m_CurTransforIndex)
            {
                case 0:
                    m_Range = new int[3, 3]{{1,0,0},
                                            {1,1,0},
                                            {0,1,0}};
                    m_CurTransforIndex = 1;
                    break;
                case 1:
                    m_Range = new int[3, 3]{{0,1,1},
                                            {1,1,0},
                                            {0,0,0}};
                    m_CurTransforIndex = 2;
                    break;
                case 2:
                    m_Range = new int[3, 3]{{0,1,0},
                                            {0,1,1},
                                            {0,0,1}};
                    m_CurTransforIndex = 3;
                    break;
                case 3:
                    m_Range = new int[3, 3]{{0,0,0},
                                           {0,1,1},
                                           {1,1,0}};
                    m_CurTransforIndex = 0;
                    break;
                default:
                    break;
            }
        }

        //重写判断是否可以左移的方法
        public override bool CanLeftMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.Y - 1 > 0)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 2] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 2] == 0)
                                result = true;
                        }
                    }
                    break;
                case 1:
                    if (m_Pos.Y - 1 > 0)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X - 1, m_Pos.Y - 2] == 0)
                                result = true;
                        }
                    }
                    break;
                case 2:
                    if (m_Pos.Y - 1 > 0)
                    {
                        if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 2] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 2] == 0 && arr[m_Pos.X - 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 3:
                    if (m_Pos.Y > 0)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y] == 0 && arr[m_Pos.X, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y] == 0 && arr[m_Pos.X, m_Pos.Y - 1] == 0 && arr[m_Pos.X - 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写判断是否可以右移的方法
        public override bool CanRightMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.Y + 1 < columns - 1)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 1:
                    if (m_Pos.Y < columns - 1)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X, m_Pos.Y + 1] == 0 && arr[m_Pos.X - 1, m_Pos.Y] == 0)
                                result = true;
                        }
                    }
                    break;
                case 2:
                    if (m_Pos.Y + 1 < columns - 1)
                    {
                        if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 1] == 0 && arr[m_Pos.X - 1, m_Pos.Y + 2] == 0)
                                result = true;
                        }
                    }
                    break;
                case 3:
                    if (m_Pos.Y + 1 < columns - 1)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 2] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 2] == 0 && arr[m_Pos.X, m_Pos.Y + 2] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 2] == 0 && arr[m_Pos.X, m_Pos.Y + 2] == 0 && arr[m_Pos.X - 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写判断是否可以下移的方法
        public override bool CanDropMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.X + 1 < rows - 1)
                    {
                        if (arr[m_Pos.X + 2, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 2, m_Pos.Y] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                            result = true;
                    }
                    break;
                case 1:
                    if (m_Pos.X + 1 < rows - 1)
                    {
                        if (arr[m_Pos.X + 2, m_Pos.Y] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                            result = true;
                    }
                    break;
                case 2:
                    if (m_Pos.X < rows - 1)
                    {
                        if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y] == 0 && arr[m_Pos.X, m_Pos.Y + 1] == 0)
                            result = true;
                    }
                    break;
                case 3:
                    if (m_Pos.X + 1 < rows - 1)
                    {
                        if (arr[m_Pos.X + 1, m_Pos.Y] == 0 && arr[m_Pos.X + 2, m_Pos.Y + 1] == 0)
                            result = true;
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写获取砖块出现时y的坐标方法
        public override int Appear()
        {
            int result = 0;
            switch (m_CurTransforIndex)
            {
                case 0:
                    result = -1;
                    break;
                case 1:
                    result = -1;
                    break;
                case 2:
                    result = 0;
                    break;
                case 3:
                    result = -1;
                    break;
                default:
                    break;
            }
            return result;
        }
    }
}

Brick6.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace OhMyTetris
{
    class Brick6:Brick
    {
        //定义新砖块的各个值
        public Brick6() 
        {
            this.m_CurTransforIndex = 0;
            this.m_NeedfulColumns = 5;
            this.m_NeedfulRows = 5;
            m_Range = new int[5, 5] { { 0, 0, 0, 0, 0 },
                                      { 0, 0, 1, 0, 0 },
                                      { 0, 0, 1, 1, 1 },
                                      { 0, 0, 0, 0, 0 },
                                      { 0, 0, 0, 0, 0 }};
            this.m_Center = new Point(2, 2);
            this.m_Pos = new Point();
        }

        //重写判断能否变形的方法
        public override bool CanTransform(int[,] arr, int rows, int columns)
        {
            if (m_Pos.X - 2 >= 0 && m_Pos.X + 2 <= rows - 1 && m_Pos.Y - 2 >= 0 && m_Pos.Y + 2 <= columns - 1)
            {
                bool result = true;
                switch (m_CurTransforIndex)
                {
                    case 0:
                        for (int i = -2; i < 3; i++)
                        {
                            for (int j = -2; j < 3; j++)
                            {
                                if (i == -1 && j == 0 || i == 0 && j == 0 || i == 0 && j == 1 || i == 0 && j == 2)
                                    continue;
                                if (arr[m_Pos.X + i, m_Pos.Y + j] == 1)
                                {
                                    result = false;
                                    goto break1;
                                }
                            }
                        }
                        break;
                    case 1:
                        for (int i = -2; i < 3; i++)
                        {
                            for (int j = -2; j < 3; j++)
                            {
                                if (i == 0 && j == 0 || i == 0 && j == 1 || i == 1 && j == 0 || i == 2 && j == 0)
                                    continue;
                                if (arr[m_Pos.X + i, m_Pos.Y + j] == 1)
                                {
                                    result = false;
                                    goto break1;
                                }
                            }
                        }
                        break;
                    case 2:
                        for (int i = -2; i < 3; i++)
                        {
                            for (int j = -2; j < 3; j++)
                            {
                                if (i == 0 && j == -2 || i == 0 && j == -1 || i == 0 && j == 0 || i == 1 && j == 0)
                                    continue;
                                if (arr[m_Pos.X + i, m_Pos.Y + j] == 1)
                                {
                                    result = false;
                                    goto break1;
                                }
                            }
                        }
                        break;
                    case 3:
                        for (int i = -2; i < 3; i++)
                        {
                            for (int j = -2; j < 3; j++)
                            {
                                if (i == -2 && j == 0 || i == -1 && j == 0 || i == 0 && j == -1 || i == 0 && j == 0)
                                    continue;
                                if (arr[m_Pos.X + i, m_Pos.Y + j] == 1)
                                {
                                    result = false;
                                    goto break1;
                                }
                            }
                        }
                        break;
                    default:
                        break;
                }
            break1: return result;
            }
            else
            {
                return false;
            }
        }

        //重写变形的方法
        public override void Transform()
        {
            switch (m_CurTransforIndex)
            {
                case 0:
                    m_Range = new int[5, 5]{{0,0,0,0,0},
                                            {0,0,0,0,0},
                                            {0,0,1,1,0},
                                            {0,0,1,0,0},
                                            {0,0,1,0,0}};
                    m_CurTransforIndex = 1;
                    break;
                case 1:
                    m_Range = new int[5, 5]{{0,0,0,0,0},
                                            {0,0,0,0,0},
                                            {1,1,1,0,0},
                                            {0,0,1,0,0},
                                            {0,0,0,0,0}};
                    m_CurTransforIndex = 2;
                    break;
                case 2:
                    m_Range = new int[5, 5]{{0,0,1,0,0},
                                            {0,0,1,0,0},
                                            {0,1,1,0,0},
                                            {0,0,0,0,0},
                                            {0,0,0,0,0}};
                    m_CurTransforIndex = 3;
                    break;
                case 3:
                    m_Range = new int[5, 5]{{0,0,0,0,0},
                                            {0,0,1,0,0},
                                            {0,0,1,1,1},
                                            {0,0,0,0,0},
                                            {0,0,0,0,0}};
                    m_CurTransforIndex = 0;
                    break;
                default:
                    break;
            }
        }

        //重写判断是否可以左移的方法
        public override bool CanLeftMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.Y > 0)
                    {
                        if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 1] == 0 && arr[m_Pos.X - 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 1:
                    if (m_Pos.Y > 0)
                    {
                        if (m_Pos.X == -2)
                        {
                            if (arr[m_Pos.X + 2, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 2, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 2, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 2:
                    if (m_Pos.Y > 2)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X, m_Pos.Y - 3] == 0)
                                result = true;
                        }
                    }
                    break;
                case 3:
                    if (m_Pos.Y > 1)
                    {
                        if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 2] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 1)
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 2] == 0 && arr[m_Pos.X - 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 2] == 0 && arr[m_Pos.X - 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X - 2, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写判断是否可以右移的方法
        public override bool CanRightMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.Y + 2 < columns - 1)
                    {
                        if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 3] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 3] == 0 && arr[m_Pos.X - 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 1:
                    if (m_Pos.Y + 1 < columns - 1)
                    {
                        if (m_Pos.X == -2)
                        {
                            if (arr[m_Pos.X + 2, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 2, m_Pos.Y + 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 2, m_Pos.Y + 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X, m_Pos.Y + 2] == 0)
                                result = true;
                        }
                    }
                    break;
                case 2:
                    if (m_Pos.Y < columns - 1)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 3:
                    if (m_Pos.Y < columns - 1)
                    {
                        if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 1)
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 1] == 0 && arr[m_Pos.X - 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 1] == 0 && arr[m_Pos.X - 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X - 2, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写判断是否可以下移的方法
        public override bool CanDropMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.X < rows - 1)
                    {
                        if (arr[m_Pos.X + 1, m_Pos.Y] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 2] == 0)
                            result = true;
                    }
                    break;
                case 1:
                    if (m_Pos.X + 2 < rows - 1)
                    {
                        if (m_Pos.X == -2)
                        {
                            if (arr[m_Pos.X + 3, m_Pos.Y] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 3, m_Pos.Y] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 2:
                    if (m_Pos.X + 1 < rows - 1)
                    {
                        if (arr[m_Pos.X + 1, m_Pos.Y - 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 2, m_Pos.Y] == 0)
                            result = true;
                    }
                    break;
                case 3:
                    if (m_Pos.X < rows - 1)
                    {
                        if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y] == 0)
                            result = true;
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写获取砖块出现时y的坐标方法
        public override int Appear()
        {
            int result = 0;
            switch (m_CurTransforIndex)
            {
                case 0:
                    result = 0;
                    break;
                case 1:
                    result = -2;
                    break;
                case 2:
                    result = -1;
                    break;
                case 3:
                    result = -0;
                    break;
                default:
                    break;
            }
            return result;
        }
    }
}

Brick7.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;

namespace OhMyTetris
{
    class Brick7:Brick
    {
        //定义新砖块的各个值
        public Brick7() 
        {
            this.m_CurTransforIndex = 0;
            this.m_NeedfulColumns = 5;
            this.m_NeedfulRows = 5;
            m_Range = new int[5, 5] { { 0, 0, 0, 0, 0 },
                                      { 0, 0, 1, 0, 0 },
                                      { 1, 1, 1, 0, 0 },
                                      { 0, 0, 0, 0, 0 },
                                      { 0, 0, 0, 0, 0 }};
            this.m_Center = new Point(2, 2);
            this.m_Pos = new Point();
        }

        //重写判断能否变形的方法
        public override bool CanTransform(int[,] arr, int rows, int columns)
        {
            if (m_Pos.X - 2 >= 0 && m_Pos.X + 2 <= rows - 1 && m_Pos.Y - 2 >= 0 && m_Pos.Y + 2 <= columns - 1)
            {
                bool result = true;
                switch (m_CurTransforIndex)
                {
                    case 0:
                        for (int i = -2; i < 3; i++)
                        {
                            for (int j = -2; j < 3; j++)
                            {
                                if (i == -1 && j == 0 || i == 0 && j == -2 || i == 0 && j == -1 || i == 0 && j == 0)
                                    continue;
                                if (arr[m_Pos.X + i, m_Pos.Y + j] == 1)
                                {
                                    result = false;
                                    goto break1;
                                }
                            }
                        }
                        break;
                    case 1:
                        for (int i = -2; i < 3; i++)
                        {
                            for (int j = -2; j < 3; j++)
                            {
                                if (i == -2 && j == 0 || i == -1 && j == 0 || i == 0 && j == 0 || i == 0 && j == 1)
                                    continue;
                                if (arr[m_Pos.X + i, m_Pos.Y + j] == 1)
                                {
                                    result = false;
                                    goto break1;
                                }
                            }
                        }
                        break;
                    case 2:
                        for (int i = -2; i < 3; i++)
                        {
                            for (int j = -2; j < 3; j++)
                            {
                                if (i == 0 && j == 0 || i == 0 && j == 1 || i == 0 && j == 2 || i == 1 && j == 0)
                                    continue;
                                if (arr[m_Pos.X + i, m_Pos.Y + j] == 1)
                                {
                                    result = false;
                                    goto break1;
                                }
                            }
                        }
                        break;
                    case 3:
                        for (int i = -2; i < 3; i++)
                        {
                            for (int j = -2; j < 3; j++)
                            {
                                if (i == 0 && j == -1 || i == 0 && j == 0 || i == 1 && j == 0 || i == 2 && j == 0)
                                    continue;
                                if (arr[m_Pos.X + i, m_Pos.Y + j] == 1)
                                {
                                    result = false;
                                    goto break1;
                                }
                            }
                        }
                        break;
                    default:
                        break;
                }
            break1: return result;
            }
            else
            {
                return false;
            }
        }

        //重写变形的方法
        public override void Transform()
        {
            switch (m_CurTransforIndex)
            {
                case 0:
                    m_Range = new int[5, 5]{{0,0,1,0,0},
                                            {0,0,1,0,0},
                                            {0,0,1,1,0},
                                            {0,0,0,0,0},
                                            {0,0,0,0,0}};
                    m_CurTransforIndex = 1;
                    break;
                case 1:
                    m_Range = new int[5, 5]{{0,0,0,0,0},
                                            {0,0,0,0,0},
                                            {0,0,1,1,1},
                                            {0,0,1,0,0},
                                            {0,0,0,0,0}};
                    m_CurTransforIndex = 2;
                    break;
                case 2:
                    m_Range = new int[5, 5]{{0,0,0,0,0},
                                            {0,0,0,0,0},
                                            {0,1,1,0,0},
                                            {0,0,1,0,0},
                                            {0,0,1,0,0}};
                    m_CurTransforIndex = 3;
                    break;
                case 3:
                    m_Range = new int[5, 5]{{0,0,0,0,0},
                                            {0,0,1,0,0},
                                            {1,1,1,0,0},
                                            {0,0,0,0,0},
                                            {0,0,0,0,0}};
                    m_CurTransforIndex = 0;
                    break;
                default:
                    break;
            }
        }

        //重写判断是否可以左移的方法
        public override bool CanLeftMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.Y - 2 > 0)
                    {
                        if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 3] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 3] == 0 && arr[m_Pos.X - 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 1:
                    if (m_Pos.Y > 0)
                    {
                        if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 1)
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 1] == 0 && arr[m_Pos.X - 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y - 1] == 0 && arr[m_Pos.X - 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X - 2, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 2:
                    if (m_Pos.Y > 0)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 3:
                    if (m_Pos.Y > 1)
                    {
                        if (m_Pos.X == -2)
                        {
                            if (arr[m_Pos.X + 2, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 2, m_Pos.Y - 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 2, m_Pos.Y - 1] == 0 && arr[m_Pos.X, m_Pos.Y - 2] == 0)
                                result = true;
                        }
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写判断是否可以右移的方法
        public override bool CanRightMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.Y < columns - 1)
                    {
                        if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 1] == 0 && arr[m_Pos.X - 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 1:
                    if (m_Pos.Y + 1 < columns - 1)
                    {
                        if (m_Pos.X == 0)
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 2] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == 1)
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 2] == 0 && arr[m_Pos.X - 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X, m_Pos.Y + 2] == 0 && arr[m_Pos.X - 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X - 2, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                    }
                    break;
                case 2:
                    if (m_Pos.Y + 2 < columns - 1)
                    {
                        if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X, m_Pos.Y + 3] == 0)
                                result = true;
                        }
                    }
                    break;
                case 3:
                    if (m_Pos.Y < columns - 1)
                    {
                        if (m_Pos.X == -2)
                        {
                            if (arr[m_Pos.X + 2, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else if (m_Pos.X == -1)
                        {
                            if (arr[m_Pos.X + 2, m_Pos.Y + 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 2, m_Pos.Y + 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X, m_Pos.Y + 1] == 0)
                                result = true;
                        }
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写判断是否可以下移的方法
        public override bool CanDropMove(int[,] arr, int rows, int columns)
        {
            bool result = false;
            switch (m_CurTransforIndex)
            {
                case 0:
                    if (m_Pos.X < rows - 1)
                    {
                        if (arr[m_Pos.X + 1, m_Pos.Y] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 1, m_Pos.Y - 2] == 0)
                            result = true;
                    }
                    break;
                case 1:
                    if (m_Pos.X < rows - 1)
                    {
                        if (arr[m_Pos.X + 1, m_Pos.Y] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0)
                            result = true;
                    }
                    break;
                case 2:
                    if (m_Pos.X + 1 < rows - 1)
                    {
                        if (arr[m_Pos.X + 1, m_Pos.Y + 2] == 0 && arr[m_Pos.X + 1, m_Pos.Y + 1] == 0 && arr[m_Pos.X + 2, m_Pos.Y] == 0)
                            result = true;
                    }
                    break;
                case 3:
                    if (m_Pos.X + 2 < rows - 1)
                    {
                        if (m_Pos.X == -2)
                        {
                            if (arr[m_Pos.X + 3, m_Pos.Y] == 0)
                                result = true;
                        }
                        else
                        {
                            if (arr[m_Pos.X + 1, m_Pos.Y - 1] == 0 && arr[m_Pos.X + 3, m_Pos.Y] == 0)
                                result = true;
                        }
                    }
                    break;
                default:
                    break;
            }
            return result;
        }

        //重写获取砖块出现时y的坐标方法
        public override int Appear()
        {
            int result = 0;
            switch (m_CurTransforIndex)
            {
                case 0:
                    result = 0;
                    break;
                case 1:
                    result = 0;
                    break;
                case 2:
                    result = -1;
                    break;
                case 3:
                    result = -2;
                    break;
                default:
                    break;
            }
            return result;
        }
    }
}

Bricks.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Collections;

namespace OhMyTetris
{
    class Bricks
    {
        //lock线程锁,所以方法和属性都要用静态的
        public static ArrayList _brickList = new ArrayList();

        //静态方法:随机获取一个砖块
        //非静态的字段、方法或属性“member”要求对象引用
        public static Brick GetBrick()
        {
            Random random = new Random(DateTime.Now.Second);
            int index = random.Next(7);
            Brick brick;
            switch (index)
            {
                case 0:
                    brick = new Brick1(); break;
                case 1:
                    brick = new Brick2(); break;
                case 2:
                    brick = new Brick3(); break;
                case 3:
                    brick = new Brick4(); break;
                case 4:
                    brick = new Brick5(); break;
                case 5:
                    brick = new Brick6(); break;
                case 6:
                    brick = new Brick7(); break;
                //default:
                    //brick = new Brick1(); break;
            }
            return brick;
        }
    }
}

Canvas.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
using System.Media;

namespace OhMyTetris
{
    class Canvas
    {
        #region 私有属性
        private int m_rows;
        private int m_columns;
        private int[,] m_arr;

        //装载声音文件
        private SoundPlayer m_bgm = new SoundPlayer("bgm.wav");
        private SoundPlayer m_disappear = new SoundPlayer("disappear.wav");

        //分数
        private int m_score;

        //当前砖块
        private Brick m_curBrick = null;
        
        //下一个砖块
        private Brick m_nextBrick = null;

        //判断是否消除行
        private bool m_flag = false;

        //当前高度
        private int m_height;

        private System.Windows.Forms.Timer m_timer = new System.Windows.Forms.Timer();

        #endregion 

        #region 公有属性

        public int m_Rows
        {
            get { return m_rows; }
            set { m_rows = value; }
        }

        public int m_Columns
        {
            get { return m_columns; }
            set { m_columns = value; }
        }

        public int[,] m_Arr
        {
            get { return m_arr; }
            set { m_arr = value; }
        }

        public int m_Score
        {
            get { return m_score; }
            set { m_score = value; }
        }
        #endregion

        //构造方法
        public Canvas()
        {
            m_rows = 20;
            m_columns = 20;
            m_arr = new int[m_rows, m_columns];
            for (int i = 0; i < m_rows; i++)
            {
                for (int j = 0; j < m_columns; j++)
                {
                    m_arr[i, j] = 0;
                }
            }
            m_score = 0;
            m_height = 0;

            m_timer.Interval = 2400;
            m_timer.Enabled = false;
            m_timer.Tick += new EventHandler(m_timer_Tick);

        }

        #region 移动
        //左移
        public void BrickLeft()
        {
            lock (m_arr)
            {
                if (m_curBrick != null && m_curBrick.CanLeftMove(m_arr, m_rows, m_columns) == true)
                {
                    ClearCurBrick();
                    m_curBrick.LeftMove();
                    SetArrayValue();
                }
            }
        }

        //右移
        public void BrickRight()
        {
            lock (m_arr)
            {
                if (m_curBrick != null && m_curBrick.CanRightMove(m_arr, m_rows, m_columns) == true)
                {
                    ClearCurBrick();
                    m_curBrick.RightMove();
                    SetArrayValue();
                }
            }
        }

        //下移
        public void BrickDown()
        {
            lock (m_arr)
            {
                if (m_curBrick != null && m_curBrick.CanDropMove(m_arr, m_rows, m_columns) == true)
                {
                    ClearCurBrick();
                    m_curBrick.DropMove();
                    SetArrayValue();
                }
            }
        }

        #endregion

        //自定义方法:变形
        public void BrickUp()
        {
            lock (m_arr)
            {
                if (m_curBrick != null && m_curBrick.CanTransform(m_arr, m_rows, m_columns) == true)
                {
                    ClearCurBrick();
                    m_curBrick.Transform();
                    SetArrayValue();
                }
            }
        }

        //自定义方法:计算当期高度
        private void SetCurHeight()
        {
            for (int i = 0; i < m_rows; i++)
            {
                for (int j = 0; j < m_columns; j++)
                {
                    if (m_arr[i, j] == 1)
                    {
                        m_height = m_rows - i;
                        return;
                    }
                }
            }
        }

        //自定义方法:定时器 判断砖块定时下降或无法下降时生成下一个新砖块
        public bool Run()
        {
            //lock 关键字可确保当一个线程位于代码的临界区时,另一个线程不会进入该临界区。
            //如果其他线程试图进入锁定的代码,则它将一直等待(即被阻止),直到该对象被释放。
            //lock 应避免锁定 public 类型,否则实例将超出代码的控制范围。
            lock (m_arr)
            {
                if (m_flag == true)
                {
                    m_bgm.PlayLooping();
                    m_flag = false;
                }
                if (m_curBrick == null && m_nextBrick == null)
                {
                    m_curBrick = Bricks.GetBrick();
                    m_nextBrick = Bricks.GetBrick();
                    m_nextBrick.RandomShape();
                    m_curBrick.SetCenterPos(m_curBrick.Appear(), m_columns / 2 - 1);
                    SetArrayValue();
                }
                else if (m_curBrick == null)
                {
                    m_curBrick = m_nextBrick;
                    m_nextBrick = Bricks.GetBrick();
                    m_nextBrick.RandomShape();
                    m_curBrick.SetCenterPos(m_curBrick.Appear(), m_columns / 2 - 1);
                    SetArrayValue();
                }
                else
                {
                    if (m_curBrick.CanDropMove(m_arr, m_rows, m_columns) == true)
                    {
                        ClearCurBrick();
                        m_curBrick.DropMove();
                        SetArrayValue();
                    }
                    else
                    {
                        m_curBrick = null;
                        SetCurHeight();
                        ClearRow();
                    }
                }
                if (m_score >= 100)
                    return false;
                if (m_height < m_rows)
                    return true;
                else
                    return false;
            }
        }

        //自定义方法:根据清除当前砖块在m_arr中的值
        private void ClearCurBrick()
        {
            int centerX = m_curBrick.m_Center.X;
            int centerY = m_curBrick.m_Center.Y;
            for (int i = 0; i < m_curBrick.m_NeedfulRows; i++)
            {
                for (int j = 0; j < m_curBrick.m_NeedfulColumns; j++)
                {
                    int realX = m_curBrick.m_Pos.X - (centerX - i);
                    int realY = m_curBrick.m_Pos.Y - (centerY - j);
                    if (realX < 0 || realX >= m_columns || realY < 0 || realY >= m_rows)
                    {
                        continue;
                    }
                    else
                    {
                        if (m_curBrick.m_Range[i, j] == 0)
                        {
                            continue;
                        }
                        else
                        {
                            m_arr[realX, realY] = 0;
                        }
                    }
                }
            }
        }

        //自定义方法:判断当前砖块设置m_arr的值
        public void SetArrayValue()
        {
            int centerX = m_curBrick.m_Center.X;
            int centerY = m_curBrick.m_Center.Y;
            for (int i = 0; i < m_curBrick.m_NeedfulRows; i++)
            {
                for (int j = 0; j < m_curBrick.m_NeedfulColumns; j++)
                {
                    int realX = m_curBrick.m_Pos.X - (centerX - i);
                    int realY = m_curBrick.m_Pos.Y - (centerY - j);
                    if (realX < 0 || realX >= m_columns || realY < 0 || realY >= m_rows)
                    {
                        continue;
                    }
                    else
                    {
                        if (m_curBrick.m_Range[i, j] == 0)
                        {
                            continue;
                        }
                        else
                        {
                            m_arr[realX, realY] = 1;
                        }
                    }
                }
            }
        }

        //自定义方法:画出下一个砖块
        public void DrawNewxBrick(Graphics gra, float width, float heigth)
        {
            int[,] arr = new int[5, 5]{{0,0,0,0,0},
                                         {0,0,0,0,0},
                                         {0,0,0,0,0},
                                         {0,0,0,0,0},
                                         {0,0,0,0,0,}};
            switch (m_nextBrick.m_NeedfulColumns)
            {
                case 2:
                    arr[2, 2] = 1;
                    arr[2, 3] = 1;
                    arr[3, 2] = 1;
                    arr[3, 3] = 1;
                    break;
                case 3:
                    for (int i = 1, m = 0; i < 4; i++, m++)
                    {
                        for (int j = 1, n = 0; j < 4; j++, n++)
                        {
                            arr[i, j] = m_nextBrick.m_Range[m, n];
                        }
                    }
                    break;
                case 5:
                    arr = m_nextBrick.m_Range;
                    break;
                default:
                    return;
            }

            for (int i = 0; i < 5; i++)
            {
                for (int j = 0; j < 5; j++)
                {
                    if (arr[i, j] == 1)
                    {
                        gra.FillRectangle(Brushes.Orange, j * width, i * heigth, width - 2, heigth - 2);
                    }
                }
            }
        }

        //自定义方法:播放声音文件
        private void PlaySound(SoundPlayer soundFile)
        {
            //使用新线程播放声音
            soundFile.Play();
        }
        //自定义方法:消除音乐的计时器
        void m_timer_Tick(object sender, EventArgs e)
        {
            m_flag = true;
            m_timer.Enabled = false;
        }

        //自定义方法:判断有没有填满的行,有就消除,更新得分
        private void ClearRow()
        {
            int clearrows = 0;
            for (int i = m_rows - m_height; i < m_rows; i++)
            {
                bool isfull = true;
                for (int j = 0; j < m_columns; j++)
                {
                    if (m_arr[i, j] == 0)
                    {
                        isfull = false;
                        break;
                    }
                }
                if (isfull == true)
                {
                    m_timer.Enabled = true;
                    m_disappear.Play();
                    clearrows++;
                    m_score++;
                    for (int k = 0; k < m_columns; k++)
                    {
                        m_arr[i, k] = 0;
                    }
                }
            }
            for (int i = m_rows - 1; i > m_rows - m_height - 1; i--)
            {
                bool isfull = true;
                for (int j = 0; j < m_columns; j++)
                {
                    if (m_arr[i, j] == 1)
                    {
                        isfull = false;
                        break;
                    }
                }
                if (isfull == true)
                {
                    
                    int n = i;
                    for (int m = n - 1; m > m_rows - m_height - 2; m--)
                    {
                        if (n == 0)
                        {
                            for (int k = 0; k < m_columns; k++)
                            {
                                m_arr[n, k] = 0;
                            }
                        }
                        else
                        {
                            for (int k = 0; k < m_columns; k++)
                            {
                                m_arr[n, k] = m_arr[m, k];
                            }
                            n--;
                        }
                    }
                }
            }
            m_height -= clearrows;
        }

    }
}

现存bug

……
关了背景音乐但关不掉特效T-T(有时间打算暑假弄一个音乐播放器,因为soundplayer只能播放wav文件我也是疯了,mp3到wav文件的转码弄得我,,,后来才发现有直接转码的网站)
https://www.aconvert.com/cn/audio/wav-to-mp3/
我用的是这个
特效和背景音乐不能同时播放(百度到的解决方案行不通…)
那个判断是否满行的方法有问题,后来直接弄了两个for循环,如果连消两行砖块的话,,,,就会报错,所以不能实现消除的行数越多,所获得的分数越高的玩家需求- -

  • 5
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值