一个简单的吃豆子游戏

1 篇文章 0 订阅
                                                                               一个简单的吃豆子游戏 (MFC)
      这是我的第一个自己写的小游戏,这其中借鉴了很多网上的思路,也向学长,同学寻求了不少的帮助,能最终完成也是出乎了我的意料,虽然它看起来非常的简单,但从这之中我收获巨大。编程是痛苦的,从来没有一步到位的程序,特别是有时候觉得自己就要到达终点,但突然发现原来自己走偏了,此路不通!难过每当此时就要重新修改,那种感觉相当难受,然而当做完的时候又会有一种巨大的成就感大笑
        下面就具体谈谈我对这个游戏的具体思路及其实现方法
         
        吃豆子游戏的基本构思:
        1.添加控件的消息响应
        2.添加在View类中的消息响应
         (在本次游戏中,主要用到了 WM_KEYDOWN ,WM_RBUTTONDOWN 和WM_TIMER)
        3.利用CView类实现游戏的具体内容
        4.具体实现游戏,包括创建豆子类,嘴类,并实例化(其中豆子实例化为对象数组,因为有多个豆子)以及嘴的图形,撞界判断,吃完食物进行判断等等功能
        5.一定注意一个程序永远不可能一步到位,途中必定会遭遇各种错误,所以建议大家一定要走一步看(运行)一步,否则会死的很惨难过敲打
        
        具体实现方法:
        第一步:创建一个MFC工程(我是用VC++做的微笑,可能版本有点老,不过不要介意大笑
        如图:
       
       选择单文档,然后双击完成
      
      


      第二步:添加必要的Windows响应消息,控件以及类和成员函数
      在已有工程下的 CView类中添加以下Windows响应信息
     1 WM_KEYDOWN
     2 WM_RBUTTONDOWN
     3 WM_TIMER
 

             并且add一个虚函数OnInitialUpdate()    

                      

             这个函数是视图窗口建立后第一个被调用的函数,所以我们用这个函数来实现嘴巴和豆子的初始化。          
             再接下来就是控件的设计了,在Menu文件夹下的IDR_MAINFRAME中可以进行控件的设计。如图:
             

             删除原有的控件后右击“属性”,并分别填写控件名和ID,并选择可否弹出。

             


             其中:

                       游戏开始 IDM_START

                       游戏暂停 IDM_PAUSE
                       游戏继续 IDM_CONTINUE
                       游戏退出 IDM_EXIT                      (也可以改为其他的ID)
    
             

             另外,要在类向导中生成响应函数(同样是右键“建立类向导”):

           

             
             在CView类下COMMAND双击即可生成响应函数。
             最后在CView类中添加一个成员函数oninit()函数

             至此,该添加的都已添加,第二部分告一段落。


          第三步:为各个函数添加代码,实现各种功能


          1.建立豆子类和嘴巴类
          class Mouth
{
public:
int x;
int y;
int len;
int direct;
}mouth;                       //实例化一个嘴巴的对象mouth




class Bean
{
public:
int x;
int y;
int isBean;
}bean[2];                      //实例化一个豆子的对象数组(数组中的每一个元素都是对象)



           2. 紧接着就在OnInitialUpdate()中进行初始化
void CEatView::OnInitialUpdate()        //初始化嘴巴与豆子
{
CView::OnInitialUpdate();
mouth.x=10;
mouth.y=10;
mouth.direct=3;                       //方向
bean[0].isBean=1;                   //豆子有无(1有0无)
bean[1].isBean=1;                   //这里就只创建了两个豆子大笑


// TODO: Add your specialized code here and/or call the base class

}          



          3.画嘴巴和豆子
CEatView::oninit()                 //利用CDC类来画嘴和srand()随机生成豆子
{
CDC *pDC=GetDC();              //用一个指向CDC类的指针去接受与该窗口相关联的DC句柄
        CBrush DrawBrush=(RGB(100,100,100));                //用定义画刷一个DrawBrush对象
        CBrush *Drawbrush=pDC->SelectObject(&DrawBrush);
        pDC->Pie(mouth.x*20,mouth.y*20,(mouth.x+1)*20,(mouth.y+1)*20,mouth.x*20,mouth.y*20,(mouth.x+1)*20,mouth.y*20);       //画嘴
srand((unsigned)time(NULL));             //随机生成豆子
for(int i=0;i<2;i++)
{
bean[i].x=rand()%20+2;
        bean[i].y=rand()%20+2;
}
for(int j=0;j<2;j++)
{
        pDC->Ellipse(bean[j].x*20,bean[j].y*20,(bean[j].x+1)*20,(bean[j].y+1)*20);         //豆子是圆形的
}
        pDC->SelectObject(DrawBrush);

}


          4.实现控件

           void CEatView::OnStart() 
{
// TODO: Add your command handler code here
SetTimer(1,1000,NULL);


    AfxMessageBox("游戏开始");
}


void CEatView::OnPause() 
{
// TODO: Add your command handler code here
KillTimer(1);
    AfxMessageBox("游戏暂停");
}


void CEatView::OnContinue() 
{
// TODO: Add your command handler code here
SetTimer(1,10,NULL);
}


void CEatView::OnExit() 
{
// TODO: Add your command handler code here
AfxMessageBox("退出游戏");
    exit;
}



           5.为OnRButtonDown()添加代码
void CEatView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)            //实现嘴的上下左右移动
{
// TODO: Add your message handler code here and/or call default
switch(nChar)
{
        case VK_UP:mouth.direct=1;break;            //上
        case VK_DOWN:mouth.direct=2;break;     //下
        case VK_LEFT:mouth.direct=3;break;       //左
        case VK_RIGHT:mouth.direct=4;break;     //右
}
    CView::OnKeyDown(nChar, nRepCnt, nFlags);
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}             
              我们利用这个函数来实现键盘(上下左右)对嘴的控制
           6. 为OnDraw()添加代码
               这个函数是用画刷画出背景并且通过调用oninit()函数来画嘴和豆子
void CEatView::OnDraw(CDC* pDC)        //画背景
{
CEatDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
CBrush backBrush(RGB(100,100,0));
        CBrush* pOldBrush = pDC->SelectObject(&backBrush);
        CRect rect;
        pDC->GetClipBox(&rect);       //得到一个能够完包含当前可见区域的最小矩形的大小
        pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),PATCOPY);
        pDC->SelectObject(pOldBrush);
        pDC->Rectangle(19,19,501,501);
        oninit();
// TODO: add draw code for native data here
}


         7.实现OnTime()的代码(这是最后一步,也是最难的一步大笑
void CEatView::OnTimer(UINT nIDEvent) 
{
// TODO: Add your message handler code here and/or call default
CDC *pDC=GetDC();
    //撞界判断
    if(mouth.x*20<=37||mouth.y*20<=37||mouth.x*20>=462||mouth.y*20>=462)
{
        KillTimer(1);
        AfxMessageBox("游戏结束");              //??????
        // s=0;
}

pDC->SelectStockObject(WHITE_PEN);                                         //重绘
pDC->Rectangle(mouth.x*20,mouth.y*20,(mouth.x+1)*20,(mouth.y+1)*20);       //用白笔擦除




    //判断行走方向,并重绘
    if(mouth.direct==1)            //上
{
mouth.y--; 
        pDC->SelectStockObject(BLACK_PEN);
        CBrush DrawBrush=(RGB(100,100,100));
        CBrush *Drawbrush=pDC->SelectObject(&DrawBrush);
        pDC->Pie(mouth.x*20,mouth.y*20,(mouth.x+1)*20,(mouth.y+1)*20,mouth.x*20,mouth.y*20,(mouth.x+1)*20,mouth.y*20);
        pDC->SelectObject(DrawBrush);
}
    if(mouth.direct==2)              //下
{
mouth.y++;
pDC->SelectStockObject(BLACK_PEN);
        CBrush DrawBrush=(RGB(100,100,100));
        CBrush *Drawbrush=pDC->SelectObject(&DrawBrush);
        pDC->Pie(mouth.x*20,mouth.y*20,(mouth.x+1)*20,(mouth.y+1)*20,(mouth.x+1)*20,(mouth.y+1)*20,mouth.x*20,(mouth.y+1)*20);
        pDC->SelectObject(DrawBrush);

    if(mouth.direct==3)            //左
{
mouth.x--;  
pDC->SelectStockObject(BLACK_PEN);
        CBrush DrawBrush=(RGB(100,100,100));
        CBrush *Drawbrush=pDC->SelectObject(&DrawBrush);
        pDC->Pie(mouth.x*20,mouth.y*20,(mouth.x+1)*20,(mouth.y+1)*20,mouth.x*20,(mouth.y+1)*20,mouth.x*20,mouth.y*20);
        pDC->SelectObject(DrawBrush);
}
    if(mouth.direct==4)              //右
{
mouth.x++;
pDC->SelectStockObject(BLACK_PEN);
        CBrush DrawBrush=(RGB(100,100,100));
        CBrush *Drawbrush=pDC->SelectObject(&DrawBrush);
        pDC->Pie(mouth.x*20,mouth.y*20,(mouth.x+1)*20,(mouth.y+1)*20,(mouth.x+1)*20,mouth.y*20,(mouth.x+1)*20,(mouth.y+1)*20);
        pDC->SelectObject(DrawBrush);
}




if(mouth.x*20==bean[0].x*20&&mouth.y*20==bean[0].y*20)
{
bean[0].isBean=0;
}
    if(mouth.x*20==bean[1].x*20&&mouth.y*20==bean[1].y*20)
{
bean[1].isBean=0;
}
    //食物吃完后结束游戏并给出成绩
if((bean[0].isBean==0)&&(bean[1].isBean==0))
{
KillTimer(1);
        AfxMessageBox("游戏结束");
}
CView::OnTimer(nIDEvent);

}


          这是游戏运行图(太简单了,有点不好意思敲打


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值