简易俄罗斯方块

砖块类:
记录着:
1.样式信息
2.颜色信息
3.旋转方法
4.在面板上画以及擦除的方法






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




namespace 俄罗斯
{
    class Block
    {
        private Color bcolor;
        private Point[] point;




        public Point[] Point
        {
            get { return point; }
            set { point = value; }
        }
        private int x_pos;
        private int y_pos;
        public int X_pos
        {
            get { return x_pos; }
            set { x_pos = value; }
        }
        public int Y_pos
        {
            get { return y_pos; }
            set { y_pos = value; }
        }
        public Color Bcolor
        {
            get { return bcolor; }
            set { bcolor = value; }
        }



        public Block()
        {
 
        }
        public Block (Point [] p,Color b)
        {
            point = p;
            bcolor = b;
        }




        private Rectangle pointTorectangle(Point p)
        {
            return new Rectangle((x_pos + p.X) * 30, (y_pos - p.Y) * 30, 29, 29); 
        }
        //画砖块
        public void Paint(Graphics g)
        {
            SolidBrush sb = new SolidBrush(bcolor);




            foreach (Point p in point)
            {
                lock (g)
                {
                    g.FillRectangle(sb, pointTorectangle(p));
                }
            }
           
        
        }
        //擦除砖块
        public void Erase(Graphics g)
        {
            SolidBrush sb = new SolidBrush(Color.Black );




            foreach (Point p in point)
            {
                lock (g)
                {
                    g.FillRectangle(sb, pointTorectangle(p));
                }
            }
            
        }




        public void SHUN()  //顺时针旋转
        {
            for (int i = 0; i < point.Length; i++)
            {
                int temp = point[i].X;
                point[i].X = point[i].Y ;
                point[i].Y = -temp;
            }
        }




        public void NI()  //逆时针旋转
        {
            for (int i = 0; i < point.Length; i++)
            {
                int temp = point[i].Y;
                point[i].Y = point[i].X;
                point[i].X = -temp;
            }
        }




    }
}








砖块组类
记录着:
1.所有砖块的样式
2.随机产生一个砖块的方法


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




namespace 俄罗斯
{
    class BlockGroup
    {
        List<Block> list=new List <Block >();
        Point[] p0 = new Point[] { new Point(-2, 0), new Point(-1, 0), new Point(0, 0), new Point(1, 0) };  //横棍
        Point[] p1 = new Point[] { new Point(0, 2), new Point(0, 1), new Point(0, 0), new Point(0, -1) };  //棍
        Point[] p2 = new Point[] { new Point(-1, 1), new Point(0, 1), new Point(0, 0), new Point(1, 0) };  //Z
        Point[] p3 = new Point[] { new Point(-1, 0), new Point(0, 1), new Point(0, 0), new Point(1, 1) }; //倒Z
        Point[] p4 = new Point[] { new Point(-1, 1), new Point(0, 1), new Point(0, 0), new Point(1, 1) }; //T
        Point[] p5 = new Point[] { new Point(-1, 1), new Point(0, 1), new Point(1, 0), new Point(1, 1) }; //倒L
        Point[] p6 = new Point[] { new Point(-1, 1), new Point(0, 1), new Point(-1, 0), new Point(1, 1) }; //倒L
        Point[] p7 = new Point[] { new Point(0, 0), new Point(1, 0), new Point(0, 1), new Point(1, 1) }; //倒L
      public BlockGroup()
      {
          list.Add(new Block(p0, Color.Green));
          list.Add(new Block(p1, Color.GreenYellow));
          list.Add(new Block(p2, Color.Blue));
          list.Add(new Block(p3, Color.Brown));
          list.Add(new Block(p4, Color.Red));
          list.Add(new Block(p5, Color.Pink));
          list.Add(new Block(p6, Color.Silver));
          list.Add(new Block(p7, Color.YellowGreen));
      }
      Random r = new Random();
      public Block GetABlock()
      {
         int temp= r.Next(8);
         return list[temp];
      }








    }
}


执行类:




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




namespace 俄罗斯
{
    public delegate void Mydele(int score);




    class DO
    {




        public Mydele Myfun = null;         //委托,将分数传递给主窗体显示用
        System.Media.SoundPlayer player;  //满行或过关时播放声音用
        public int Fenshu = 0;                          //分数
        Block runblock;                                     //运行中的方块
        public int flag = 1;//0游戏结束 1没结束
        internal Block Runblock
        {
            get { return runblock; }
            set { runblock = value; }
        }
        Block readyblock;
        private string levelstr = "小弟";          //等级 初始化为  小弟




        public int Sco                                    //自动属性    分数
        {
            get;
            set;
        }
        public string Level
        {




            set { levelstr = value; }
        }








        internal Block Readyblock           //准备这的砖块
        {
            get { return readyblock; }
            set { readyblock = value; }
        }
        BlockGroup blocks;                   //砖块组,生产砖块用
        Graphics main;                            //主画板  (游戏区)
        Graphics ready;                            //下一个砖块显示在的画板
        Color[,] solid;                                //用来存放固定住的砖块颜色




        public Color[,] Solid
        {
            get { return solid; }
            set { solid = value; }
        }








        double level = 900;                                     //900 毫秒   每个900毫秒执行砖块向下
        System.Timers.Timer t;                          //控制下降速度的时钟




        public System.Timers.Timer T
        {
            get { return t; }
            set { t = value; }
        }
        public DO(Graphics m, Graphics r)              // 构造函数
        {




            main = m;
            ready = r;
            solid = new Color[10, 15];
        }




        public void Start()                                    // 开始了!!
        {




            flag = 1;                                                    //是否游戏结束标记
            t = new System.Timers.Timer(level);  //初始化时钟
            blocks = new BlockGroup();
            readyblock = blocks.GetABlock();    //获取下一个砖块
            readyblock.X_pos = 2;   //初始化下一个砖块的位置
            readyblock.Y_pos = 2;
            ready.Clear(Color.Black);    //清空画板
            readyblock.Paint(ready);//将砖块画出来
            Thread.Sleep(100);    //休眠线程,因为刚刚用随机函数产生一个下一个砖块,防止随机数产生相同的砖块




            runblock = blocks.GetABlock();     //随机产生一个砖块
            int tempy = 0;
            foreach (Point p in runblock.Point)
            {
                if (p.Y > tempy)
                {
                    tempy = p.Y;
                }
            }
            runblock.Y_pos = tempy;               //保证砖块顶部在画板顶部
            runblock.X_pos = 5;
            main.Clear(Color.Black);             //清空画板
            runblock.Paint(main);               //画出砖块




            t.Elapsed += new System.Timers.ElapsedEventHandler(t_Elapsed);  //定义时钟执行的事件




            t.Start();   //开启时钟   ,方块将每900毫秒下降一次




        }




        void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            if (flag == 1)                    //没有被暂停的标记
            {
                Down();                     //向下
            }
        } 
        public void Drop()         //丢下
        {
            if (flag == 1)
            {
                t.Stop();
                while (Down()) ;
                t.Start();
            }




        }




        public bool Down()//砖块向下的方法
        {




            if (IsCanDown())      //判断是否可以向下的方法  
            {




                runblock.Erase(main);     //擦除旧的
                runblock.Y_pos++;           




                runblock.Paint(main); //画新的
                return true;




            }
            else  //不能向下,则
            {




                foreach (Point p in runblock.Point)    //先将砖块保存的固定砖块
                {
                    solid[runblock.X_pos + p.X, runblock.Y_pos - p.Y] = runblock.Bcolor;        




                }
                IsLineFull();   //判断是否满行
                Thread.Sleep(100);
                runblock = readyblock;  //下一个砖块变为这一个方块
                int tempy = 0;
                foreach (Point p in runblock.Point)
                {
                    if (p.Y > tempy)
                    {
                        tempy = p.Y;
                    }
                }                                                 




                runblock.Y_pos = tempy;






                readyblock = blocks.GetABlock();
                readyblock.X_pos = 2;
                readyblock.Y_pos = 2;
                ready.Clear(Color.Black);
                readyblock.Paint(ready);




                runblock.X_pos = 5;
                runblock.Paint(main);
                foreach (Point p in runblock.Point)
                {
                    if (solid[runblock.X_pos + p.X, runblock.Y_pos - p.Y] != Color.Empty)     //出生砖块区域是否有固定砖块
                    {
                        flag = 0;   //游戏结束
                        main.DrawString("顶不住了吧!!", new Font("黑体", 40, FontStyle.Bold), new SolidBrush(Color.DarkOrange), 0, 100);
                        main.DrawString("你的成绩是:" + Sco + "\n你获得新称号:"+ levelstr, new Font("宋体", 20, FontStyle.Bold), new SolidBrush(Color.SkyBlue), 0, 200);
                        
                        t.Stop();




                        return false;




                    }
                }




                return false;




            }
















        }
        public void Left()    //左
        {
            if (IsCanLeft())
            {




                runblock.Erase(main);
                runblock.X_pos--;




                runblock.Paint(main);
            }
        }




        public void Right()   //右
        {
            if (IsCanRight())
            {
                runblock.Erase(main);
                runblock.X_pos++;




                runblock.Paint(main);
            }
        }




        public void SHUN()//顺时针
        {
            if (flag == 0)
            {
                return;
            }
            runblock.Erase(main);
            if (!IsCanSHUN())
            {
                runblock.NI();




            }




            runblock.Paint(main);








        }
        public void NI()//逆时针
        {
            if (flag == 0)
            {
                return;
            }




            runblock.Erase(main);
            if (!IsCanNI())
            {
                runblock.SHUN();




            }
            runblock.Paint(main);
        }




        public bool IsCanDown()              //方法:判断能发下降
        {




            bool b = true;
            if (flag == 0)
            {
                return false;
            }
            foreach (Point p in runblock.Point)
            {
                if (runblock.Y_pos - p.Y > 13 || solid[runblock.X_pos + p.X, runblock.Y_pos - p.Y + 1] != Color.Empty)   //到底或者下面有固定砖块
                {




                    b = false;
                    break;
                }
            }












            return b;
        }
        public bool IsCanLeft()
        {
            bool b = true;
            if (flag == 0)
            {
                return false;
            }
            foreach (Point p in runblock.Point)
            {
                if (runblock.X_pos + p.X < 1 || solid[runblock.X_pos + p.X - 1, runblock.Y_pos - p.Y] != Color.Empty)
                {
                    b = false;
                    break;
                }
            }












            return b;
        }








        public bool IsCanRight()
        {
            bool b = true;
            if (flag == 0)
            {
                return false;
            }
            foreach (Point p in runblock.Point)
            {
                if (runblock.X_pos + p.X > 8 || solid[runblock.X_pos + p.X + 1, runblock.Y_pos - p.Y] != Color.Empty)
                {
                    b = false;
                    break;
                }
            }
            return b;
        }




        public bool IsCanSHUN()
        {
            bool b = true;




            runblock.SHUN();
            foreach (Point p in runblock.Point)
            {
                if (runblock.X_pos + p.X > 9 || runblock.X_pos + p.X < 0 || runblock.Y_pos - p.Y > 14 || runblock.Y_pos - p.Y < 0 || solid[runblock.X_pos + p.X, runblock.Y_pos - p.Y] != Color.Empty)
                {
                    b = false;
                    break;
                }
            }
            return b;
        }
        public bool IsCanNI()
        {
            bool b = true;




            runblock.NI();
            foreach (Point p in runblock.Point)
            {
                if (runblock.X_pos + p.X > 9 || runblock.X_pos + p.X < 0 || runblock.Y_pos - p.Y > 14 || runblock.Y_pos - p.Y < 0 || solid[runblock.X_pos + p.X, runblock.Y_pos - p.Y] != Color.Empty)
                {
                    b = false;
                    break;
                }
            }
            return b;
        }








        public void IsLineFull()     //是否满行
        {
            int temp = 0;








            int top = 100;
            int bottom = 0;
            foreach (Point p in runblock.Point)       //先去到砖块的最高行和最低行,满行只可能在这之间产生
            {
                if (runblock.Y_pos - p.Y > bottom)
                {
                    bottom = runblock.Y_pos - p.Y;
                }
                if (runblock.Y_pos - p.Y < top)
                {
                    top = runblock.Y_pos - p.Y;
                }
            }




            for (int i = top; i <= bottom; i++)//遍历砖块所占的每一行
            {




                for (int j = 0; j < 10; j++)    //遍历每一列是否有空固定砖块
                {
                    if (solid[j, i] == Color.Empty)//只要发现有一个空,则肯定该行不满行,break
                    {
                        break;
                    }
                    if (j == 9)
                    {
                        temp++;




                        //有满行的
                        for (int jj = i; jj > 0; jj--)           //消行,下面的行由上面的行代替,画板最上面一行用空代替
                        {
                            for (int ii = 0; ii <= 9; ii++)
                            {
                                solid[ii, jj] = solid[ii, jj - 1];
                            }
                        }
                        for (int jjj = 0; jjj < 10; jjj++)
                        {
                            solid[jjj, 0] = Color.Empty;
                        }
                        main.Clear(Color.Black);








                        PaintSolid();
                    }




                }
















            }
            switch (temp)   //播放声音   根据消去的行数
            {
                case 0: break;
                case 1: Fenshu += 300; player = new System.Media.SoundPlayer("1.wav");
                    player.Play(); break;
                case 2: Fenshu += 800; player = new System.Media.SoundPlayer("2.wav");




                    player.Play(); break;
                case 3: Fenshu += 1500; player = new System.Media.SoundPlayer("3.wav");




                    player.Play(); break;
                case 4: Fenshu += 2000; player = new System.Media.SoundPlayer("4.wav");




                    player.Play(); break;
            }




            if (Myfun != null)
            {
                // Myfun(Fenshu);
                Myfun.Invoke(Fenshu);
                
            }




        }
        public void PaintSolid()   //重画固定砖块的方法,后面会用到
        {
            for (int i = 0; i < 10; i++)
            {
                for (int j = 0; j < 15; j++)
                {
                    if (solid[i, j] != Color.Empty)
                    {
                        SolidBrush sb = new SolidBrush(solid[i, j]);
                        lock (main)
                        {
                            main.FillRectangle(sb, i * 30, j * 30, 28, 28);
                        }
                    }
                }
            }
        }
        public void Close()
        {
            main.Dispose();
            ready.Dispose();
            t.Dispose();
        }








    }
}






主窗体:
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.Threading;




namespace 俄罗斯
{
    public partial class Form1 : Form
    {
        System.Media.SoundPlayer player;
        public Form1()
        {
            InitializeComponent();
        }
        DO d;
        private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
        {




        }




        private void btnStart_Click(object sender, EventArgs e)
        {
            lblFenShu.Text = "0";
            lblPAOHUI.Focus();
            if (d != null)
            {
                d.Close();
            }
            d = new DO(picboxMain.CreateGraphics(), lblReady.CreateGraphics());
            d.Myfun = Fun;
            d.Start();
        }












        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {




            if (e.KeyCode == Keys.A)
            {
                d.Left();
            }
            if (e.KeyCode == Keys.D)
            {
                d.Right();
            }
            if (e.KeyCode == Keys.W)
            {
                d.SHUN();
            }
            if (e.KeyCode == Keys.S)
            {
                d.NI();
            }
            if (e.KeyCode == Keys.Space)
            {
                d.Drop();
            }
        }




        private void picboxMain_Paint(object sender, PaintEventArgs e)
        {
            if (d != null)
            {
                e.Graphics.Clear(Color.Black);
                d.PaintSolid();




                d.Runblock.Paint(e.Graphics);




               
            }
        }




        private void lblReady_Paint(object sender, PaintEventArgs e)
        {
            if (d != null)
            {
                e.Graphics.Clear(Color.Black);
                d.Readyblock.Paint(e.Graphics);
            }
        }




        private void picboxMain_Click(object sender, EventArgs e)
        {




        }




        private void btnPause_Click(object sender, EventArgs e)
        {
            lblPAOHUI.Focus();
            if (btnPause.Text == "暂停")
            {
                d.T.Stop();
                btnPause.Text = "继续";
                d.flag = 0;




            }
            else
                if (btnPause.Text == "继续")
                {
                    d.T.Start();
                    btnPause.Text = "暂停";
                    d.flag = 1;
                }
        }




        private void Form1_Load(object sender, EventArgs e)
        {
            Control.CheckForIllegalCrossThreadCalls = false;




        }








        public void Fun(int score)
        {
            
            
            lblFenShu.Text = Convert.ToString(score);
        }




        private void lblFenShu_TextChanged(object sender, EventArgs e)
        {
            int s = Convert.ToInt32(lblFenShu.Text);
            if (s >= 3000 && s < 8000)
            {                          
                lbllevel.Text = "大弟";
                
            }
            if (s >= 8000 && s < 15000)
            {               
                lbllevel.Text = "小哥";
                
            }
            if (s >= 15000 && s < 20000)
            {              
                lbllevel.Text = "大哥";
               
            }
            if (s >= 20000 && s < 30000)
            {             
                lbllevel.Text = "大哥大";
                
            }
            if (s >= 30000 && s < 40000)
            {              
                lbllevel.Text = "大叔大";
                
            }
            if (s >= 40000 && s < 50000)
            {              
                lbllevel.Text = "高手";
                
            }
            if (s >= 50000 && s < 60000)
            {
                lbllevel.Text = "绝世高手";
                
            }
            if (s >= 60000)
            {
                lbllevel.Text = "神";
               
            }
            if (d != null)
            {
                d.Sco = s;
            }
           
        }




        private void lbllevel_Paint(object sender, PaintEventArgs e)
        {
            player = new System.Media.SoundPlayer("a.wav");
            player.Play();
            if (d != null)
            {
                d.T.Interval -= 100;
                d.Level = lbllevel.Text;
            }
            
        }


        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show(d.Runblock.X_pos.ToString ());
            d.Down();




        }

        private void button2_Click(object sender, EventArgs e)
        {
            MessageBox.Show(d.Runblock.X_pos.ToString());
        }


    }

}














  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值