C#版俄罗斯方块

C++是游戏编程的首选语言,但我相信C++能做到的C#也能做到。

本篇介绍用C#编写一个俄罗斯方块程序的原理,以及在C#里面播放声音,保存游戏设置的方法。

游戏界面预览:



菜单预览:



自定义每个小方块颜色功能界面:



游戏主要有四部分组成:Square类,Block类,gameField类,游戏引擎

Square类:
          这个类描述的对象是组成大方块中的每个小正方形实体。
     类设计:
    class Square
    {
        public Point location;   //小方块的坐标
        public Size size;          //小方块大小
        public Color foreColor;  //小方块前景色
        public Color backColor; //小方块背景色
        public Square(Size initSize,Color initForeColor,Color initBackColor) //构造函数
        {  ……}
         public void Draw(System.IntPtr winHandle) //在指定设备上画方块
        {  …… }
         public void Erase(System.IntPtr winHandle)//擦除方块
        { ……  }
     }

Block类:
          这个类描述的对象是某一个大方块的实体。每个大方块由四个小正方形组成,一共有7种组合方式。这个类需要实现一个大方块实体所有的属性和动作。包括:方块的形状,位置,方块左移,右移,下移,旋转等。
      类设计:
 class Block
    {
        public Square square1;  //组成block的四个小方块
        public Square square2;
        public Square square3;
        public Square square4;

        private const int squareSize = GameField.SquareSize; //小方块的边长
        public enum BlockTypes
        {
            undefined = 0,
            square = 1,
            line = 2,
            J = 3,
            L = 4,
            T = 5,
            Z = 6,
            S = 7
        };//一共有7种形状
        public BlockTypes blockType;  //方块的形状
        //七个小方块的颜色数组
        private Color foreColor;
        private Color backColor;
        //方块的方向
        public enum RotateDirections
        {
            North = 1,
            East = 2,
            South = 3,
            West = 4
        };
        public RotateDirections myRotation = RotateDirections.North;
       
        public Block(Point thisLocation,BlockTypes bType)
        { ……}
        //含有自定义颜色的重载
        public Block(Point thisLocation, BlockTypes bType,Color fc,Color bc)
        { ……}

        /*画方块*/
        public void Draw(System.IntPtr winHandle)
        {…… }
        /*擦方块*/
        public void Erase(System.IntPtr winHandle)
        {…… }

        /*移动*/
        public bool down()
        {……}
        public bool left()
        {……}
        public bool right()
        {……}
        /*旋转block*/
        public void Rotate()
        {……}
        /*检测是否到顶*/
        public int Top()
        {……}
    }

GameField类:
        这个类描述的对象是游戏场景实体,包括场景的背景色,大小,方块是否还可以移动,以及场景中填满一行的检测等。
        类设计:
     class GameField
    {
        public const int width = 20;           //场景的宽,以方块个数为单位
        public const int height = 30;
        public const int SquareSize = 15;      //每个四分之一小方块的边长
        public static Color BackColor;         //场景的背景色
        public static System.IntPtr winHandle; //场景的handle
        public static Color[] BlockForeColor ={ Color.Blue, Color.Beige, Color.DarkKhaki, Color.DarkMagenta, Color.DarkOliveGreen, Color.DarkOrange, Color.DarkRed };
        public static Color[] BlockBackColor ={ Color.LightCyan, Color.DarkSeaGreen, Color.Beige, Color.Beige, Color.Beige, Color.Beige, Color.Beige };
        public static bool isChanged=false; //设置是否被更改的标志位
        public static SoundPlayer sound = new SoundPlayer();  //播放声音

        public static Square[,] arriveBlock = new Square[width, height]; //保存已经不能再下落了的方块
        public static int[] arrBitBlock=new int[height];  //位数组:当某个位置有方块时,该行的该位为1
        private const int bitEmpty = 0x0;      //0000 0000 0000 0000 0000
        private const int bitFull = 0xFFFFF;   //1111 1111 1111 1111 1111

        /*检测某个位置是否为空*/
        public static bool isEmpty(int x, int y)
        {……}
        /*将方块停住*/
        public static void stopSquare(Square sq, int x, int y)
        {……}
        /*检测行是否满
         * 返回:成功消除的行数和  (方便统计分数)
         */

        public static int CheckLines()
        { ……}
        /*播放声音*/
        public static void PlaySound(string soundstr)
        {……}
        /*重画*/
        public static void Redraw()
        { …… }
         //结束
    }

游戏引擎:
      游戏引擎正如其名,就像一个发动机一样让游戏不间断运行。本游戏中就是让方块以一定的速度下落。并响应键盘事件,实行左右移动,和向下加速功能。(代码见源码)

声音播放:

     音效是游戏不可缺少的一部分。在.Net2.0中已经提供了一个类来播放声音。在using System.Media;命名空间。
     本游戏中播放声音的代码如下:(在 GameField类中)
     using System.Media;

     public static SoundPlayer sound = new SoundPlayer();
     
     /*播放声音*/
        public static void PlaySound(string soundstr)
        {
            switch (soundstr)
            {
                case "FinishOneLine": //消除一行的声音
                    if (!File.Exists("FinishOneLine.wav")) return;
                    sound.SoundLocation = "FinishOneLine.wav";
                    break;
                case "CanNotDo": //当无法操作时
                    if (!File.Exists("CanNotDo.wav")) return;
                    sound.SoundLocation = "CanNotDo.wav";
                    break;
            }
            sound.Play();
        }
        要播放的时候调用PlaySound()方法即可。
        其实步骤很简单,先引用System.Media空间,然后创建一个SoundPlayer 对象,用SoundLocation 属性设置声音文件的地址,然后调用Play()方法即可播放。不过注意,这个类可以播放的声音格式只有Wav文件。

保存游戏设置:
      在游戏中经常要保存用户自定义的设置。本游戏通过写进ini文件来保存。
      主要代码如:

       /*加载窗体时从配置文件Setting.ini中读取游戏设置*/
        private void getSettings()
        {
            if (!File.Exists("Setting.ini"))
                return;
            FileStream fs = new FileStream("Setting.ini", FileMode.OpenOrCreate, FileAccess.ReadWrite);
            StreamReader sr = new StreamReader(fs);
            string line1=sr.ReadLine();
            string line2=sr.ReadLine();
            string line3=sr.ReadLine();
            if (line1 != null && line1.Split('=').Length > 1)
            {
                GameField.BackColor = Color.FromArgb(int.Parse(line1.Split('=')[1]));
                picBackGround.BackColor = GameField.BackColor;
            }
            if (line2 != null && line2.Split('=').Length > 1)
                GameField.BlockForeColor = strToColor(line2.Split('=')[1]);
            if (line3 != null && line3.Split('=').Length > 1)
                GameField.BlockBackColor = strToColor(line3.Split('=')[1]);
            sr.Close();
            fs.Close();
        }
        /*如果游戏设置被更改,将新的设置保存到Setting.ini*/
        private void saveSettings()
        {
            FileStream fs = new FileStream("Setting.ini", FileMode.Create, FileAccess.ReadWrite);
            StreamWriter sw = new StreamWriter(fs);
            sw.WriteLine("GameFieldColor="+GameField.BackColor.ToArgb());
            sw.WriteLine("BlockFroeColor=" + colorToStr(GameField.BlockForeColor));
            sw.WriteLine("BlockBackColor=" + colorToStr(GameField.BlockBackColor));
            sw.Flush();
            sw.Close();
            fs.Close();
        }

麻雀虽小,五脏俱全,了解更多请看源码。
游戏源码下载:CODE

posted @ 2007-05-16 11:10  小y  阅读(37472)  评论(58编辑  收藏  举报