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

📄 tankframe.cpp

📁 疯狂坦克源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*-----------------------------------------------------
坦克大决战主窗口实现
版权所有:JT Studio 王景焘
2001年12月  保留所有权利
-------------------------------------------------------*/

#include "stdafx.h"
#include "Tank.h"
#include "TankFrame.h"
#include <math.h>
#include <stdio.h>


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CTankFrame

//IMPLEMENT_DYNCREATE(CTankFrame,CWnd)

CTankFrame::CTankFrame()
{
 int x,y;
 x=::GetSystemMetrics(SM_CXSCREEN);//显示屏幕宽度
 y=::GetSystemMetrics(SM_CYSCREEN);

 CRect rect((x-640)/2,(y-480)/2,(x-640)/2+640,(y-480)/2+480);

 LPCSTR strClass=AfxRegisterWndClass(CS_DBLCLKS,::LoadCursor(NULL,IDC_ARROW),
                                     (HBRUSH)GetStockObject(BLACK_BRUSH),  
                                     AfxGetApp()->LoadIcon(IDR_MAINFRAME));

 if(CreateEx(WS_EX_APPWINDOW,strClass,"坦克大决战",WS_POPUP,rect.left,rect.top,
             rect.Width(),rect.Height(),NULL,NULL,0)==FALSE)exit(1);  
}

CTankFrame::~CTankFrame()
{ 
 ReleaseObjects();//释放DirectX资源
 Cleanup();//释放多媒体文件资源
 DestroyLink();//释放链表资源
 delete top;
 delete tops;
 delete topt;
 delete topa;//释放表头
 mciSendCommand(wDeviceID,MCI_CLOSE,MCI_WAIT,NULL);//释放背景midi
}

BEGIN_MESSAGE_MAP(CTankFrame, CWnd)
	//{{AFX_MSG_MAP(CTankFrame)
	ON_WM_ACTIVATEAPP()
	ON_WM_KEYDOWN()
	ON_WM_KEYUP()
	ON_MESSAGE(MM_MCINOTIFY,OnMciNotify)//背景midi播完消息
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// CTankFrame message handlers

void CTankFrame::OnActivateApp(BOOL bActive, HTASK hTask) 
{
	CWnd::OnActivateApp(bActive, hTask);
	
	// TODO: Add your message handler code here
	window_active = bActive;
}

/*--------------------------------------------------
初始化函数
----------------------------------------------------*/
void CTankFrame::Init()
{
 DDCOLORKEY ddck;
 FILE *fp;
 CDC *cdc;

 cdc=GetDC();
 cdc->SetBkMode(TRANSPARENT);
 cdc->SetTextColor(RGB(255,255,0));
 cdc->TextOut(250,200,"正在初始化,请稍候...");
 ReleaseDC(cdc);
 /*全局变量初始化*/ 
 FrameTime=timeGetTime();
 FrameCount=0;
 Frames=0;
 FrameTime=timeGetTime();
 mapupdate=timeGetTime();
 top=new TANK;
 tops=new SHOT;
 topt=new TREE;
 topa=new APPL;
 if(top==NULL||tops==NULL||topt==NULL||topa==NULL)Fail("链表初始化错误!");
 top->next=NULL;
 tops->next=NULL;
 topt->next=NULL;
 topa->next=NULL;
 end=top;
 ends=tops;
 endt=topt;
 enda=topa;//初始化链表
 lpDSBFire=NULL;
 lpDSBExplo=NULL;
 lpDSBBem=NULL;
 lpDSBBon=NULL;
 if(FAILED(InitDdraw()))Fail("DirectDraw初始化错误!");
 lpDDSOtank=DDLoadBmp(lpDD,"OTANK",0,0,0);
 lpDDSTank=DDLoadBmp(lpDD,"TANK",0,0,0);
 lpDDSShot=DDLoadBmp(lpDD,"SHOT",0,0,0);
 lpDDSMap=DDLoadBmp(lpDD,"MAP",0,0,0);
 lpDDSAppl=DDLoadBmp(lpDD,"APPL",0,0,0);
 lpDDSExplo=DDLoadBmp(lpDD,"EXPLO",0,0,0);
 if(lpDDSOtank==NULL||lpDDSShot==NULL||lpDDSMap==NULL
    ||lpDDSTank==NULL||lpDDSExplo==NULL||lpDDSAppl==NULL)
  Fail("图片资源加载错误!");
 
 if(FAILED(InitDsound()))Fail("DirectSound初始化错误!");
 LoadStatic(lpDS,"Explo.wav",lpDSBExplo);
 LoadStatic(lpDS,"fire.wav",lpDSBFire);
 LoadStatic(lpDS,"BEM.wav",lpDSBBem);
 LoadStatic(lpDS,"BON.wav",lpDSBBon);
 if(lpDSBExplo==NULL||lpDSBFire==NULL||
    lpDSBBem==NULL||lpDSBBon==NULL)Fail("声音资源加载错误!");

 /*设置黑色为关键色*/
 ddck.dwColorSpaceLowValue=RGB(0,0,0);
 ddck.dwColorSpaceHighValue=RGB(0,0,0);
 lpDDSOtank->SetColorKey(DDCKEY_SRCBLT,&ddck);
 lpDDSTank->SetColorKey(DDCKEY_SRCBLT,&ddck);
 lpDDSGround->SetColorKey(DDCKEY_SRCBLT,&ddck);
 lpDDSMap->SetColorKey(DDCKEY_SRCBLT,&ddck);
 lpDDSAppl->SetColorKey(DDCKEY_SRCBLT,&ddck);
 lpDDSExplo->SetColorKey(DDCKEY_SRCBLT,&ddck);
 
 /*加载配置文件*/  
 fp=fopen("tank.cfg","rb");
 if(fp==NULL)Fail("配置文件错误!");
 if(fread(&config,sizeof(config),1,fp)!=1)Fail("读取配置文件错误!"); 
 fclose(fp);
 config.playernum=1;

 srand(timeGetTime());//初始化随机数发生器
 /*初始化游戏状态变量*/
 mode.gamestatus=0;
 mode.stage=0; 
 mode.isplay=FALSE;
 /*字体动画变量*/
 txtupdate=timeGetTime();
 spd=0; 
}

/*-------------------------------------
初始化具体关卡
---------------------------------------*/
void CTankFrame::InitStage()
{
 int i;

 if(!mode.isplay)
 {
  sprintf(fname,"bkm%d.mid",rand()%6+1);//随机生成背景音乐的文件名
  PlayMid();
 }
 if(config.playernum==1)mp.tanknum=4;
 DisMap();//显示地图
 for(i=0;i<config.playernum;i++)
 { 
  InitOtank(&players[i],i);//初始化我方坦克 
  for(int j=0;j<4;j++)players[i].tank[j]=0;
 }
 bons.valid=0;//宝物无效
 mode.status=0;
}

/*---------------------------------------------
加载地图初始化地图变量
-----------------------------------------------*/
BOOL CTankFrame::LoadMap()
{
 FILE *fp;
  
 mode.tanknum=0;//同现坦克数为0
 
 fp=fopen("mm.map","rb");
 if(fp==NULL)return FALSE;  
 fseek(fp,sizeof(mp)*(long)mode.stage,SEEK_SET);
 if(!fread(&mp,sizeof(mp),1,fp))
 {
  mode.stage=0;
  fseek(fp,0L,SEEK_SET);
  if(!fread(&mp,sizeof(mp),1,fp))return FALSE;
 }//如果读文件失败就读第一关
 mode.stage++;
 fclose(fp);
 return TRUE;
}  

/*-----------------------------------------------
显示所加载的地图
-------------------------------------------------*/
void CTankFrame::DisMap()
{
 int i,j; 
 RECT src; 
 LPTREE tree;
    
 Cls(lpDDSGround,RGB(0,0,0));//背景页面为黑色 
 for(i=0;i<36;i++)
 {
  for(j=0;j<46;j++)
  {
   if(mp.array[i][j]==7)//如果是树林就保存
   {
    tree=new TREE;
	if(tree==NULL)Fail("内存不够!");
	tree->x=i;
	tree->y=j;
	tree->next=NULL;
    endt->next=tree;  
    endt=tree;
    mp.array[i][j]=0;
   }
   else	    
   {
    src.top=0;
    src.left=mp.array[i][j]*12;
	if(mp.array[i][j]==11)src.left=6*12;
    src.right=src.left+12;
    src.bottom=12;
    if(FAILED(lpDDSGround->BltFast(12*j,12*i,lpDDSMap,&src,
	                               DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT)))
	 Fail("不能显示地图");//将地图元素画到背景页
   }
  }       
 }
}

/*--------------------------------------
游戏循环
----------------------------------------*/
void CTankFrame::Go()
{
 HDC hdc;
 HFONT ft,oldf;
 HGDIOBJ hpen,hold;
 DWORD time;
 RECT src;
 char tm[128];
 int i,j,stg,tkn1=0,tkn2=0,score;

 if(mode.gamestatus==0)//状态0--标题画面
 {
  time=timeGetTime();
  if((time-txtupdate)>50&&spd<=420)//字体动画
  {
   Cls(lpDDSBack,RGB(0,0,0));
   lpDDSBack->GetDC(&hdc);
   SetBkMode(hdc,TRANSPARENT);
   ft=CreateFont(100,0,0,0,500,FALSE,FALSE,0,DEFAULT_CHARSET,
                 OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
                 DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"隶书");
   oldf=(HFONT)SelectObject(hdc,ft);
   SetTextColor(hdc,RGB(136,234,28));
   TextOut(hdc,70,480-spd,"坦克大决战",10);
   SelectObject(hdc,oldf);
   DeleteObject(ft);
   ft=CreateFont(30,0,0,0,200,FALSE,FALSE,0,DEFAULT_CHARSET,
                 OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
                 DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"楷体_GB2312"); 
   oldf=(HFONT)SelectObject(hdc,ft);
   SetTextColor(hdc,RGB(220,234,28));
   TextOut(hdc,260,600-spd,"版本 1.0b",9);
   TextOut(hdc,280,680-spd,"单人游戏",8);
   TextOut(hdc,280,720-spd,"双人游戏",8);
   SelectObject(hdc,oldf);
   DeleteObject(ft);
   ft=CreateFont(20,0,0,0,200,FALSE,FALSE,0,DEFAULT_CHARSET,
                 OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
                 DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,NULL);
   oldf=(HFONT)SelectObject(hdc,ft);
   SetTextColor(hdc,RGB(220,55,33));
   TextOut(hdc,170,830-spd,"版权所有 JT Studio  王景焘  2001年12月",38);
   TextOut(hdc,260,860-spd,"保留所有权利",12);
   SelectObject(hdc,oldf);
   DeleteObject(ft);
   lpDDSBack->ReleaseDC(hdc);
   txtupdate=time;
   spd+=10; 
   if FAILED(lpDDSPrimary->Flip(NULL,DDFLIP_WAIT))Fail("不能翻转页面!");//翻转页面
  }
  if(spd>=420)//画选择坦克、写最初任务
  { 
   src.top=0;
   src.left=72;
   src.bottom=24;
   src.right=96;
   if(FAILED(lpDDSPrimary->BltFast(240,225+config.playernum*40,lpDDSOtank,&src,
                            DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT)))Fail("不能生成标题画面"); 
   lpDDSPrimary->GetDC(&hdc);
   ft=CreateFont(20,0,0,0,200,FALSE,FALSE,0,DEFAULT_CHARSET,
                 OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
                 DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"楷体_GB2312");
   oldf=(HFONT)SelectObject(hdc,ft);
   SetTextColor(hdc,RGB(0,255,255));
   SetBkColor(hdc,RGB(0,0,0));
   sprintf(tm,"任务%02d",mode.stage+1);
   TextOut(hdc,280,350,tm,6);
   SelectObject(hdc,oldf);
   DeleteObject(ft);
   lpDDSPrimary->ReleaseDC(hdc); 
  }
  for(int i=0;i<config.playernum;i++)CreateOtank(&players[i],i);//生成我方坦克
  players[0].score=0;players[0].lifenum=5;
  players[1].score=0;players[1].lifenum=5;//分数为0,初始坦克数量为5
 } 
 else if(mode.gamestatus==1)//状态1--加载地图
 { 
  LoadMap();
  mode.gamestatus=2; 
 }
 else if(mode.gamestatus==2)//状态2--任务画面
 {
  Cls(lpDDSBack,RGB(60,113,60));
  if(!mode.isplay)
  {
   strcpy(fname,"start.mid");
   PlayMid();//播放开始音乐
   mode.isplay=TRUE;
  }
  lpDDSBack->GetDC(&hdc);
  SetBkMode(hdc,TRANSPARENT);
  ft=CreateFont(50,0,0,0,200,FALSE,FALSE,0,DEFAULT_CHARSET,
                 OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
                 DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,NULL);
  oldf=(HFONT)SelectObject(hdc,ft);
  SetTextColor(hdc,RGB(255,255,255));
  if(mode.stage==0)stg=1;
  else stg=mode.stage;
  sprintf(tm,"任务 %d",stg);
  TextOut(hdc,210,220,tm,strlen(tm));  
  SelectObject(hdc,oldf);
  DeleteObject(ft); 
  lpDDSBack->ReleaseDC(hdc);
  if FAILED(lpDDSPrimary->Flip(NULL,DDFLIP_WAIT))Fail("不能翻转页面!");//翻转页面   
 } 
 else if(mode.gamestatus==7)//状态7--初始化关卡
 { 
  InitStage();
  mode.gamestatus=3;
  txtupdate=timeGetTime();
  spd=0;//恢复字体动画变量
 } 
 else if(mode.gamestatus==3)//状态3--正常游戏
 {
  if((mp.tank[0]+mp.tank[1]+mp.tank[2]+mp.tank[3]+mode.tanknum)==0)mode.gamestatus=5;//任务完成
  if(players[0].lifenum==0&&config.playernum==1||
     players[0].lifenum==0&&players[1].lifenum==0&&config.playernum==2)mode.gamestatus=4;//任务失败
  Cls(lpDDSBack,RGB(0,0,0));
  Update();//更新游戏画面
 }	
 else if(mode.gamestatus==4)//状态4--任务失败
 {
  Update();
  time=timeGetTime();
  if((time-txtupdate)>50&&spd<=250)
  {
   txtupdate=time;
   spd+=5; 
  }//设置字体动画变量    
  lpDDSPrimary->GetDC(&hdc);
  IntersectClipRect(hdc,TANK_XL,TANK_YU,TANK_XR,TANK_YD);
  SetBkMode(hdc,TRANSPARENT);
  ft=CreateFont(50,0,0,0,500,FALSE,FALSE,0,DEFAULT_CHARSET,
                OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
                DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"隶书");
  oldf=(HFONT)SelectObject(hdc,ft);
  SetTextColor(hdc,RGB(255,28,28));
  TextOut(hdc,180,480-spd,"任务失败",8);
  SelectObject(hdc,oldf);
  DeleteObject(ft);
  lpDDSPrimary->ReleaseDC(hdc);       
 }
 else if(mode.gamestatus==5)//状态5--任务完成
 {
  Update();
  time=timeGetTime();
  if((time-txtupdate)>50&&spd<=250)
  {
   txtupdate=time;
   spd+=5; 
  }//设置字体动画变量
  lpDDSPrimary->GetDC(&hdc);
  IntersectClipRect(hdc,TANK_XL,TANK_YU,TANK_XR,TANK_YD);
  SetBkMode(hdc,TRANSPARENT);
  ft=CreateFont(50,0,0,0,500,FALSE,FALSE,0,DEFAULT_CHARSET,
                OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
                DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"隶书");
  oldf=(HFONT)SelectObject(hdc,ft);
  SetTextColor(hdc,RGB(28,255,28));
  TextOut(hdc,180,480-spd,"任务完成",8);
  SelectObject(hdc,oldf);
  DeleteObject(ft);
  lpDDSPrimary->ReleaseDC(hdc);
 }
 else if(mode.gamestatus==6)//状态6--游戏失败分数画面
 {
  Cls(lpDDSBack,RGB(0,0,0));
  src.top=0;
  src.left=72;
  src.bottom=24;
  src.right=96;
  /*画各种敌方坦克*/
  if(FAILED(lpDDSBack->BltFast(200,200,lpDDSTank,&src,
                            DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT)))Fail("不能生成得分画面");  
  src.top+=24;
  src.bottom+=24;
  if(FAILED(lpDDSBack->BltFast(250,200,lpDDSTank,&src,
                            DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT)))Fail("不能生成得分画面");
  src.top+=24;
  src.bottom+=24;
  if(FAILED(lpDDSBack->BltFast(300,200,lpDDSTank,&src,
                            DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT)))Fail("不能生成得分画面");
  src.top+=24;
  src.bottom+=24;
  if(FAILED(lpDDSBack->BltFast(350,200,lpDDSTank,&src,
                            DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT)))Fail("不能生成得分画面");
  
  for(i=0;i<config.playernum;i++)
  { 
   src.top=24*i;
   src.bottom=src.top+24;
   if(FAILED(lpDDSBack->BltFast(90,240+40*i,lpDDSOtank,&src,
                            DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT)))Fail("不能生成得分画面");
  }//画我方坦克
  lpDDSBack->GetDC(&hdc);
  SetBkMode(hdc,TRANSPARENT);
  ft=CreateFont(50,0,0,0,500,FALSE,FALSE,0,DEFAULT_CHARSET,
                OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,
                DEFAULT_QUALITY,DEFAULT_PITCH|FF_SWISS,"仿宋GB_2312");
  oldf=(HFONT)SelectObject(hdc,ft);
  SetTextColor(hdc,RGB(255,28,28));
  TextOut(hdc,200,50,"任务失败!",10);
  SelectObject(hdc,oldf);
  DeleteObject(ft);
  sprintf(tm,"第%02d关",mode.stage);
  TextOut(hdc,280,130,tm,6); 
  TextOut(hdc,405,200,"奖励",4);
  TextOut(hdc,455,200,"加分",4);
  TextOut(hdc,550,200,"总分",4);
  hpen=CreatePen(PS_SOLID,1,RGB(255,255,0));
  hold=SelectObject(hdc,hpen);
  MoveToEx(hdc,30,190,NULL);
  LineTo(hdc,610,190);
  for(i=0;i<config.playernum+1;i++)
  {
   MoveToEx(hdc,30,190+40*i,NULL);
   LineTo(hdc,30,230+40*i);
   MoveToEx(hdc,185,190+40*i,NULL);
   LineTo(hdc,185,230+40*i);
   MoveToEx(hdc,235,190+40*i,NULL);
   LineTo(hdc,235,230+40*i);
   MoveToEx(hdc,285,190+40*i,NULL);
   LineTo(hdc,285,230+40*i);
   MoveToEx(hdc,335,190+40*i,NULL);
   LineTo(hdc,335,230+40*i);
   MoveToEx(hdc,385,190+40*i,NULL);
   LineTo(hdc,385,230+40*i);
   MoveToEx(hdc,445,190+40*i,NULL);
   LineTo(hdc,445,230+40*i);
   MoveToEx(hdc,515,190+40*i,NULL);

⌨️ 快捷键说明

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