📄 game.cpp
字号:
}
if(m_pPlayerBuffer)
{
m_pPlayerBuffer->Release();
m_pPlayerBuffer=NULL;
}
if(m_pTankAppBuffer)
{
m_pTankAppBuffer->Release();
m_pTankAppBuffer=NULL;
}
if(m_pTankStateBuffer)
{
m_pTankStateBuffer->Release();
m_pTankStateBuffer=NULL;
}
if(m_pEnemyBuffer)
{
m_pEnemyBuffer->Release();
m_pEnemyBuffer=NULL;
}
if(m_pWaitBuffer)
{
m_pWaitBuffer->Release();
m_pWaitBuffer=NULL;
}
if(m_pGameOverBuffer)
{
m_pGameOverBuffer->Release();
m_pGameOverBuffer=NULL;
}
if(m_pBeginBuffer)
{
m_pBeginBuffer->Release();
m_pBeginBuffer=NULL;
}
if(m_pLevelBuffer)
{
m_pLevelBuffer->Release();
m_pLevelBuffer=NULL;
}
}
m_pDD->Release();
m_pDD=NULL;
}
}
HRESULT CGame::DDSetColorKey(LPDIRECTDRAWSURFACE pdds, COLORREF rgb)
{
DDCOLORKEY ddck;
ddck.dwColorSpaceLowValue = DDColorMatch(pdds, rgb);
ddck.dwColorSpaceHighValue = ddck.dwColorSpaceLowValue;
return pdds->SetColorKey(DDCKEY_SRCBLT, &ddck);
}
DWORD CGame::DDColorMatch(LPDIRECTDRAWSURFACE pdds, COLORREF rgb)
{
COLORREF rgbT;
HDC hdc;
DWORD dw = CLR_INVALID;
DDSURFACEDESC ddsd;
HRESULT hres;
//
// Use GDI SetPixel to color match for us
//
if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
{
rgbT = GetPixel(hdc, 0, 0); // Save current pixel value
SetPixel(hdc, 0, 0, rgb); // Set our value
pdds->ReleaseDC(hdc);
}
//
// Now lock the surface so we can read back the converted color
//
ddsd.dwSize = sizeof(ddsd);
while ((hres = pdds->Lock(NULL, &ddsd, 0, NULL)) == DDERR_WASSTILLDRAWING)
;
if (hres == DD_OK)
{
dw = *(DWORD *) ddsd.lpSurface; // Get DWORD
if (ddsd.ddpfPixelFormat.dwRGBBitCount < 32)
dw &= (1 << ddsd.ddpfPixelFormat.dwRGBBitCount) - 1; // Mask it to bpp
pdds->Unlock(NULL);
}
//
// Now put the color that was there back.
//
if (rgb != CLR_INVALID && pdds->GetDC(&hdc) == DD_OK)
{
SetPixel(hdc, 0, 0, rgbT);
pdds->ReleaseDC(hdc);
}
return dw;
}
BOOL CGame::GameInit()
{
//*init sound
if(!m_wavBang.Create(IDR_BANG))
return FALSE;
if(!m_wavDie.Create(IDR_DIE))
return FALSE;
if(!m_wavShoot.Create(IDR_SHOOT))
return FALSE;
if(!m_wavEgg.Create(IDR_EGG))
return FALSE;
if(!m_midiBKMusic.Create(IDR_MIDIBKMUSIC))
return FALSE;
return TRUE;
}
void CGame::SetWndRect(RECT &rc)
{
m_rcWnd=rc;
}
void CGame::FlipScreen()
{
HRESULT hr;
hr = m_pddsFrontBuffer->Blt( &m_rcWnd, m_pddsBackBuffer,NULL, DDBLT_WAIT, NULL );
if( hr == DDERR_SURFACELOST )
ResetSurface();
}
void CGame::ResetSurface()
{
m_pddsBackBuffer->Restore();
m_pddsFrontBuffer->Restore();
m_TankMap.ResetSurface();
DDReLoadBitmap( m_TankMap.GetSoilBmp(),IDB_SOIL);
DDReLoadBitmap( m_TankMap.GetStoneBmp(),IDB_STONE);
DDReLoadBitmap( m_TankMap.GetSteelBmp(),IDB_STEEL);
DDReLoadBitmap( m_TankMap.GetWaterBmp(),IDB_WATER);
DDReLoadBitmap( m_TankMap.GetIceBmp(),IDB_ICE);
DDReLoadBitmap( m_TankMap.GetTreeBmp(),IDB_TREE);
}
HRESULT CGame::DDReLoadBitmap(LPDIRECTDRAWSURFACE pdds, LPCSTR szBitmap)
{
HBITMAP hbm;
HRESULT hr;
hbm = (HBITMAP) LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, 0,
0, LR_CREATEDIBSECTION);
if (hbm == NULL)
hbm = (HBITMAP) LoadImage(NULL, szBitmap, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION);
if (hbm == NULL)
{
OutputDebugString("handle is null\n");
return E_FAIL;
}
hr = DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
if (hr != DD_OK)
{
OutputDebugString("ddcopybitmap failed\n");
}
DeleteObject(hbm);
return hr;
}
HRESULT CGame::DDReLoadBitmap(LPDIRECTDRAWSURFACE pdds, int id)
{
HBITMAP hbm;
HRESULT hr;
CBitmap bmp;
if(bmp.LoadBitmap(id)==FALSE)
return NULL;
hbm=HBITMAP(bmp.GetSafeHandle());
if (hbm == NULL)
{
OutputDebugString("handle is null\n");
return E_FAIL;
}
hr = DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
if (hr != DD_OK)
{
OutputDebugString("ddcopybitmap failed\n");
}
DeleteObject(hbm);
return hr;
}
void CGame::DDClear(RECT *prc, DWORD dwFillColor)
{
DDBLTFX ddbfx;
ZeroMemory( &ddbfx, sizeof(ddbfx) );
ddbfx.dwSize = sizeof(ddbfx);
ddbfx.dwFillColor = dwFillColor;
m_pddsBackBuffer->Blt( prc, NULL, NULL,
DDBLT_COLORFILL | DDBLT_WAIT, &ddbfx );
}
void CGame::DrawWait(int n)
{
if(n>3)return;
RECT rc;
rc.left=0;
rc.right=SCREEN_WIDTH;
rc.top=0;
rc.bottom=SCREEN_HEIGHT;
DDClear(&rc,RGB(0,0,0));
//取消背景图
// m_pddsBackBuffer->BltFast(0,0, m_pBackGroundBuffer, &rc, DDBLTFAST_WAIT );
//draw general
rc.left=0;
rc.right=m_rcGeneral.Width();
rc.top=0;
rc.bottom=m_rcGeneral.Height();
m_pddsBackBuffer->BltFast(m_rcGeneral.left,m_rcGeneral.top,m_pGeneralBuffer,&rc,DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
m_TankMap.DrawMap(m_pddsBackBuffer);
m_TankMap.DrawShield(m_pddsBackBuffer); //对于可以遮蔽的物体
rc.left=720-n*240;
rc.right=rc.left+240;
rc.top=0;
rc.bottom=240;
m_pddsBackBuffer->BltFast(200,200, m_pWaitBuffer, &rc, DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY );
FlipScreen();
}
void CGame::DrawGameOver()
{
RECT rc;
rc.left=0;
rc.right=424;
rc.top=0;
rc.bottom=317;
m_pddsBackBuffer->BltFast(120,100, m_pGameOverBuffer, &rc,DDBLTFAST_SRCCOLORKEY | DDBLTFAST_WAIT );
FlipScreen();
}
void CGame::DrawWorldMap()
{
CBullet * p;
RECT rc;
rc.left=0;
rc.right=SCREEN_WIDTH;
rc.top=0;
rc.bottom=SCREEN_HEIGHT;
//以下是背景图片(为了节约空间,略去)
//* m_pddsBackBuffer->BltFast(0,0, m_pBackGroundBuffer, &rc, DDBLTFAST_WAIT );
//将背景改为黑屏
DDClear(&rc,RGB(0,0,0));
//draw general
rc.left=0;
rc.right=m_rcGeneral.Width();
rc.top=0;
rc.bottom=m_rcGeneral.Height();
m_pddsBackBuffer->BltFast(m_rcGeneral.left,m_rcGeneral.top,m_pGeneralBuffer,&rc,DDBLTFAST_WAIT|DDBLTFAST_SRCCOLORKEY);
//此处判断一下是否老盖是否被改变
if(m_nBorderTime==1)
{
CellType temp;
temp.cell=CT_SOIL;
temp.mask=0;
temp.defence=100;
m_TankMap.SetHeadQuarterBorder(temp);
}
if(m_nBorderTime>0)m_nBorderTime--;
m_TankMap.DrawMap(m_pddsBackBuffer);
CEgg * egg;
POSITION prepos;
POSITION position=m_Egg.GetHeadPosition();
while(position)
{
prepos=position;
egg=m_Egg.GetNext(position);
if(egg->m_nLife-- <= 0 )
{
delete egg;
m_Egg.RemoveAt(prepos);
break;
}
egg->DrawEgg(m_pddsBackBuffer);
}
CTank *tp=NULL;
position=m_Player.GetHeadPosition();
while(position)
{
tp=m_Player.GetNext(position);
tp->DrawTank(m_pddsBackBuffer);
}
position=m_Enemy.GetHeadPosition();
if(!position && m_nLeftEnemy==0)
{
if(m_nGameLevel > GAMETOTALLEVEL)
m_nGameState=GAMEWIN;
else
m_nGameState=GAMENEXT;
return;
}
while(position)
{
tp=m_Enemy.GetNext(position);
tp->DrawTank(m_pddsBackBuffer);
}
position=m_BulletList.GetHeadPosition();
while(position)
{
p=m_BulletList.GetNext(position);
p->DrawBullet(m_pddsBackBuffer);
}
CExplode *te;
position=m_Explode.GetHeadPosition();
while(position)
{
te=m_Explode.GetNext(position);
te->DrawExplode(m_pddsBackBuffer);
}
m_TankMap.DrawShield(m_pddsBackBuffer);
FlipScreen();
}
void CGame::OutputText(int x, int y, LPCTSTR string,COLORREF rgb,CFont *font)
{
HDC hdc;
if( m_pddsBackBuffer &&
m_pddsBackBuffer->GetDC(&hdc) == DD_OK )
{
HGDIOBJ oldFont=SelectObject(hdc,font->GetSafeHandle());
SetBkMode( hdc, TRANSPARENT );
SetTextColor( hdc, rgb);
TextOut( hdc, x, y, string, lstrlen(string) );
SelectObject(hdc,oldFont);
m_pddsBackBuffer->ReleaseDC( hdc );
}
}
void CGame::Run()
{
if(m_nGameState==GAMEACTIVE)
{
POSITION position,pre=NULL;
position=m_BulletList.GetHeadPosition();
while(position)
{
pre=position;
CBullet * p=m_BulletList.GetNext(position);
BOOL ret=p->BulletTrack();
if(!ret && pre)
{
delete p;
m_BulletList.RemoveAt(pre);
break;
}
}
int nEnemy=0;
if(m_nFreezeTime<=0)
{
position=m_Enemy.GetHeadPosition();
while(position)
{
CTank * p=m_Enemy.GetNext(position);
p->TankMove();
nEnemy++;
}
if(nEnemy < 4 && m_nLeftEnemy > 0)
{
for(int i=0;i<3;i++)
BringTank(i+1);
}
}
else m_nFreezeTime--;
position=m_Explode.GetHeadPosition();
while(position)
{
pre=position;
CExplode * p=m_Explode.GetNext(position);
BOOL ret=p->Burn();
if(!ret && pre)
{
if(p->GetSort()==1) //1: 产生坦克时的闪动效果
{
int side=p->GetSide();
if(side==1)
{
m_tankleft=new CTank;
if(m_tankleft)
{
m_bLeftBring=false;
m_tankleft->Init(this,15,38,m_pPlayerBuffer,m_pTankStateBuffer,0);
m_Player.AddHead(m_tankleft);
m_nLeftPlayer--;
}
}
else if(side==2)
{
m_tankright=new CTank;
if(m_tankright)
{
m_bRightBring=false;
m_tankright->Init(this,23,38,m_pPlayerBuffer,m_pTankStateBuffer,1);
m_Player.AddTail(m_tankright);
m_nRightPlayer--;
}
}
else
{
}
}
delete p;
m_Explode.RemoveAt(pre);
break;
}
}
if(m_tankleft==NULL && !m_bLeftBring && m_nLeftPlayer>0)
{
CExplode *p=new CExplode;
if(p)
{
p->Init(15*TANKMAPCELL,38*TANKMAPCELL,5,8,m_pTankAppBuffer,32,32,1,1);
m_Explode.AddTail(p);
m_bLeftBring=true;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -