代码改变世界

俄罗斯方块游戏设计

2010-03-12 13:03  Tedi  阅读(300)  评论(0编辑  收藏  举报

我花了些时间用c#写了一个应用程序--俄罗斯方块游戏。增加了一些新的功能,基于xml的应用,可以自己配置砖块样式和快捷键,让你随心所欲,挑战自己的极限。此外我还在游戏中添加了默认的3首歌,当然你也可以自己添加你自己电脑上的歌曲,创建播放列表,让游戏不再单调。我自己玩了一下,非常的难,我还没通关过,自知水平不够。惭愧惭愧!~~~通关以后你会得到很大的奖励(暂时保密)。可惜我不知道博客上怎么传附件。如果有意者,可留言~~~~。

  以下是一个文件的源代码,仅供参考:

using System;
using System.Drawing;
using System.Threading;
using System.Timers;
using System.Windows.Forms;
using System.Media;
namespace 俄罗斯方块
{
    class Palette
    {
        private int _width = 15;//画板宽度
        private int _height = 25;//画板高度
        private Color[,] coorArr;//固定砖块数组
        private Color disappearColor;//背景色
        private Graphics gpPalette;//砖块活动画板
        private Graphics gpReady;//下一个砖块样式画板
        private BlockGroup bGroup;//砖块生产机
        private Block runBlock;//正在活动的砖块
        private Block readyBlock;//下一个砖块
        private int rectPix;//单元格像素
        private System.Timers.Timer timerBlock;//定时器
        private int timeSpan = 800;//定时器间隔
       private  int score = 0;
       private bool[] flag = { true, true,true,true,true,true };
        public Palette(int x, int y, int pix, Color dcolor, Graphics gp, Graphics gr)
        {
            _width = x;
            _height = y;
            coorArr = new Color[_width, _height];
            disappearColor = dcolor;
            gpPalette = gp;
            gpReady = gr;
            rectPix = pix;
        }
        public void Settime(int time)
        {
            //初始化并启动定时器
            timerBlock = new System.Timers.Timer(time);
            timerBlock.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
            timerBlock.AutoReset = true;
            timerBlock.Start();
        }

        public void Start()
        {
            bGroup = new BlockGroup();
            runBlock = bGroup.GetABlock();
            runBlock.XPos = _width / 2;
           int y = 0;
          for (int i = 0; i < runBlock.Lenght; i++)
            {
                if (runBlock[i].Y > y)
               {
                   y = runBlock[i].Y;
             }
       }

            runBlock.YPos =y;
            gpPalette.Clear(disappearColor);
            runBlock.Paint(gpPalette);
            Thread.Sleep(20);
            readyBlock = bGroup.GetABlock();//取另一个砖块赋给readyblock
            readyBlock.XPos = 2; //5*5矩阵的中心点
            readyBlock.YPos = 2;
            gpReady.Clear(disappearColor);//清空画板
            readyBlock.Paint(gpReady);
            Settime(timeSpan);
            //初始化并启动定时器
            //timerBlock = new System.Timers.Timer(timeSpan);
           // timerBlock.Elapsed += new System.Timers.ElapsedEventHandler(OnTimedEvent);
            //timerBlock.AutoReset = true;
            //timerBlock.Start();

        }
        private void OnTimedEvent(object source, ElapsedEventArgs e)
        {
            CheckAndOverBlock();
            Down();
        }


        public bool Down()
        {

            int xPos = runBlock.XPos;
            int yPos = runBlock.YPos+1;
            for (int i = 0; i < runBlock.Lenght; i++)
            {
                if (yPos - runBlock[i].Y > _height-1 ) //如果超出下边界则失败
                    return false;
                if (!coorArr[xPos + runBlock[i].X, yPos - runBlock[i].Y].IsEmpty)//如果下边有东西挡则失败
                    return false;
            }

             runBlock.erase(gpPalette);//擦除原来的砖块
            runBlock.YPos++;
            runBlock.Paint(gpPalette);//在新的位置上画砖块
            return true;
        }
        public void Drop()
        {
            timerBlock.Stop();
            while (Down())
                timerBlock.Start();
        }
        public void MoveLeft()
        {

            int xPos = runBlock.XPos-1;
            int yPos = runBlock.YPos ;
            for (int i = 0; i < runBlock.Lenght; i++)
            {
                if (xPos+runBlock[i].X<0) //如果超出左边界则失败
                    return ;
                if (!coorArr[xPos + runBlock[i].X, yPos - runBlock[i].Y].IsEmpty)//如果有东西挡则失败
                    return ;
            }

            runBlock.erase(gpPalette);//擦除原来的砖块
            runBlock.XPos--;
            runBlock.Paint(gpPalette);//在新的位置上画砖块
           
        }
        public void MoveRight()
        {

            int xPos = runBlock.XPos + 1;
            int yPos = runBlock.YPos;
            for (int i = 0; i < runBlock.Lenght; i++)
            {
                if (xPos + runBlock[i].X >_width-1) //如果超出右边界则失败
                    return;
                if (!coorArr[xPos + runBlock[i].X, yPos - runBlock[i].Y].IsEmpty)//如果下边有东西挡则失败
                    return;
            }

            runBlock.erase(gpPalette);//擦除原来的砖块
            runBlock.XPos++;
            runBlock.Paint(gpPalette);//在新的位置上画砖块

        }
        public void DeasilRotate()
        {
            for (int i = 0; i < runBlock.Lenght; i++)
            {
                int x = runBlock.XPos + runBlock[i].Y;
                int y = runBlock.YPos + runBlock[i].X;
                if (x < 0||x>_width-1) //如果超出左右边界则失败
                    return;
                if (y < 0 || y > _height - 1)//如果超出上下边界则失败
                    return;
                if (!coorArr[x,y].IsEmpty)//如果旋转后有东西挡则失败
                    return;
            }

            runBlock.erase(gpPalette);//擦除原来的砖块
            runBlock.DeasilRotate();
            runBlock.Paint(gpPalette);//在新的位置上画砖块

        }
        public void ContraRotate()
        {
            for (int i = 0; i < runBlock.Lenght; i++)
            {
                int x = runBlock.XPos - runBlock[i].Y;
                int y = runBlock.YPos - runBlock[i].X;
                if (x < 0 || x > _width - 1) //如果超出左右边界则失败
                    return;
                if (y < 0 || y > _height - 1)//如果超出上下边界则失败
                    return;
                if (!coorArr[x, y].IsEmpty)//如果旋转后有东西挡则失败
                    return;
            }

            runBlock.erase(gpPalette);//擦除原来的砖块
            runBlock.ContraRotate();
            runBlock.Paint(gpPalette);//在新的位置上画砖块

        }
        private void PaintBackground(Graphics gp)//重画画板背景
        {
            gp.Clear(Color.Black);//首先清空画板
            for (int i = 0; i < _height; i++)
            {
                for (int j = 0; j < _width; j++)
                {
                    if (!coorArr[j, i].IsEmpty)
                    {
                        SolidBrush sb = new SolidBrush(coorArr[j, i]);
                        gp.FillRectangle(sb, j * rectPix + 1, i * rectPix, rectPix - 2, rectPix - 2);
                    }
                }
            }

        }
        public void PaintPalette(Graphics gp)//重画整个画板
        {
            PaintBackground(gp);//先画背景
            if (runBlock != null)
            {
                runBlock.Paint(gp);//再画活动砖块
            }
        }
        public void PaintReady(Graphics gp)//重画下一个砖块
        {
           
            if (readyBlock != null)
            {
                readyBlock.Paint(gp);//再画活动砖块
            }
        }
        public void CheckAndOverBlock()//检查砖块是否到底,如果到底则归入corrarr数组中并产生新的砖块
        {
            bool over = false;//设置当前运行砖块是否到底的标志
            for (int i = 0; i < runBlock.Lenght; i++)//遍历当前运行的所有小方块
            {
                int x = runBlock.XPos + runBlock[i].X;
                int y = runBlock.YPos - runBlock[i].Y;
                if (y == _height - 1)//如果达到下界则结束
                {
                    over = true;
                    break;
                }
                if (!coorArr[x, y + 1].IsEmpty)//如果下面有其他砖块,则结束
                {
                    over = true;
                    break;
                }
            }
            if (over)
            {
                for (int i = 0; i < runBlock.Lenght; i++)//把当前砖块归入coorArr数组中
                {
                    coorArr[runBlock.XPos + runBlock[i].X, runBlock.YPos - runBlock[i].Y] = runBlock.BlockColor;
                }
                CheckAndDelFullRow();
                //产生新的砖块
                runBlock = readyBlock;//新的砖块为准备好的砖块
                runBlock.XPos = _width / 2;//确定当前砖块产生位置
                int y = 0;
                for (int i = 0; i < runBlock.Lenght; i++)
                {
                    if (runBlock[i].Y > y)
                    {
                        y = runBlock[i].Y;
                    }
                }
                runBlock.YPos = y;
                //检查新的砖块是否还有位置,如果没有则游戏结束
                for (int i = 0; i < runBlock.Lenght; i++)
                {
                    if (!coorArr[runBlock.XPos + runBlock[i].X, runBlock.YPos - runBlock[i].Y].IsEmpty)
                    { //游戏结束
                        StringFormat drawFormat = new StringFormat();
                        drawFormat.Alignment = StringAlignment.Center;
                        gpPalette.DrawString("GAME OVER", new Font("Arial Black", 25f), new SolidBrush(Color.White),
                            new RectangleF(0, _height * rectPix/2 - 100, _width * rectPix, 100), drawFormat);
                        timerBlock.Stop();
                        return;
                    }
                }

                runBlock.Paint(gpPalette);
                //获取新的准备砖块
                readyBlock = bGroup.GetABlock();//取另一个砖块赋给readyblock
                readyBlock.XPos = 2;
                readyBlock.YPos = 2;
                gpReady.Clear(Color.Black);//清空画板
                readyBlock.Paint(gpReady);
            }
        }
        private void CheckAndDelFullRow()//检查并删除满行
        {
            //找出当前砖块所在行的范围
            int lowRow = runBlock.YPos - runBlock[0].Y;//lowRow表示当前砖块y轴最小值
            int highRow = lowRow;//highRow表示最大值
            for (int i = 1; i < runBlock.Lenght; i++)//找出当前砖块所在行的范围,放入low,high变量中
            {
                int y = runBlock.YPos - runBlock[i].Y;
                if (y < lowRow)
                    lowRow = y;
                if (y > highRow)
                    highRow = y;
            }
            bool repaint = false;//判断是否重画标志
            int sum = 0;
            for (int i = lowRow; i <= highRow; i++)//检查满行,如果有就删除它
            {
                bool rowFull = true;
                {
                    for (int j = 0; j < _width; j++)//判断是否满行
                    {
                        if (coorArr[j, i].IsEmpty)
                        {
                            rowFull = false;
                            break;
                        }
                    }
                    if (rowFull)//如果满行则删除这一行
                    {
                        sum++;
                        repaint = true;//如果有删除的行则需要重画
                        for (int k = i; k > 0; k--)
                        {

                            for (int j = 0; j < _width; j++)
                            {
                                coorArr[j, k] = coorArr[j, k - 1];


                            }
                        }
                        for (int j = 0; j < _width; j++)
                        {
                            coorArr[j, 0] = Color.Empty;//清空第0行
                        }
                    }
                }
                if (repaint)//重画
                    PaintBackground(gpPalette);

            }
            int sum_score = 1;
            for (int j = 0; j < sum - 1; j++)
            {
                sum_score = sum_score * 2;
            }
            if (repaint)
            {
                score = score + 100 * sum_score;
                if (score >= 20000)
                {
                    StringFormat drawFormat = new StringFormat();
                    drawFormat.Alignment = StringAlignment.Center;
                    gpPalette.DrawString("恭喜你通关了,全世界人向你致敬!", new Font("Arial Black", 25f), new SolidBrush(Color.Red),
                        new RectangleF(0, _height * rectPix / 2 - 100, _width * rectPix, 100), drawFormat);
                    timerBlock.Stop();
                }
            
                   else if (flag[0])
                    {
                        if (score >= 2000&& score <= 2700)
                        {
                            flag[0] = false;
                            timerBlock.Dispose();
                            Settime(timeSpan - 300);
                        }

                    }
                    else if (flag[1])
                    {
                        if (score >= 4000 && score <= 4700)
                        {
                            flag[1] = false;
                            timerBlock.Dispose();
                            Settime(timeSpan - 400);   
                        }
                    }
                    else  if (flag[2])
                    {
                        if (score >= 6000 && score <= 6700)
                        {
                            flag[2] = false;
                            timerBlock.Dispose();
                            Settime(timeSpan - 500);
                        }
                    }
                    else  if (flag[3])
                    {
                        if (score >= 8000 && score <= 8700)
                        {
                            flag[3] = false;
                            timerBlock.Dispose();
                            Settime(timeSpan - 600);
                        }
                    }
                    else if (flag[4])
                    {
                        if (score >= 12000 && score <= 12700)
                        {
                            flag[4] = false;
                            timerBlock.Dispose();
                            Settime(timeSpan - 700);
                        }
                    }
                    else if (flag[5])
                    {
                        if (score >= 16000 && score <= 16700)
                        {
                            flag[5] = false;
                            timerBlock.Dispose();
                            Settime(timeSpan - 800);
                        }
                    }
            }
        }
        public void Pause()//暂停
        {
            if (timerBlock.Enabled == true)
              timerBlock.Enabled = false;  
        }
        public void EndPause()
        {
            if (timerBlock.Enabled == false)
          
                timerBlock.Enabled = true;
         
           
        }
        public void Close()//关闭
        {
            timerBlock.Close();
            gpPalette.Dispose();
            gpReady.Dispose();
        }


        public int Score()
        {
         
            return score;
        }
     
    }
}

“七”乐无穷,尽在新浪新版博客,快来体验啊~~~请点击进入~