17

C#版俄罗斯方块

 3 years ago
source link: https://www.cnblogs.com/tuyile006/archive/2007/05/16/748256.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

C#版俄罗斯方块

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

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

游戏界面预览:

blockField.jpg
菜单预览:
blockMenu.jpg
自定义每个小方块颜色功能界面:
blockColor.jpg
游戏主要有四部分组成: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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK