# 自制俄罗方块Silverlight

1、如何创建各种形状的方块。
2、方块在游戏区域的定位。
4、方块在游戏中形态的改变。
3、方块在游戏区域的移动。
5、方块填满整行后消除以及未消除的方块下移。

<Rectangle x:Name="rectBlock" Stroke="Black" Width="20" Height="20" RadiusX="2" RadiusY="2"></Rectangle>

public static DependencyProperty AbsolutePositionProperty = DependencyProperty.Register("AbsolutePosition", typeof(Point), typeof(SingleBlock), new PropertyMetadata(new Point(0, 0)));/// <summary>/// 方块绝对位置/// </summary>public Point AbsolutePosition{    get    {        return (Point)GetValue(AbsolutePositionProperty);    }    set    {        SetValue(AbsolutePositionProperty, value);    }}

public class TBlock : DependencyObject{        public TBlock()        {            //初始化图形            SingleBlock blocks = new SingleBlock[4];            //设置元方块坐标            blocks[0].AbsolutePosition = new Point(0, 0);            blocks[1].AbsolutePosition = new Point(-1, 0);            blocks[2].AbsolutePosition = new Point(0, -1);            blocks[3].AbsolutePosition = new Point(1, 0);            //设置元方块显示位置        for (int i = 0; i < blocks.Length; i++)            {                blocks[i].SetValue(Canvas.LeftProperty, blocks[i].AbsolutePosition.X * blocks[i].Width);                blocks[i].SetValue(Canvas.TopProperty, blocks[i].AbsolutePosition.Y * blocks[i].Height);            }        }}

public static DependencyProperty RelativelyPositionProperty = DependencyProperty.Register("RelativelyPosition", typeof(Point), typeof(BlockGeometry), new PropertyMetadata(new Point(0, 0)));/// <summary>/// 图形相对位置/// </summary>public Point RelativelyPosition{    get    {        return (Point)GetValue(RelativelyPositionProperty);    }    set    {        SetValue(RelativelyPositionProperty, value);    }}

this.RelativelyPosition = new Point(4, 0);/// <summary>/// 设置图形出现位置/// </summary>public void SetPosition(){    for (int i = 0; i < blocks.Length; i++)    {        blocks[i].SetValue(Canvas.LeftProperty, (blocks[i].AbsolutePosition.X + this.RelativelyPosition.X) * blocks[i].Width);        blocks[i].SetValue(Canvas.TopProperty, (blocks[i].AbsolutePosition.Y + this.RelativelyPosition.Y) * blocks[i].Height);    }}

private Point virtualPoint = new Point(0, 1);   //虚坐标，用于坐标互换/// <summary>/// T旋转/// 规则：/// 沿中心点旋转/// </summary>public override void Rotation(){    Point[] points = new Point[4];    points[0] = new Point(0, 0);    for (int i = 1; i < 3; i++)    {        //前一个变成后一个        points[i] = new Point(this.Blocks[i + 1].AbsolutePosition.X, this.Blocks[i + 1].AbsolutePosition.Y);    }    //最后一个与虚坐标互换    points[3] = new Point(virtualPoint.X, virtualPoint.Y);    //虚坐标与第一个坐标互换    virtualPoint = new Point(this.Blocks[1].AbsolutePosition.X, this.Blocks[1].AbsolutePosition.Y);    //旋转    for (int i = 0; i < points.Length; i++)    {        this.Blocks[i].AbsolutePosition = points[i];    }}

public static Dictionary<Point, SingleBlock> GameCanvas = new Dictionary<Point, SingleBlock>(); //定义游戏区域变量//初始化游戏区域变量，每个区域开始时不存在任何基准图形for (int i = 0; i < 10; i++){    for (int j = 0; j < 20; j++)    {        GameCanvas.Add(new Point(i, j), null);    }}

/// <summary>/// 检验方块是否可移动（移动及旋转）/// </summary>private bool IsCanMove(Point newPoint){    foreach (SingleBlock block in Blocks)    {        //检验X轴是否超出画布区域        double x = block.AbsolutePosition.X + newPoint.X;        if (x < 0 || x > 9)        {            return false;        }        //检验Y轴是否超出画布区域        double y = block.AbsolutePosition.Y + newPoint.Y;        if (y > 19)        {            return false;        }        //检验当前位置是否已存在方块        if (y >= 0 && (!App.GameCanvas.ContainsKey(new Point(x, y)) || App.GameCanvas[new Point(x, y)] != null))        {            return false;        }    }    return true;}

/// <summary>/// 检验方块是否可旋转/// </summary>protected bool IsCanRotation(Point[] newPoints){    foreach (Point point in newPoints)    {        double x = this.RelativelyPosition.X + point.X;        if (x < 0 || x > 9)        {            return false;        }        //检验Y轴是否超出画布区域        double y = this.RelativelyPosition.Y + point.Y;        if (y > 19)        {            return false;        }        //检验当前位置是否已存在方块        if (!App.GameCanvas.ContainsKey(new Point(x, y)) || App.GameCanvas[new Point(x, y)] != null)        {            return false;        }    }    return true;}

/// <summary>/// 图形是否已停止（到达指定位置）/// </summary>public bool IsStop{    get;    set;}：/// <summary>/// 方块移动方法/// 参数：/// newPoint：移动后的新坐标/// isJudgeStop：是否判断移动结束/// </summary>public void Move(Point newPoint, bool isJudgeStop){    //判断是否可移动到新坐标    if (!IsCanMove(newPoint))    {        if (isJudgeStop)        {            this.IsStop = true;        }        return;    }    //移动    RelativelyPosition = newPoint;    SetPosition();}

//判断游戏是否结束，顶层只要存在一个方块即结束Point point;//消除成功的行List<int> lisSuccessRow = new List<int>();for (int i = 19; i >= 0; i--){    bool isSuccess = true;    for (int j = 0; j < 10; j++)    {        point = new Point(j, i);        if (App.GameCanvas[point] == null)        {            isSuccess = false;        }    }    if (!isSuccess)    {        continue;    }    //记录将要移除的方块    lisSuccessRow.Add(i);}            //移除方块int downCount = 0;  //未消除的行需要下移的次数for (int i = 19; i >= 0; i--){    if (lisSuccessRow.Contains(i))    {        //判断并消除当前行        for (int j = 0; j < 10; j++)        {            point = new Point(j, i);            gameArea.Children.Remove(App.GameCanvas[point]);            App.GameCanvas[point] = null;        }        downCount += 1;        continue;    }    if (downCount == 0)    {        continue;    }    //未消除行下移    for (int j = 0; j < 10; j++)    {        point = new Point(j, i);        if (App.GameCanvas[point] == null)        {            continue;        }        double y = i * 1.0 + downCount;        App.GameCanvas[point].SetValue(Canvas.TopProperty, y * App.GameCanvas[point].Height);        App.GameCanvas[new Point(point.X, y)] = App.GameCanvas[point];        App.GameCanvas[point] = null;    }}

//添加定时器private DispatcherTimer timer = new DispatcherTimer();private double initFallStep = 0.5;      //BLOCK下降步长（s）timer.Tick += timer_Tick;timer.Interval = TimeSpan.FromSeconds(curFallStep);timer.Start();this.KeyDown += OnKeyDown;    //侦听键盘事件private void timer_Tick(object sender, EventArgs e){    //SETP1：创建方块并显示    //SETP2：改变相对位置Y    //SETP3：判断结束并计算得分}private void OnKeyDown(object sender, KeyEventArgs e){    if (btStart.IsEnabled)    {        return;    }    if (e.Key == Key.Up)    {        //上方向键旋转        curGeometry.Rotation();    }    if (e.Key == Key.Left)    {        //左方向键左移        curGeometry.Move(new Point(curGeometry.RelativelyPosition.X - 1, curGeometry.RelativelyPosition.Y), false);    }    if (e.Key == Key.Right)    {        //右方向键右移        curGeometry.Move(new Point(curGeometry.RelativelyPosition.X + 1, curGeometry.RelativelyPosition.Y), false);    }    if (e.Key == Key.Down)    {        //下方向键加速，连续移动两次        for (int i = 0; i < 2; i++)        {            curGeometry.Move(new Point(curGeometry.RelativelyPosition.X, curGeometry.RelativelyPosition.Y + 1), true);        }    }    if (e.Key == Key.Space)    {         //空格键，直接结束移动        for (int i = 0; i < 20; i++)        {            curGeometry.Move(new Point(curGeometry.RelativelyPosition.X, curGeometry.RelativelyPosition.Y + 1), true);        }    }}//判断游戏是否结束，顶层只要存在一个方块即结束Point point;if (curGeometry.IsStop){    for (int i = 0; i < 10; i++)    {        point = new Point(i, 0);        if (App.GameCanvas[point] != null)        {            GameOver();            return;        }    }}

Demo下载

posted @ 2011-09-17 12:34  flysoul  阅读(2224)  评论(7编辑  收藏