Silverlight:手把手教你写俄罗斯方块(二)
protected Point[] point;
protected Color c;
point用来存储小方块坐标,c存储方块颜色。然后定义3个属性:
/// <summary>
/// 方块颜色
/// </summary>
public Color color
{
get { return c; }
}
/// <summary>
/// 中心点横坐标
/// </summary>
public int posX { get; set; }
/// <summary>
/// 中心点纵坐标
/// </summary>
public int posY { get; set; }
中心点横坐标和中心点纵坐标是指这个方块在画板中的坐标,而point存储的是在方块内部定义的坐标,以“L”方块为例,我们这样设置:
point[0].X = -1;
point[0].Y = 0;
point[1].X = -1;
point[1].Y = -1;
point[2].X = 0;
point[2].Y = 0;
point[3].X = 1;
point[3].Y = 0;
您不妨在纸上画个坐标系,然后画出这4个点的位置,看是否够成了“L”这个形状。中心点横坐标和中心点纵坐标可以看成是原点(0,0)在画板中的坐标,这样一旦确定了posX和posY,我们就可以通过posX + this.point[index].X和 posY - this.point[index].Y来获取其他点在画板中的坐标了。于是我们再写一个索引器用来取得小方块的坐标:
/// <summary>
/// 小方块的坐标
/// </summary>
/// <param name="index">俄罗斯方块内部小方块索引</param>
/// <returns></returns>
public Point this[int index]
{
get
{
return new Point(posX + this.point[index].X, posY - this.point[index].Y);
}
}
构造函数,当方块出现在画板之前,我们要先确定它在画板中的位置,所以需要对这posX和posY属性赋值。
/// <summary>
/// 俄罗斯方块中心点在画板上的坐标
/// </summary>
/// <param name="x">横坐标</param>
/// <param name="y">纵坐标</param>
public Block(int x, int y)
{
point = new Point[4];
this.posX = x;
this.posY = y;
}
方块还需要变形,我们还是以“L”方块为例,我们规定它的变形是在同样的坐标系中沿着原点(0,0)做顺时针旋转,这样一来它的每个小方块的坐标会发生什么变化呢?您可以用笔在纸上画一下,看看是不是旧坐标的Y轴变成了新坐标的X轴,旧坐标的X轴变成了新坐标的负Y轴,变形方法如下:
public virtual void Change()
{
for (int z = 0; z < 4; z++)
{
double oldX = point[z].X;
double oldY = point[z].Y;
point[z].X = oldY;
point[z].Y = -oldX;
}
}
这里使用的是虚方法,因为我们并不想所有的方块都以这种方式变形,一些特殊的方块我们希望能够重载,比如“正方形”方块并不需要旋转。但是还有一点需要注意,方块在某些情况是不能变形的,比如变形后超出了边界,或者变形后的新坐标上已经存在方块(即被其它方块挡住),所以在变形前我们需要先要取得方块变形后的坐标,然后判断方块能否变形。代码如下:
public virtual Point[] GetChangedPoint()
{
Point[] newPoint = new Point[4];
for (int z = 0; z < 4; z++)
{
double oldX = point[z].X;
double oldY = point[z].Y;
double newX = oldY;
double newY = -oldX;
newPoint[z] = new Point(posX + newX, posY - newY);
}
return newPoint;
}
同样采用虚方法。最后还需要2个方法用来控制方块在画板上的显示和消失:
public void Show(Rect[,] board)
{
for (int i = 0; i < 4; i++)
{
int x = (int)this[i].X;
int y = (int)this[i].Y;
board[x, y].Color = this.color;
}
}
public void Hidden(Rect[,] board)
{
for (int i = 0; i < 4; i++)
{
int x = (int)this[i].X;
int y = (int)this[i].Y;
board[x, y].Color = null;
}
}
这里的参数board就是我们用Rect填充的画板,通过索引器遍历每个小方块,取得它们在画板上的坐标,然后给相应的Rect绘制方块的颜色,前面说过,当我们赋值为null的时候,相应的Rect就隐藏了,方块也就消失了,我们就是通过方块的消失和显示,来实现方块的移动和变形效果。
俄罗斯方块的基类到此就构建完毕了,下一节中,我将介绍构建具体形状的俄罗斯方块,敬请关注。

浙公网安备 33010602011771号