HitCheckDemoDlg.cpp
上传用户:sycq158
上传日期:2008-10-22
资源大小:15361k
文件大小:12k
- // HitCheckDemoDlg.cpp : implementation file
- //
- #include "stdafx.h"
- #include "HitCheckDemo.h"
- #include "HitCheckDemoDlg.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CAboutDlg dialog used for App About
- class CAboutDlg : public CDialog
- {
- public:
- CAboutDlg();
- // Dialog Data
- //{{AFX_DATA(CAboutDlg)
- enum { IDD = IDD_ABOUTBOX };
- //}}AFX_DATA
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(CAboutDlg)
- protected:
- virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
- //}}AFX_VIRTUAL
- // Implementation
- protected:
- //{{AFX_MSG(CAboutDlg)
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- };
- CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
- {
- //{{AFX_DATA_INIT(CAboutDlg)
- //}}AFX_DATA_INIT
- }
- void CAboutDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CAboutDlg)
- //}}AFX_DATA_MAP
- }
- BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
- //{{AFX_MSG_MAP(CAboutDlg)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CHitCheckDemoDlg dialog
- LPDIRECTDRAW7 GetDirectDraw()
- {
- return ((CHitCheckDemoDlg*)AfxGetMainWnd())->m_pDD;
- }
- CHitCheckDemoDlg::CHitCheckDemoDlg(CWnd* pParent /*=NULL*/)
- : CDialog(CHitCheckDemoDlg::IDD, pParent)
- {
- //{{AFX_DATA_INIT(CHitCheckDemoDlg)
- // NOTE: the ClassWizard will add member initialization here
- //}}AFX_DATA_INIT
- // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
- m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
- }
- void CHitCheckDemoDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CHitCheckDemoDlg)
- // NOTE: the ClassWizard will add DDX and DDV calls here
- //}}AFX_DATA_MAP
- }
- BEGIN_MESSAGE_MAP(CHitCheckDemoDlg, CDialog)
- //{{AFX_MSG_MAP(CHitCheckDemoDlg)
- ON_WM_SYSCOMMAND()
- ON_WM_PAINT()
- ON_WM_QUERYDRAGICON()
- ON_WM_CLOSE()
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- //画面绘制的线程函数UpdateFrame
- UINT UpdateFrame(LPVOID pVoid)
- {
- BOOL bStop;
- RECT rcRect;
- DDBLTFX ddbltfx;
- ZeroMemory( &ddbltfx, sizeof(ddbltfx) );
- ddbltfx.dwSize = sizeof(ddbltfx);
- ddbltfx.dwFillColor = RGB(0,0,0);
- bStop = FALSE;
- while(!bStop)
- {
- ((CHitCheckDemoDlg*)pVoid)->GetWindowRect(&rcRect);
- bStop = ((CHitCheckDemoDlg*)pVoid)->m_bStop;
- //绘制背景曲面,黑色区域
- ((CHitCheckDemoDlg*)pVoid)->m_pBackBuffer->Blt( NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx );
- //绘制飞船
- ((CHitCheckDemoDlg*)pVoid)->DrawShip();
- //绘制小行星
- ((CHitCheckDemoDlg*)pVoid)->DrawAsteroids();
- //将背景曲面重绘到前景,即刷屏
- ((CHitCheckDemoDlg*)pVoid)->m_pFrontBuffer->Blt( &rcRect, ((CHitCheckDemoDlg*)pVoid)->m_pBackBuffer,
- NULL, DDBLT_WAIT, NULL );
- //挂起50毫秒
- Sleep(20);
- }
- return 0;
- }
- /////////////////////////////////////////////////////////////////////////////
- // CHitCheckDemoDlg message handlers
- BOOL CHitCheckDemoDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- // Add "About..." menu item to system menu.
- // IDM_ABOUTBOX must be in the system command range.
- ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
- ASSERT(IDM_ABOUTBOX < 0xF000);
- CMenu* pSysMenu = GetSystemMenu(FALSE);
- if (pSysMenu != NULL)
- {
- CString strAboutMenu;
- strAboutMenu.LoadString(IDS_ABOUTBOX);
- if (!strAboutMenu.IsEmpty())
- {
- pSysMenu->AppendMenu(MF_SEPARATOR);
- pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
- }
- }
- // Set the icon for this dialog. The framework does this automatically
- // when the application's main window is not a dialog
- SetIcon(m_hIcon, TRUE); // Set big icon
- SetIcon(m_hIcon, FALSE); // Set small icon
-
- // TODO: Add extra initialization here
- //初始化DirectX
- InitDirectX();
- //载入碰撞信息的文字曲面:“Ship Hitted!”
- m_surfShipHitted.Create(80,16, RGB(0,0,0));
- m_surfShipHitted.LoadBitmap(AfxGetInstanceHandle(), IDB_SHIPHITTED, 0,0, 80, 16);
- //使用cSurface创建小行星和飞船的曲面(平面)
- m_surfShip.Create(60,60, RGB(0,0,0));
- m_surfShip.LoadBitmap(AfxGetInstanceHandle(), IDB_SPACESHIP, 0,0, 60, 60);
- m_surfAsteroid.Create(60,60, RGB(0,0,0));
- m_surfAsteroid.LoadBitmap(AfxGetInstanceHandle(), IDB_ASTEROID, 0,0, 50, 50);
- //把飞船放到屏幕底部的中间位置
- RECT rcRect;
- this->GetWindowRect(&rcRect);
- pShipPos.x = (rcRect.right - rcRect.left - 60)/2;
- pShipPos.y = rcRect.bottom - 70;
- m_iIncrement = 0;
- //初始化3个小行星的位置
- m_pAsteroid1.x = 40;
- m_pAsteroid1.y = 0;
- m_pAsteroid2.x = 230;
- m_pAsteroid2.y = 0;
- m_pAsteroid3.x = 380;
- m_pAsteroid3.y = 0;
-
-
- // Here we will create the Heat Checker objects
- // for each one of the objects, Asteroid and Ship
- //创建飞船边界的多边形顶点数组
- POINT lpPointsShip[] = { {5,42}, {22,48}, {22,52}, {38,52},
- {38,47}, {54,41}, {54,29}, {37,8},
- {31,15}, {28,15}, {22,8}, {5,31} };
- //利用上面的数组,创建飞船碰撞检测类
- m_hcShip.CreatePolygonBound(lpPointsShip, 12);
- //创建小行星的多边形顶点数组
- POINT lpPointsAsteroid[] = { {8,31}, {22,46}, {37,38}, {49,26},
- {37,9}, {19,6}, {10,6}, {8,16} };
- //利用上面的数组,创建小行星碰撞检测类
- m_hcAsteroid.CreatePolygonBound(lpPointsAsteroid, 8);
- //停止运动标志
- m_bStop = FALSE;
- //创建绘制线程,线程参数就是这个对话框类
- AfxBeginThread(UpdateFrame, this);
- return TRUE; // return TRUE unless you set the focus to a control
- }
- void CHitCheckDemoDlg::OnSysCommand(UINT nID, LPARAM lParam)
- {
- if ((nID & 0xFFF0) == IDM_ABOUTBOX)
- {
- CAboutDlg dlgAbout;
- dlgAbout.DoModal();
- }
- else
- {
- CDialog::OnSysCommand(nID, lParam);
- }
- }
- // If you add a minimize button to your dialog, you will need the code below
- // to draw the icon. For MFC applications using the document/view model,
- // this is automatically done for you by the framework.
- void CHitCheckDemoDlg::OnPaint()
- {
- if (IsIconic())
- {
- CPaintDC dc(this); // device context for painting
- SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
- // Center icon in client rectangle
- int cxIcon = GetSystemMetrics(SM_CXICON);
- int cyIcon = GetSystemMetrics(SM_CYICON);
- CRect rect;
- GetClientRect(&rect);
- int x = (rect.Width() - cxIcon + 1) / 2;
- int y = (rect.Height() - cyIcon + 1) / 2;
- // Draw the icon
- dc.DrawIcon(x, y, m_hIcon);
- }
- else
- {
- CDialog::OnPaint();
- }
- }
- // The system calls this to obtain the cursor to display while the user drags
- // the minimized window.
- HCURSOR CHitCheckDemoDlg::OnQueryDragIcon()
- {
- return (HCURSOR) m_hIcon;
- }
- //初始化DirectX
- void CHitCheckDemoDlg::InitDirectX()
- {
- HRESULT hRet;
- LPDIRECTDRAW pDD;
- DDSURFACEDESC2 ddsd;
- DDSCAPS2 ddscaps;
- LPDIRECTDRAWCLIPPER pcClipper;
- // 首先,创建DirectX对象
- hRet = DirectDrawCreate( NULL, &pDD, NULL );
- if(hRet != DD_OK)
- {
- return;
- }
- //取DirectDraw7接口
- hRet = pDD->QueryInterface(IID_IDirectDraw7, (LPVOID*)&m_pDD);
- if(hRet != DD_OK)
- {
- return;
- }
- //既然不再需要DirectDraw接口,所以释放掉
- pDD->Release();
-
- //确定应用程序的显示方式,正常的窗口显示方式
- hRet = m_pDD->SetCooperativeLevel(m_hWnd, DDSCL_NORMAL);
- if(hRet != DD_OK)
- {
- return;
- }
-
- //创建主曲面,这里我们不使用cSurface创建而是直接使用IDirectDraw7
- ZeroMemory( &ddsd, sizeof( ddsd ) );
- ddsd.dwSize = sizeof( ddsd );
- ddsd.dwFlags = DDSD_CAPS;
- //创建主曲面,在DirectX中,主曲面需要用主DirectDrawSurface对象表示。
- ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
-
- //ddsd.dwBackBufferCount = 1;
- //m_pFrontBuffer被DirectDraw对象创建为主曲面
- hRet = m_pDD->CreateSurface(&ddsd, &m_pFrontBuffer, NULL );
- if(hRet != DD_OK)
- {
- return;
- }
- // Create back buffer
-
- ZeroMemory(&ddscaps, sizeof(ddscaps));
- RECT rcRect;
- this->GetWindowRect(&rcRect);
- //创建后台缓冲曲面
- ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
- ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_3DDEVICE;
- ddsd.dwWidth = rcRect.right - rcRect.left;
- ddsd.dwHeight = rcRect.bottom - rcRect.top;
- ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
- hRet = m_pDD->CreateSurface( &ddsd, &m_pBackBuffer, NULL );
-
- if(hRet != DD_OK)
- {
- return;
- }
-
- //创建DirectDraw裁剪对象
- if( FAILED( hRet = m_pDD->CreateClipper( 0, &pcClipper, NULL ) ) )
- return;
- //裁剪对象设置主窗口
- if( FAILED( hRet = pcClipper->SetHWnd( 0, m_hWnd ) ) )
- {
- pcClipper->Release();
- return;
- }
- //设置前台缓冲的裁剪对象
- if( FAILED( hRet = m_pFrontBuffer->SetClipper( pcClipper ) ) )
- {
- pcClipper->Release();
- return;
- }
- //释放裁剪对象
- pcClipper->Release();
-
- DDBLTFX ddbltfx;
- ZeroMemory( &ddbltfx, sizeof(ddbltfx) );
- ddbltfx.dwSize = sizeof(ddbltfx);
- ddbltfx.dwFillColor = RGB(0,0,0);
- //Blt函数用来进行位块信息传输
- m_pBackBuffer->Blt( NULL, NULL, NULL, DDBLT_COLORFILL, &ddbltfx );
- }
- void CHitCheckDemoDlg::OnClose()
- {
- //设置线程结束标志
- m_bStop = TRUE;
- //休眠一会,等待绘制线程结束
- Sleep(100);
-
- // TODO: Add your message handler code here and/or call default
-
- //释放前台缓冲、后台缓冲和DirectDraw对象
- if( m_pBackBuffer != NULL )
- m_pBackBuffer->Release();
- if( m_pFrontBuffer != NULL )
- m_pFrontBuffer->Release();
- if( m_pDD != NULL )
- m_pDD->Release();
- CDialog::OnClose();
- }
- //绘制飞船
- void CHitCheckDemoDlg::DrawShip()
- {
- RECT rcRect;
- GetWindowRect(&rcRect);
- //滑动飞船的水平位置
- pShipPos.x += m_iIncrement;
- //如果飞船到了边界则停下来
- if(pShipPos.x == 0)
- m_iIncrement = 0;
- if(pShipPos.x == rcRect.right-60)
- m_iIncrement = 0;
- //在背景绘制表面绘制飞船
- m_surfShip.Draw(m_pBackBuffer, pShipPos.x, pShipPos.y);
- }
- //绘制小行星
- void CHitCheckDemoDlg::DrawAsteroids()
- {
- // Draw each one of the 3 asteroids
- RECT rcRect;
- GetWindowRect(&rcRect);
- //绘制三个小行星
- m_surfAsteroid.Draw(m_pBackBuffer, m_pAsteroid1.x, m_pAsteroid1.y);
- m_surfAsteroid.Draw(m_pBackBuffer, m_pAsteroid2.x, m_pAsteroid2.y);
- m_surfAsteroid.Draw(m_pBackBuffer, m_pAsteroid3.x, m_pAsteroid3.y);
- //改变小行星的位置
- m_pAsteroid1.y++;
- m_pAsteroid2.y+=2;
- m_pAsteroid3.y+=3;
- if(m_pAsteroid1.y > rcRect.bottom -rcRect.top- 51)
- m_pAsteroid1.y = 40;
- if(m_pAsteroid2.y > rcRect.bottom - rcRect.top - 51)
- m_pAsteroid2.y = 40;
- if(m_pAsteroid3.y > rcRect.bottom - rcRect.top - 51)
- m_pAsteroid3.y = 40;
- //分别测试3个小行星是否和飞船发生了碰撞
- if(m_hcShip.HaveHitted(&m_hcAsteroid,m_pAsteroid1.x, m_pAsteroid1.y, pShipPos.x, pShipPos.y) == TRUE)
- {
- //显示Ship Hitted!
- m_surfShipHitted.Draw(m_pBackBuffer, 10,40,0,0);
- OutputDebugString("Ship Hitted by Asteroid 1!n");
- }
- if(m_hcShip.HaveHitted(&m_hcAsteroid,m_pAsteroid2.x, m_pAsteroid2.y, pShipPos.x, pShipPos.y) == TRUE)
- {
- m_surfShipHitted.Draw(m_pBackBuffer, 10,40,0,0);
- OutputDebugString("Ship Hitted by Asteroid 2!n");
- }
- if(m_hcShip.HaveHitted(&m_hcAsteroid,m_pAsteroid3.x, m_pAsteroid3.y, pShipPos.x, pShipPos.y) == TRUE)
- {
- m_surfShipHitted.Draw(m_pBackBuffer, 10,40,0,0);
- OutputDebugString("Ship Hitted by Asteroid 3!n");
- }
- }
- //需要在PreTranslateMessage中截获对话框中键盘消息,而不是OnKeyDown消息相应函数
- BOOL CHitCheckDemoDlg::PreTranslateMessage(MSG* pMsg)
- {
- // TODO: Add your specialized code here and/or call the base class
- if(pMsg->message == WM_KEYDOWN)
- {
- int nVirtKey = (int) pMsg->wParam;
- switch(nVirtKey)
- {
- case VK_LEFT:
- m_iIncrement = -1;
- break;
- case VK_RIGHT:
- m_iIncrement = +1;
- break;
- case VK_DOWN:
- m_iIncrement = 0;
- break;
- }
- }
- return CDialog::PreTranslateMessage(pMsg);
- }