📄 canvasframe.cpp
字号:
// canvasFrame.cpp : implementation file
//
#define DIRECTINPUT_VERSION 0x0700
#include "stdafx.h"
#include "canvasr.h"
#include "canvasFrame.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// canvasFrame
IMPLEMENT_DYNCREATE(canvasFrame, CFrameWnd)
//声明 DirectDraw 变量
LPDIRECTDRAW7 DD;
LPDIRECTDRAWSURFACE7 DDSur;
LPDIRECTDRAWSURFACE7 DDBuf;
LPDIRECTDRAWSURFACE7 DDPla[20];
DDSCAPS2 DDcaps;
DDSURFACEDESC2 DDde;
HRESULT result;
DDCOLORKEY key;
//声明 DirectSound 变量
LPDIRECTSOUND DS;
LPDIRECTSOUNDBUFFER DSPri;
LPDIRECTSOUNDBUFFER DSBuf[3];
WAVEFORMATEX DSfmt;
WAVEFORMATEX wfmt;
DSBUFFERDESC DSde;
MMCKINFO ckRiff;
MMCKINFO ckInfo;
MMRESULT mmresult;
HMMIO hmmio;
DWORD wsize;
LPVOID pAudio;
DWORD bytesAudio;
//声明 DirectInput 变量
LPDIRECTINPUT7 DI;
LPDIRECTINPUTDEVICE7 DIms;
DIMOUSESTATE2 DImstate;
//声明其它变量
HDC hdc,dhdc;
HBITMAP bitmap;
int a,i,j,t,num;
int x=1,y=190;
int bg[8][640][480];
int px[16];
int py[16];
BOOL collide,over,win;
char str[10];
canvasFrame::canvasFrame()
{
Create(NULL,"绘图窗口",WS_POPUP);
hdc = ::CreateCompatibleDC(NULL);
::ShowCursor(false);
CreateDDPla(640,480,"load.bmp",19);
DDBuf->BltFast( 0 , 0 , DDPla[19], CRect(0,0,640,480) , DDBLTFAST_WAIT);
DDSur->Flip( NULL , DDFLIP_WAIT );
for(i=0;i<=7;i++) //载入前景图与背景图
{
sprintf(str,"bgbmp%d.bmp",i);
CreateDDPla(640,480,str,i);
sprintf(str,"mbgbmp%d.bmp",i);
CreateDDPla(640,480,str,i+8);
}
CreateDDPla(34,34,"ball.bmp",16); //载入小球图
CreateDDPla(638,180,"win.bmp",17); //载入过关图
CreateDDPla(638,180,"lose.bmp",18); //加载失败图
ColorKey(16);
ColorKey(17);
ColorKey(18);
for(a=0;a<=7;a++)
{
DDPla[a+8]->GetDC( &hdc );
for(i=0;i<640;i++)
for(j=0;j<480;j++)
bg[a][i][j] = ::GetPixel(hdc,i,j);
DDPla[a+8]->ReleaseDC(hdc);
}
CreateDSBuf("s0.wav",0); //加载背景音乐
CreateDSBuf("s1.wav",1); //加载碰撞音乐
CreateDSBuf("s2.wav",2); //加载过关音乐
DSBuf[0]->Play(0,0,1);
}
canvasFrame::~canvasFrame()
{
delete bitmap;
delete hdc;
delete dhdc;
DD->Release();
DDSur->Release();
for(i=0;i<=19;i++)
DDPla[i]->Release();
DI->Release();
DIms->Release();
DS->Release();
DSPri->Release();
for(i=0;i<1;i++)
DSBuf[i]->Release();
}
BEGIN_MESSAGE_MAP(canvasFrame, CFrameWnd)
//{_7bAFX_MSG_MAP(canvasFrame)
ON_WM_CREATE()
ON_WM_TIMER()
ON_WM_KEYDOWN()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// canvasFrame message handlers
int canvasFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
InitDD();
InitDS();
InitDI();
SetTimer(1,0,NULL);
return 0;
}
void canvasFrame::CreateDDPla(int width,int height,char* filename,int num)
{
//设定幕后内存区大小
DDde.dwWidth = width;
DDde.dwHeight = height;
//建立幕后内存区
result = DD->CreateSurface(&DDde, &DDPla[num], NULL);
if(result !=DD_OK)
{
MessageBox("建立幕后内存区失败!");
return;
}
//载入位图
bitmap = (HBITMAP)::LoadImage(NULL,filename,IMAGE_BITMAP,width,height,LR_LOADFROMFILE);
if(bitmap==NULL)
{
MessageBox("无法加载位图!");
return;
}
//复制位图到绘图中
::SelectObject(hdc,bitmap);
DDPla[num]->GetDC( &dhdc );
::BitBlt( dhdc , 0 , 0 ,width,height, hdc , 0 , 0 , SRCCOPY );
DDPla[num]->ReleaseDC(dhdc);
}
void canvasFrame::ColorKey(int num)
{
key.dwColorSpaceHighValue = 0;
key.dwColorSpaceLowValue = 0;
DDPla[num]->SetColorKey(DDCKEY_SRCBLT,&key);
}
void canvasFrame::OnTimer(UINT nIDEvent)
{
if(!over)
Playing(); //游戏正在进行中
else
Over(); //过关或发生碰撞
DDSur->Flip( NULL , DDFLIP_WAIT );
CFrameWnd::OnTimer(nIDEvent);
}
void canvasFrame::Over()
{
t++;
if(t%10 == 0)
{
num++;
if(num == 8)
num =0;
t=0;
}
DDBuf->BltFast( 0 , 0 , DDPla[num], CRect(0,0,640,480) , DDBLTFAST_WAIT);
DDBuf->BltFast(x,y,DDPla[16],CRect(0,0,34,34),DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
if(win)
DDBuf->BltFast(0,150,DDPla[17],CRect(0,0,638,180),DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
if(collide)
DDBuf->BltFast(0,150,DDPla[18],CRect(0,0,638,180),DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
}
void canvasFrame::Playing()
{
t++;
if(t%5 == 0)
{
num++;
if(num == 8)
num = 0;
t=0;
}
DDBuf->BltFast( 0 , 0 , DDPla[num], CRect(0,0,640,480) , DDBLTFAST_WAIT);
result = DIms->GetDeviceState(sizeof(DImstate),(LPVOID)&DImstate);
if(result != DI_OK )
{
MessageBox("取得鼠标状态失败!");
return;
}
x += DImstate.lX;
y += DImstate.lY;
if(x<=1)
x=1;
if(x>=605)
x=605;
if(y<=20)
y=20;
if(y>=430)
y=430;
px[0] = x+16;
px[1] = x;
px[2] = x+33;
px[3] = x+16;
px[4] = x+5;
px[5] = x+28;
px[6] = x+27;
px[7] = x+5;
px[8] = x+2;
px[9] = x+9;
px[10] = x+31;
px[11] = x+23;
px[12] = x+24;
px[13] = x+30;
px[14] = x+9;
px[15] = x+1;
py[0] = y+0;
py[1] = y+16;
py[2] = y+16;
py[3] = y+33;
py[4] = y+5;
py[5] = y+5;
py[6] = y+29;
py[7] = y+28;
py[8] = y+24;
py[9] = y+31;
py[10] = y+23;
py[11] = y+31;
py[12] = y+2;
py[13] = y+8;
py[14] = y+2;
py[15] = y+10;
DDBuf->BltFast(x,y,DDPla[16],CRect(0,0,34,34),DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
for(i=0;i<=15;i++)
if(bg[num][px[i]][py[i]] ==0) //发生碰撞
{
DDBuf->BltFast(0,150,DDPla[18],CRect(0,0,638,180),DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
over = true;
DSBuf[1]->Play(0,0,0);
collide = true;
break;
}
if(px[2] > 630) //过关
{
DDBuf->BltFast(0,150,DDPla[17],CRect(0,0,638,180),DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
DSBuf[0]->Stop();
win = true;
over = true;
DSBuf[2]->Play(0,0,1);
}
}
void canvasFrame::CreateDSBuf(char* filename,int num)
{
//开启与检查文件格式
hmmio = mmioOpen(filename, NULL, MMIO_ALLOCBUF|MMIO_READ );
if(hmmio == NULL)
{
MessageBox("文件不存在!");
return;
}
ckRiff.fccType = mmioFOURCC('W', 'A', 'V', 'E');
mmresult = mmioDescend(hmmio,&ckRiff,NULL,MMIO_FINDRIFF);
if(mmresult != MMSYSERR_NOERROR)
{
MessageBox("文件格式错误!");
return;
}
ckInfo.ckid = mmioFOURCC('f','m','t',' ');
mmresult = mmioDescend(hmmio,&ckInfo,&ckRiff,MMIO_FINDCHUNK);
if(mmresult != MMSYSERR_NOERROR)
{
MessageBox("文件格式错误!");
return;
}
//读取文件格式
mmresult = mmioRead(hmmio,(HPSTR)&wfmt,sizeof(wfmt));
if(mmresult == -1)
{
MessageBox("读取格式失败!");
return;
}
mmresult = mmioAscend(hmmio,&ckInfo,0);
ckInfo.ckid = mmioFOURCC('d','a','t','a');
mmresult = mmioDescend(hmmio,&ckInfo,&ckRiff,MMIO_FINDCHUNK);
if(mmresult != MMSYSERR_NOERROR)
{
MessageBox("文件格式错误!");
return;
}
wsize = ckInfo.cksize;
//设定次缓冲区特性
memset( &DSde,0,sizeof(DSde));
DSde.dwSize = sizeof(DSde);
DSde.dwFlags = DSBCAPS_STATIC |DSBCAPS_CTRLPAN |DSBCAPS_CTRLVOLUME| DSBCAPS_GLOBALFOCUS;
DSde.dwBufferBytes = wsize;
DSde.lpwfxFormat = &wfmt;
//建立次缓冲区
result = DS->CreateSoundBuffer( &DSde, &DSBuf[num], NULL );
if(result != DS_OK)
{
MessageBox("建立次缓冲区失败!");
return;
}
//锁定次缓冲区并载入音文件
result = DSBuf[num]->Lock(0,wsize,&pAudio,&bytesAudio,NULL,NULL,NULL);
if(result != DS_OK)
{
MessageBox("锁定缓冲区失败!");
return;
}
mmresult = mmioRead(hmmio,(HPSTR)pAudio,bytesAudio);
if(mmresult == -1)
{
MessageBox("读取音文件数据失败!");
return;
}
result = DSBuf[num]->Unlock(pAudio,bytesAudio,NULL,NULL);
if(result != DS_OK)
{
MessageBox("解除锁定缓冲区失败!");
return;
}
mmioClose(hmmio,0);
}
void canvasFrame::InitDD()
{
//建立 DirectDraw 对象
result = DirectDrawCreateEx(NULL, (VOID**)&DD, IID_IDirectDraw7, NULL);
if (result != DD_OK)
{
MessageBox("建立DirectDraw对象失败!");
return;
}
//设定协调层级
result = DD->SetCooperativeLevel(m_hWnd,DDSCL_EXCLUSIVE |
DDSCL_FULLSCREEN|DDSCL_ALLOWREBOOT );
if(result !=DD_OK)
{
MessageBox("设定程序协调层级失败!");
return;
}
//设定显示模式
result = DD->SetDisplayMode(640,480,16,0,DDSDM_STANDARDVGAMODE);
if(result !=DD_OK)
{
MessageBox("设定屏幕显示模式失败!");
return;
}
//建立主绘图页
memset(&DDde,0,sizeof(DDde));
DDde.dwSize = sizeof(DDde);
DDde.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
DDde.dwBackBufferCount = 1;
DDde.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_COMPLEX | DDSCAPS_FLIP;
result = DD->CreateSurface(&DDde,&DDSur,NULL);
if(result !=DD_OK)
{
MessageBox("建立主绘图页失败!");
return;
}
//连结后缓冲区
DDcaps.dwCaps = DDSCAPS_BACKBUFFER;
result = DDSur->GetAttachedSurface(&DDcaps,&DDBuf);
if(result !=DD_OK)
{
MessageBox("连接后缓冲区失败!");
return;
}
//声明幕后内存区的共同特性
memset(&DDde,0,sizeof(DDde));
DDde.dwSize = sizeof(DDde);
DDde.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH;
DDde.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN ;
}
void canvasFrame::InitDS()
{
//建立 DirectSound 对象
result = DirectSoundCreate( NULL, &DS, NULL );
if(result != DS_OK)
{
MessageBox("建立 DirectSound 对象失败!");
return;
}
//设定协调层级
result = DS->SetCooperativeLevel( m_hWnd, DSSCL_PRIORITY );
if(result != DS_OK)
{
MessageBox("设定协调层级失败!");
return;
}
//建立主缓冲区
memset( &DSde,0, sizeof(DSde) );
DSde.dwSize = sizeof(DSde);
DSde.dwFlags = DSBCAPS_PRIMARYBUFFER;
DSde.dwBufferBytes = 0;
DSde.lpwfxFormat = NULL;
result = DS->CreateSoundBuffer( &DSde, &DSPri, NULL );
if(result != DS_OK)
{
MessageBox("建立主缓冲区失败!");
return;
}
//设定声音播放格式
memset( &DSfmt,0, sizeof(DSfmt) );
DSfmt.wFormatTag = WAVE_FORMAT_PCM;
DSfmt.nChannels = 2;
DSfmt.nSamplesPerSec = 44100;
DSfmt.wBitsPerSample = 16;
DSfmt.nBlockAlign = DSfmt.wBitsPerSample / 8 * DSfmt.nChannels;
DSfmt.nAvgBytesPerSec = DSfmt.nSamplesPerSec * DSfmt.nBlockAlign;
result = DSPri->SetFormat(&DSfmt);
if(result != DS_OK)
{
MessageBox("设定播放格式失败!");
return;
}
}
void canvasFrame::InitDI()
{
//建立 DirectInput 对象
HINSTANCE hinst = AfxGetInstanceHandle();
result = DirectInputCreateEx(hinst, DIRECTINPUT_VERSION,IID_IDirectInput7, (void**)&DI, NULL);
if(result != DI_OK)
{
MessageBox("建立 DirectInput 对象失败!");
return;
}
//建立输入装置对象
result = DI->CreateDeviceEx(GUID_SysMouse, IID_IDirectInputDevice7,(void**)&DIms, NULL);
if(result != DI_OK)
{
MessageBox("建立鼠标输入装置失败!");
return;
}
//设定数据格式
result = DIms->SetDataFormat(&c_dfDIMouse2);
if(result != DI_OK)
{
MessageBox("设定数据格式失败!");
return;
}
//设定协调层级
result = DIms->SetCooperativeLevel(m_hWnd,DISCL_BACKGROUND | DISCL_NONEXCLUSIVE);
if(result != DI_OK)
{
MessageBox("设定程序协调层级失败!");
return;
}
//取用输入装置
result = DIms->Acquire();
if(result != DI_OK)
{
MessageBox("取用输入装置失败!");
return;
}
}
void canvasFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
if( nChar== VK_ESCAPE ) //按下 Esc 键
PostMessage(WM_CLOSE ); //结束程序
if( nChar == VK_F1) //按下 F1 键
{
over = false;
if(win)
{
win = false;
DSBuf[2]->Stop();
DSBuf[0]->Play(0,0,1);
}
else
collide = false;
x = 1;
y = 190;
}
CFrameWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -