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

📄 mygame.cpp

📁 坦克大战游戏.很值得学习的东东.希望对大家有帮助
💻 CPP
字号:
// MyGame.cpp: implementation of the MyGame class.
//游戏类工程文件
//创建于 2006. 修改于 2008.10
//吴文捷
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "mmsystem.h"
#pragma comment(lib,"winmm.lib")

#include "常数定义.h"
#include "MyGame.h"
#include "Control.h"

//==============全局变量=================
MyDDraw   ddraw;
MyDInput  dinput;
MyDSound  dsound;
CMyFile   file;
CTank     *tank;
CPlayer   player;
CBullete  *bullete;
bool      NewGame;
bool      ShowMainMenu;
bool      ShowStage;
short     MainMenuSelect;
bool      SetPause;
bool      StartGame1,StartGame2;
bool      DrawGame;
bool      playsound[10];
//===============================
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
/**********构造函数*************
函数名:CGame()
用途:游戏开始前只初始化一次的
参数:
返回值:
其它:
********************************/
MyGame::MyGame()
{
//变量初始化
	DrawGame=false;
    ShowStage=false;
	StartGame1=false;
	StartGame2=false;
	SetPause=false;
	MainMenuSelect=0;
	ShowMainMenu=true;
	NewGame=false;
	player.blood =24;
	m_iFrameRate=FPS;

    ThisTick=0;
	LastTick=0;
	Fps=0;
	tFPS=0;
	SetFrameRate(m_iFrameRate);   //设置帧频(1秒30帧)

//加载声音文件到各次缓冲区
//    char c[10];
	dsound.CreateBuffer("Music\\menu.WAV",0);
	dsound.CreateBuffer("Music\\butt_press.wav",1);
    dsound.CreateBuffer("Music\\决定.wav",2);
	dsound.CreateBuffer("Music\\PShot.wav",3);
	dsound.CreateBuffer("Music\\EShot.wav",4);
	dsound.CreateBuffer("Music\\击中.WAV",5);
    dsound.CreateBuffer("Music\\爆炸.WAV",6);
    dsound.CreateBuffer("Music\\吸收.WAV",7);
    dsound.CreateBuffer("Music\\炸弹.WAV",8);

    for(i=0;i<9;i++){playsound[i]=false,playsound[0]=true;}
}

/******析构函数*****
函数名:~CGame()
用途:
参数:
返回值:
其它:
********************/
MyGame::~MyGame()
{
	FreeSpace();
//    ChangeDisplaySettings(NULL,0);  //恢复原有设置
}

/******************************
函数名:GameInit()
用途:每关开始前的游戏初始化
参数:程序主窗口句柄,程序实例句柄
返回值:初始化成功返回TRUE
其它:
*******************************/
BOOL MyGame::GameInit()
{
/*  MySprite= new CSprite;        //重新创建子画面

//读取地图文件
	char s[12];
    sprintf(s,"map\\%d.txt",MyFile->m_MapIndex);
    m_Mappath=s;
    MyFile->ReadFile(m_Mappath);

	CGame::GameMusic("sound\\BACK.MID",1,1);
*/
	//读取地图文件
	char s[15];
    //sprintf(s,"map\\MapDIY.map");
    if(MainMenuSelect==0){sprintf(s,"map\\%d.map",file.MapIndex);}
	if(MainMenuSelect==32){sprintf(s,"map\\MapDIY.map");}
    m_MapPath=s;
	file.ReadFile(m_MapPath);

	tank = new CTank[11];
	bullete= new CBullete[11];
	for(i=1;i<11;i++)
	{
		tank[i].OnShip=false;
		tank[i].BoomNow=false;
		tank[i].EatKind=0;
		short k=tank[i].things.kind=Rando(6);
		if(k!=0)
		{
			tank[i].things.BmpXY.x=k*23;
			tank[i].things.BmpXY.y=0;
			tank[i].things.LiveTime=10;
		}
		tank[i].showrect=false;
		tank[i].things.show=false;
		tank[i].blood=16;  //8的倍数
		tank[i].GetBulleteStartPoint=true;
		tank[i].way=1;
		tank[i].MoveSpeed=2;
		tank[i].ScreenXY.x=GAMET_X+i*64-32;		
		tank[i].ScreenXY.y=32;
		tank[i].MoveStop=false;
		tank[i].GetTankRect();      //	取得坦克矩形结构

		bullete[i].Speed=3;
		bullete[i].BulleteHit=true;
		bullete[i].ShowBomb=false;
	}
	tank[0].OnShip=false;
	tank[0].BoomNow=false;
	tank[0].showrect=false;
	tank[0].things.show=false;
	tank[0].EatKind=0;
    tank[0].blood =player.blood;
	tank[0].GetBulleteStartPoint=true;
	tank[0].way=3;
	tank[0].MoveSpeed=2;
	tank[0].ScreenXY.x=player.ScreenXY.x=GAMET_X+16*20;
	tank[0].ScreenXY.y=player.ScreenXY.y=16*30;
	tank[0].MoveStop=player.MoveStop=false;
	tank[0].GetTankRect();
	bullete[0].Speed=6;
	bullete[0].BulleteHit=true;
	bullete[0].ShowBomb=false;

	ddraw.showdoop=false;
	ddraw.PutDoop=0;
	ddraw.StartDoopTest=true;


	return  FALSE;
}

/******************************
函数名:GameStart()
用途:  开始游戏
参数:  无
返回值:无
其它:
*******************************/
void MyGame::GameStart()
{
	dinput.GetKey();
   
	GetFrameDelay();
//playsound
	if(playsound[0]){dsound.PlayWav(0,1);}
	else{dsound.StopWav(0);}
	for(i=1;i<9;i++)
	{
	    if(playsound[i]){dsound.PlayWav(i,0);playsound[i]=false;}
	}
//======================================================
	short t=0;
    for(i=1;i<11;i++)
	{
		if(tank[i].dead){t++;}
		else
		{
		//检测吃到的物品
          tank[i].EatKind=EatThingTest(tank[i].ScreenXY);
		  ChangeTankStyle(i,tank[i].EatKind);
		}
	}
    tank[0].ScreenXY=player.ScreenXY;
    tank[0].EatKind=EatThingTest(tank[0].ScreenXY);
    ChangeTankStyle(0,tank[0].EatKind);

	if(t==10)
	{
		t=0;
		file.NextFile=true;
		FreeSpace();
		file.MapIndex++;
		if(file.MapIndex>10){file.MapIndex=1;}
		GameInit();
		ShowStage=true;
		for(i=0;i<8;i++){playsound[i]=false,dsound.StopWav(i);}

		return ;
	}

	if(NewGame)
	{
		file.MapIndex=1;
		GameInit();
		tank[0].blood=24;

	}

//=========================================================
	ddraw.Render(); //绘制场景
/*
//文本
    DrawText(g_hOffscreenDC, 0  ,0,TRUE); 
	
    BitBlt(hdc1, 0, 0, 800, 600, g_hOffscreenDC, 0  ,0, SRCCOPY);  //绘制到屏幕
*/
}

/******************************
函数名:GameEnd()
用途:  清理
参数:  无
返回值:无
其它:
*******************************/
void MyGame::GameEnd()
{
/*
    delete  MyFile;
	delete  []MyBitmap;
	delete  MySprite;
*/
}

/******************************
函数名:HandleKeys()
用途:  取得键盘控制
参数:  无
返回值:无
其它:
*******************************/
void MyGame::HandleKeys()
{	
/*   用在DP中
//检测闪屏
    if(GetAsyncKeyState(VK_RETURN) < 0 && m_ShowStartScreen)
	{

	}
    if(GetAsyncKeyState(VK_RETURN) < 0 && m_ShowEndScreen)
	{

	}

//不是闪屏状态
  	if(!m_ShowStartScreen && !m_ShowEndScreen)  
	{
		if (GetAsyncKeyState(VK_LEFT) < 0 || GetAsyncKeyState('A') < 0)
		{
          //MessageBox(GetFocus(),"按下左方向键!","键盘消息!",MB_OK);
			if(m_movex !=0)m_movex -=10;
		}
		if (GetAsyncKeyState(VK_RIGHT) < 0 || GetAsyncKeyState('D') < 0)
		{
            if(m_movex <2*SCREEN_W)m_movex +=10;
		}
		if (GetAsyncKeyState(VK_UP) < 0 || GetAsyncKeyState('W') < 0)
		{
            if(m_movey!=0)m_movey-=10;
		}
		if (GetAsyncKeyState(VK_DOWN) < 0 || GetAsyncKeyState('S') < 0)
		{
            if(m_movey<2*SCREEN_H)m_movey+=10;
		}
		if (GetAsyncKeyState('J') < 0 )
		{

		}
		if (GetAsyncKeyState('K') < 0 )
		{}
	}
	*/
}

/******************************
函数名:SetFrameRate()
用途:  设置帧频
参数:  帧频率
返回值:无
其它:
*******************************/
inline void MyGame::SetFrameRate(int iFrameRate)
{
	m_iFrameDelay=1000/iFrameRate;  //得到1帧经过的毫秒数

}

/******************************
函数名:GetFrameDelay()
用途:  建立并进入游戏循环
参数:  无
返回值:无
其它:
*******************************/
void MyGame::GetFrameDelay()
{
	tFPS++;
	ThisTick = timeGetTime();  //须包含#include "mmsystem.h"
                               //和#pragma comment(lib,"winmm.lib")头文件
	if (ThisTick - LastTick > m_iFrameDelay )  //1帧
	{
		LastTick = ThisTick;
		Fps = tFPS;
		tFPS = 0;
        ddraw.OneFps=true;  //1帧
  
		    
		static short add=0;
		static short add2=0;
		static short add3=0;
		add++;add2++;add3++;
		if(add>=FPS){ddraw.OneSecond=true;add=0;}//1秒 
		else{ddraw.OneSecond=false;}
		if(add2>=FPS/15){ddraw.flash=true;add2=0;}  //1/15秒
		else{ddraw.flash=false;}
		if(add3>=FPS/2){ddraw.halfsecond=true;add3=0;}  //1/2秒
		else{ddraw.halfsecond=false;}
	//	HandleKeys();  //取得键盘控制

//     GamePaint(g_hOffscreenDC);  //绘制游戏
	}else{ddraw.OneFps=false;}
}

/******************************
函数名:GamePaint()
用途:  游戏重绘
参数:  离屏页DC
返回值:无
其它:
*******************************/
void MyGame::GamePaint(HDC &hDC)
{
/*	if(MyFile->NextFile)  //下一关
	{
		delete MySprite;
		GameInit();
        MyFile->NextFile=false;
	}
*/
/*
//背景	
    MySprite->Render(hDC,MySprite->flashdc);
    MySprite->DrawMenu(hdc2);
    BitBlt(hDC, m_movex  ,490+m_m_movey, 800, 600, hdc2, 0 ,0, SRCCOPY);  
//地图	 
	MySprite->DrawMap(hDC,21,17,32,32);
//物品(仅序号2、4、6、8的坦克可能携带)
	for(i=2;i<=8;i+=2){MySprite->DrawThings(hDC,i);} 
//坦克
	for(i=1;i<=10;i++){MySprite->DrawSharp(hDC,i);DrawBloodBar(hDC,i);}   //敌人
	MySprite->DrawPlayer(hDC);  //玩家
//血槽
    DrawBloodBar(hDC,0,RGB(0,255,0));
//子弹
	MySprite->DrawMyBullets(hDC,Bullet[0].m_MoveWay);  //玩家的
    MySprite->DrawBoom(hDC,0);  //玩家爆炸
	for(i=1;i<=10;i++)
	{
    MySprite->DrawEnemyBullets(hDC,Bullet[i].m_MoveWay,i);  //敌人的
    //爆炸
    MySprite->DrawBoom(hDC,i);
	}
//草地
	MySprite->DrawGress(hDC,21,17,32,32);
//开始的闪屏
	if(m_ShowStartScreen){MySprite->DrawFlassScreen(hDC,true);}
//游戏结束的闪屏
	if(m_ShowEndScreen){MySprite->DrawFlassScreen(hDC,false);}
*/
}

/******************************
函数名:DrawText()
用途:  绘制文本
参数:  离屏页DC,是否绘制
返回值:无
其它:
*******************************/
void MyGame::DrawText(HDC &hDC, int x, int y, BOOL draw)
{/*
	if(!draw){return;}
	SetTextColor(hDC,RGB(0,255,255));  //文本颜色
	SetBkMode(hDC,TRANSPARENT);        //背景透明

	char s8[9];
	ZeroMemory( s8, 9 );
	sprintf(s8, "每秒=%d帧", m_iFrameRate);
    TextOut(hDC,x,y,s8,9);
    TextOut(hDC,x,20+y,"ESC退出",7);

	char s1[6];
	ZeroMemory( s1, 6 );
	sprintf(s1, "第%d关", gs->GMT.y);
	TextOut(hDC,10,50,s1,6);

    char s2[7];
	ZeroMemory( s2, 7 );
	sprintf(s2, "敌人:%d", (10-(MySprite->m_DeadAdd)));
	TextOut(hDC,10,100,s2,7);

    char s3[13];
	ZeroMemory( s3, 13 );
	sprintf(s3, "有效时间:%d", MySprite->t);
	TextOut(hDC,350,550,s3,13);

    char s4[9];
	ZeroMemory( s4, 9 );
	sprintf(s4, "最高分:%d", Tank[0].m_MoveSpeed);
	TextOut(hDC,10,160,s4,9);

	char s9[5];
	ZeroMemory( s4, 5 );
	sprintf(s4, "分数:%d", Tank[0].m_rect.top);
	TextOut(hDC,10,160,s4,5);

	char s5[11];
	ZeroMemory( s5, 11 );
	sprintf(s5, "粒子数:%d", bomb->m_n);
	TextOut(hDC,150,550,s5,11);

	char s6[5];
	ZeroMemory( s5, 5 );
	sprintf(s6, "血:%d", Tank[0].m_blood);
	TextOut(hDC,10,180,s6,5);
*/
//	TextOut(hDC,650,550,"吴文捷 于 2007.11.5",19);
}

/****************************************************************
函数名:GameMusic()
用途:  播放游戏音乐和音效
参数:  音乐路径,音乐格式代号(1:MIDI,2:WAV,3:MP3),
        播放状态(0:停止,1播放,2:重播)
返回值:
其它:
*****************************************************************/
void MyGame::GameMusic(char *path, short n, short control)
{
	/*    用在DS中
   	if(m_ShowStartScreen){return;}
	if(n==1){playmusic.PlayMIDI(g_hwnd,path);}
    if(n==2){playmusic.PlayWav(path,false);}
	if(control==0){playmusic.Stop();}
	if(control==1){}
	if(control==2){playmusic.Replay();}   
	*/

}

/****************************************************************
函数名:SetDevMode()
用途:  设置显示模式
参数:  
返回值:
其它:
*****************************************************************/
void MyGame::SetDevMode()
{
	/*      DX环境中暂时不用
  	DEVMODE     lpDevMode;
	lpDevMode.dmBitsPerPel=32;
	lpDevMode.dmPelsWidth=SCREEN_W;
	lpDevMode.dmPelsHeight=SCREEN_H;
	lpDevMode.dmSize=sizeof(lpDevMode);
	lpDevMode.dmFields =DM_PELSWIDTH|DM_PELSHEIGHT|DM_BITSPERPEL;
	LONG result;
	result=ChangeDisplaySettings(&lpDevMode,0);
	if (result==DISP_CHANGE_SUCCESSFUL)
	{
	    //AfxMessageBox("修改成功!");
	    ChangeDisplaySettings(&lpDevMode,0);  //使用0表示动态修改//使用CDS_UPDATEREGISTRY表示次修改是持久的,//并在注册表中写入了相关的数据
	}
	else
	{
		MessageBox(GetFocus(),"修改失败,恢复原有设置!","窗口关闭!",MB_OK|MB_ICONHAND);
	    ChangeDisplaySettings(NULL,0);  //恢复原有设置
	}
	*/
}

void MyGame::FreeSpace()
{
	delete []tank;
	delete []bullete;
}

short MyGame::Rando(short n)
{
     short r=rand() % (n+1);             //r的范围在0~n间

 //    if(r==2 || r==5){r=rand() % (n+1);}  //减少定时和炸弹的出现几率

     return r;   
}

short MyGame::EatThingTest(POINT &TankScreenPoint)
{
	short  kind=0;

 	RECT RT,rect1,rect2;

	rect2.left=TankScreenPoint.x+1;
	rect2.top=TankScreenPoint.y+1;
	rect2.right=rect2.left+30;
	rect2.bottom=rect2.top+30;

	 for(int i=1;i<11;i++)
	 {
		if(tank[i].things.show)
		{
			int a=tank[i].things.ScreenXY.x;
			int b=tank[i].things.ScreenXY.y;
		  	SetRect(&rect1,a,b,a+23,b+23);  //物品矩形范围
            if(IntersectRect(&RT,&rect2,&rect1))
			{
				playsound[7]=true;
				kind=tank[i].things.kind;
			    tank[i].things.show=false;  //吃掉了不显示
				tank[i].things.LiveTime=0;
				//sound!			
				return  kind;
			} 
		}
	 }

	return  0;
}

void MyGame::ChangeTankStyle(int n, short &EatKind)
{
    switch (EatKind)
	{
	case 0:
		break;
	case 1:
		tank[n].MoveSpeed++;
		bullete[n].Speed+=2;
		break;
	case 2:
		if(n==0)
		{
			for(i=1;i<11;i++){tank[i].MoveStop=true;}
		}
		else{tank[0].MoveStop=true;}
		break;
	case 3:
		if(tank[n].blood<32){tank[n].blood+=8;}
		break;
	case 4:
		tank[n].showrect=true;
		break;
	case 5:
        ddraw.StartDoopTest=true;
		ddraw.showdoop=true;
		ddraw.setdoop =true;
		if(n==0){ddraw.PutDoop=1;}
		else{ddraw.PutDoop=2;}
		break;
	case 6:
        tank[n].OnShip=true;
		break;
	default:
		break;
	}

}

//DEL void MyGame::SetTimer(int n, short kind)
//DEL {/*
//DEL     static  int  tt;
//DEL 	if(kind==2)
//DEL 	{
//DEL 		tt++;
//DEL 	    if(tt>=10)
//DEL 		{
//DEL 			tt=0;
//DEL 			if(n==0){tank[0].MoveSpeed=2;}
//DEL 			for(i=1;i<11;i++)
//DEL 			{
//DEL 				if(kind==2){tank[i].MoveSpeed=2;}
//DEL                 tank[i].EatKind=0;
//DEL 			}
//DEL 		}
//DEL 	}
//DEL 	else{tt=0;}*/
//DEL }

⌨️ 快捷键说明

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