📄 fight.cpp
字号:
else
break;
}
return ;
}
//********************************************************&|*
//处理键盘输入
//***********************************************************
void GetInput(void)
{
int i=0;
if(GetAsyncKeyState(VK_UP)){A11.direct=Aup;}
if(GetAsyncKeyState(VK_RIGHT)){A11.direct=Aright;}
if(GetAsyncKeyState(VK_DOWN)){A11.direct=Adown;}
if(GetAsyncKeyState(VK_LEFT)){A11.direct=Aleft;}
if(GetAsyncKeyState(VK_SPACE))
{
if(A11.bfire)return;
A11.bfire=TRUE;
while(!Afire[i].bdead){i++;}
if(i<cenemy)
{
Afire[i].bdead=FALSE;
Afire[i].direct=A11.direct;
Afire[i].type=Fplane;
Afire[i].x=A11.x+2*A11.width/6;
Afire[i].y=A11.y+2*A11.height/6;
}
}
return;
}
//**********************************************************
//checkhit()处理碰撞
//**********************************************************
void CheckHit()
{
//注意:
//1.在进行碰撞的检查时,检查的距离必须小于赋值的条件检测的距离。
//2.注意区别:碰撞检测距离、赋值检测距离、于距离合法性的赋值距离
//即:a.(if(A11.x<100||A11.x>640||A11.y<5||A11.y>530)
// b.if(A11.y<10 ){Aflame[i].x=A11.x;Aflame[i].y=A11.y;}
// c.if(Aflame[i].x<100){Aflame[i].x=100;}
//中的三个检测距离的作用和大小的顺序必须符合的条件。
//否则将产生不可预测的结果。
RECT drect,srect;
int i=0;
//1.下次考虑一下飞机碰撞后的时间延迟(闪烁)
//2.碰撞的精确位置
if(!A11.bdead)
{
if(A11.x<100||A11.x>640||A11.y<3||A11.y>535)
{
while(!Aflame[i].bdead){i++;}
if(i<cenemy)
{
if(A11.y<5 ){Aflame[i].x=A11.x;Aflame[i].y=A11.y;}
if(A11.y>535){Aflame[i].x=A11.x;Aflame[i].y=A11.y+5;}
if(A11.x<103){Aflame[i].x=A11.x;Aflame[i].y=A11.y;}
if(A11.x>640){Aflame[i].x=A11.x;Aflame[i].y=A11.y;}
Aflame[i].bdead=FALSE;
Aflame[i].ftps =0;
}
A11.lifenum--;
A11.planestatus=super;
A11.x=400;
A11.y=400;
A11.direct=Aup;
}
}
for(int j=0;j<cenemy;j++)
{
i=0;
if(!Afire[j].bdead)
{
if(Afire[j].x<103||Afire[j].x>660||Afire[j].y<2||Afire[j].y>560)
{
if(Afire[j].type==Fplane)A11.bfire=FALSE;
else{Aenemy[Afire[j].Efire].bfire =FALSE;}
Afire[j].bdead=TRUE;
while(!Aflame[i].bdead){i++;}
if(i<cenemy)
{
if(Afire[j].y<15 ){Aflame[i].x=Afire[j].x-15;Aflame[i].y=Afire[j].y;}
if(Afire[j].y>560){Aflame[i].x=Afire[j].x-15;Aflame[i].y=Afire[j].y;}
if(Afire[j].x<110){Aflame[i].x=Afire[j].x;Aflame[i].y=Afire[j].y-20;}
if(Afire[j].x>660){Aflame[i].x=Afire[j].x;Aflame[i].y=Afire[j].y-20;}
Aflame[i].bdead=FALSE;
Aflame[i].ftps=0;
}
}
}
}
for(i=0;i<cenemy;i++)
{
if(!Afire[i].bdead)
{
GetRect(&drect,Afire[i].x,Afire[i].y,Afire[i].height,Afire[i].width);
if(Afire[i].type==Fplane)
{
for(int k=0;k<cenemy;k++)
{
if(!Aenemy[k].bdead)
{
GetRect(&srect,Aenemy[k].x,Aenemy[k].y,Aenemy[k].height,Aenemy[k].width);
if(Hit(drect,srect))
{
int h=0;
while(!Aflame[h].bdead){h++;}
if(h<cenemy)
{
Aflame[h].bdead=FALSE;
Aflame[h].ftps=0;
Aflame[h].x=Aenemy[k].x;
Aflame[h].y=Aenemy[k].y;
}
Aenemy[k].bdead=TRUE;
nsorce++;
Afire[i].bdead=TRUE;
A11.bfire=FALSE;
}
}
}
}
else
{
if(A11.planestatus==super)return;
if(!A11.bdead)
{
GetRect(&srect,A11.x,A11.y,A11.height,A11.width);
if(Hit(drect,srect))
{
int n=0;
while(!Aflame[n].bdead){n++;}
if(n<cenemy)
{
Aflame[n].bdead=FALSE;
Aflame[n].ftps=0;
Aflame[n].x=A11.x;
Aflame[n].y=A11.y;
}
A11.lifenum--;
A11.planestatus=super;
A11.x=400;
A11.y=400;
A11.direct=Aup;
Afire[i].bdead=TRUE;
Aenemy[Afire[i].Efire].bfire=FALSE;
}
}
}
}
}
}
//********************************************************
//Hit()检测两个矩形是否相互重叠
//********************************************************
bool Hit(RECT drect,RECT srect)
{
int xcount,ycount;
int xmax,ymax;
xcount=abs((drect.left-srect.left));
ycount=abs((drect.top-srect.top));
if(drect.left<srect.left)xmax=4*(drect.right-drect.left)/5;
else
xmax=3*(srect.right-srect.left)/5;
if(drect.top<srect.top)ymax=4*(drect.bottom-drect.top)/5;
else
ymax=4*(srect.bottom-srect.top)/5;
if(xcount<xmax&&ycount<ymax)return TRUE;
else
return FALSE;
}
//******************************************************
//EnemyAI处理敌机的发射、躲避、追踪等各项动作
//******************************************************
//1.同一直线上优先处理。
//则正面相对的追踪的比例比背面相对的大。
//2.不在同一直线上,则以一定的半径为追踪范围。
//3.如果是子弹,则以一对同心环为躲避范围。
//同时正面躲避比背面躲避的机率大。
//4.敌机在中间区域飞行的机率高,因为这样比较容易追踪。
void EnemyAI(void)
{
for(int i=0;i<cenemy;i++)
{
//避免于四周相撞
if(!Aenemy[i].bdead)
{
if(Aenemy[i].x<100||Aenemy[i].x>660||Aenemy[i].y<10||Aenemy[i].y>560)
{
if(Aenemy[i].direct==Aup ){Aenemy[i].y=10 ;}
if(Aenemy[i].direct==Adown ){Aenemy[i].y=560;}
if(Aenemy[i].direct==Aleft ){Aenemy[i].x=100;}
if(Aenemy[i].direct==Aright){Aenemy[i].x=660;}
Aenemy[i].direct+=rand()%3;
Aenemy[i].direct=Aenemy[i].direct%4;//注意对变量取值的定义
//例如:direct代表方向所以不可能大于3(0、1、2、3代表一个方向)
//所以需要对值进行检测。
}
}
//发弹控制功能
if(!Aenemy[i].bdead&&!Aenemy[i].bfire)
{
if((abs((Aenemy[i].y-A11.y))<10&&
(((Aenemy[i].x-A11.x)>10&&(Aenemy[i].x-A11.x)<60&&Aenemy[i].direct==3)||
((A11.x-Aenemy[i].x)>10&&(A11.x-Aenemy[i].x)<60&&Aenemy[i].direct==1)||
((A11.x-Aenemy[i].x)>60&&(rand()%10==4)&&Aenemy[i].direct==1)||
((Aenemy[i].x-A11.x)>60&&(rand()%10==4)&&Aenemy[i].direct==3)))||
(abs((Aenemy[i].x-A11.x))<10&&
(((Aenemy[i].y-A11.y)>10&&(Aenemy[i].y-A11.y)<60&&Aenemy[i].direct==0)||
((A11.y-Aenemy[i].y)>10&&(A11.y-Aenemy[i].y)<60&&Aenemy[i].direct==2)||
((A11.y-Aenemy[i].y)>60&&(rand()%10==4)&&Aenemy[i].direct==2)||
((Aenemy[i].y-A11.y)>60&&(rand()%10==4)&&Aenemy[i].direct==0))))
//三种情况
{
Aenemy[i].bfire=TRUE;
int n=0;
while(!Afire[n].bdead){n++;}
if(n<cenemy)
{
Afire[n].bdead=FALSE;
Afire[n].direct=Aenemy[i].direct;
Afire[n].Efire=i;
Afire[n].type=Fenemy;
Afire[n].x=Aenemy[i].x+Aenemy[i].width/3;
Afire[n].y=Aenemy[i].y+Aenemy[i].height/3;
}
}
//追踪功能
if(abs(Aenemy[i].y-A11.y)<8)
{
if(((Aenemy[i].x-A11.x)<100&&(Aenemy[i].x-A11.x)>30)||((Aenemy[i].x-A11.x)>100&&(rand()%10==5)))
Aenemy[i].direct=3;
if(((A11.x-Aenemy[i].x)<100&&(A11.x-Aenemy[i].x)>30)||((A11.x-Aenemy[i].x)>100&&(rand()%10==5)))
Aenemy[i].direct=1;
}
if(abs(Aenemy[i].x-A11.x)<8)
{
if(((Aenemy[i].y-A11.y)<100&&(Aenemy[i].y-A11.y)>30)||((Aenemy[i].y-A11.y)>100&&(rand()%10==5)))
Aenemy[i].direct=0;
if(((A11.y-Aenemy[i].y)<100&&(A11.y-Aenemy[i].y)>30)||((A11.y-Aenemy[i].y)>100&&(rand()%10==5)))
Aenemy[i].direct=2;
}
//所处位置的控制功能,例如:是飞机大部分时间在中间部分飞行,以便飞机的追踪
if(((Aenemy[i].x<200&&Aenemy[i].x>190)||
(Aenemy[i].x>600&&Aenemy[i].x<610)||
(Aenemy[i].y>500&&Aenemy[i].y<510)||
(Aenemy[i].y<100&&Aenemy[i].y>90))&&
(rand()%7==3))
{
Aenemy[i].direct+=rand()%10;
Aenemy[i].direct=Aenemy[i].direct%4;
}
//对炸弹的躲避功能,以一定的半径为躲避范围。同时对不同的情况有不同的躲避几率。
//if
}
}
}
//**********************************************************
//清屏clrscr()
//**********************************************************
void clrscr(DWORD color=RGB(0,0,0))
{
DDBLTFX ddbltfx;
ddbltfx.dwSize=sizeof(ddbltfx);
ddbltfx.dwFillColor=color;
lpddsprimary->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
lpddsback->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&ddbltfx);
}
//*********************************************************
//WinMain();主函数
//*********************************************************
int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine
,int nCmdShow)
{
MSG msg;
hWnd=InitWin(hInstance,nCmdShow);
if(hWnd==NULL)
{
MessageBox(hWnd,"failed in initwin","INITWIN",NULL);
return FALSE;
}
if(FAILED(InitDraw()))
{
FreeObject();
PostQuitMessage(WM_CLOSE);
return FALSE;
}
if(FAILED(InitInput(hWnd)))
{
OutputDebugString("failed init input ");
PostQuitMessage(WM_CLOSE);
return FALSE;
}
if(FAILED(InitSound()))
{
OutputDebugString("failed in initsouund");
PostQuitMessage(WM_CLOSE);
return FALSE;
}
InitData();
clrscr();
while(1)
{
if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
{
if(!GetMessage(&msg,NULL,0,0))
return msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
}
else if(active)
{
UpFlame();
}
else
WaitMessage();
}
}
//*********************************************************
//WinProc()窗口处理函数
//*********************************************************
HRESULT CALLBACK WinProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
char buf[256];
switch(msg)
{
case WM_ACTIVATEAPP:
active=wParam;
SetFocus(hWnd);
break;
case WM_SETCURSOR:
SetCursor(NULL);
return TRUE;
case WM_KEYDOWN:
switch(wParam)
{
case VK_ESCAPE:
PostQuitMessage(0);
break;
case VK_RETURN:
mciSendString( closemidi, buf, sizeof(buf), NULL);
mciSendString(openmidi, buf, sizeof(buf), NULL);
InitData();
nsorce=0;
gamerank=0;
gamestatus=GamePass;
InitPass();
A11.bfire=FALSE;
if(A11.bdead)A11.bdead=FALSE;
else
A11.bdead=TRUE;
gamestatus=GameStart;
break;
}
break;
case WM_DESTROY:
FreeObject();
mciSendString(stopmidi,buf,sizeof(buf),NULL);
mciSendString( closemidi, buf, sizeof(buf), NULL);
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd,msg,wParam,lParam);
}
//******************************************************
//UpFlame()
//******************************************************
void UpFlame(void)
{
thistickcount=GetTickCount();
if((thistickcount-lasttickcount)<TimeValue)return;
else
{
DrawMap();
// GetInput();
UpdataInputData();
DrawFire();
DrawPlane();
DrawEnemy();
EnemyAI();
CheckHit();
DrawFlame();
DataPro();
InitPass();
DrawText();
Flip();
lasttickcount=thistickcount;
}
return;
}
//********************************************************
//Initpass()过关后数据处理
//********************************************************
void InitPass()
{
int nok=0;
if(gamestatus==GameStart)
{
for(int j=0;j<cenemy;j++)
{
if(Aenemy[j].bdead==TRUE)nok++;
}
if(nok==cenemy)
{
gamestatus=GamePass;
A11.planestatus=super;
}
}
if(gamestatus==GamePass)
{
gamerank++;
if(gamerank>8)gamerank=8;
for(int i=0;i<gamerank;i++)
{
Aenemy[i].bfire =FALSE;
Aenemy[i].bdead =FALSE;
Aenemy[i].direct=rand()%4;
Aenemy[i].x =leftblank+rand()%560;
Aenemy[i].y =rand()%560;
}
gamestatus=GameStart;
}
}
//********************************************************
//DrawText()桌面text控制
//********************************************************
void DrawText()
{
// HRESULT rval;
// RECT rect;
HDC hdc;
char temp[100];
lpddsback->GetDC(&hdc);
/*
if(gamestatus==GameLogo)
{
SetBkMode(hdc, TRANSPARENT);//设置透明映射方式.
SetTextColor(hdc, RGB(100,100,0));
sprintf(temp, " FIGHY 0.6");
TextOut(hdc,396,260,temp,strlen(temp));
SetTextColor(hdc, RGB(0,200,100));
TextOut(hdc,392,320,"子 弹:SPACE",12);
TextOut(hdc,392,340,"结 束:ESC ",12);
SetTextColor(hdc, RGB(200,0,100));
sprintf(temp, "作者:盛崇山 SCUT");
TextOut(hdc, 350, 280, temp,strlen(temp));
sprintf(temp, "E_M: sintler@263.net");
TextOut(hdc, 350, 300, temp,strlen(temp));
}
else
{*/
SetBkMode(hdc, TRANSPARENT);//设置透明映射方式.
SetTextColor(hdc, RGB(100,100,0));
sprintf(temp, " FIGHT 0.6");
TextOut(hdc,0,360,temp,strlen(temp));
SetTextColor(hdc, RGB(0,100,200));
sprintf(temp, " 作者:盛崇山 ");
TextOut(hdc,0,380, temp,strlen(temp));
sprintf(temp, " 2001.10 SCUT");
TextOut(hdc,0,400, temp,strlen(temp));
SetTextColor(hdc, RGB(200,0,100));
sprintf(temp, "sintler@263.net");
TextOut(hdc, 0, 420, temp,strlen(temp));
TextOut(hdc,0,440,"子 弹:SPACE",12);
TextOut(hdc,0,460,"开 始: ENTER",12);
TextOut(hdc,0,480,"结 束:ESC ",12);
if(gamestatus==GameOver)
{
SetTextColor(hdc, RGB(200,250,0));
sprintf(temp, "GAME OVER");
TextOut(hdc,360,300,temp,strlen(temp));
}
if(gamestatus==GameStart)
{
SetTextColor(hdc, RGB(200,0,0));
sprintf(temp,"Lifenum: %d",A11.lifenum);
TextOut(hdc,0,0,temp,strlen(temp));
sprintf(temp,"SORCE: %6d",nsorce*100);
TextOut(hdc,700,0,temp,strlen(temp));
sprintf(temp,"PART: %d",gamerank);
TextOut(hdc,700,500,temp,strlen(temp));
}
lpddsback->ReleaseDC(hdc);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -