四、定义扑克控件Card
屏幕上存在那么多的扑克,我们是如何管理的呢?答案是:在本游戏中,我们把每张扑克定义为一个独立的Silverlight用户控件—Card。
基于这个想法,我们需要定义扑克控件Card的正面朝上还是朝下,扑克点数,扑克花色,这些皆定义为控件的公共属性。但是,如何处理扑克图像还是一个问题。在这一点,不同的开发者可能有自己的实现方案。我的想法是,让扑克控件维护一个Uri数组,并使每个Uri指向相应的扑克图像文件(.png格式,这也是Silverlight开发中被广泛应用的图像格式)。下面的清单给出了扑克控件Card的定义。
public partial class Card : UserControl{
public Face CurrentFace { get; set; } //扑克正面朝上还是朝下
public int Number { get; set; } //扑克点数
public Suits CurrentSuit { get; set; } //扑克花色
private Uri[] uriPokerImages = {
new Uri("/Poker_MVP;Component/images/cards/cl1.PNG", UriKind.RelativeOrAbsolute),
new Uri("/Poker_MVP;Component/images/cards/cl2.PNG", UriKind.RelativeOrAbsolute),
//省略其他……
new Uri("/Poker_MVP;Component/images/cards/spq.PNG", UriKind.RelativeOrAbsolute),
new Uri("/Poker_MVP;Component/images/cards/spk.PNG", UriKind.RelativeOrAbsolute),
new Uri("/Poker_MVP;Component/images/cards/background.PNG", UriKind.RelativeOrAbsolute),
new Uri("/Poker_MVP;Component/images/cards/go.PNG", UriKind.RelativeOrAbsolute),
new Uri("/Poker_MVP;Component/images/cards/placeholder.PNG", UriKind.RelativeOrAbsolute),
};
public Uri this[int nIndex] {
get {
return uriPokerImages[nIndex];}
set{
uriPokerImages[nIndex]=value;}
}
public Card(){
InitializeComponent();
}
public Card(Face face, int number, Suits currSuit ) {
InitializeComponent();
this.CurrentFace = face;
this.Number = number;
this.CurrentSuit = currSuit;
if(face==Face.faceup)
this.imageHolder.Source = new BitmapImage(this[(int)currSuit * 13 + (number - 1)]);
else if (face == Face.facedown) //反面图像
this.imageHolder.Source =new BitmapImage(this[52]);
else if (face == Face.empty)
this.imageHolder.Source = new BitmapImage(this[53]);//空牌图像
else
this.imageHolder.Source = new BitmapImage(this[54]);//占位符图像
}
public void SetToFaceUp(){
this.CurrentFace = Face.faceup;
this.imageHolder.Source = new BitmapImage(
this[(int)(CurrentSuit) * 13 + (Number - 1)]);
}
public void SetToFaceDown(){
this.CurrentFace = Face.facedown;
this.imageHolder.Source = new BitmapImage(this[52]);
}
}
public Face CurrentFace { get; set; } //扑克正面朝上还是朝下
public int Number { get; set; } //扑克点数
public Suits CurrentSuit { get; set; } //扑克花色
private Uri[] uriPokerImages = {
new Uri("/Poker_MVP;Component/images/cards/cl1.PNG", UriKind.RelativeOrAbsolute),
new Uri("/Poker_MVP;Component/images/cards/cl2.PNG", UriKind.RelativeOrAbsolute),
//省略其他……
new Uri("/Poker_MVP;Component/images/cards/spq.PNG", UriKind.RelativeOrAbsolute),
new Uri("/Poker_MVP;Component/images/cards/spk.PNG", UriKind.RelativeOrAbsolute),
new Uri("/Poker_MVP;Component/images/cards/background.PNG", UriKind.RelativeOrAbsolute),
new Uri("/Poker_MVP;Component/images/cards/go.PNG", UriKind.RelativeOrAbsolute),
new Uri("/Poker_MVP;Component/images/cards/placeholder.PNG", UriKind.RelativeOrAbsolute),
};
public Uri this[int nIndex] {
get {
return uriPokerImages[nIndex];}
set{
uriPokerImages[nIndex]=value;}
}
public Card(){
InitializeComponent();
}
public Card(Face face, int number, Suits currSuit ) {
InitializeComponent();
this.CurrentFace = face;
this.Number = number;
this.CurrentSuit = currSuit;
if(face==Face.faceup)
this.imageHolder.Source = new BitmapImage(this[(int)currSuit * 13 + (number - 1)]);
else if (face == Face.facedown) //反面图像
this.imageHolder.Source =new BitmapImage(this[52]);
else if (face == Face.empty)
this.imageHolder.Source = new BitmapImage(this[53]);//空牌图像
else
this.imageHolder.Source = new BitmapImage(this[54]);//占位符图像
}
public void SetToFaceUp(){
this.CurrentFace = Face.faceup;
this.imageHolder.Source = new BitmapImage(
this[(int)(CurrentSuit) * 13 + (Number - 1)]);
}
public void SetToFaceDown(){
this.CurrentFace = Face.facedown;
this.imageHolder.Source = new BitmapImage(this[52]);
}
}
注意:上面代码中,我们共定义了除大王和小王以外的55幅扑克图像。其中,最后面的三幅特别的图像用于特殊的用途。而且,为了检索相关的图像,我们定义了一个索引属性Uri,用于作为指向此图像Uri的指针。此外,为了方便创建扑克控件的实例,我们还重载了Card控件的构造器函数。至于其他两个方法—SetToFaceUp和SetToFaceDown,如其自的名称所暗示的,分别用来改变扑克的状态,即设置扑克的正面朝上与朝下。
从下一篇开始,我们将讨论如何使用上面定义的数据结构来生成扑克和发牌问题。