📄 a10.cpp
字号:
oldtime=GetTickCount();
planenumber=planeremain;
super=TRUE;
cancontrol=FALSE;
pos.x=backwidth/2-25;
pos.y=backrect.bottom;
}
if (super==TRUE)
if (GetTickCount()>oldtime+3000)//无敌时间3秒
super=FALSE;
if (cancontrol==FALSE)
{
if (pos.y>backrect.bottom-100) //飞机刚出现时是无法控制的
{
pos.y-=movespeed;
Plane=1;
}
else
cancontrol=TRUE;
}
else
{
//检测方向键
Plane=1;
if(GetAsyncKeyState(VK_UP)) {pos.y=pos.y-movespeed;}
if(GetAsyncKeyState(VK_DOWN)) {pos.y=pos.y+movespeed;}
if(GetAsyncKeyState(VK_LEFT)) {pos.x=pos.x-movespeed;Plane=0;}
if(GetAsyncKeyState(VK_RIGHT)) {pos.x=pos.x+movespeed;Plane=2;}
//范围检查
if (pos.x<65) pos.x=65;
if (pos.x>backwidth-65-50) pos.x=backwidth-65-50;
if (pos.y<65) pos.y=65;
if (pos.y>backheight-65-60) pos.y=backheight-65-60;
}
if (super==TRUE) //无敌时的闪烁效果
{
static int ot=0;//延时
if (GetTickCount()-ot>30)
ot=GetTickCount();
else
return;
}
//绘制飞机
RECT rect;
GetRect(&rect, pos.x, pos.y, 50, 60);
HRESULT rval=lpDDSBack->Blt( &rect, lpDDSPlane[Plane], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
if(rval == DDERR_SURFACELOST) lpDDSBack->Restore();
}
//***************************************
//绘制背景地图
void DrawMap(void )
{
//背景贴图的偏移坐标
static int mapposX=64, mapposY=64;
mapposX--;
if (mapposX<=0 ) mapposX=64;
if (Plane==0) mapposY--;
if (Plane==2) mapposY++;
if (mapposY<=0) mapposY=64;
if (mapposY>64) mapposY=1;
for (int x=0; x<=(int)backwidth/64; x++)
for (int y=0; y<=(int)backheight/64; y++)
{
RECT rect;
GetRect(&rect, 64*x-mapposY, 64*y-mapposX, 64, 64);
HRESULT rval=lpDDSBack->Blt( &rect, lpDDSMap, NULL, DDBLT_WAIT, NULL);
if(rval == DDERR_SURFACELOST) lpDDSBack->Restore();
}
}
//************************************
//绘制说明文字及图象
void DrawText(void )
{
HRESULT rval;
RECT rect;
HDC hdc;
char temp[100];
if (gamestatus==GAME_LOG)//初始画面
{
lpDDSBack->GetDC(&hdc);
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(0,255,0));
sprintf(temp, "A10 攻击机");
TextOut(hdc, 200, 170, temp, strlen(temp));
TextOut(hdc, 200, 240, "子 弹: Ctrl", 12);
TextOut(hdc, 200, 260, "炸 弹: Space", 13);
TextOut(hdc, 200, 280, "加 速: +", 11);
TextOut(hdc, 200, 300, "减 速: -", 11);
TextOut(hdc, 200, 320, "地 图: Return", 14);
TextOut(hdc, 200, 340, "结 束: Esc", 11);
SetTextColor(hdc, RGB(255,0,0));
lpDDSBack->ReleaseDC(hdc);
GetRect(&rect, 135, 150, 50, 50);
rval=lpDDSBack->Blt( &rect, lpDDSPlane[1], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
if(rval == DDERR_SURFACELOST) lpDDSBack->Restore();
GetRect(&rect, 292, 150, 50, 50);
rval=lpDDSBack->Blt( &rect, lpDDSPlane[1], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
if(rval == DDERR_SURFACELOST) lpDDSBack->Restore();
}
if (gamestatus==GAME_START)//游戏进行中
{
for (int i=0; i<planeremain; i++)//绘制我机
{
GetRect(&rect, backrect.left+10+(i*25), backrect.bottom-30,20,20);
rval=lpDDSBack->Blt( &rect, lpDDSPlane[1], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
if(rval == DDERR_SURFACELOST) lpDDSBack->Restore();
}
//绘制敌机
GetRect(&rect, backrect.right-60, backrect.bottom-30,20,20);
rval=lpDDSBack->Blt( &rect, lpDDSEnemy, NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
if(rval == DDERR_SURFACELOST) lpDDSBack->Restore();
//总分
lpDDSBack->GetDC(&hdc);
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(255,0,0));
//得分
sprintf(temp, "得分:%6d", enemylost*50);
SetTextColor(hdc,RGB(0,255,0));
TextOut(hdc, backwidth/2-40, 70, temp, strlen(temp));
//击落敌机数
sprintf(temp, "x%d", enemylost);
TextOut(hdc, backrect.right-35, backrect.bottom-25, temp, strlen(temp));
//帧频率
SetTextColor(hdc, RGB(255,0,0));
sprintf(temp, "%d帧 / 秒",fps);
TextOut(hdc, 70, 70, temp, strlen(temp));
lpDDSBack->ReleaseDC(hdc);
}
if (gamestatus==GAME_OVER)//游戏结束
{
lpDDSBack->GetDC(&hdc);
SetBkMode(hdc, TRANSPARENT);
SetTextColor(hdc, RGB(0,255,0));
sprintf(temp, "共击落敌机 %d 架", enemylost);
TextOut(hdc, backwidth/2-40, backheight/2-80, "Game Over", 9);
TextOut(hdc, backwidth/2-55, backheight/2-30, temp, strlen(temp));
TextOut(hdc, backwidth/2-50, backheight/2, "按回车键继续", 12);
TextOut(hdc, backwidth/2-100, backheight/2+50, "A10攻击机 作者:王正盛 1998.12", 29);
lpDDSBack->ReleaseDC(hdc);
}
}
//****************************
//更新屏幕
void UpdateFrame(void )
{
//检测发射子弹
if(GetAsyncKeyState(VK_CONTROL) && gamestatus==GAME_START && cancontrol==TRUE )
{
static int newtime,oldtime=GetTickCount();
newtime=GetTickCount();
if (newtime>oldtime+100)
{
oldtime=newtime;
buletposleft[bulet].x=pos.x+13;
buletposleft[bulet].y=pos.y;
buletposright[bulet].x=pos.x+32;
buletposright[bulet].y=pos.y;
bulet++;
if (bulet==BULETNUMBER) bulet=0;
}
}
//在后台页面上调用一系列绘制函数完成绘图工作
DrawMap();
//单色填充
/*DDBLTFX ddbltfx;
ZeroMemory( &ddbltfx, sizeof(ddbltfx));
ddbltfx.dwSize = sizeof(ddbltfx);
ddbltfx.dwFillColor =DDColorMatch(lpDDSBack, RGB(255,0,0)) ; //
lpDDSBack->Blt(
NULL, // 目标矩形
NULL, NULL, // 源页面和源矩形
DDBLT_COLORFILL, &ddbltfx);
*/
CheckHit();
DrawEnemy();
DrawBom();
DrawBulet();
DrawPlane();
DrawFlame();
DrawText();
//最后将后台页面换至前台
Flip();
}
//********************************
//改变背景地图
void ChangeMap(void)
{
static int b=0;
if (b==0)
{
DDReLoadBitmap(lpDDSMap, "map2.bmp");
b=1;
}
else if (b==1)
{
DDReLoadBitmap(lpDDSMap, "map3.bmp");
b=2;
}
else if (b==2)
{
DDReLoadBitmap(lpDDSMap, "map1.bmp");
b=0;
}
}
//************************
//绘制炸弹
void DrawBom(void)
{
static int bbom=0;
for (int i=0; i<BOMNUMBER; i++)
{
if (bompos[i].y<0) continue;
RECT rect;
rect.left=bompos[i].x;
rect.top=bompos[i].y;
rect.right=rect.left+14;
rect.bottom=rect.top+36;
HRESULT rval=lpDDSBack->Blt( &rect, lpDDSBom[bbom], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
if(rval == DDERR_SURFACELOST) lpDDSFront->Restore();
bompos[i].y-=3;
}
if (bbom==1)
bbom=0;
else
bbom=1;
}
//******************************************
//绘制子弹
void DrawBulet(void)
{
for (int i=0; i<BULETNUMBER; i++)
{
RECT rectleft, rectright;
rectleft.left=buletposleft[i].x;
rectleft.top=buletposleft[i].y;
rectleft.right=rectleft.left+5;
rectleft.bottom=rectleft.top+13;
rectright.left=buletposright[i].x;
rectright.top=buletposright[i].y;
rectright.right=rectright.left+5;
rectright.bottom=rectright.top+13;
HRESULT rval;
rval=lpDDSBack->Blt( &rectleft, lpDDSBulet[0], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
if(rval == DDERR_SURFACELOST) lpDDSBack->Restore();
rval=lpDDSBack->Blt( &rectright, lpDDSBulet[1], NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
if(rval == DDERR_SURFACELOST) lpDDSBack->Restore();
buletposleft[i].x--;
buletposleft[i].y-=12;
buletposright[i].x++;
buletposright[i].y-=12;
}
}
//*************************
//绘制敌机
void DrawEnemy(void)
{
RECT rect;
HRESULT rval;
for (int i=0; i<ENEMYNUMBER; i++)
{
if (enemydead[i]!=0)//如果敌机未毁
{
switch (enemystyle[i])
{
case 0://敌机0
GetRect( &rect, enemypos[i].x, enemypos[i].y, 35, 35);
rval=lpDDSBack->Blt( &rect, lpDDSEnemy, NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
if(rval == DDERR_SURFACELOST) lpDDSBack->Restore();
enemypos[i].y+=enemyspeed[i]+(movespeed-2);
enemypos[i].x+=enemydir[i];
break;
case 1://子弹
GetRect( &rect, enemypos[i].x, enemypos[i].y, 8, 8);
rval=lpDDSBack->Blt( &rect, lpDDSBall, NULL, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
if(rval == DDERR_SURFACELOST) lpDDSBack->Restore();
enemypos[i].y+=enemyspeed[i]+(movespeed-2);
enemypos[i].x+=enemydir[i];
break;
}
}
if (enemypos[i].y>backrect.bottom || enemydead[i]==0)
{
enemypos[i].x=(int)(forewidth*((long)rand()/32767.0)) +35;
enemypos[i].y=(int)(35*((long)rand()/32767.0));
enemyspeed[i]=(int)(4*((long)rand()/32767.0))+1;
enemydir[i]=(int)(3*((long)rand()/32767.0))-1;//-1,0,1
//敌机类型
enemystyle[i]=(int)(2*((long)rand()/32767.0));//0,1
enemydead[i]=1;//敌人复活
}
}
}
//******************************
//碰撞检测
void CheckHit(void)
{
if (gamestatus!=GAME_START) return;//如果游戏结束
//检测敌机是否被击落
for (int e=0; e<ENEMYNUMBER; e++)
{
if (enemydead[e]==0) continue;//敌人已消灭
switch (enemystyle[e])
{
case 1://是子弹
break;
case 0://是敌机
if (OutOfRange(enemypos[e])) continue;//敌机不在窗口内
for (int b=0; b<BULETNUMBER; b++)
{
//检测左子弹
if (!OutOfRange(buletposleft[b]))
{
if (abs(enemypos[e].x-buletposleft[b].x+15)<10 && abs(enemypos[e].y-buletposleft[b].y+11)<10)
{
enemydead[e]=0;//使敌机销毁
buletposleft[b].y=0;//使子弹消失
flamepos[e].x=enemypos[e].x-10;//火焰坐标
flamepos[e].y=enemypos[e].y-8;//火焰坐标
flamestatus[e]=1;//火焰状态
enemylost++;
MessageBeep(0);
}
}
//检测右子弹
if (!OutOfRange(buletposright[b]))
{
if (abs(enemypos[e].x-buletposright[b].x+15)<10 && abs(enemypos[e].y-buletposright[b].y+11)<10)
{
enemydead[e]=0;//使敌机销毁
buletposright[b].y=0;//使子弹消失
flamepos[e].x=enemypos[e].x-10;//火焰坐标
flamepos[e].y=enemypos[e].y-8;//火焰坐标
flamestatus[e]=1;//火焰状态
enemylost++;
MessageBeep(0);
}
}
//是敌机完
}
}
}
//检测我机是否撞毁
if (super==FALSE)
{
for (int p=0; p<ENEMYNUMBER; p++)
{
if(enemydead[p]==0) continue;
if (OutOfRange(enemypos[p])) continue;
switch (enemystyle[p])
{
case 1://子弹
if (abs(pos.x-enemypos[p].x+21)<15 && abs(pos.y-enemypos[p].y+26)<12)
{
enemydead[p]=0;
deadflamepos.x=enemypos[p].x-29;
deadflamepos.y=enemypos[p].y-29;
deadflamestatus=1;
planeremain--;
MessageBeep(0);
}
break;
case 0://敌机
if (abs(pos.x-enemypos[p].x+7)<15 && abs(pos.y-enemypos[p].y+12)<12)
{
enemydead[p]=0;
deadflamepos.x=enemypos[p].x-15;
deadflamepos.y=enemypos[p].y-15;
deadflamestatus=1;
planeremain--;
MessageBeep(0);
}
break;
}
}
}
if (planeremain==-1) //游戏结束
{
gamestatus=GAME_OVER;
KillTimer(hWnd, TIMER_CHANGEMAP);
}
}
//*************************
//检测物体是否超出边界
BOOL OutOfRange(POINT p)
{
if (p.x<35 || p.x>WINDOW_WIDTH+35 || p.y<35 || p.y>WINDOW_HEIGHT+35)
return TRUE;
else
return FALSE;
}
//******************
//填充一个RECT结构
void GetRect(RECT* rect, long left, long top, long width, long height)
{
rect->left=left;
rect->top=top;
rect->right=left+width;
rect->bottom=top+height;
return;
}
//***************************************
//绘制爆炸火焰
void DrawFlame(void )
{
//绘制敌机火焰
for (int f=0; f<ENEMYNUMBER; f++)
{
if (flamestatus[f]!=0)
{
RECT rect,srect;
GetRect(&rect, flamepos[f].x, flamepos[f].y, 54, 50);
GetRect(&srect, (flamestatus[f]-1)*54, 0, 54, 50);
HRESULT rval;//绘制火焰
rval=lpDDSBack->Blt( &rect, lpDDSFlame, &srect, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
if(rval == DDERR_SURFACELOST) lpDDSBack->Restore();
static int otime[ENEMYNUMBER];
if (GetTickCount()-otime[f]>150)
{
otime[f]=GetTickCount();
flamestatus[f]++;//更新火焰状态
if (flamestatus[f]==11 ) flamestatus[f]=0;//火焰完毕
}
}
}
//绘制我机撞毁火焰
if (deadflamestatus!=0)
{
RECT rect, srect;
GetRect(&rect, deadflamepos.x, deadflamepos.y, 66, 66);
GetRect(&srect,(deadflamestatus-1)*66, 0, 66, 66);
HRESULT rval;//绘制火焰
rval=lpDDSBack->Blt( &rect, lpDDSDead, &srect, DDBLT_WAIT|DDBLT_KEYSRC , NULL);
if(rval == DDERR_SURFACELOST) lpDDSBack->Restore();
static int oldtime=0;//延时
if (GetTickCount()-oldtime>200)
{
oldtime=GetTickCount();
deadflamestatus++;//更新火焰状态
if (deadflamestatus==9 ) deadflamestatus=0;//火焰完毕
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -