您的位置:首页 > 移动开发 > Objective-C

简易俄罗斯方块

2012-08-08 22:13 225 查看
砖块类:

记录着:

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;                   //砖块组,生产砖块用<
4000
br />
        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");

                   
bb69
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());

        }

    }
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息