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

📄 tankframe.cpp

📁 疯狂坦克源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
 dir=rand()%100;
 if(dir<50)dir=3;
 else dir=rand()%3;//随生成方向,有50%的可能性往下走
 old=abs(tank->speedx+tank->speedy);

 switch(dir)//原理同UpdateOtank
 {
  case 0://左
  {
   if(tank->speedx>=0)
   {
    if((tank->y-TANK_YU)%12<6)tank->y=int((tank->y-TANK_YU)/12)*12+TANK_YU;
    else tank->y=int((tank->y-TANK_YU)/12)*12+TANK_YU+12; 
   }
   tank->speedx=-old;tank->speedy=0;tank->frame=2;
   break;
  }
  case 1://上
  {
   if(tank->speedy>=0)
   {
    if((tank->x-TANK_XL)%12<6)tank->x=int((tank->x-TANK_XL)/12)*12+TANK_XL;
    else tank->x=int((tank->x-TANK_XL)/12)*12+TANK_XL+12;
   }
   tank->speedy=-old;tank->speedx=0;tank->frame=0;
   break;
  }
  case 2://右
  {
   if(tank->speedx<=0)
   {
    if((tank->y-TANK_YU)%12<6)tank->y=int((tank->y-TANK_YU)/12)*12+TANK_YU;
    else tank->y=int((tank->y-TANK_YU)/12)*12+TANK_YU+12; 
   }
   tank->speedx=old;tank->speedy=0;tank->frame=3;
   break;
  }
  case 3://下
  {
   if(tank->speedy<=0)
   { 
    if((tank->x-TANK_XL)%12<6)tank->x=int((tank->x-TANK_XL)/12)*12+TANK_XL;
    else tank->x=((tank->x-TANK_XL)/12*12)+TANK_XL+12; 	  
   }
   tank->speedy=old;tank->speedx=0;tank->frame=1;
   break;
  } 
 }
}

/*-------------------------------------
判断两个矩形区域是否有重合部分
--------------------------------------*/
BOOL CTankFrame::CheckIn(RECT &rec1,RECT &rec2)
{
 int wd,ht;
 wd=(rec2.right-rec2.left)/2;
 ht=(rec2.bottom-rec2.top)/2;
 /*判断src2的四个顶点及四条边的中点是否在src1内*/
 if((rec2.left>rec1.left&&rec2.left<rec1.right)&&
    (rec2.top>rec1.top&&rec2.top<rec1.bottom))return TRUE;
 if((rec2.right>rec1.left&&rec2.right<rec1.right)&&
    (rec2.top>rec1.top&&rec2.top<rec1.bottom))return TRUE;
 if((rec2.left>rec1.left&&rec2.left<rec1.right)&&
    (rec2.bottom>rec1.top&&rec2.bottom<rec1.bottom))return TRUE;
 if((rec2.right>rec1.left&&rec2.right<rec1.right)&&
    (rec2.bottom>rec1.top&&rec2.bottom<rec1.bottom))return TRUE;
 
 if(((rec2.left+wd)>rec1.left&&(rec2.left+wd)<rec1.right)&&
    (rec2.top>rec1.top&&rec2.top<rec1.bottom))return TRUE;
 if((rec2.right>rec1.left&&rec2.right<rec1.right)&&
    ((rec2.top+ht)>rec1.top&&(rec2.top+ht)<rec1.bottom))return TRUE;
 if(((rec2.left+wd)>rec1.left&&(rec2.left+wd)<rec1.right)&&
    (rec2.bottom>rec1.top&&rec2.bottom<rec1.bottom))return TRUE;
 if((rec2.left>rec1.left&&rec2.left<rec1.right)&&
    ((rec2.top+ht)>rec1.top&&(rec2.top+ht)<rec1.bottom))return TRUE;
  
 return FALSE;
}

/*-----------------------------------------
生成子弹
------------------------------------------*/
LPSHOT CTankFrame::CreateShot(int x,int y,int dx,int dy,BYTE type,int force)
{
 LPSHOT shot;
 shot=new SHOT;
 if(shot==NULL)Fail("内存不够!");
 shot->frame=type;
 shot->type=type;
 shot->x=x;
 shot->y=y;
 shot->speedx=dx;
 shot->speedy=dy;
 shot->force=force;
 shot->timeupdate=timeGetTime();
 Add(shot);//加入子弹链表
 return shot;
}

/*----------------------------------------------
生成我方坦克
-----------------------------------------------*/
BOOL CTankFrame::CreateOtank(LPOTANK tank,BYTE type)
{
 InitOtank(tank,type);//部分初始化
 tank->speedy=-config.speed;
 tank->speed=24;
 tank->type=type;
 tank->force=1;
 tank->firemaxnum=2;
 return TRUE; 
}

/*-----------------------------------------------
部分初始化otank参数----过关时初始化
------------------------------------------------*/
BOOL CTankFrame::InitOtank(LPOTANK tank,BYTE type)
{
 if(type==0)tank->x=9*24+TANK_XL;
 else tank->x=13*24+TANK_XL;
 tank->y=17*24+TANK_YU;
 tank->frame=10;
 tank->firenum=0;
 tank->timefire=timeGetTime();
 tank->timeupdate=timeGetTime();
 tank->CtrlD=0;
 tank->CtrlF=0;
 tank->status=0;
 tank->bornd=1;
 tank->speedy=-abs(tank->speedx)-abs(tank->speedy);
 tank->speedx=0;
 tank->timestart=timeGetTime();
 return TRUE; 
}

/*----------------------------------------------
生成敌方坦克
-----------------------------------------------*/
LPTANK CTankFrame::CreateTank(int x,int y,BYTE type)
{
 LPTANK tank;
 tank=new TANK;
 if(tank==NULL)Fail("不能生成,内存不够!");
 tank->frame=10;
 tank->timeupdate=timeGetTime();
 tank->timeborn=tank->timeupdate;
 tank->timestart=tank->timeupdate;
 tank->timefire=tank->timeupdate;
 tank->type=type;
 tank->x=x;
 tank->y=y;
 tank->speedx=0;
 switch(type)
 {
  case 0://一般坦克
  {
   tank->speedy=config.speed;
   tank->speed=24;
   tank->life=0;
   break;
  }
  case 1://速度快的坦克
  {
   tank->speedy=config.speed*3/2;
   tank->speed=24;
   tank->life=1;
   break;
  }
  case 2://子弹速度快的坦克
  {
   tank->speedy=config.speed;
   tank->speed=36;
   tank->life=1;
   break;
  }
  case 3://装甲坦克
  {
   tank->speedy=config.speed*3/4;
   tank->speed=24;
   tank->life=4;
   break;
  }
 } 
  
 tank->force=1;
 tank->status=0;
 Add(tank);//加入敌方坦克链表
 return tank;
}

/*---------------------------------------------
生成爆炸效果及宝物
----------------------------------------------*/
LPAPPL CTankFrame::CreateAppl(int x,int y,BYTE type)
{
 LPAPPL appl;
 if(type==0)//类型0--爆炸效果
 {
  appl=new APPL;
  if(appl==NULL)Fail("不能生成,内存不够!");
  if(x<=TANK_XL)x=TANK_XL;
  if(x>=TANK_XR-30)x=TANK_XR-30;
  if(y<=TANK_YU)y=TANK_YU;
  if(y>=TANK_YD-30)y=TANK_YD-30;//爆炸效果是30*30的
  appl->frame=0;
  appl->x=x;
  appl->y=y;
  appl->type=type;
  appl->timeupdate=timeGetTime();
  Add(appl);//加入爆炸效果链表
  return appl;
 }
 else//类型1-9--宝物
 {
  bons.x=x;
  bons.y=y;
  bons.type=type;
  bons.frame=type-1;
  bons.valid=1;//宝物有效
  return NULL;
 }
}

/*------------------------------------------------------
画我方坦克
-------------------------------------------------------*/
HRESULT CTankFrame::DrawOtanks(LPDIRECTDRAWSURFACE lpDDS)
{
 HRESULT ddrval=DD_OK;
 RECT src;
 DWORD dwTime;

 for(int i=0;i<config.playernum;i++)
 { 
  if(players[i].lifenum==0)continue;//阵亡就不画
  src.top=players[i].type*24;
  src.left=players[i].frame*24;
  src.right=src.left+24;
  src.bottom=src.top+24;
  if(players[i].status==2) 
   ddrval=lpDDS->BltFast((DWORD)players[i].x,(DWORD)players[i].y,lpDDSOtank,&src,
                         DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT); 
  else if(players[i].status==0)//出生状态
  {
   src.top=0;
   src.bottom=24;
   ddrval=lpDDS->BltFast((DWORD)players[i].x,(DWORD)players[i].y,lpDDSAppl,&src,
                         DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT); 
  }
  else if(players[i].status==1||players[i].status==3)//保护和长保护状态
  {
   dwTime=timeGetTime();
   if((dwTime-players[i].superupdate)>30)//每30ms画一次,产生闪烁效果
   {
    ddrval=lpDDS->BltFast((DWORD)players[i].x,(DWORD)players[i].y,lpDDSOtank,&src,
                           DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT); 
    players[i].superupdate=dwTime;
   }
  }
  if FAILED(ddrval)Fail("不能输出我方坦克!");
 } 
 return ddrval;
} 

/*---------------------------------------------------
画敌方坦克
----------------------------------------------------*/
HRESULT CTankFrame::DrawTanks(LPDIRECTDRAWSURFACE lpDDS)
{
 HRESULT ddrval=DD_OK;
 RECT src;
 LPTANK tank;
 DWORD dwTime;
 
 tank=top->next;
 while(tank)//画每一辆敌方坦克
 {
  src.top=tank->type*24;
  src.bottom=src.top+24;
  src.left=tank->frame*24;
  src.right=src.left+24;
  if(tank->status==2) 
   ddrval=lpDDS->BltFast((DWORD)tank->x,(DWORD)tank->y,lpDDSTank,&src,
                        DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT); 
  else if(tank->status==0)//出生状态
  {
   src.top=0;
   src.bottom=24;
   ddrval=lpDDS->BltFast((DWORD)tank->x,(DWORD)tank->y,lpDDSAppl,&src,
                         DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT); 
  }
  else if(tank->status==1)//保护状态
  {
   dwTime=timeGetTime();
   if((dwTime-tank->superupdate)>30)
   {
    ddrval=lpDDS->BltFast((DWORD)tank->x,(DWORD)tank->y,lpDDSTank,&src,
                           DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT); 
    tank->superupdate=dwTime;
   }
  } 
  
  if FAILED(ddrval)Fail("不能输出敌方坦克!");
  tank=tank->next;
 }
 return ddrval;
}
 
/*----------------------------------------------------
画子弹
-----------------------------------------------------*/
HRESULT CTankFrame::DrawShots(LPDIRECTDRAWSURFACE lpDDS)
{
 HRESULT ddrval=DD_OK;
 RECT src;
 LPSHOT shot;
 shot=tops->next;
 while(shot!=NULL)//画每一颗子弹
 {
  src.left=shot->frame*4;
  src.top=0;
  src.right=src.left+4;
  src.bottom=4;
  ddrval=lpDDS->BltFast((DWORD)shot->x,(DWORD)shot->y,lpDDSShot,&src,DDBLTFAST_WAIT);
  if FAILED(ddrval)Fail("不能输出子弹!");
  shot=shot->next;
 }   
 return ddrval;
}

/*-----------------------------------------------------
画爆炸效果及宝物
------------------------------------------------------*/
HRESULT CTankFrame::DrawAppls(LPDIRECTDRAWSURFACE lpDDS)
{
 HRESULT ddrval=DD_OK;
 RECT src;
 LPAPPL appl;
 appl=topa->next;
 while(appl!=NULL)//画每一个爆炸效果
 {
  src.left=appl->frame*30;
  src.top=0;
  src.right=src.left+30;
  src.bottom=30;
  ddrval=lpDDS->BltFast((DWORD)appl->x,(DWORD)appl->y,lpDDSExplo,&src,
						DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT);
  if FAILED(ddrval) Fail("不能画爆炸效果"); 
  appl=appl->next;
 }  
 if(bons.valid==1)//宝物有效就画
 {
  src.left=bons.frame*24;
  src.top=0;
  src.right=src.left+24;
  src.bottom=24;
  ddrval=lpDDS->BltFast((DWORD)bons.x,(DWORD)bons.y,lpDDSAppl,&src,
       					DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT);
  if FAILED(ddrval) Fail("不能画宝物");
 }
 return ddrval;
}

/*-------------
画水
--------------*/
HRESULT CTankFrame::DrawWater(LPDIRECTDRAWSURFACE lpDDS)
{
 HRESULT ddrval=DD_OK;
 RECT src;
 DWORD time;
 int i,j;
 
 time=timeGetTime();
 if((time-mapupdate)>500)//每隔500ms更新一次
 {
  mapupdate=time;
  for(i=0;i<36;i++)
   for(j=0;j<46;j++)
   {
    if(mp.array[i][j]==8||mp.array[i][j]==9)
	{
	 if(mp.array[i][j]==8)mp.array[i][j]=9;//8、9相互交换
     else mp.array[i][j]=8;
     src.left=mp.array[i][j]*12;
     src.top=0;
     src.right=src.left+12;
     src.bottom=12;
     ddrval=lpDDS->BltFast((DWORD)j*12,(DWORD)i*12,lpDDSMap,&src,DDBLTFAST_WAIT);
     if FAILED(ddrval) Fail("不能输出水!");
    }
   }
 }     
 return ddrval;
}

/*------------------------------
响应窗口被激活消息
-------------------------------*/
void CTankFrame::Active()
{
}

/*-------------------------------------
游戏结束善后工作
--------------------------------------*/
void CTankFrame::End()
{
}

/*--------------------------------------
响应键盘按键消息
---------------------------------------*/
void CTankFrame::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) 
{
	// TODO: Add your message handler code here and/or call default
 
 int i,j,tkn1=0,tkn2=0;
 
 if(nChar==VK_ESCAPE)DestroyWindow();//ESC退出
 if(nChar==config.start)//开始键
 {
  if(mode.gamestatus==0)mode.gamestatus=1;
  else if(mode.gamestatus==2)
  {
   mciSendCommand(wDeviceID,MCI_CLOSE,MCI_WAIT,NULL);
   mode.isplay=FALSE;
   mode.gamestatus=7;
  }
  else if(mode.gamestatus==4)
  {
   mciSendCommand(wDeviceID,MCI_CLOSE,MCI_WAIT,NULL);
   mode.isplay=FALSE;
   spd=0;
   txtupdate=timeGetTime();
   mode.gamestatus=6;
   for(i=0;i<config.playernum;i++)
	for(j=0;j<4;j++)
	 players[i].score=players[i].score+100*(j+1)*players[i].tank[j];//计算总分
  }
  else if(mode.gamestatus==5)
  {
   mciSendCommand(wDeviceID,MCI_CLOSE,MCI_WAIT,NULL);
   mode.isplay=FALSE;
   spd=0;
   txtupdate=timeGetTime();
   mode.gamestatus=8;
   for(i=0;i<config.playernum;i++)
	for(j=0;j<4;j++)
	 players[i].score=players[i].score+100*(j+1)*players[i].tank[j];//计算总分
   if(config.playernum==2)
   {
	for(j=0;j<4;j++)
	{
	 tkn1+=players[0].tank[j];
	 tkn2+=players[1].tank[j];
    }
	if(tkn1>tkn2)players[0].score+=1000;
	else players[1].score+=1000;//1000分奖励
   }
  }
  else if(mode.gamestatus==6)
  {
   mode.gamestatus=0;
   mode.stage=0;
   DestroyLink();
   for(i=0;i<config.playernum;i++)
	for(j=0;j<4;j++)
	 players[i].score=players[i].score+100*(j+1)*players[i].tank[j];//计算总分
  }
  else if(mode.gamestatus==8)
  {
   mode.gamestatus=1;
   DestroyLink();

⌨️ 快捷键说明

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