📄 tankframe.cpp
字号:
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 + -