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

📄 tankframe.cpp

📁 疯狂坦克源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
   LineTo(hdc,515,230+40*i);
   MoveToEx(hdc,610,190+40*i,NULL);
   LineTo(hdc,610,230+40*i); 
   MoveToEx(hdc,30,230+40*i,NULL);
   LineTo(hdc,610,230+40*i);   
   if(i==0)continue;
   score=0;
   for(j=0;j<4;j++)
   {
    sprintf(tm,"%2d",players[i-1].tank[j]);
    TextOut(hdc,200+50*j,205+40*i,tm,2);  
    score+=players[i-1].tank[j]*100*(j+1);
   }
   sprintf(tm,"%d",score);
   TextOut(hdc,450,205+40*i,tm,strlen(tm));
   sprintf(tm,"%d",players[i-1].score);
   TextOut(hdc,520,205+40*i,tm,strlen(tm));
  }//画表格及玩家分数
  SelectObject(hdc,hold);
  DeleteObject(hpen);  
  lpDDSBack->ReleaseDC(hdc);
  if FAILED(lpDDSPrimary->Flip(NULL,DDFLIP_WAIT))Fail("不能翻转页面!");//翻转页面
 }
 else if(mode.gamestatus==8)//状态8--游戏成功分数画面
 {
  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(28,255,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);
   LineTo(hdc,515,230+40*i);
   MoveToEx(hdc,610,190+40*i,NULL);
   LineTo(hdc,610,230+40*i); 
   MoveToEx(hdc,30,230+40*i,NULL);
   LineTo(hdc,610,230+40*i);   
   if(i==0)continue;
   score=0;
   for(j=0;j<4;j++)
   {
    sprintf(tm,"%2d",players[i-1].tank[j]);
    TextOut(hdc,200+50*j,205+40*i,tm,2);  
    score+=players[i-1].tank[j]*100*(j+1);
   }
   sprintf(tm,"%d",score);
   TextOut(hdc,450,205+40*i,tm,strlen(tm));
   sprintf(tm,"%d",players[i-1].score);
   TextOut(hdc,520,205+40*i,tm,strlen(tm));
  }//画表格及玩家分数
  tkn1=0;tkn2=0;
  if(config.playernum==2)
  {
   for(j=0;j<4;j++)
   {
    tkn1+=players[0].tank[j];
    tkn2+=players[1].tank[j];
   }
	if(tkn1>tkn2)TextOut(hdc,400,245,"1000",4);
	else TextOut(hdc,400,285,"1000",4);
  }//奖励1000分  
  SelectObject(hdc,hold);
  DeleteObject(hpen);  
  lpDDSBack->ReleaseDC(hdc);
  if FAILED(lpDDSPrimary->Flip(NULL,DDFLIP_WAIT))Fail("不能翻转页面!");//翻转页面
 }  
}

/*--------------------------------------
更新画面
----------------------------------------*/
void CTankFrame::Update()
{
 DWORD time,time2;
 char str[255];
 HDC hdc;
 HGDIOBJ hold,hpen;
 LPTREE tree;
 RECT src;
 
 /*计算帧速*/
 time=timeGetTime();	
 FrameCount++;
 time2=time-FrameTime;
 
 /*更新所有对象位置和参数*/
 if(mode.gamestatus==3)
 {
  if(players[0].lifenum>0)UpdateOtank(&players[0]);
  if(config.playernum==2&&players[1].lifenum>0)UpdateOtank(&players[1]);
 }//只有在正常时候才更新
 UpdateTank();
 if(mode.status==1)
  if((time-mode.timestart)>config.stime)mode.status=0;//超过怀表作用时间
 UpdateShots();
 UpdateAppl();
  
 Cls(lpDDSBack,RGB(0,0,0));//背景为黑色
 
 /*画各种元素到背景页面*/
 if FAILED(DrawWater(lpDDSGround))Fail("不能在后备表面输出'水'!");//画水
 if(FAILED(lpDDSBack->BltFast(TANK_XL,TANK_YU,lpDDSGround,NULL,DDBLTFAST_WAIT)))
  Fail("不能将地图输出到后备表面!");//画地图
 if FAILED(DrawShots(lpDDSBack))Fail("不能再后备表面输出子弹!");//画子弹
 if FAILED(DrawOtanks(lpDDSBack))Fail("不能再后备表面输出我方坦克!");//画我方坦克
 if FAILED(DrawTanks(lpDDSBack))Fail("不能再后备表面输出敌方坦克!");//画敌方坦克
 src.top=0;
 src.left=84;
 src.right=96;
 src.bottom=12;
 tree=topt->next;
 while(tree!=NULL)
 {
  if FAILED(lpDDSBack->BltFast(tree->y*12+TANK_XL,tree->x*12+TANK_YU,lpDDSMap,&src,
                               DDBLTFAST_SRCCOLORKEY|DDBLTFAST_WAIT))
   Fail("不能再后备表面输出树林!");//画树林							   
  tree=tree->next;
 }   
 if FAILED(DrawAppls(lpDDSBack))Fail("不能在后备表面输出爆炸效果和宝物!");//画爆炸效果和宝物
 
 if(time2>1000)
 {
  Frames=(FrameCount*1000)/time2;
  FrameTime=timeGetTime();
  FrameCount=0;
 }//计算帧速
 /*写上游戏当前信息*/
 lpDDSBack->GetDC(&hdc);
 SetBkMode(hdc,TRANSPARENT);
 SetTextColor(hdc,RGB(0,200,32));
 sprintf(str,"任务 %d",mode.stage);
 TextOut(hdc,570,40,str,strlen(str));
 sprintf(str,"帧速:%d",Frames);
 TextOut(hdc,570,90,str,strlen(str));
 sprintf(str,"剩下:%d",mp.tank[0]+mp.tank[1]+mp.tank[2]+mp.tank[3]);
 TextOut(hdc,570,110,str,strlen(str));
 for(int i=0;i<config.playernum;i++)
 {
  sprintf(str,"%dP",i+1);  
  TextOut(hdc,570,250+i*60,str,strlen(str));
  sprintf(str,"坦克:%d",players[i].lifenum);
  TextOut(hdc,570,270+i*60,str,strlen(str));
 }
 MoveToEx(hdc,TANK_XL,TANK_YU,NULL);
 hpen=CreatePen(PS_SOLID,1,RGB(255,255,255));
 hold=SelectObject(hdc,hpen);
 LineTo(hdc,TANK_XR,TANK_YU);
 LineTo(hdc,TANK_XR,TANK_YD);
 LineTo(hdc,TANK_XL,TANK_YD);
 LineTo(hdc,TANK_XL,TANK_YU);
 SelectObject(hdc,hold);
 DeleteObject(hpen);
 lpDDSBack->ReleaseDC(hdc);
 if FAILED(lpDDSPrimary->Flip(NULL,DDFLIP_WAIT))Fail("不能翻转页面!");//翻转页面
}

/*--------------------------------------
更新子弹
----------------------------------------*/
void CTankFrame::UpdateShots()
{
 DWORD dwTime;
 double FrameRatio;
 LPSHOT shot,shotm,shoti;
 LPTANK tank;
 int i[2],j[2],l,fl,force; 
 RECT src,src1;
 
 shot=tops->next;
 while(shot)//循环更新每一颗子弹
 {
  /*计算子弹的新位置*/
  dwTime=timeGetTime();
  FrameRatio=float(dwTime-shot->timeupdate)/float(FRAME_RATE);
  shot->x+=get(shot->speedx*FrameRatio);
  shot->y+=get(shot->speedy*FrameRatio);
  shot->timeupdate=dwTime;
  
  /*是否越界*/
  if((shot->x>=TANK_XR-4)||(shot->x<=TANK_XL)||(shot->y>=TANK_YD-4)||(shot->y<=TANK_YU))
  {
   shotm=shot->prev;
   if(shot->type==0&&players[0].firenum)players[0].firenum--;
   else if(shot->type==1&&players[1].firenum)players[1].firenum--;
   Remove(shot);
   shot=shotm;
   goto end;//结束本次循环	   
  }  
  
  src.left=shot->x;
  src.top=shot->y;
  src.right=src.left+4;
  src.bottom=src.top+4;
  
  /*这颗子弹与每辆敌方坦克的相互作用*/
  tank=top->next;
  while(tank)
  {
   if(tank->status==0||tank->status==1)goto end1;//如果坦克处于出生或保护状态子弹无效
   src1.left=tank->x;
   src1.top=tank->y;
   src1.right=src1.left+24;
   src1.bottom=src1.top+24;
   if(CheckIn(src1,src)&&shot->type<=1)
   {
    tank->life-=shot->force;//打中则失去相应的生命
    lpDSBExplo->SetCurrentPosition(0);
	lpDSBExplo->Play(0,0,0);//播放音乐
	if(shot->type==0&&players[0].firenum)players[0].firenum--;
	else if(shot->type==1&&players[1].firenum)players[1].firenum--;
	fl=shot->type;
	shotm=shot->prev;
	Remove(shot);
	shot=shotm;
    if(tank->life<=0)
	{
	 CreateAppl(tank->x-6,tank->y-6,0);//坦克死掉了
     (players[fl].tank[tank->type])++;
	 Remove(tank);
	 mode.tanknum--;
	 if(rand()%100<15)//有15%的可能性产生宝物
	 {
	  CreateAppl(rand()%528+TANK_XL,rand()%408+TANK_YU,rand()%8+1);
      lpDSBBem->SetCurrentPosition(0);
	  lpDSBBem->Play(0,0,0);//播放音乐  
 	 }
	}
    goto end;//结束本次循环
   }   
   end1:

   tank=tank->next;
  }
   
  /*这颗子弹与每一我方坦克相互作用*/
  for(l=0;l<config.playernum;l++)
  {
   src1.left=players[l].x;
   src1.top=players[l].y;
   src1.right=src1.left+24;
   src1.bottom=src1.top+24;
   if(players[l].status==0||players[l].status==1||players[l].status==3)continue;//如果坦克处于出生或保护状态子弹无效
   if(CheckIn(src1,src)&&shot->type==2)
   {
    lpDSBExplo->SetCurrentPosition(0);
	lpDSBExplo->Play(0,0,0);//播放音乐
	shotm=shot->prev;
	Remove(shot);
	shot=shotm;
    CreateAppl(players[l].x-6,players[l].y-6,0);//坦克死掉了
    players[l].lifenum--;
	if(players[l].lifenum>0)CreateOtank(&players[l],l);
    else 
	{
	 players[l].x=620;players[l].y=0;//清除出战斗区域
	}  
    goto end;
   }  
  }

  shoti=tops->next;
  while(shoti)//这颗子弹与每一颗其他子弹相互作用
  {
   if(shoti->x!=shot->x||shoti->y!=shot->y)
   {
    src1.left=shoti->x;
	src1.top=shoti->y;
	src1.right=src1.left+4;
	src1.bottom=src1.top+4;
	if(CheckIn(src,src1)&&shoti->type!=shot->type)
	{
	 if(shoti->type==0&&players[0].firenum)players[0].firenum--;
	 else if(shoti->type==1&&players[1].firenum)players[1].firenum--;
	 Remove(shoti);
	 shotm=shot->prev;
     if(shot->type==0&&players[0].firenum)players[0].firenum--;
	 else if(shot->type==1&&players[1].firenum)players[1].firenum--;
	 Remove(shot);
	 shot=shotm;
	 goto end;
    }
   }
   shoti=shoti->next;
  }
  
  /*这颗子弹与地图元素相互作用*/ 
  i[0]=shot->x-TANK_XL;
  j[0]=shot->y-TANK_YU;
  i[1]=i[0];
  j[1]=j[0];
  /*计算出子弹前进方向上的中点及两个端点中的一个*/
  if(shot->speedx>0)
  { 
   i[0]+=4;i[1]+=4;
   j[1]+=4;  
  }
  if(shot->speedx<0)
  {
   j[1]+=4;
  }
  if(shot->speedy>0)
  {
   i[1]+=4;
   j[0]+=4;j[1]+=4;
  }  
  if(shot->speedy<0)
  {
   i[1]+=4;
  } 
  
  fl=0;//是否请过子弹标志清零
  force=shot->force;//保存子弹威力
  for(l=0;l<2;l++)//判断子弹前方的两个地图元素
  {
   i[l]/=12;j[l]/=12;//得到在矩阵中的位置
  
   if(mp.array[j[l]][i[l]]==0||mp.array[j[l]][i[l]]==8||mp.array[j[l]][i[l]]==9
      ||mp.array[j[l]][i[l]]==7)continue;//不做任何事情   
   
   if(mp.array[j[l]][i[l]]==5&&force<4||mp.array[j[l]][i[l]]==6
      ||mp.array[j[l]][i[l]]<=4)//遇见不可摧毁的地图元素  
   {
    if(fl==0)
	{
	 shotm=shot->prev;
	 if(shot->type==0&&players[0].firenum)players[0].firenum--;
	 else if(shot->type==1&&players[1].firenum)players[1].firenum--;
	 Remove(shot);
     shot=shotm;
     fl=1;
    }
   }//清除子弹
   if(mp.array[j[l]][i[l]]==11||(mp.array[j[l]][i[l]]==5&&force>=4))//遇见可摧毁的地图元素(force>=4可摧毁钢板)
   {
	if(fl==0)
	{
	 shotm=shot->prev;
	 if(shot->type==0&&players[0].firenum)players[0].firenum--;
	 else if(shot->type==1&&players[1].firenum)players[1].firenum--;
	 Remove(shot);
     shot=shotm;
     fl=1;
    }//清除子弹
	mp.array[j[l]][i[l]]=0;
    src.top=0;
    src.left=0;
    src.right=12;
    src.bottom=12;
    if(FAILED(lpDDSGround->BltFast(i[l]*12,j[l]*12,lpDDSMap,&src,DDBLTFAST_WAIT)))
	 Fail("不能更改地图元素!");
   }//清除障碍物 
  
   if(mp.array[j[l]][i[l]]==6)mp.array[j[l]][i[l]]=11;//普通砖块打一枪变为一枪可打坏的砖块
   if(mp.array[j[l]][i[l]]<=4&&mp.array[j[l]][i[l]]>=1)//打中司令部
   {
    lpDSBExplo->SetCurrentPosition(0);
	lpDSBExplo->Play(0,0,0);//播放音乐 
	mode.gamestatus=4;//任务失败状态
   }
  }  
  
  end:
  shot=shot->next;
 }
}

/*-------------------------------------------------
更新我方坦克
--------------------------------------------------*/
void CTankFrame::UpdateOtank(LPOTANK tank)
{
 DWORD dwTime,dwDelta;
 double FrameRatio;
 int i[2],j[2],k=0,l,xo,yo;
 LPTANK etank,etankm;
 RECT src1,src2; 
 int old;

 dwTime=timeGetTime();
 dwDelta=dwTime-tank->timeupdate;
 
 if(dwDelta<1000/FRAME_RATE)return;//不到刷新时间则返回
 
 FrameRatio=float(dwDelta)/float(FRAME_RATE);
 tank->timeupdate=dwTime;
 if(tank->status==0)//出生状态
 {
  if((dwTime-tank->timestart)>config.borntime)//出生状态结束
  {
   tank->timestart=dwTime;
   tank->superupdate=dwTime;
   tank->status=1;
   tank->frame=0;
  }
  if((dwTime-tank->superupdate)>50)//出生状态动画
  {   
   tank->frame=tank->frame+tank->bornd;
   if(tank->frame==13)tank->bornd=-1;
   else if(tank->frame==10)tank->bornd=1;
   tank->superupdate=dwTime;
  }
 } 
 else if(tank->status==1&&(dwTime-tank->timestart)>config.supertime)//保护状态结束
  tank->status=2; 
 else if(tank->status==3&&(dwTime-tank->timestart)>config.stime)//长保护状态结束
  tank->status=2;
 
 if(tank->CtrlF)//按下了开火键
 {
  if(tank->firenum<tank->firemaxnum&&(dwTime-tank->timefire)>200)
  {
   if(tank->speedx!=0)//生成x方向的子弹
    CreateShot(tank->x+10,tank->y+10,tank->speedx*tank->speed/abs(tank->speedx),
               0,tank->type,tank->force); 
   else//生成y方向的子弹
    CreateShot(tank->x+10,tank->y+10,0,
               tank->speedy*tank->speed/abs(tank->speedy),tank->type,tank->force);
   tank->firenum++;

⌨️ 快捷键说明

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