网页功能: 加入收藏 设为首页 网站搜索  
用VC作的一个扑克游戏
发表日期:2004-09-18作者:肖战龙[转贴] 出处:  

近来和女朋友去打电玩发现了一个很好玩的游戏。规划是用电脑发给你的牌放在屏幕的空白处尽量使它们的和为21每个空白处可入5张牌。由于近来在学习游戏制作,感到这个游戏容易实现。回家后用有VC作了起。用程序来作扑克游戏的难点在于如何确定扑克的面值和花色。在本程序中我是把每个扑克的图像按顺序排列并加以编号,扑克的花色同样也加以编号。并用一个公式计算编号大于13的扑克图像的面值公式如下:扑克图像的编号-13*扑克花色的编号就可以得出该扑克图像编号的扑克的面值。例如扑克图像编号为15,花色的编号为1用公式15-13*1得出该扑克图像编号的扑克的面值是红桃2。

现将实现过程写出以。

用VC建立一个Win32 Application工程。在工程中加入stdafx.h文件在其中加入#include<afxwin.h>和
#include<math.h>。在工程加入资源文件。使用Alt+F7调出设置对话框。在General下的Microsoft Foundation Classes选择use MFX inaStatic Libarary。为工程建立一个窗口类。在窗口类的头文件中把构造函数声明修改为public,例如:protected: cbruceFrame()改为public:cbruceFrame()。在窗口类的头文件中定义变量:

CDC *mdc,*bgmdc;
CBitmap *bitmap,*bgmap;
RECT rect;
CFont newf,*oldf;
自定义一个函数:

void fp();
为工程定义全局数组变量:

struct pk //扑克基本信息
{
  int pkbmp;
  int h;
  int f;
}pkdata[52];

其中pkbmp用来存放扑克图像编号,h用来保存扑克的花色编码、f用来保存此扑克是否也发出过。
其中扑克图像编号从1--52,扑克花色编码黑为0;红桃为1;梅花为2;方块为3。

struct pkno
{
  int pkbmpo;
  int ho;
}a[5],b[5],c[5],d[5];
为工程定义全局变量:

int an=0,bn=0,cn=0,dn=0,ao=0,bo=0,co=0,ddo=0,j,m=3;

其中后加n的为各块的计数器,后加o的为各块的计分数,j为暂存变量,m为pass的次数。

定义两个字符数组:

f[255],cs[255];

在构造函数中加入下面程序代码:(cbruceFrame.cpp中)

int i;
Create(NULL,"扑克游戏");
CClientDC dc(this);
int width=dc.GetDeviceCaps(HORZRES);  //取得屏幕区宽
int height=dc.GetDeviceCaps(VERTRES);  //取得屏幕区高
GetWindowRect(&rect);      //取得窗口区矩形大小
width=(width-(rect.right-rect.left))/2;
height=(height-(rect.bottom-rect.top))/2;
MoveWindow(width,height,500,450,true);
bgmdc=new CDC;
mdc=new CDC;        //建立内存DC对象
bgmap=new CBitmap;
ffor(i=1;i<53;i++)    
{
  pkdata[i-1].pkbmp=i;
  if((i-1)<13)
    pkdata[i-1].h=0;//根据扑克图像编号设置扑克的花色编码
  if((i-1)>=13&&(i-1)<26)
    pkdata[i-1].h=1;
  if((i-1)>=26&&(i-1)<39)
    pkdata[i-1].h=2;
  if((i-1)>=39&&(i-1)<52)
    pkdata[i-1].h=3;
  pkdata[i-1].f=0;
}//将标志设为没有发出

bgmdc->CreateCompatibleDC(&dc);
mdc->CreateCompatibleDC(&dc);    //转换成与dc相容的DC
bgmap->LoadBitmap(BG);
bgmdc->SelectObject(bgmap);
newf.CreateFont(20,10,0,0,0,FALSE,FALSE,FALSE,DEFAULT_CHARSET,OUT_CHARACTER_PRECIS,   
    CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,FIXED_PITCH|FF_MODERN,"楷体"); /设置字体
CPoint *p=new CPoint(50,35);
ClientToScreen(p);
::SetCursorPos(p->x,p->y);            //设置鼠标的范围
srand((unsigned)time(NULL));       //发牌
t=rand()%52;
bitmap=new CBitmap;
bitmap->LoadBitmap(pkdata[t].pkbmp);
mdc->SelectObject(bitmap);
dc.BitBlt(10,10,100,100,mdc,0,0,SRCCOPY);
pkdata[t].f=1;
j=(t+1);
for(i=0;i<5;i++)
{
  a[i].pkbmpo=c[i].pkbmpo=b[i].pkbmpo=d[i].pkbmpo=0;
}
使用插入---->新建类建立应用程序类,在Class type对话框中选择Generic Class在Name中输入类名(cbruceApp)在Base class(es)中的Derived From中输入CWinApp。在cbruceApp.h文件中加入程序初始函数的声明:

public:BOOL Initinstance();
在cbruceApp.cpp文件中加入如下代码:

cbruceApp bruce;
CBruceApp::InitInstance()
{
  m_pMainWnd= new CBruceFrame; 
  m_pMainWnd->ShowWindow(m_nCmdShow);
  m_pMainWnd->UpdateWindow();
  return true;
}
这样工程的框架就组建完成了。下一步加入具体代码。

为工程加入WM_PAINT消息实现绘图:

oldf=dc.SelectObject(&newf);                     //选择新新字体。
dc.SetTextColor(RGB(0,255,0));      //设置文本颜色
dc.SetBkColor(1);        //设置背景颜色
GetClientRect(&rect);
dc.BitBlt(0,0,rect.right,rect.bottom,bgmdc,0,0,SRCCOPY);//载入背景图
dc.BitBlt(10,10,100,100,mdc,0,0,SRCCOPY);  //载入扑克图像
dc.BitBlt(10,190,110,190,bgmdc,0,0,WHITENESS); //绘制空白处
dc.BitBlt(130,190,110,190,bgmdc,0,0,WHITENESS);
dc.BitBlt(250,190,110,190,bgmdc,0,0,WHITENESS);
dc.BitBlt(370,190,110,190,bgmdc,0,0,WHITENESS);
if(an>0)
{
  int i;     
      for(i=0;i<=an;i++)
  {
      if(a[i].pkbmpo!=0)
      {
    bitmap=new CBitmap;
    bitmap->LoadBitmap(a[i].pkbmpo);
    mdc->SelectObject(bitmap);
    dc.BitBlt(15,195+i*20,100,100,mdc,0,0,SRCCOPY);
      }
  }
  if(ao==21)
    {
      dc.TextOut(5,150,"恭喜您赢了!");
          
    }
    if(ao>21)
    {
      dc.TextOut(5,150,"已超出21分!");
           
    }
    if(ao<21)
    {
      sprintf(f,"数分为:%d",ao);
          dc.TextOut(5,150,f);
    }
       
   
}
  if(bn>0)
{
  int i;
  for(i=0;i<=bn;i++)
  {   if(b[i].pkbmpo!=0)
     {
    bitmap=new CBitmap;
    bitmap->LoadBitmap(b[i].pkbmpo);
    mdc->SelectObject(bitmap);
    dc.BitBlt(135,195+i*20,100,100,mdc,0,0,SRCCOPY);
    }
  }
  if(bo==21)
    {
      dc.TextOut(135,150,"恭喜您赢了!");
          
    }
    if(bo>21)
    {
      dc.TextOut(135,150,"已超出21分!");
           
    }
    if(bo<21)
    {
      sprintf(f,"数分为:%d",bo);
          dc.TextOut(135,150,f);
    }
}
  if(cn>0)
{
  int i;
  for(i=0;i<=cn;i++)
  {
    if(c[i].pkbmpo!=0)
    {
    bitmap=new CBitmap;
    bitmap->LoadBitmap(c[i].pkbmpo);
    mdc->SelectObject(bitmap);
    dc.BitBlt(255,195+i*20,100,100,mdc,0,0,SRCCOPY);
    }
  }
  if(co==21)
    {
      dc.TextOut(255,150,"恭喜您赢了!");
     
     
    }
    if(co>21)
    {
      dc.TextOut(255,150,"已超出21分!");
     
     
    }
    if(co<21)
    {
      sprintf(f,"数分为:%d",co);
          dc.TextOut(255,150,f);
    }
}
  if(dn>0)
{
  int i;
  for(i=0;i<=dn;i++)
  {
    if(d[i].pkbmpo!=0)
    {
    bitmap=new CBitmap;
    bitmap->LoadBitmap(d[i].pkbmpo);
    mdc->SelectObject(bitmap);
    dc.BitBlt(375,195+i*20,100,100,mdc,0,0,SRCCOPY);
    }
  }
   if(ddo==21)
    {
      dc.TextOut(375,150,"恭喜您赢了!");
     
           
    }
    if(ddo>21)
    {
      dc.TextOut(375,150,"已超出21分!");
     
           
    }
    if(ddo<21)
    {
      sprintf(f,"数分为:%d",ddo);
          dc.TextOut(375,150,f);
     
    }
}
dc.TextOut(150,50,"F2重新开始游戏!");
sprintf(cs,"右键PASS当前牌:%d",m);
dc.TextOut(150,100,cs);
dc.SelectObject(oldf);
为工程加入WM_LBUTTONDOWN消息:

CClientDC dc(this);    //建立客户区DC
int zn;        //用来存放坐标
oldf=dc.SelectObject(&newf);
dc.SetTextColor(RGB(0,255,0));
dc.SetBkColor(1);
zn=(int)floor(point.x/10);         //计算作标值
if(zn<=11)                         //在第一个空白处
{
  if((ao<21)&&(an<5))
  {
    bitmap=new CBitmap;         //加载扑克图像
    bitmap->LoadBitmap(pkdata[t].pkbmp);
    dc.BitBlt(15,195+an*20,100,100,mdc,0,0,SRCCOPY);
    a[an].pkbmpo=j;      //扑克面值
    ao=j-(13*pkdata[t].h))+ao;   //计算分数
    if(ao==21)                 
    {
      dc.TextOut(5,150,"恭喜您赢了!");
           
    }
    if(ao>21)
    {
      dc.TextOut(5,150,"已超出21分!");
           
    }
    if(ao<21)
    {  
   
      sprintf(f,"数分为:%d",ao);
      dc.TextOut(5,150,f);
      an++;
    }
    fp();
  }
  else
  {
    Beep(150,100);   //错误报警
  }
}

if(zn>11&&zn<=23)
{
  if((bo<21)&&(bn<5))
  {
    bitmap=new CBitmap;
    bitmap->LoadBitmap(pkdata[t].pkbmp);
    mdc->SelectObject(bitmap);
    dc.BitBlt(135,195+bn*20,100,100,mdc,0,0,SRCCOPY);
    b[bn].pkbmpo=j;
    bo=j-(13*pkdata[t].h))+bo;
    if(bo==21)
    {
      dc.TextOut(135,150,"恭喜您赢了!");
          
    }
    if(bo>21)
    {
      dc.TextOut(135,150,"已超出21分!");
           
    }
    if(bo<21)
    {
     
      sprintf(f,"数分为:%d",bo);
                  dc.TextOut(135,150,f);
      bn++;
   
    }
    fp();
  }
  else
  {
    Beep(150,100);
  }
}

if(zn>23&&zn<=35)
{
  if((co<21)&&(cn<5))
  {
    bitmap=new CBitmap;
    bitmap->LoadBitmap(pkdata[t].pkbmp);
    dc.BitBlt(255,195+cn*20,100,100,mdc,0,0,SRCCOPY);
    c[cn].pkbmpo=j;
    co=j-(13*pkdata[t].h))+co;
    if(co==21)
    {
      dc.TextOut(255,150,"恭喜您赢了!");
          
    }
    if(co>21)
    {
      dc.TextOut(255,150,"已超出21分!");
         
    }
    if(co<21)
    {
      
      sprintf(f,"数分为:%d",co);
      dc.TextOut(255,150,f);
      cn++;
     
    }
    fp();
  }
  else
  {
    Beep(150,100);
  }

}

if(zn>35&&zn<=47)
{
  if((ddo<21)&&(dn<5))
  {
    bitmap=new CBitmap;
    bitmap->LoadBitmap(pkdata[t].pkbmp);
    mdc->SelectObject(bitmap);
    dc.BitBlt(375,195+dn*20,100,100,mdc,0,0,SRCCOPY);
    d[dn].pkbmpo=j;
    ddo=j-(13*pkdata[t].h)+ddo;
    if(ddo==21)
    {
      dc.TextOut(375,150,"恭喜您赢了!");
           
    }
    if(ddo>21)
    {
      dc.TextOut(375,150,"已超出21分!");
           
    }
    if(ddo<21)
    {
      
      sprintf(f,"数分为:%d",ddo);
      dc.TextOut(375,150,f);
      dn++;
     
    }
    fp();
  }
  else
  {
    Beep(150,100);
  }
}
为工程加入WM_KEYDOWN消息:

CClientDC dc(this);
int i;
if(nChar==VK_F2)    //当玩家按下F2键时,重新开始游戏。使之复位。
{
  oldf=dc.SelectObject(&newf);
  dc.SetTextColor(RGB(0,255,0));
  dc.SetBkColor(1);
  GetClientRect(&rect);
  dc.BitBlt(0,0,rect.right,rect.bottom,bgmdc,0,0,SRCCOPY);
  dc.BitBlt(10,10,100,100,mdc,0,0,SRCCOPY);
  dc.BitBlt(10,190,110,190,bgmdc,0,0,WHITENESS);
  dc.BitBlt(130,190,110,190,bgmdc,0,0,WHITENESS);
  dc.BitBlt(250,190,110,190,bgmdc,0,0,WHITENESS);
  dc.BitBlt(370,190,110,190,bgmdc,0,0,WHITENESS);
  an=bn=cn=dn=0;
  ao=bo=co=ddo=0;
  for(i=0;i<52;i++)
  {
    pkdata[i].f=0;
  }
  srand((unsigned)time(NULL));      //发牌
  t=rand()%52;
  bitmap=new CBitmap;
  bitmap->LoadBitmap(pkdata[t].pkbmp);
  mdc->SelectObject(bitmap);
  dc.BitBlt(10,10,100,100,mdc,0,0,SRCCOPY);
  pkdata[t].f=1;
  j=(t+1);
  m=3;
  dc.TextOut(150,50,"F2重新开始游戏!");
  sprintf(cs,"右键PASS当前牌:%d",m);
  dc.TextOut(150,100,cs);
  for(i=0;i<5;i++)
  {
    a[i].pkbmpo=c[i].pkbmpo=b[i].pkbmpo=d[i].pkbmpo=0;
  }
}
dc.SelectObject(oldf);
为工程加入WM_RBUTTONDOWN消息(PASS当前牌):

CClientDC dc(this);
oldf=dc.SelectObject(&newf);
dc.SetTextColor(RGB(0,255,0));
dc.SetBkColor(1);
if(m>0)
{
  fp();
  m--;
  sprintf(cs,"右键PASS当前牌:%d",m);
  dc.TextOut(150,100,cs);
}
else
{
  Beep(150,100);
}
dc.SelectObject(oldf);
编辑fp函数(发牌):

CClientDC dc(this);
srand((unsigned)time(NULL));

loop1: t=rand()%52;
if(pkdata[t].f!=1)
{
  bitmap=new CBitmap;
  bitmap->LoadBitmap(pkdata[t].pkbmp);
  mdc->SelectObject(bitmap);
  dc.BitBlt(10,10,100,100,mdc,0,0,SRCCOPY);
  pkdata[t].f=1;
  j=(t+1);
}
else
{
  goto loop1;
}
这样一个小的扑克游戏就成完。我不并不是什么名校毕业的。也没有上过大学。只是自己非常喜欢编程,一切都是自学的。所以有错误的地方请大家指出。最后我想说句话:兴趣是你最好的老师,没有兴趣你是学不好一样东西。编程并没有什么难,只要努力你也能编出好的程序来的。
本程序在Windows 2000+VC6.0中编译通过。

 

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 用VC作的一个扑克游戏
本类热点文章
  C++新手必问之头文件
  C++新手必问之头文件
  基于VFW的视频应用程序开发
  VC入门宝典
  VC入门宝典
  Visual C++ 入门精解
  送给正在学习C++朋友的50条建议
  用c++实现的"贪吃蛇"游戏源码
  VC常用数据类型使用转换详解
  对VC的批判,我要打击大家学VC的积极性了
  对VC的批判,我要打击大家学VC的积极性了
  用Debug函数实现API函数的跟踪
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00389