好久没上BLOG了,上学期期末课程设计我做了一个大鱼吃小鱼的小程序,只是实现了基本的操作。现在把主要的代码发上来,大家给我指点指点。
// FishTestView.h
class CFishTestView : public CView
{
protected: // create from serialization only
CFishTestView();
DECLARE_DYNCREATE(CFishTestView)
// Attributes
public:
CFishTestDoc* GetDocument();
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CFishTestView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CFishTestView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
//{{AFX_MSG(CFishTestView)
afx_msg void OnPaint();
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
afx_msg void OnStart();
afx_msg void OnStop();
afx_msg void OnMouse();
afx_msg void OnKeyboard();
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
BOOL m_bMouseControl;
int m_iPoint; //得分
BOOL m_bBegin; //代表是否读入开始背景图
BOOL m_bEat; //代表Fish是否在吃
int m_iDirFish; //代表Fish的方向
BOOL m_bEat_john; //代表JohnDory是否被吃
BOOL m_bEat_angel; //代表Angel是否被吃
void EatCheck(); //检查是否有鱼被吃
CPoint pt_john; //JohnDory当前的位置
int m_index_john; //JohnDory当前读入的位图序号
int m_index_angel; //Angel当前读入的位图序号
CPoint pt_angel; //Angel的当前位置
CPoint pt_Oldfish; //保存Fish当前位置
CPoint pt_fish; //Fish的下一个位置
int m_index_fish; //Fish当前读入的位图序号
CBitmap bitmap; //背景图
};
// FishTestView.cpp
#include "stdafx.h"
#include "FishTest.h"
#include "FishTestDoc.h"
#include "FishTestView.h"
#include "mmsystem.h"
#include <cmath>
#pragma comment(lib,"winmm.lib")
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/
// CFishTestView
IMPLEMENT_DYNCREATE(CFishTestView, CView)
BEGIN_MESSAGE_MAP(CFishTestView, CView)
//{{AFX_MSG_MAP(CFishTestView)
ON_WM_PAINT()
ON_WM_TIMER()
ON_WM_MOUSEMOVE()
ON_COMMAND(ID_MENUITEM32775, OnStart)
ON_COMMAND(ID_MENUITEM32776, OnStop)
ON_COMMAND(ID_MOUSE, OnMouse)
ON_COMMAND(ID_KEYBOARD, OnKeyboard)
ON_COMMAND(ID_START, OnStart)
ON_COMMAND(ID_STOP, OnStop)
ON_WM_KEYDOWN()
//}}AFX_MSG_MAP
// Standard printing commands
ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
END_MESSAGE_MAP()
/
// CFishTestView construction/destruction
CFishTestView::CFishTestView()
{
// TODO: add construction code here
bitmap.LoadBitmap(IDB_BACKGROUND); //读入背景图
m_iPoint=0;
pt_fish.x=0;
pt_fish.y=0;
pt_Oldfish.x=0;
pt_Oldfish.y=0;
pt_angel.x=790;
pt_angel.y=70;
pt_john.x=850;
pt_john.y=300;
m_index_fish=0;
m_index_angel=0;
m_index_john=0;
m_bMouseControl=TRUE;
m_bBegin=TRUE;
m_bEat=FALSE;
m_bEat_angel=FALSE;
m_bEat_john=FALSE;
m_iDirFish=1;
srand((unsigned)time(NULL));
sndPlaySound("menuMusic.wav",SND_ASYNC | SND_LOOP);
}
CFishTestView::~CFishTestView()
{
}
BOOL CFishTestView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/
// CFishTestView drawing
void CFishTestView::OnDraw(CDC* pDC)
{
CFishTestDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
}
/
// CFishTestView printing
BOOL CFishTestView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CFishTestView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CFishTestView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/
// CFishTestView diagnostics
#ifdef _DEBUG
void CFishTestView::AssertValid() const
{
CView::AssertValid();
}
void CFishTestView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CFishTestDoc* CFishTestView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CFishTestDoc)));
return (CFishTestDoc*)m_pDocument;
}
#endif //_DEBUG
/
// CFishTestView message handlers
void CFishTestView::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
CBitmap *pOldbmp;
CDC memDC;
CRect rect;
GetClientRect(&rect);
memDC.CreateCompatibleDC(&dc);
if(m_bBegin)//如果游戏没有开始,读入开始背景图
{
bitmap.DeleteObject();
bitmap.LoadBitmap(IDB_BEGIN);
}
//将背景图和标题图选入设备环境
pOldbmp = memDC.SelectObject(&bitmap);
dc.BitBlt(0,0,rect.right,rect.bottom,&memDC,0,0,SRCCOPY); //贴图
//恢复设备环境
memDC.SelectObject(pOldbmp);
if(m_bBegin)
{
bitmap.DeleteObject();
bitmap.LoadBitmap(IDB_BACKGROUND); //恢复游戏背景图
}
// Do not call CView::OnPaint() for painting messages
}
void CFishTestView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
CDC *pDC;// 目标DC
CDC MemDC; //缓冲DC
CDC pActiveDC;// 装载位图Fish的DC
CDC pMaskDC;// 装有掩码位图FishMask的DC
CDC pBackDC; //装载背景图的DC
CDC pAngelDC,pAngelMaskDC; //Angel的位图和掩码位图的DC
CDC pJohnDC,pJohnMaskDC; //JohnDory的位图和掩码位图的DC
CBitmap MemBitmap; //缓冲位图
CBitmap bmpfish,bmpMask;// MaskDC上使用的位图
CBitmap bmpAngel,bmpAngelMask; //AngelDC上使用的位图
CBitmap bmpJohn,bmpJohnMask; //JohnDC上使用的位图
BITMAP bmpinfo,bmpAngelinfo,bmpJohninfo,bmpBackinfo; //位图的大小信息
CRect rect; //用户区的大小
CBitmap *pOldbackground,*pOldbmp,*pOldbmpMask;
CBitmap *pOldAngel,*pOldAngelMask;
CBitmap *pOldJohn,*pOldJohnMask;
//取得用户区的区域范围
GetClientRect(&rect);
pDC=GetDC();
//生成缓冲DC
MemDC.CreateCompatibleDC(NULL);
//生成与背景一样大小的缓冲兼容位图
MemBitmap.CreateCompatibleBitmap(pDC,rect.Width(),rect.Height());
CBitmap *pOldMemBmp=MemDC.SelectObject(&MemBitmap); //将兼容位图选入缓冲DC
//生成兼容DC
pActiveDC.CreateCompatibleDC(pDC);
pMaskDC.CreateCompatibleDC(pDC);
pBackDC.CreateCompatibleDC(pDC);
pAngelDC.CreateCompatibleDC(pDC);
pAngelMaskDC.CreateCompatibleDC(pDC);
pJohnDC.CreateCompatibleDC(pDC);
pJohnMaskDC.CreateCompatibleDC(pDC);
//装载Fish的位图和掩码位图
if(!m_bEat)
{
bmpfish.LoadBitmap(IDB_FISH1+m_index_fish);//按顺序装载鱼游动的位图
bmpfish.GetBitmap(&bmpinfo); //按顺序获取位图的信息
bmpMask.LoadBitmap(IDB_FISHMASK1+m_index_fish);//装载掩码图
}
else
{
bmpfish.LoadBitmap(IDB_FISHEAT1+m_index_fish); //按顺序装载鱼吃的位图
bmpfish.GetBitmap(&bmpinfo);
bmpMask.LoadBitmap(IDB_FISHEATMASK1+m_index_fish);
}
//装载Angel的位图和掩码位图
bmpAngel.LoadBitmap(IDB_ANGELFISH1+m_index_angel);//按顺序装载鱼的位图
bmpAngel.GetBitmap(&bmpAngelinfo); //按顺序获取位图的信息
bmpAngelMask.LoadBitmap(IDB_ANGELFISHMASK1+m_index_angel);
//装载John的位图和掩码位图
bmpJohn.LoadBitmap(IDB_JOHNDORY1+m_index_john); //按顺序装载位图
bmpJohn.GetBitmap(&bmpJohninfo); //获得位图信息
bmpJohnMask.LoadBitmap(IDB_JOHNDORYMASK1+m_index_john); //按顺序装载掩码位图
//将Fish和背景位图选入设备环境
pOldbackground=pBackDC.SelectObject(&bitmap);
pOldbmp=pActiveDC.SelectObject(&bmpfish);
pOldbmpMask=pMaskDC.SelectObject(&bmpMask);
//将Angel位图选入设备环境
pOldAngel=pAngelDC.SelectObject(&bmpAngel);
pOldAngelMask=pAngelMaskDC.SelectObject(&bmpAngelMask);
//将JohnDory位图选入设备环境
pOldJohn=pJohnDC.SelectObject(&bmpJohn);
pOldJohnMask=pJohnMaskDC.SelectObject(&bmpJohnMask);
//刷新背景
bitmap.GetBitmap(&bmpBackinfo);
MemDC.BitBlt(0,0,bmpBackinfo.bmWidth,bmpBackinfo.bmHeight,
&pBackDC,0,0,SRCCOPY);
// set the mask
pAngelMaskDC.BitBlt(0,0,bmpAngelinfo.bmWidth,bmpAngelinfo.bmHeight,&pAngelMaskDC,
0,0,NOTSRCCOPY);
pJohnMaskDC.BitBlt(0,0,bmpJohninfo.bmWidth,bmpJohninfo.bmHeight,&pJohnMaskDC,
0,0,NOTSRCCOPY);
//设置Angel的新位置
if(pt_angel.x>rect.left-150)
pt_angel.x-=10;
else
{
pt_angel.x=790;
pt_angel.y=rand()%(rect.bottom-bmpAngelinfo.bmHeight); //随机生成y坐标
}
//设置JohnDory的新位置
if(pt_john.x>rect.left-150)
pt_john.x-=20;
else
{
pt_john.x=850;
pt_john.y=rand()%(rect.bottom-bmpJohninfo.bmHeight); //随机生成y坐标
}
//Do the painting
//Angel
MemDC.BitBlt(pt_angel.x,pt_angel.y,bmpAngelinfo.bmWidth,bmpAngelinfo.bmHeight,
&pAngelDC,0,0,SRCINVERT);
MemDC.BitBlt(pt_angel.x,pt_angel.y,bmpAngelinfo.bmWidth,bmpAngelinfo.bmHeight,
&pAngelMaskDC,0,0,SRCAND);
MemDC.BitBlt(pt_angel.x,pt_angel.y,bmpAngelinfo.bmWidth,bmpAngelinfo.bmHeight,
&pAngelDC,0,0,SRCINVERT);
//JohnDory
MemDC.BitBlt(pt_john.x,pt_john.y,bmpJohninfo.bmWidth,bmpJohninfo.bmHeight,
&pJohnDC,0,0,SRCINVERT);
MemDC.BitBlt(pt_john.x,pt_john.y,bmpJohninfo.bmWidth,bmpJohninfo.bmHeight,
&pJohnMaskDC,0,0,SRCAND);
MemDC.BitBlt(pt_john.x,pt_john.y,bmpJohninfo.bmWidth,bmpJohninfo.bmHeight,
&pJohnDC,0,0,SRCINVERT);
//Fish
if(m_iDirFish==1)
{//鱼的方向向左
pMaskDC.BitBlt(0,0,bmpinfo.bmWidth,bmpinfo.bmHeight,&pMaskDC,
0,0,NOTSRCCOPY);
MemDC.BitBlt(pt_fish.x,pt_fish.y,bmpinfo.bmWidth,bmpinfo.bmHeight,
&pActiveDC,0,0,SRCINVERT);
MemDC.BitBlt(pt_fish.x,pt_fish.y,bmpinfo.bmWidth,bmpinfo.bmHeight,
&pMaskDC,0,0,SRCAND);
MemDC.BitBlt(pt_fish.x,pt_fish.y,bmpinfo.bmWidth,bmpinfo.bmHeight,
&pActiveDC,0,0,SRCINVERT);
}
else
{//鱼的方向向右
pMaskDC.StretchBlt(0,0,bmpinfo.bmWidth,bmpinfo.bmHeight,&pMaskDC,
bmpinfo.bmWidth,0,-bmpinfo.bmWidth,bmpinfo.bmHeight,NOTSRCCOPY);
MemDC.StretchBlt(pt_fish.x,pt_fish.y,bmpinfo.bmWidth,bmpinfo.bmHeight,
&pActiveDC,bmpinfo.bmWidth,0,-bmpinfo.bmWidth,
bmpinfo.bmHeight,SRCINVERT);
MemDC.BitBlt(pt_fish.x,pt_fish.y,bmpinfo.bmWidth,bmpinfo.bmHeight,
&pMaskDC,0,0,SRCAND);
MemDC.StretchBlt(pt_fish.x,pt_fish.y,bmpinfo.bmWidth,bmpinfo.bmHeight,
&pActiveDC,bmpinfo.bmWidth,0,-bmpinfo.bmWidth,
bmpinfo.bmHeight,SRCINVERT);
}
//判断是否有鱼被Fish吃掉
EatCheck();
if(m_bEat_angel)
{//angel被fish吃掉
sndPlaySound("playereat.wav",SND_ASYNC);
m_iPoint+=10;
pt_angel.x=1000;
pt_angel.y=rand()%(rect.bottom-bmpAngelinfo.bmHeight); //随机生成y坐标
m_bEat=TRUE;
m_index_fish=0;
m_bEat_angel=FALSE;
// sndPlaySound("menuMusic.wav",SND_ASYNC | SND_LOOP);
}
if(m_bEat_john)
{ //johndory被fish吃掉
sndPlaySound("playereat.wav",SND_ASYNC);
m_iPoint+=20;
pt_john.x=900;
pt_john.y=rand()%(rect.bottom-bmpJohninfo.bmHeight); //随机生成y坐标
m_bEat=TRUE;
m_index_fish=0;
m_bEat_john=FALSE;
// sndPlaySound("menuMusic.wav",SND_ASYNC | SND_LOOP);
}
//恢复设备环境,释放DC
pBackDC.SelectObject(pOldbackground);
pActiveDC.SelectObject(pOldbmp);
pMaskDC.SelectObject(pOldbmpMask);
pAngelDC.SelectObject(pOldAngel);
pAngelMaskDC.SelectObject(pOldAngelMask);
pJohnDC.SelectObject(pOldJohn);
pJohnMaskDC.SelectObject(pOldJohnMask);
pt_Oldfish=pt_fish; //保存fish的旧位置
//设置下一次读入的图的序号
if(!m_bEat)
m_index_fish=(m_index_fish+1)%15;
else if(m_bEat&&(m_index_fish<5))
m_index_fish++;
else
{
m_index_fish=0;
m_bEat=FALSE;
}
//显示得分
char str[10];
//定义字体
CFont font;
font.CreatePointFont(200,"MyFont");
itoa(m_iPoint,str,10);
MemDC.SetBkMode(TRANSPARENT);
MemDC.SelectObject(&font);
MemDC.SetTextColor(RGB(255,0,0));
MemDC.TextOut(10,10,str,strlen(str));
//将缓冲DC中的图像显示到屏幕上
pDC->BitBlt(0,0,rect.Width(),rect.Height(),&MemDC,0,0,SRCCOPY);
m_index_angel=(m_index_angel+1)%9;
m_index_john=(m_index_john+1)%9;
//清理缓冲DC和兼容位图
MemBitmap.DeleteObject();
MemDC.DeleteDC();
ReleaseDC(pDC);
CView::OnTimer(nIDEvent);
}
void CFishTestView::OnMouseMove(UINT nFlags, CPoint point)
{
// TODO: Add your message handler code here and/or call default
if(m_bMouseControl==TRUE)
{
if(pt_fish.x+100<point.x)
m_iDirFish=-1;//设置fish游动的方向
else
m_iDirFish=1;
pt_fish.x=point.x-100; //鼠标在fish的中间
pt_fish.y=point.y-100;
}
CView::OnMouseMove(nFlags, point);
}
void CFishTestView::EatCheck()//检查是否有鱼被吃
{
CBitmap bmpfish,bmpangel,bmpjohn;
BITMAP bmpfishinfo,bmpangelinfo,bmpjohninfo;
int x1,y1,x2,y2;
//载入三条鱼的位图
bmpfish.LoadBitmap(IDB_FISH1);
bmpangel.LoadBitmap(IDB_ANGELFISH1);
bmpjohn.LoadBitmap(IDB_JOHNDORY1);
//获得三个位图的大小信息
bmpfish.GetBitmap(&bmpfishinfo);
bmpangel.GetBitmap(&bmpangelinfo);
bmpjohn.GetBitmap(&bmpjohninfo);
//判断Fish和Angel的位图是否相交
x1=pt_Oldfish.x+bmpfishinfo.bmWidth/2;
y1=pt_Oldfish.y+bmpfishinfo.bmHeight/2;
x2=pt_angel.x+bmpangelinfo.bmWidth/2;
y2=pt_angel.y+bmpangelinfo.bmHeight/2;
if(sqrt(pow((x1-x2),2)+pow((y1-y2),2))<
((bmpfishinfo.bmWidth+bmpangelinfo.bmWidth)/2-50))
m_bEat_angel=TRUE;
//判断Fish和JohnDory位图是否相交
x2=pt_john.x+bmpjohninfo.bmWidth/2;
y2=pt_john.y+bmpjohninfo.bmHeight/2;
if(sqrt(pow((x1-x2),2)+pow((y1-y2),2))<
((bmpfishinfo.bmWidth+bmpjohninfo.bmWidth)/2-50))
m_bEat_john=TRUE;
}
void CFishTestView::OnStart()
{
// TODO: Add your command handler code here
SetTimer(1,100,NULL); //设置定时器
//将所有变量初始化
pt_fish.x=0;
pt_fish.y=0;
pt_Oldfish.x=0;
pt_Oldfish.y=0;
pt_angel.x=790;
pt_angel.y=70;
pt_john.x=850;
pt_john.y=300;
m_index_fish=0;
m_index_angel=0;
m_index_john=0;
m_bBegin=FALSE;
m_bEat=FALSE;
m_bEat_angel=FALSE;
m_bEat_john=FALSE;
m_iDirFish=1;
sndPlaySound("menuMusic.wav",SND_ASYNC | SND_LOOP);//播放背景音乐
}
void CFishTestView::OnStop()
{
// TODO: Add your command handler code here
KillTimer(1);
CBitmap *pOldbmp;
CDC memDC,*pDC;
CRect rect;
GetClientRect(&rect);//取得用户区大小
pDC=GetDC();
bitmap.DeleteObject();
bitmap.LoadBitmap(IDB_BEGIN);//读入开始游戏背景图
memDC.CreateCompatibleDC(pDC);
//将开始背景图选入设备环境
pOldbmp = memDC.SelectObject(&bitmap);
pDC->BitBlt(0,0,rect.right,rect.bottom,&memDC,0,0,SRCCOPY); //贴图
//恢复设备环境
memDC.SelectObject(pOldbmp);
bitmap.DeleteObject();
bitmap.LoadBitmap(IDB_BACKGROUND);//重新读入游戏背景图
m_bBegin=TRUE;
m_iPoint=0; //分数清零
ReleaseDC(pDC);
}
void CFishTestView::OnMouse()
{
// TODO: Add your command handler code here
m_bMouseControl=TRUE;
}
void CFishTestView::OnKeyboard()
{
// TODO: Add your command handler code here
m_bMouseControl=FALSE;
}
void CFishTestView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
if(m_bMouseControl==FALSE)
{
CRect rect;
GetClientRect(&rect);
switch(nChar)
{
case VK_LEFT:
m_iDirFish=1;
if(pt_fish.x>=5)
pt_fish.x-=10;
break;
case VK_RIGHT:
m_iDirFish=-1;
if(pt_fish.x<=rect.right-80)
pt_fish.x+=10;
break;
case VK_UP:
if(pt_fish.y>=5)
pt_fish.y-=10;
break;
case VK_DOWN:
if(pt_fish.y<=rect.bottom-80)
pt_fish.y+=10;
break;
}
}
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}