游戏人生Silverlight(1) - 七彩俄罗斯方块[Silverlight 2.0(c#)]

简介:
[源码下载]


游戏人生Silverlight(1) - 七彩俄罗斯方块[Silverlight 2.0(c#)]


作者: webabcd


介绍
使用 Silverlight 2.0(c#) 开发一个七彩俄罗斯方块


玩法
↑ - 变形;← - 向左移动;→ - 向右移动;↓ - 向下移动


在线DEMO



思路
1、每个形状都是由4个“块”组成的,也就是“块”是俄罗斯方块的最小单位,首先要有一个“块”的用户控件。要求可以设置“块”的位置和颜色
2、经典俄罗斯方块一共7种形状,把每种形状所需要的功能抽象出来写一个抽象类,7个具体形状分别继承这个抽象类,并重写其抽象属性和抽象方法
3、核心控制部分:在容器内铺满隐藏的“块”,上/下/左/右/控制形状的变形和移动,通过控制容器内“块”的颜色来响应变化,当形状下一步移动或变形的位置处已经有颜色时则禁止移动或变形,当形状下一步移动或变形的位置在底边有颜色或处于容器的底部则判断消行并生成新的形状


关键代码
1、形状抽象类
PieceBase.cs
InBlock.gif using System; 
InBlock.gif using System.Net; 
InBlock.gif using System.Windows; 
InBlock.gif using System.Windows.Controls; 
InBlock.gif using System.Windows.Documents; 
InBlock.gif using System.Windows.Ink; 
InBlock.gif using System.Windows.Input; 
InBlock.gif using System.Windows.Media; 
InBlock.gif using System.Windows.Media.Animation; 
InBlock.gif using System.Windows.Shapes; 
InBlock.gif 
InBlock.gif namespace YYTetris.Piece 
InBlock.gif
InBlock.gif         public  abstract  class PieceBase 
InBlock.gif        { 
InBlock.gif                 public PieceBase() 
InBlock.gif                { 
InBlock.gif                        InitPiece(); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 // 形状的矩阵 
InBlock.gif                 public  int[,] Matrix { get; set; } 
InBlock.gif 
InBlock.gif                 // 形状的索引 
InBlock.gif                 private  int _index = 0; 
InBlock.gif 
InBlock.gif                 // 形状的最大索引 
InBlock.gif                 public  int MaxIndex { get; set; } 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 初始化形状,需要设置 Matrix 和 MaxIndex 
InBlock.gif                 /// </summary> 
InBlock.gif                 public  abstract  void InitPiece(); 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 变形 
InBlock.gif                 /// </summary> 
InBlock.gif                 /// <returns>变形后的矩阵</returns> 
InBlock.gif                 public  abstract  int[,] GetRotate(); 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 形状的颜色 
InBlock.gif                 /// </summary> 
InBlock.gif                 public  abstract Color Color { get; } 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 获取下一个形状的索引。如果超过最大索引则返回最初索引 
InBlock.gif                 /// </summary> 
InBlock.gif                 /// <returns></returns> 
InBlock.gif                 public  int GetNextIndex() 
InBlock.gif                { 
InBlock.gif                         int nextIndex = _index >= MaxIndex ? 0 : _index + 1; 
InBlock.gif 
InBlock.gif                         return nextIndex; 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 变形。设置 Matrix 为变形后的矩阵 
InBlock.gif                 /// </summary> 
InBlock.gif                 public  void Rotate() 
InBlock.gif                { 
InBlock.gif                        Matrix = GetRotate(); 
InBlock.gif 
InBlock.gif                        _index = GetNextIndex(); 
InBlock.gif                } 
InBlock.gif        } 
InBlock.gif}
 
2、继承PieceBase类,以“L”为例。每种形状均为一个4×4矩阵,1代表有“块”,0代表空
L.cs
InBlock.gif using System; 
InBlock.gif using System.Net; 
InBlock.gif using System.Windows; 
InBlock.gif using System.Windows.Controls; 
InBlock.gif using System.Windows.Documents; 
InBlock.gif using System.Windows.Ink; 
InBlock.gif using System.Windows.Input; 
InBlock.gif using System.Windows.Media; 
InBlock.gif using System.Windows.Media.Animation; 
InBlock.gif using System.Windows.Shapes; 
InBlock.gif 
InBlock.gif namespace YYTetris.Piece 
InBlock.gif
InBlock.gif         public  class L : PieceBase 
InBlock.gif        { 
InBlock.gif                 public  override  void InitPiece() 
InBlock.gif                { 
InBlock.gif                        Matrix =  new  int[,] 
InBlock.gif                        { 
InBlock.gif                                {0,1,0,0}, 
InBlock.gif                                {0,1,0,0}, 
InBlock.gif                                {0,1,1,0}, 
InBlock.gif                                {0,0,0,0} 
InBlock.gif                        }; 
InBlock.gif 
InBlock.gif                        MaxIndex = 3; 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 public  override  int[,] GetRotate() 
InBlock.gif                { 
InBlock.gif                         switch (GetNextIndex()) 
InBlock.gif                        { 
InBlock.gif                                 case 0: 
InBlock.gif                                         return  new  int[,] 
InBlock.gif                                        { 
InBlock.gif                                                {0,1,0,0}, 
InBlock.gif                                                {0,1,0,0}, 
InBlock.gif                                                {0,1,1,0}, 
InBlock.gif                                                {0,0,0,0} 
InBlock.gif                                        }; 
InBlock.gif                                 case 1: 
InBlock.gif                                         return  new  int[,] 
InBlock.gif                                        { 
InBlock.gif                                                {0,0,0,0}, 
InBlock.gif                                                {1,1,1,0}, 
InBlock.gif                                                {1,0,0,0}, 
InBlock.gif                                                {0,0,0,0} 
InBlock.gif                                        }; 
InBlock.gif                                 case 2: 
InBlock.gif                                         return  new  int[,] 
InBlock.gif                                        { 
InBlock.gif                                                {1,1,0,0}, 
InBlock.gif                                                {0,1,0,0}, 
InBlock.gif                                                {0,1,0,0}, 
InBlock.gif                                                {0,0,0,0} 
InBlock.gif                                        }; 
InBlock.gif                                 case 3: 
InBlock.gif                                         return  new  int[,] 
InBlock.gif                                        { 
InBlock.gif                                                {0,0,1,0}, 
InBlock.gif                                                {1,1,1,0}, 
InBlock.gif                                                {0,0,0,0}, 
InBlock.gif                                                {0,0,0,0} 
InBlock.gif                                        }; 
InBlock.gif                                 default
InBlock.gif                                         return Matrix; 
InBlock.gif                        } 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 public  override Color Color 
InBlock.gif                { 
InBlock.gif                        get {  return Helper.GetColor( "#339933"); } 
InBlock.gif                } 
InBlock.gif        } 
InBlock.gif}
 
3、核心控制类
UIControl.cs
InBlock.gif using System; 
InBlock.gif using System.Net; 
InBlock.gif using System.Windows; 
InBlock.gif using System.Windows.Controls; 
InBlock.gif using System.Windows.Documents; 
InBlock.gif using System.Windows.Ink; 
InBlock.gif using System.Windows.Input; 
InBlock.gif using System.Windows.Media; 
InBlock.gif using System.Windows.Media.Animation; 
InBlock.gif using System.Windows.Shapes; 
InBlock.gif 
InBlock.gif using YYTetris.Piece; 
InBlock.gif using System.Windows.Threading; 
InBlock.gif using System.Collections.Generic; 
InBlock.gif using System.ComponentModel; 
InBlock.gif 
InBlock.gif namespace YYTetris 
InBlock.gif
InBlock.gif         public  class UIControl : INotifyPropertyChanged 
InBlock.gif        { 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 俄罗斯方块容器 
InBlock.gif                 /// </summary> 
InBlock.gif                 public Block[,] Container { get; set; } 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 下一个形状的容器(4×4) 
InBlock.gif                 /// </summary> 
InBlock.gif                 public Block[,] NextContainer { get; set; } 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 游戏状态(Ready, Play, Pause, Over) 
InBlock.gif                 /// </summary> 
InBlock.gif                 public GameStatus GameStatus { get; set; } 
InBlock.gif 
InBlock.gif                 private  int _rows = 20;  // 行数(Y 方向) 
InBlock.gif                 private  int _columns = 10;  // 列数(X 方向) 
InBlock.gif                 private  int _positionX = 3;  // 形状所属的 4×4 容器的 X 坐标 
InBlock.gif                 private  int _positionY = 0;  // 形状所属的 4×4 容器的 Y 坐标 
InBlock.gif 
InBlock.gif                 private List<PieceBase> _pieces;  // 形状集合 
InBlock.gif 
InBlock.gif                 private PieceBase _currentPiece;  // 当前形状 
InBlock.gif                 private PieceBase _nextPiece;  // 下一个形状 
InBlock.gif 
InBlock.gif                 private  int _initSpeed = 400;  // 初始速率(毫秒) 
InBlock.gif                 private  int _levelSpeed = 50;  // 每增加一个级别所需增加的速率(毫秒) 
InBlock.gif 
InBlock.gif                 private DispatcherTimer _timer; 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 构造函数 
InBlock.gif                 /// </summary> 
InBlock.gif                 public UIControl() 
InBlock.gif                { 
InBlock.gif                         // 初始化形状集合,共七种形状 
InBlock.gif                        _pieces =  new List<PieceBase>() {  new I(),  new L(),  new L2(),  new N(),  new N2(),  new O(),  new T() }; 
InBlock.gif 
InBlock.gif                         // 初始化方块容器(用 Block 对象填满整个容器) 
InBlock.gif                        Container =  new Block[_rows, _columns]; 
InBlock.gif                         for ( int i = 0; i < _rows; i++) 
InBlock.gif                        { 
InBlock.gif                                 for ( int j = 0; j < _columns; j++) 
InBlock.gif                                { 
InBlock.gif                                        var block =  new Block(); 
InBlock.gif                                        block.Top = i * block.rectangle.ActualHeight; 
InBlock.gif                                        block.Left = j * block.rectangle.ActualWidth; 
InBlock.gif                                        block.Color =  null
InBlock.gif 
InBlock.gif                                        Container[i, j] = block; 
InBlock.gif                                } 
InBlock.gif                        } 
InBlock.gif 
InBlock.gif                         // 初始化下一个形状的容器(用 Block 对象将其填满) 
InBlock.gif                        NextContainer =  new Block[4, 4]; 
InBlock.gif                         for ( int i = 0; i < 4; i++) 
InBlock.gif                        { 
InBlock.gif                                 for ( int j = 0; j < 4; j++) 
InBlock.gif                                { 
InBlock.gif                                        var block =  new Block(); 
InBlock.gif                                        block.Top = i * block.rectangle.ActualHeight; 
InBlock.gif                                        block.Left = j * block.rectangle.ActualWidth; 
InBlock.gif                                        block.Color =  null
InBlock.gif 
InBlock.gif                                        NextContainer[i, j] = block; 
InBlock.gif                                } 
InBlock.gif                        } 
InBlock.gif 
InBlock.gif                         // 创建一个新的形状 
InBlock.gif                        CreatePiece(); 
InBlock.gif                         // 呈现当前创建出的形状 
InBlock.gif                        AddPiece(0, 0); 
InBlock.gif 
InBlock.gif                         // Timer 用于定时向下移动形状 
InBlock.gif                        _timer =  new DispatcherTimer(); 
InBlock.gif                        _timer.Interval = TimeSpan.FromMilliseconds(_initSpeed); 
InBlock.gif                        _timer.Tick +=  new EventHandler(_timer_Tick); 
InBlock.gif 
InBlock.gif                        GameStatus = GameStatus.Ready; 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 开始游戏(启动计时器) 
InBlock.gif                 /// </summary> 
InBlock.gif                 public  void Play() 
InBlock.gif                { 
InBlock.gif                        GameStatus = GameStatus.Play; 
InBlock.gif                        _timer.Start(); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 暂停游戏(停止计时器) 
InBlock.gif                 /// </summary> 
InBlock.gif                 public  void Pause() 
InBlock.gif                { 
InBlock.gif                        GameStatus = GameStatus.Pause; 
InBlock.gif                        _timer.Stop(); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 创建一个新的形状 
InBlock.gif                 /// </summary> 
InBlock.gif                 private  void CreatePiece() 
InBlock.gif                { 
InBlock.gif                         // 逻辑移到 下坠后 的逻辑内 
InBlock.gif                         for ( int x = 0; x < _columns; x++) 
InBlock.gif                        { 
InBlock.gif                                 if (Container[0, x].Color !=  null
InBlock.gif                                { 
InBlock.gif                                        OnGameOver( null); 
InBlock.gif                                         break
InBlock.gif                                } 
InBlock.gif                        } 
InBlock.gif 
InBlock.gif                         // 计算 当前形状 和 下一个形状 
InBlock.gif                        Random random =  new Random(); 
InBlock.gif                        _currentPiece = _nextPiece ==  null ? _pieces[random.Next(0, 7)] : _nextPiece; 
InBlock.gif                        _nextPiece = _pieces[random.Next(0, 7)]; 
InBlock.gif 
InBlock.gif                         // 形状所属的 4×4 容器的 X 坐标和 Y 坐标 
InBlock.gif                        _positionX = 3; 
InBlock.gif                        _positionY = 0; 
InBlock.gif 
InBlock.gif                         // 设置“下一个形状的容器”的 UI 
InBlock.gif                        SetNextContainerUI(); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 private  void _timer_Tick( object sender, EventArgs e) 
InBlock.gif                { 
InBlock.gif                        MoveToDown(); 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 向左移动 
InBlock.gif                 /// </summary> 
InBlock.gif                 public  void MoveToLeft() 
InBlock.gif                { 
InBlock.gif                         if (GameStatus != GameStatus.Play)  return
InBlock.gif 
InBlock.gif                         if (!IsBoundary(_currentPiece.Matrix, -1, 0)) 
InBlock.gif                        { 
InBlock.gif                                RemovePiece(); 
InBlock.gif                                AddPiece(-1, 0); 
InBlock.gif                        } 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 向右移动 
InBlock.gif                 /// </summary> 
InBlock.gif                 public  void MoveToRight() 
InBlock.gif                { 
InBlock.gif                         if (GameStatus != GameStatus.Play)  return
InBlock.gif 
InBlock.gif                         if (!IsBoundary(_currentPiece.Matrix, 1, 0)) 
InBlock.gif                        { 
InBlock.gif                                RemovePiece(); 
InBlock.gif                                AddPiece(1, 0); 
InBlock.gif                        } 
InBlock.gif                } 
InBlock.gif 
InBlock.gif                 /// <summary> 
InBlock.gif                 /// 向下移动 
InBlock.gif                 /// </summary> 
InBlock.gif                 public  void MoveToDown() 
InBlock.gif                { 
InBlock.gif                         if (GameStatus != GameStatus.Play)  return
InBlock.gif 
InBlock.gif                         if (!IsBoundary(_currentPiece.Matrix, 0, 1)) 
InBlock.gif                        { 
InBlock.gif                                RemovePiece(); 
InBlock.gif                                AddPiece(0, 1); 
InBlock.gif                        } 
InBlock.gif                         else 
InBlock.gif                        { 
InBlock.gif                                 // 如果触及底边了,则消除可消的行并且创建新的形状 
InBlock.gif                                RemoveRow(); 
InBlock.gif                                CreatePiece(); 
InBlock.gif 
InBlock.gif                                 // 每落下一个形状加 1 分 
InBlock.gif                                Score++; 
InBlock.gif                        } 
InBlock.gif                }




     本文转自webabcd 51CTO博客,原文链接: http://blog.51cto.com/webabcd/345633 ,如需转载请自行联系原作者

相关文章

热门文章

最新文章

相关实验场景

更多