⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 canvasframe.cpp

📁 《Visual C++游戏设计入门》的配套代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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
struct bullet       //飞机的子弹    
{
   int x;           //贴图的 X 坐标
   int y;           //贴图的 Y 坐标
   int hitx;        //碰撞点的 X 坐标
   int hity;        //碰撞点的 Y 坐标
   BOOL exist;      //子弹是否存在
};
struct cartridge    //怪物的子弹
{
	int x;
	int y;
	int hitx;
	int hity;
	BOOL exist;
};
struct ship         //飞机
{
	int x;          //贴图的 X 坐标
	int y;          //贴图的 Y 坐标
	RECT r[3];      //飞机的区块
};
struct monster      //怪物
{
	int x;          //贴图的 X 坐标
	int y;          //贴图的 Y 坐标
	int type;       //怪物的类型
	int draw;       //控制贴图速度的变量
	RECT r[3];      //怪物的区块
	POINT p[4];     //怪物的碰撞点
	BOOL exist;     //怪物是否存在
};

/////////////////////////////////////////////////////////////////////////////
// canvasFrame

IMPLEMENT_DYNCREATE(canvasFrame, CFrameWnd)

//声明 DirectDraw 变量
LPDIRECTDRAW7              DD;  
LPDIRECTDRAWSURFACE7       DDSur; 
LPDIRECTDRAWSURFACE7       DDBuf; 
LPDIRECTDRAWSURFACE7	   DDPla[10];
DDSCAPS2				   DDcaps;
DDSURFACEDESC2             DDde;
HRESULT					   result;
DDCOLORKEY                 key;

//声明 DirectSound 变量
LPDIRECTSOUND			   DS;          
LPDIRECTSOUNDBUFFER        DSPri;  
LPDIRECTSOUNDBUFFER        DSBuf[6];  
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 i,j,m,n;
int bgx;
int bcount,mcount,ccount;
int t,f;              //控制屏幕贴图
int score=0;          //分数
BOOL press,hit,over;
cartridge c[100];     //怪物子弹数组
bullet b[100];        //飞机子弹数组
monster mon[50];      //怪物数组
ship ship;
char str[20];
canvasFrame::canvasFrame()
{
	Create(NULL,"绘图窗口",WS_POPUP); 
	hdc = ::CreateCompatibleDC(NULL);
	::ShowCursor(false);
	CreateDDPla(640,480,"load.bmp",9);
	DDBuf->BltFast( 0 , 0 , DDPla[9], CRect(0,0,640,480) , DDBLTFAST_WAIT);
	DDSur->Flip( NULL , DDFLIP_WAIT );   //显示加载中图案
	CreateDDPla(640,480,"bgbmp.bmp",0);
	CreateDDPla(100,74,"ship.bmp",1);
	CreateDDPla(10,10,"bullet.bmp",2);
	CreateDDPla(80,59,"mon0.bmp",3);
	CreateDDPla(60,56,"mon1.bmp",4);
	CreateDDPla(79,51,"mon2.bmp",5);
	CreateDDPla(10,10,"cartridge.bmp",6);
	CreateDDPla(80,80,"hit.bmp",7);
	CreateDDPla(640,159,"over.bmp",8);
	CreateDSBuf("s0.wav",0);
	CreateDSBuf("s1.wav",1);
	CreateDSBuf("s2.wav",2);
	CreateDSBuf("s3.wav",3);
	ColorKey(1);
	ColorKey(2);
	ColorKey(3);
	ColorKey(4);
	ColorKey(5);
	ColorKey(6);
	ColorKey(7);
	ColorKey(8);
	ship.x = 540;     
	ship.y = 200;      
	DSBuf[0]->Play(0,0,1);   //播放背景音乐
}

canvasFrame::~canvasFrame()
{
	delete bitmap;
	delete hdc;
	delete dhdc;
	DD->Release();
	DDSur->Release();
	for(i=0;i<=9;i++)
		DDPla[i]->Release();
	DI->Release();
	DIms->Release();
	DS->Release();
	DSPri->Release();
	for(i=0;i<=2;i++)
		DSBuf[i]->Release();

}


BEGIN_MESSAGE_MAP(canvasFrame, CFrameWnd)
	//{{AFX_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::Generate()
{
	switch(rand()%3)
	{
	case 0:
		for(i=0;i<50;i++)
		{
			if(!mon[i].exist)
			{
				mon[i].type = 0;
				mon[i].x = 0;
				mon[i].y = rand()%420;
				mon[i].exist = true;
				mon[i].r[0].left = mon[i].x + 28;
				mon[i].r[0].top = mon[i].y + 7;
				mon[i].r[0].right = mon[i].x + 72;
				mon[i].r[0].bottom = mon[i].y + 34;
				mon[i].r[1].left = mon[i].x;
				mon[i].r[1].top = mon[i].y + 23;
				mon[i].r[1].right = mon[i].x + 49;
				mon[i].r[1].bottom = mon[i].y + 59;
				mon[i].r[2].left = mon[i].x + 24;
				mon[i].r[2].top = mon[i].y + 50;
				mon[i].r[2].right = mon[i].x + 48;
				mon[i].r[2].bottom = mon[i].y + 59;
				mon[i].p[0].x = mon[i].x +46;
				mon[i].p[0].y = mon[i].y + 8;
				mon[i].p[1].x = mon[i].x + 71;
				mon[i].p[1].y = mon[i].y + 22;
				mon[i].p[2].x = mon[i].x + 36;
				mon[i].p[2].y = mon[i].y + 57;
				mon[i].p[3].x = mon[i].x + 1;
				mon[i].p[3].y = mon[i].y + 31;
				mcount++;
				break;
			}
		}
		break;
	case 1:
		for(i=0;i<50;i++)
		{
			if(!mon[i].exist)
			{
				mon[i].type = 1;
				mon[i].x = 0;
				mon[i].y = rand()%420;
				mon[i].exist = true;
				mon[i].r[0].left = mon[i].x + 14;
				mon[i].r[0].top = mon[i].y + 4;
				mon[i].r[0].right = mon[i].x + 57;
				mon[i].r[0].bottom = mon[i].y + 26;
				mon[i].r[1].left = mon[i].x+1;
				mon[i].r[1].top = mon[i].y + 14;
				mon[i].r[1].right = mon[i].x + 43;
				mon[i].r[1].bottom = mon[i].y + 41;
				mon[i].r[2].left = mon[i].x + 5;
				mon[i].r[2].top = mon[i].y + 34;
				mon[i].r[2].right = mon[i].x + 22;
				mon[i].r[2].bottom = mon[i].y + 55;
				mon[i].p[0].x = mon[i].x +52;
				mon[i].p[0].y = mon[i].y + 18;
				mon[i].p[1].x = mon[i].x + 20;
				mon[i].p[1].y = mon[i].y + 4;
				mon[i].p[2].x = mon[i].x + 3;
				mon[i].p[2].y = mon[i].y + 22;
				mon[i].p[3].x = mon[i].x + 14;
				mon[i].p[3].y = mon[i].y + 50;
				mcount++;
				break;
			}
		}
		break;
	case 2:
		for(i=0;i<50;i++)
		{
			if(!mon[i].exist)
			{
				mon[i].type = 2;
				mon[i].x = 580;
				mon[i].y = rand()%420;
				mon[i].exist = true;
				mon[i].r[0].left = mon[i].x + 1;
				mon[i].r[0].top = mon[i].y + 8;
				mon[i].r[0].right = mon[i].x + 78;
				mon[i].r[0].bottom = mon[i].y + 37;
				mon[i].r[1].left = mon[i].x+8;
				mon[i].r[1].top = mon[i].y + 36;
				mon[i].r[1].right = mon[i].x + 52;
				mon[i].r[1].bottom = mon[i].y + 50;
				mon[i].r[2].left = mon[i].x + 20;
				mon[i].r[2].top = mon[i].y;
				mon[i].r[2].right = mon[i].x + 37;
				mon[i].r[2].bottom = mon[i].y + 8;
				mon[i].p[0].x = mon[i].x +4;
				mon[i].p[0].y = mon[i].y + 21;
				mon[i].p[1].x = mon[i].x + 31;
				mon[i].p[1].y = mon[i].y + 3;
				mon[i].p[2].x = mon[i].x + 72;
				mon[i].p[2].y = mon[i].y + 24;
				mon[i].p[3].x = mon[i].x + 36;
				mon[i].p[3].y = mon[i].y + 45;
				mcount++;
				break;
			}
		}
		break;
	}
}

void canvasFrame::OnTimer(UINT nIDEvent)
{
	if(!over)
	{
		t++;
		if(score>10000)
			f = 20;
		else if(score<=10000 && score>5500)
			f = 30;
		else if(score<=5500 && score >2000)
			f = 40;
		else 
			f = 50;
		if(t%f==0)
		{
			Generate();            //产生怪物
			t=0;
		}
		result = DIms->GetDeviceState(sizeof(DImstate),(LPVOID)&DImstate); 
		if(result != DI_OK )
		{
			MessageBox("取得鼠标状态失败!");
			return;
		}
		DDBuf->BltFast( bgx , 0 , DDPla[0], CRect(0,0,640-bgx,480) , DDBLTFAST_WAIT);
		DDBuf->BltFast( 0 , 0 , DDPla[0], CRect(640-bgx,0,640,480) , DDBLTFAST_WAIT);
		ShipMove();       
		PasteMon();      
		Shoot();            
		if(ccount !=0)            //贴上怪物子弹
			for(i=0;i<100;i++)
				if(c[i].exist)
					DDBuf->BltFast(c[i].x,c[i].y,DDPla[6],CRect(0,0,10,10),DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
		if(bcount != 0)           //贴上飞机子弹
			for(i=0;i<100;i++)
				if(b[i].exist)
					DDBuf->BltFast(b[i].x,b[i].y,DDPla[2],CRect(0,0,10,10),DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
		MonBombShip();
		HitShip();
		HitMon();
		bgx+=10;
		if(bgx==640)
			bgx=0;
		DDBuf->GetDC( &hdc );           
		sprintf(str,"分数:%d",score);
		::TextOut(hdc, 0, 0,str, lstrlen(str));  //显示分数
		DDBuf->ReleaseDC( hdc);      
		DDSur->Flip( NULL , DDFLIP_WAIT );
	}
	CFrameWnd::OnTimer(nIDEvent);
}

void canvasFrame::ShipMove()
{
	ship.x += DImstate.lX;     
	ship.y += DImstate.lY;      
	if(ship.x<0)				 //是否已至左边界
		ship.x = 0;
	if(ship.x>540)				 //是否已至右边界
		ship.x = 540;
	if(ship.y<0)			     //是否已至上边界
		ship.y = 0;
	if(ship.y>406)				 //是否已至下边界
		ship.y = 406;
	ship.r[0].left = ship.x + 16;
	ship.r[0].top = ship.y + 3;
	ship.r[0].right = ship.x + 50;
	ship.r[0].bottom = ship.y + 53;
	ship.r[1].left = ship.x + 8;
	ship.r[1].top = ship.y + 16;
	ship.r[1].right = ship.x + 78;
	ship.r[1].bottom = ship.y + 50;
	ship.r[2].left = ship.x + 35;
	ship.r[2].top = ship.y + 35;
	ship.r[2].right = ship.x + 81;
	ship.r[2].bottom = ship.y + 71;
	DDBuf->BltFast(ship.x,ship.y,DDPla[1],CRect(0,0,100,74),DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
}
void canvasFrame::Shoot()
{
	if(DImstate.rgbButtons[0] & 0x80)  //判断是否按下鼠标左键
	{
		if(!press)
		{
			for(i=0;i<100;i++)
			{
				if(!b[i].exist)
				{
					DSBuf[1]->Play(0,0,0);
					b[i].x = ship.x;
					b[i].y = ship.y+30;
					b[i].exist = true;
					bcount++;
					break;
				}
			}
			press = true;
		}
	}
	else
		press = false;
}

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;
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -