`
什么世道
  • 浏览: 222423 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

C#实现俄罗斯方块游戏

阅读更多

    还记得小时候经常拿袖珍电子游戏机或者小霸王玩过最多的就是俄罗斯方块,冒险岛,超级玛丽还有魂斗罗之类的。 这些游戏由于其中简单易上上手的特点,曾经风靡了全世界。

 

    俄罗斯方块的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多行并且消除得分。现在新流行的各种游戏像Tecent的《天天爱消除》 的都参照了此游戏的一些经典元素。

  

    游戏规格分析:俄罗斯方块游戏可能产生下面七种形状的方块。这些方块有我们的方向键的控制可以产生旋转,左右移动和加速前进等,往下掉,只到遇到下面已经有方块挡住停下来。如果一行完全排列满,则会消掉,如果排列到了顶部,则游戏结束。

 

    游戏Demo设计分析:

 

    a、方块的类型:关于俄罗斯方块游戏中方块的产生。我们假设产生四种方块。实际上俄罗斯方块产生的方块要多余四个(暂时绘制4个)。每种方块有4中放置方式。所以要做一个Demo绘制方块。见图一。

图一

 

 

        /// <summary>
        /// 定义背景
        /// 14*20的二维数组
        /// 20行,14列
        /// </summary>
        private int[,] bgGround ={  
                                    {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,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,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,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,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,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,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,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,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,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,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,0,0,0,0,0}  
                                };
 
 

 

    b、方块的绘制:俄罗斯方块当需要变化方块的时候,每个方块需要顺时针旋转90°,具体可能产生的形状也见图一。从数学,或者计算机的角度来看:我们根据图一来看,我们可以把所有的方块看成一个4*4的二维数组。把有“砖”的地方表示为1,没有“砖”的地方表示为0,所以所有的的方块都可以表示为图二的样式。

 

图二

 

 

 /// <summary>
        /// 定义砖块int[i,j,y,x] 
        /// tricks:i为块砖,j为状态,y为列,x为行
        /// </summary>
        private int[, , ,] tricks = {{  
                                     {  
                                         {1,0,0,0},  
                                         {1,0,0,0},  
                                         {1,0,0,0},  
                                         {1,0,0,0}  
                                     },  
                                     {  
                                         {1,1,1,1},  
                                         {0,0,0,0},  
                                         {0,0,0,0},  
                                         {0,0,0,0}  
                                     },  
                                     {  
                                         {1,0,0,0},  
                                         {1,0,0,0},  
                                         {1,0,0,0},  
                                         {1,0,0,0}  
                                     },  
                                     {  
                                         {1,1,1,1},  
                                         {0,0,0,0},  
                                         {0,0,0,0},  
                                         {0,0,0,0}  
                                     }  
                                },  
                                {  
                                      {  
                                          {1,1,0,0},  
                                          {1,1,0,0},  
                                          {0,0,0,0},  
                                          {0,0,0,0}  
                                      },  
                                      {  
                                          {1,1,0,0},  
                                          {1,1,0,0},  
                                          {0,0,0,0},  
                                          {0,0,0,0}  
                                      },  
                                      {  
                                          {1,1,0,0},  
                                          {1,1,0,0},  
                                          {0,0,0,0},  
                                          {0,0,0,0}  
                                      },  
                                      {  
                                          {1,1,0,0},  
                                          {1,1,0,0},  
                                          {0,0,0,0},  
                                          {0,0,0,0}  
                                      }  
                                  },  
                                  {  
                                      {  
                                          {1,0,0,0},  
                                          {1,1,0,0},  
                                          {0,1,0,0},  
                                          {0,0,0,0}  
                                      },  
                                      {  
                                          {0,1,1,0},  
                                          {1,1,0,0},  
                                          {0,0,0,0},  
                                          {0,0,0,0}  
                                      },  
                                      {  
                                          {1,0,0,0},  
                                          {1,1,0,0},  
                                          {0,1,0,0},  
                                          {0,0,0,0}  
                                      },  
                                      {  
                                          {0,1,1,0},  
                                          {1,1,0,0},  
                                          {0,0,0,0},  
                                          {0,0,0,0}  
                                      }  
                                  },  
                                  {  
                                      {  
                                          {1,1,0,0},  
                                          {0,1,0,0},  
                                          {0,1,0,0},  
                                          {0,0,0,0}  
                                      },  
                                      {  
                                          {0,0,1,0},  
                                          {1,1,1,0},  
                                          {0,0,0,0},  
                                          {0,0,0,0}  
                                      },  
                                      {  
                                          {1,0,0,0},  
                                          {1,0,0,0},  
                                          {1,1,0,0},  
                                          {0,0,0,0}  
                                      },  
                                      {  
                                          {1,1,1,0},  
                                          {1,0,0,0},  
                                          {0,0,0,0},  
                                          {0,0,0,0}  
                                      }  
                                  }
                                    };

 

 

PS:最初画方块会出现方块下降的时候会闪屏的情况,之前想用双缓冲原理解决这个问题,但一直没有找到具体的解决方法,所以采用了分别取每一次画过方块之后的面板作为画布的载体。即分别取了2个画布对象g和gg。

 

 

  //初始化面板,得到面板对象作背景图片
  myImage = new Bitmap(panel1.Width, panel1.Height);
 

 

 

        /// <summary>
        /// 画方块的方法
        /// </summary>
        private void DrawTetris()
        {
            //创建窗体画布
            Graphics g = Graphics.FromImage(myImage);
            //清除以前画的图形
            g.Clear(this.BackColor);
            //画出已经掉下的方块
            for (int bgy = 0; bgy < 20; bgy++)
            {
                for (int bgx = 0; bgx < 14; bgx++)
                {
                    if (bgGround[bgy, bgx] == 1)
                    {
                        g.FillRectangle(new SolidBrush(Color.Blue), bgx * 20, bgy * 20, 20, 20);
                        g.DrawRectangle(new Pen(Color.Red,1), bgx * 20, bgy * 20, 20, 20);
                    }
                }
            }
            //绘制当前的方块  
            for (int y = 0; y < 4; y++)
            {
                for (int x = 0; x < 4; x++)
                {
                    if (currentTrick[y, x] == 1)
                    {
                        //定义方块每一个小单元的边长为20
                        g.FillRectangle(new SolidBrush(Color.Blue), (x + currentX) * 20, (y + currentY) * 20, 20, 20);
                        g.DrawRectangle(new Pen(Color.Black,1f), (x + currentX) * 20, (y + currentY) * 20, 20, 20);
                    }
                }
            }

            //获取面板的画布
            Graphics gg = panel1.CreateGraphics();

            gg.DrawImage(myImage, 0, 0);
        }
 

 

    c、方块的移动:我们也可以把背景看成是14*20的二维数组。机从方块的4个4*4的矩阵中挑选出来一个,并且随机的挑选一个他的初始化状态(关于状态变化,我们同样可以把他们表示在一个4*4的矩阵中)。然后这个被挑选的矩阵,在一个14*20的矩阵中不断的按照一种速度进行往下运动。

 

        /// <summary>  
        /// 随机生成方块和状态  
        /// </summary>  
        private void BeginTricks()
        {
            //随机生成砖码和状态码(0-4)  
            int i = rand.Next(0, tricksNum);
            int j = rand.Next(0, statusNum);
            currentTrickNum = i;
            currentDirection = j;
            //分配数组  
            for (int y = 0; y < 4; y++)
            {
                for (int x = 0; x < 4; x++)
                {
                    currentTrick[y, x] = tricks[i, j, y, x];
                }
            }
            //从(7,0)位置开始放砖块
            currentX = 7;
            currentY = 0;
            //开启计时器
            timer1.Start();
        }
 

 

 

    d、方块的控制:可以使用W、A、S、D四个方向键,对这个矩阵进行控制,使得它可以左右运动,同时可以循环的变化摆放的方位。如果这个矩阵在运动的方向上遇到了数值为1(此处已经放置方块)的时候则停止运动,在左右运动上表现为不能移动,在往下运动的时候则表现为这个方块运动的结束。把这个矩阵的数值复制到背景矩阵中去。

 

        /// <summary>
        /// 键盘释放事件监听器方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.S)
            {
                //方块往下掉落
                //Console.WriteLine("S键被释放");
                timer1.Stop();
                timer1.Interval = 1000;
                timer1.Start();
            }
        }

        /// <summary>
        /// 键盘按下事件监听器方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {

            //Console.WriteLine("键盘监听器被检测");
            if (e.KeyCode == Keys.W)
            {
                //旋转方块
                //Console.WriteLine("W键被按下");
                ChangeTricks();
                DrawTetris();
            }
            else if (e.KeyCode == Keys.A)
            {
                //方块往左边移动
                //Console.WriteLine("方块往左边移动");
                if (CheckIsLeft())
                {
                    currentX--;
                }
                DrawTetris();
            }
            else if (e.KeyCode == Keys.D)
            {
                //方块加速下落
                //Console.WriteLine("方块往右边移动");
                if (CheckIsRight())
                {
                    currentX++;
                }
                DrawTetris();
            }
            else if (e.KeyCode == Keys.S)
            {
                //方块往右边移动
                //Console.WriteLine("S键被按下");
                timer1.Stop();
                timer1.Interval = 10;
                timer1.Start();
            }
        }
    }

 

 

  e、检查得分和游戏是否结束:这个时候检查背景矩阵,如果背景矩阵中有一个行全部为1,那么在y轴上比该行小的所有行向下移动一行,用户得分增加100。同理,检查所有的行,并且做同样动作。检查完成后,进入下个方块的随机挑选,下落。当某个方块下落完成的时候。他的y坐标在背景中为0的时候。游戏结束。作为游戏的界面,我们需要在游戏的状态发生改变的时候,把背景矩阵和运动矩阵都重绘出来。数值为0的地方不绘图,数值为1的地方绘制图片。

 

        /// <summary>
        /// 判断是否一行填满取得奖励得分的方法
        /// </summary>
        private void CheckScore()
        {
            for (int y = 19; y > -1; y--)
            {
                bool isFull = true;
                for (int x = 13; x > -1; x--)
                {
                    if (bgGround[y, x] == 0)
                    {
                        isFull = false;
                        break;
                    }
                }
                if (isFull)
                {
                    //增加积分  
                    score = score + 100;
                    for (int yy = y; yy > 0; yy--)
                    {
                        for (int xx = 0; xx < 14; xx++)
                        {
                            int temp = bgGround[yy - 1, xx];
                            bgGround[yy, xx] = temp;
                        }
                    }
                    y++;
                    label1.Text = "游戏得分: "+score.ToString(); ;
                    DrawTetris();
                }

            }
        }

 

        /// <summary>
        /// 重写窗体重绘的方法
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            //调用画方块的方法
            DrawTetris();
            base.OnPaint(e);
        }

 

游戏运行效果:

 

 

制作该游戏需要对C#图形图像编程(GDI+)有一定的了解;如果不太清楚,请看鄙人的上一篇博文:

 C#图形图像编程基础

该游戏实现了其基本的功能,但有些地方还有待提升。如游戏方块不全,Demo太单调,方块颜色单一,没有立体感。下一篇博客将会具体解决这些问题:

 http://yacare.iteye.com/blog/1949398

 

 游戏所有源代码和项目已打包上传到:

http://download.csdn.net/detail/u011458382/6341843

 

希望大家多多支持和指正。

 

  • 大小: 18.2 KB
  • 大小: 16.8 KB
  • 大小: 8.1 KB
分享到:
评论

相关推荐

    C#实现俄罗斯方块游戏代码

    总结来说,"C#实现俄罗斯方块游戏代码"项目涵盖了以下知识点: 1. C#基础语法和面向对象编程 2. Windows Forms应用程序开发 3. GDI+图形绘制技术 4. 游戏逻辑设计与实现,包括方块的生成、旋转、移动和消除 5. 用户...

    c#实现俄罗斯方块游戏

    在着手实现俄罗斯方块之前,我们需要对C#的基本语法和特性有深入的理解,包括类、对象、方法、变量、条件语句(如if-else)、循环(如for和while)、异常处理等。同时,C#支持事件和委托,这对于构建用户交互的游戏...

    C#实现俄罗斯方块游戏源码.zip

    【C#实现俄罗斯方块游戏源码】 C#是一种面向对象的编程语言,由微软公司开发,主要用于构建Windows平台的应用程序。在这个项目中,我们关注的是如何使用C#来实现经典的游戏——俄罗斯方块。俄罗斯方块是一款由苏联...

    C# 实现俄罗斯方块游戏

    在本项目中,我们将深入探讨如何使用C#编程语言在Visual Studio 2010环境下实现经典的俄罗斯方块游戏。俄罗斯方块是一款历史悠久且深受喜爱的电子游戏,它通过不断下落的形状组合来测试玩家的空间想象和反应速度。...

    C#俄罗斯方块游戏源代码,带背景音乐和音效

    《C#实现的俄罗斯方块游戏源代码解析》 在编程世界中,游戏开发一直是一项深受程序员喜爱的挑战。本文将深入探讨一个基于C#语言的俄罗斯方块游戏源代码,该代码集成了背景音乐和音效,为初学者提供了一个良好的实践...

    用C#实现俄罗斯方块

    总结来说,用C#实现俄罗斯方块游戏涉及到以下几个主要步骤: 1. 创建游戏板数据结构。 2. 设计方块形状及其旋转逻辑。 3. 实现用户输入控制和方块的移动、旋转、下落。 4. 检测并消除填满的行,更新得分。 5. 创建...

    基于C#实现俄罗斯方块游戏

    基于C#实现俄罗斯方块游戏 本文主要介绍了基于C#实现俄罗斯方块游戏的相关知识点,旨在为读者提供一个完整的俄罗斯方块游戏实现方案。以下是相关知识点的详细解释: 1.C#语言基础 在实现俄罗斯方块游戏之前,需要...

    C#实现俄罗斯方块 C# 小游戏

    《C#实现俄罗斯方块:探索游戏编程的艺术》 俄罗斯方块是一款经典的益智游戏,以其简单的规则和无尽的挑战性吸引了全世界的玩家。在本文中,我们将深入探讨如何使用C#编程语言来实现这一经典游戏。C#,作为微软开发...

    C#实现俄罗斯方块小游戏

    《C#实现俄罗斯方块小游戏详解》 在编程领域,实现经典游戏如俄罗斯方块是一种常见的练习,既能提升编程技能,又能对游戏设计有深入理解。本项目采用C#语言,利用简单工厂模式来构建俄罗斯方块游戏,下面将详细阐述...

    c#俄罗斯方块游戏源代码

    总之,通过C#实现俄罗斯方块游戏,不仅可以加深对C#编程语言的理解,也能锻炼到面向对象设计、事件驱动编程、数据结构和算法等多方面技能。这是一个既有趣又有挑战性的项目,无论是初学者还是经验丰富的开发者,都...

    C#实现俄罗斯方块

    在本项目中,"C#实现俄罗斯方块"是一个初学者使用C#编程语言开发的简单游戏。俄罗斯方块是一款经典的电子游戏,玩家需要操控不同形状的方块下落并排列,填满一行即可消除得分。以下是这个项目可能涉及的一些C#编程...

    C#编写俄罗斯方块游戏

    《C#实现俄罗斯方块游戏详解》 在编程领域,创建一款经典的游戏是学习和实践编程技能的好方法。本文将深入探讨如何使用C#语言在Visual Studio 2005环境下构建一个俄罗斯方块游戏。俄罗斯方块是一款极具挑战性的益智...

    C#写的简单俄罗斯方块游戏

    《C#实现的简单俄罗斯方块游戏详解》 在编程世界中,开发一款经典的小游戏是许多初学者和爱好者热衷的项目。本篇将详细解析一个使用C#语言编写的简单俄罗斯方块游戏,带你深入理解游戏的核心机制以及C#编程在游戏...

    C#代码俄罗斯方块游戏

    《C#实现俄罗斯方块游戏详解》 俄罗斯方块,这款经典的电子游戏,自1984年诞生以来,就以其简洁的规则和无尽的挑战性吸引了无数玩家。如今,借助C#编程语言,我们可以自己动手实现这样一个游戏。本文将深入探讨如何...

    C#俄罗斯方块游戏[内附源代码]

    总结来说,用C#实现俄罗斯方块游戏是一个综合性的项目,涵盖了编程基础、图形编程、游戏逻辑等多个方面。它既适合C#初学者作为入门实践,也对有经验的开发者提供了深入研究和优化的机会。无论你是想学习游戏开发,...

    基于C# Unity实现俄罗斯方块游戏【100012704】

    综上所述,实现C# Unity版的俄罗斯方块游戏,需要掌握Unity的UI系统、动画系统、游戏逻辑编程以及一些基本的视觉特效技巧。通过这个项目,开发者不仅可以提升编程技能,还能对游戏开发流程有更深入的理解。

    C#实现俄罗斯方块代码

    《C#实现俄罗斯方块代码详解》 在编程领域,实现经典游戏如俄罗斯方块是学习新语言或技术的良好实践。本教程将深入探讨如何使用C#编程语言来实现这一著名的益智游戏。C#是一种面向对象的、类型安全的编程语言,常...

    基于C#,俄罗斯方块游戏系统

    《基于C#实现的俄罗斯方块游戏系统》 在编程领域,C#是一种广泛应用的面向对象的编程语言,尤其在Windows平台上的应用开发中占据重要地位。本项目以C#为开发工具,构建了一个经典的俄罗斯方块游戏系统,充分展示了...

    C#课程设计 俄罗斯方块游戏 源码

    在本项目中,我们将深入探讨一个基于C#编程语言的课程设计项目——“俄罗斯方块”游戏的源码实现。这个项目旨在帮助学生理解和掌握C#的基础知识,以及如何运用这些知识来创建一个完整的交互式游戏。让我们逐一解析...

    C#版编写的俄罗斯方块游戏

    本篇介绍用C#编写一个俄罗斯方块程序的原理,以及在C#里面播放声音,保存游戏设置的方法。 游戏界面预览: 菜单预览: 自定义每个小方块颜色功能界面: 游戏主要有四部分组成:Square类,Block类,game...

Global site tag (gtag.js) - Google Analytics