📄 game.cpp
字号:
}
//------------------------------------------------------------------------------
//场景更换
void CGame::UpdateFrame()
{
//如果游戏结束
if ( 0==m_iGameStatus ||
2==m_iGameStatus )
{
DrawScore();
return;
}
#if _WIN32_WCE
Fire();
#else
if(FALSE == m_iniAutoFire)
{
if(GetAsyncKeyState(m_iniFire))
Fire();
}
else
Fire();
#endif
//放雷
if(GetAsyncKeyState(m_iniThunder))
FlashScreen();
DrawMap();
Check();
CheckBoss();
DrawPlane();
DrawBall();
DrawFoe();
DrawBlast();
DrawFoeBoss();
DrawScore();
DrawFlip();
}
//------------------------------------------------------------------------------
//将缓冲内容贴到屏幕
void CGame::DrawFlip()
{
RECT Window;
POINT pt;
GetClientRect(hWnd, &Window);
pt.x=pt.y=0;
ClientToScreen(hWnd, &pt);
OffsetRect(&Window, pt.x, pt.y);
HDC hDC = GetDC(hWnd);
BitBlt(hDC,0,0,ScreenW,ScreenH,g_hBufDC,0,0,SRCCOPY);
ReleaseDC(hWnd,hDC);
hDC = NULL;
return ;
}
//------------------------------------------------------------------------------
//画我机子弹
void CGame::DrawBall()
{
for (int i=0; i<BALLNUM; i++)
{
RECT rcL,rcR;
rcL.left = BallPosL[i].x;
rcL.top = BallPosL[i].y;
rcL.right = rcL.left + 10;
rcL.bottom = rcL.top + 20;
rcR.left = BallPosR[i].x;
rcR.top = BallPosR[i].y;
rcR.right = rcR.left + 10;
rcR.bottom = rcR.top + 20;
BitBlt(g_hBufDC,rcL.left,rcL.top,ScreenW,ScreenH,g_hBalDC[0],0,0,SRCINVERT);
BitBlt(g_hBufDC,rcR.left,rcR.top,ScreenW,ScreenH,g_hBalDC[1],0,0,SRCINVERT);
BallPosL[i].x --;
BallPosL[i].y -= 26;
BallPosR[i].x ++;
BallPosR[i].y -= 26;
}
}
//------------------------------------------------------------------------------
//画敌机
void CGame::DrawFoe()
{
RECT rect;
for(int i=0; i<FOENUM; i++)
{
if( FoePos[i].x<=0 || FoePos[i].x>=ScreenW ||
FoePos[i].y<=0 || FoePos[i].y>=ScreenH )
{
FoeDead[i] = 0;
}
if (0 != FoeDead[i]) //敌机未毁
{
switch (FoeType[i])
{
case 0://敌机2
GetRect( &rect, FoePos[i].x, FoePos[i].y, 50, 57);
BitBlt(g_hBufDC,rect.left-10 ,rect.top-10,ScreenW,ScreenH,
g_hFoePlaDC[1],0,0,SRCINVERT);
FoePos[i].y+=FoeSpeed[i]+(movespeed);
FoePos[i].x+=FoeWay[i];
break;
case 1://子弹1
GetRect( &rect, FoePos[i].x, FoePos[i].y, 8, 8);
BitBlt(g_hBufDC,rect.left,rect.top,ScreenW,ScreenH,
g_hFoeBalDC[0],0,0,SRCINVERT);
FoePos[i].y+=FoeSpeed[i]+(movespeed+2);
FoePos[i].x+=FoeWay[i];
break;
case 2://敌机1(自杀型)
GetRect( &rect, FoePos[i].x, FoePos[i].y, 35, 35);
BitBlt(g_hBufDC,rect.left,rect.top,ScreenW,ScreenH,
g_hFoePlaDC[0],0,0,SRCINVERT);
FoePos[i].y+=FoeSpeed[i]+(movespeed+2);
FoePos[i].x+=FoeWay[i];
break;
case 3://子弹2
GetRect( &rect, FoePos[i].x, FoePos[i].y, 26, 28);
BitBlt(g_hBufDC,rect.left-10,rect.top-10,ScreenW,ScreenH,
g_hFoeBalDC[1],0,0,SRCINVERT);
FoePos[i].y+=FoeSpeed[i]+(movespeed);
FoePos[i].x+=FoeWay[i];
break;
}
}
if ( FoeDead[i]==0 )
{
FoePos[i].x=(int)(ScreenW*((long)rand()/32767.0))+50;
FoePos[i].y=(int)(35*((long)rand()/32767.0));
FoeSpeed[i]=(int)(4*((long)rand()/32767.0));
FoeWay[i]=(int)(3*((long)rand()/32767.0))-1;//-1,0,1
//敌机类型
FoeType[i]=(int)(4*((long)rand()/32767.0));//0,1,2,3
FoeDead[i]=1; //敌人复活
}
}
}
//------------------------------------------------------------------------------
//画爆炸火焰效果
void CGame::DrawBlast()
{
//敌机爆炸火焰
for (int f=0; f<FOENUM; f++)
{
if (0 != FoeBlastType[f])
{
RECT rc,rc1;
GetRect(&rc, FoeBlastPos[f].x, FoeBlastPos[f].y, 66, 66);
GetRect(&rc1, (FoeBlastType[f] - 1)*66, 0, 66, 66);
BitBlt(g_hBufDC,rc.left,rc.top,rc1.right-rc1.left,rc1.bottom-rc1.top,
g_hFoeBusDC,rc1.left,rc1.top,SRCINVERT);
static int otime[FOENUM];
if (GetTickCount()-otime[f]>150)
{
otime[f]=GetTickCount();
FoeBlastType[f]++;//更新火焰状态
if (FoeBlastType[f]==9 ) FoeBlastType[f]=0;//火焰完毕
}
}
}
//我机爆炸火焰
if (0 != BlastTpye)
{
RECT rect, srect;
GetRect(&rect, BlastPos.x, BlastPos.y, 66, 66);
GetRect(&srect,(BlastTpye-1)*66, 0, 66, 66);
BitBlt(g_hBufDC,rect.left,rect.top,srect.right-srect.left,srect.bottom-srect.top,
g_hBusDC,srect.left,srect.top,SRCINVERT);
static int oldtime=0;//延时
if (GetTickCount()-oldtime>200)
{
oldtime=GetTickCount();
BlastTpye++;//更新火焰状态
if (BlastTpye==9 ) BlastTpye=0;//火焰完毕
}
}
}
//------------------------------------------------------------------------------
//游戏检测
void CGame::Check()
{
int b=0;
//检测敌机是否被击落
for (int e=0; e<FOENUM; e++)
{
//敌人已消灭
if (0 == FoeDead[e])
continue;
switch (FoeType[e])
{
case 0:
case 2://是敌机
//敌机不在窗口内
if (TRUE == IsOutRect(FoePos[e]))
continue;
for (b=0; b<FOENUM; b++)
{
//检测左子弹
if (FALSE == IsOutRect(BallPosL[b]))
{
if ( abs(FoePos[e].x-BallPosL[b].x+15)<15 &&
abs(FoePos[e].y-BallPosL[b].y+11)<15 )
{
PlaySound(MAKEINTRESOURCE(IDR_WAVE_BOMB),g_hInst,SND_RESOURCE|SND_ASYNC);
FoeDead[e] = 0; //使敌机销毁
BallPosL[b].y = 0; //使子弹消失
FoeBlastPos[e].x = FoePos[e].x - 10; //火焰坐标
FoeBlastPos[e].y = FoePos[e].y - 8; //火焰坐标
FoeBlastType[e] = 1; //火焰状态
//敌机损失数量++
m_iFoeDead ++;
m_iFoeTotalDead++;
}
}
//检测右子弹
if (FALSE == IsOutRect(BallPosR[b]))
{
if ( abs(FoePos[e].x-BallPosR[b].x+15)<15 &&
abs(FoePos[e].y-BallPosR[b].y+11)<15 )
{
PlaySound(MAKEINTRESOURCE(IDR_WAVE_BOMB),g_hInst,SND_RESOURCE|SND_ASYNC);
FoeDead[e] = 0; //使敌机销毁
BallPosR[b].y = 0; //使子弹消失
FoeBlastPos[e].x = FoePos[e].x - 10; //火焰坐标
FoeBlastPos[e].y = FoePos[e].y - 8; //火焰坐标
FoeBlastType[e] = 1; //火焰状态
//敌机损失数量++
m_iFoeDead ++;
m_iFoeTotalDead++;
}
}
}
break;
case 1:
case 3://是子弹
break;
}
}
//检测我机是否撞毁
for (int p=0; p<FOENUM; p++)
{
//超级用户,打不死哈哈
if(TRUE == m_iniSuperUser) break;
//我机重新初始化的时候
if(TRUE == m_bNewReset) break;
if(FoeDead[p]==0)
continue;
if(IsOutRect(FoePos[p]))
continue;
switch (FoeType[p])
{
case 1:
case 3: //子弹
if ( abs(pos.x-FoePos[p].x+21)<15 &&
abs(pos.y-FoePos[p].y+26)<12 )
{
FoeDead[p]=0;
BlastPos.x=FoePos[p].x-29;
BlastPos.y=FoePos[p].y-29;
BlastTpye = 1;
//我机飞机数量--,被击中
m_iReMain --;
//损失总数++
m_iTotalPlane++;
}
break;
case 0:
case 2: //敌机
if ( abs(pos.x-FoePos[p].x+7)<15 &&
abs(pos.y-FoePos[p].y+12)<12 )
{
FoeDead[p]=0;
BlastPos.x=FoePos[p].x-15;
BlastPos.y=FoePos[p].y-15;
BlastTpye = 1;
//我机飞机数量--,被撞毁
m_iReMain --;
//损失总数++
m_iTotalPlane++;
}
break;
}
}
if (m_iReMain <= 0) //游戏结束
{
m_iGameStatus = 2;
m_bResetGame = TRUE;
}
}
//------------------------------------------------------------------------------
//检测我机是否被敌机BOSS击中
void CGame::CheckBoss()
{
//BOSS没有出现
if(FALSE == m_bSeeBoss) return;
int b;
//BOSS是否被我机击中
for(b=0;b<BALLNUM;b++)
{
if ( abs(m_pFoeBossPos.x-BallPosL[b].x)<10 &&
abs(m_pFoeBossPos.y-BallPosL[b].y)<20 )
{
m_iFoeBossBlood--;
}
if ( abs(m_pFoeBossPos.x-BallPosR[b].x)<10 &&
abs(m_pFoeBossPos.y-BallPosR[b].y)<20 )
{
m_iFoeBossBlood--;
}
}
//超级用户,打不死哈哈
if(TRUE == m_iniSuperUser) return;
//我机重新初始化的时候
if(TRUE == m_bNewReset) return;
//我机是否被BOSS击中
switch(m_iLevel)
{
case 1: //第一关
case 2:
case 3:
case 4:
case 5:
for (b=0; b<m_iBossTotalBalNum; b++)
{
if ( abs(pos.x-m_pFoeBossBalPos[b].x+12)<25 &&
abs(pos.y-m_pFoeBossBalPos[b].y+12)<30)
{
BlastPos.x=m_pFoeBossBalPos[b].x-29;
BlastPos.y=m_pFoeBossBalPos[b].y-29;
BlastTpye = 1;
//我机飞机数量--,被击中
m_iReMain --;
//损失总数++
m_iTotalPlane++;
}
}
//我机被BOSS撞毁,重叠半个飞机距离
if ( abs(m_pFoeBossPos.x+50-pos.x)<25 &&
abs(m_pFoeBossPos.y+60-pos.y)<30 )
{
BlastPos.x=pos.x-29;
BlastPos.y=pos.y-29;
BlastTpye = 1;
//我机飞机数量--,被撞毁
m_iReMain --;
//损失总数++
m_iTotalPlane++;
}
break;
}
}
//------------------------------------------------------------------------------
//是否在区域内
BOOL CGame::IsOutRect(POINT p)
{
if (p.x<35 || p.x>ScreenW+35 || p.y<35 || p.y>ScreenH+35)
return TRUE;
else
return FALSE;
}
//------------------------------------------------------------------------------
//我机放雷
void CGame::FlashScreen()
{
//一架飞机只有3次放雷的机会
if(m_iBomb <= 0) return;
TCHAR tcWaveFile[MAX_PATH]={'\0'};
wcscpy(tcWaveFile,tcAppExePath);
wcscat(tcWaveFile,TEXT("Q11\\thunder.WAV"));
PlaySound (tcWaveFile,NULL,SND_FILENAME|SND_ASYNC);
HDC hDC = GetDC(hWnd);
int iBombW = 84; //雷的图片宽度
for(int i=0;i<(ScreenW/iBombW)+1;i++)
BitBlt(hDC,i*84,0,ScreenW,ScreenH,g_hBomDC,0,0,SRCINVERT);
ReleaseDC(hWnd,hDC);
hDC = NULL;
//敌机消失,只是消失呢,不给计算敌机损失,
//保护一下自己而已。想打通关,就用作弊方式吧
for (i=0; i<FOENUM; i++)
FoeDead[i] = 0;
//如果有BOSS
if(TRUE == m_bSeeBoss)
{
//如果BOSS与我机相距少于等于一个飞机宽AND
//少于等于一个飞机高度,BOSS血减掉5
//否则雷白放了哦:-)减少一点难度吧,呵呵
m_iFoeBossBlood -= 5;
for(i=0;i<m_iBossTotalBalNum;i++)
{
m_pFoeBossBalPos[i].x = ScreenW;
m_pFoeBossBalPos[i].y = ScreenH;
}
}
//雷数量--
//超级用户当然不减了哈哈
if(FALSE == m_iniSuperUser)
m_iBomb --;
Sleep(500);
}
//------------------------------------------------------------------------------
//垂直方向开启屏幕效果
void CGame::VOpen()
{
HDC hDC = GetDC(hWnd);
RECT rc;
GetWindowRect(hWnd,&rc);
for (int m=0;m<121;m++)
{
BitBlt(hDC,0,rc.top,
ScreenW,(rc.bottom-rc.top),
g_hBufDC,0,rc.top,BLACKNESS);
rc.top -= 2;
rc.bottom += 2;
::Sleep(5);
}
ReleaseDC(hWnd,hDC);
hDC = NULL;
}
//------------------------------------------------------------------------------
//垂直方向关闭屏幕效果
void CGame::VClose()
{
TCHAR tcWaveFile[MAX_PATH]={'\0'};
wcscpy(tcWaveFile,tcAppExePath);
wcscat(tcWaveFile,TEXT("Q11\\open.wav"));
PlaySound (tcWaveFile,NULL,SND_FILENAME|SND_ASYNC);
HDC hDC = GetDC(hWnd);
RECT rc;
GetClientRect(hWnd,&rc);
int a,b;
#if _WIN32_WCE
a = 121;
b = 2;
#else
a = 30;
b = 20;
#endif
for (int m=0;m<a;m++)
{
BitBlt(hDC,0,0,ScreenW,rc.top,g_hBufDC,0,0,BLACKNESS);
BitBlt(hDC,0,rc.bottom,ScreenW,(ScreenH-rc.bottom),g_hBufDC,0,0,BLACKNESS);
rc.top += b;
rc.bottom -= b;
::Sleep(5);
}
//用于绘制“请稍候……”
rc.left=0;
rc.top=ScreenH/2;
rc.right=ScreenW;
rc.bottom=ScreenH;
SetTextColor(hDC,0x0000ffff);//黄色
SetBkMode(hDC,TRANSPARENT);//设置透明背景
if(m_iLevel > 1)
{
TCHAR str[256] = {'\0'};
swprintf(str,TEXT("祝贺通过第%d关!"),m_iLevel-1);
DrawText(hDC,str,-1,&rc,DT_CENTER);
rc.top += 20;
rc.bottom += 20;
}
DrawText(hDC,TEXT("请稍侯……"),-1,&rc,DT_CENTER);
ReleaseDC(hWnd,hDC);
hDC = NULL;
Sleep(1000);
}
//------------------------------------------------------------------------------
//平行方向打开屏幕效果
void CGame::LOpen()
{
HDC hDC = GetDC(hWnd);
RECT rc;
GetWindowRect(hWnd,&rc);
for (int m=0;m<121;m++)
{
BitBlt(hDC,rc.left,0,(rc.right-rc.left),
ScreenH,g_hBufDC,rc.left,0,SRCCOPY);
rc.left -= 1;
rc.right += 1;
}
ReleaseDC(hWnd,hDC);
hDC = NULL;
}
//------------------------------------------------------------------------------
//平行方向关闭屏幕效果
void CGame::LClose()
{
TCHAR tcWaveFile[MAX_PATH]={'\0'};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -