开发.Net版的纸牌游戏

        最近我刚完成一个大项目后有一段比较休闲的时光。但是休息久了也很无聊,偶尔玩玩小游戏,像纸牌之类的.大游戏不敢玩,怕被领导发现,嘿嘿emsmilep.gif

        想必大家都玩过Windows自带的一个小游戏"纸牌"吧。在空闲时间我也开发了一个.net版的纸牌游戏,其界面、功能及操作都跟Windows的差不多。下图就是我的作品的截图:

            cardgame.jpg

源代码文件说明:
CardsResources.resx ---------------牌图像资源
Cards.cs----------------------------牌对象
CardCollections.cs------------------牌列表对象
GamePlace.cs-----------------------游戏平台
GameForm.cs-----------------------游戏窗口
OptionForm.cs----------------------选项设置窗口
BackImageForm.cs------------------牌背面选择窗口
ImageBrowser.cs--------------------图片浏览控件
PassPlayer.cs------------------------过关动画播放器

        说到像这类似的牌类游戏,也许大家都有自己的思路和想法,下面我就来谈谈我在开发过程中的思路以及遇到的问题和处理方法。


        一,建立对象(包括资源对象,牌对象,牌列表对象)
            (一)资源对象:将所有牌的图像(包括背景和其他特殊图片)做成资源"CardsResources.resx",我一共做了69张图片,54张牌面+12张背景+1张阴影图片+2张发牌底面。
            (二)牌对象 Card:继承System.Windows.Forms.PictureBox,其图像源即为资源中的牌图像.首先建立Cards用于创建牌的图像

ExpandedBlockStart.gif ContractedBlock.gif /**/ /// <summary>
InBlock.gif    
/// 创建牌的图像资源。
ExpandedBlockEnd.gif    
/// </summary>

None.gif      public   class  Cards
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
private static Image[] cardImages;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 牌的尺寸
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public static readonly Size CardImageSize=new Size(71,96);
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 牌的图像列表
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        internal static Image[] CardImages
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return cardImages;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 创建图像列表
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public static void CreateCardsImages()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            ResourceManager resmanager
=new ResourceManager("CardGame.CardsResources",Assembly.GetExecutingAssembly());
InBlock.gif            cardImages
=new Image[69];
InBlock.gif            
InBlock.gif            
for(int i=0;i<69;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                cardImages[i]
=(resmanager.GetObject(i+""as Image);
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 获得牌的显示区域
InBlock.gif        
/// </summary>
InBlock.gif        
/// <param name="size">牌的尺寸</param>
ExpandedSubBlockEnd.gif        
/// <returns>牌的显示区域</returns>

InBlock.gif        public static Region GetCardRegion(Size size)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            GraphicsPath gp 
= new GraphicsPath();
ExpandedSubBlockStart.gifContractedSubBlock.gif            gp.AddPolygon(
new Point[]dot.gif{
InBlock.gif                                         
new Point(0,2),
InBlock.gif
InBlock.gif                                         
new Point(2,0),
InBlock.gif                                         
new Point(size.Width-2,0),
InBlock.gif
InBlock.gif                                         
new Point(size.Width,2),
InBlock.gif                                         
new Point(size.Width,size.Height-2),
InBlock.gif
InBlock.gif                                         
new Point(size.Width-2,size.Height),
InBlock.gif                                         
new Point(2,size.Height),
InBlock.gif
InBlock.gif                                         
new Point(0,size.Height-2),
InBlock.gif                                         
new Point(0,2)
ExpandedSubBlockEnd.gif                                     }
);
InBlock.gif            
return new Region(gp);
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

然后创建牌基类(Card)

ExpandedBlockStart.gif ContractedBlock.gif      /**/ /// <summary>
InBlock.gif    
/// 牌的基类
ExpandedBlockEnd.gif    
/// </summary>

None.gif      public   abstract   class  Card:PictureBox
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
protected int cardFaceImageIndex;
InBlock.gif        
protected int cardBackImageIndex;
InBlock.gif        
protected bool isFace=true;
InBlock.gif        
protected int index=0;
InBlock.gif        
private CardCollections cardsGroup;
InBlock.gif        
InBlock.gif        
protected Card():base()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
base.BackColor=Color.Transparent;
InBlock.gif            
base.Size=Cards.CardImageSize;
InBlock.gif            
base.Region=Cards.GetCardRegion(base.Size);
InBlock.gif            
base.SizeMode=PictureBoxSizeMode.AutoSize;
InBlock.gif            
base.Location=new Point(-1,-1);
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 所属的牌列表
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public CardCollections CardsGroup
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return cardsGroup;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                cardsGroup
=value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 所在牌列表的索引
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public int Index
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return index;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                index
=value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 是否显示的是牌的正面
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public bool IsFace
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return isFace;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 牌正面的图像列表索引
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public int CardFaceImageIndex
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return cardFaceImageIndex;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 牌背面的图像列表索引
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public int CardBackImageIndex
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
get
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
return cardBackImageIndex;
ExpandedSubBlockEnd.gif            }

InBlock.gif            
set
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                cardBackImageIndex
=value;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public Card(int cardFaceImageIndex):this(cardFaceImageIndex,-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
public Card(int cardFaceImageIndex,int cardBackImageIndex):this()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
this.cardFaceImageIndex=cardFaceImageIndex;
InBlock.gif            
this.cardBackImageIndex=cardBackImageIndex;
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 显示正面
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public void ShowFace()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if(cardFaceImageIndex>=0&&cardFaceImageIndex<Cards.CardImages.Length)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
base.Image=Cards.CardImages[cardFaceImageIndex];
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
base.Image=null;
ExpandedSubBlockEnd.gif            }

InBlock.gif            isFace
=true;
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 显示背面
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public void ShowBack()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if(cardBackImageIndex>=0&&cardBackImageIndex<Cards.CardImages.Length)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
base.Image=Cards.CardImages[cardBackImageIndex];
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
base.Image=null;
ExpandedSubBlockEnd.gif            }

InBlock.gif            isFace
=false;
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }


有了基类Card后就可以派生出一般的扑克牌NormalCard以及其他的牌.对于NormalCard我们可以这样来派生:

ExpandedBlockStart.gif ContractedBlock.gif /**/ /// <summary>
InBlock.gif    
/// 普通牌
ExpandedBlockEnd.gif    
/// </summary>

None.gif      public   class  NormalCard:Card
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        
public static int[] CardBackImageIndexSection;
InBlock.gif        
private int faceNum;
InBlock.gif        
private NormalCardFaceType faceType;
InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 牌面数字
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public int FaceNum
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return faceNum;}
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 牌面类型,如:红黑梅方
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public NormalCardFaceType FaceType
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockStart.gifContractedSubBlock.gif            
getdot.gif{return faceType;}
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        
static NormalCard()
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            CardBackImageIndexSection
=new int[12];
InBlock.gif            
for(int i=54;i<=65;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                CardBackImageIndexSection[i
-54]=i;
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
public NormalCard(int cardFaceImageIndex,int cardBackImageIndex):base(cardFaceImageIndex,cardBackImageIndex)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if(base.cardFaceImageIndex<0||base.cardFaceImageIndex>51)base.cardFaceImageIndex=0;
InBlock.gif            
if(base.cardBackImageIndex<54||base.cardBackImageIndex>65)base.cardBackImageIndex=54;
InBlock.gif            
this.faceType=(NormalCardFaceType)(cardFaceImageIndex%4);
InBlock.gif            
this.faceNum=(int)(cardFaceImageIndex-(int)this.faceType)/4+1;
InBlock.gif            ShowBack();
ExpandedSubBlockEnd.gif        }

InBlock.gif        
public NormalCard(int faceNum,NormalCardFaceType faceType,int cardBackImageIndex):this((faceNum-1)*4+(int)faceType,cardBackImageIndex)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
ExpandedSubBlockEnd.gif        }

InBlock.gif        
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// 改变背面图像
InBlock.gif        
/// </summary>
ExpandedSubBlockEnd.gif        
/// <param name="cardBackImageIndex">背面索引</param>

InBlock.gif        public void ChangeBack(int cardBackImageIndex)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
base.cardBackImageIndex=cardBackImageIndex;
InBlock.gif            
if(!isFace)ShowBack();
ExpandedSubBlockEnd.gif        }

InBlock.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>
InBlock.gif        
/// Hearts 红心,Clubs 梅花,Diamonds 方块,Spade=黑桃
ExpandedSubBlockEnd.gif        
/// </summary>

InBlock.gif        public enum NormalCardFaceType:int
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Clubs
=0,
InBlock.gif            Diamonds
=1,
InBlock.gif            Hearts
=2,
InBlock.gif            Spade
=3
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }


还有其他的牌的派生,这里就不介绍了.

            (三)牌列表对象:关于这个概念其实就是,牌所属的区域,比如发牌区,排列区(又称非处理区),以及收集区(又称处理区)如下图:
cardgame2.JPG
这个对象是由CollectionBase继承而来的.在列表对象里我们可以定义拍的正面和方面的排列方式,以及可以接受的牌的性质等,比如在排列区,背面的位置偏移是(0,3),正面是(0,15),可以接受的牌为不同颜色而且牌面数比最上面一张牌小一,诸如此类的定义都将类个对象里完成,在实际的游戏操作过程中,也就是调用此类的一系列方法.

对象建立完成以后,就可以创建一个游戏平台类了,我将它命名为 "GamePlace".

    二,创建游戏平台,
        在此平台中我们将要完成,与用户的交互,洗牌功能,创建并初始化牌列表,以及如何将52张牌分配给各个牌列表区.以上这一些都是些逻辑功能,只要玩过纸牌游戏的人想必都有思路了吧.关于GamePlace的代码有点长,这里就不给出了.

        三,结束语:
              该类游戏的关键主要在于对象的创建,对象创建得合理,那么用起来就方便,我认为这也是对象编程思想的难点吧.这篇文章只提供大家一些思路.我已经完成了这个游戏的开发,也测试过了.

点击此处下载源代码

给新手参考,请高手指教,大家交个朋友~~~~~

我的联系方式:QQ:26387232,email:dotnetbar@gmail.com

posted on 2005-11-04 12:02 volcano 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/volcano/archive/2005/11/04/268711.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值