📄 glb.cpp
字号:
// GLB.cpp: implementation of the GLB class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "BubbleII.h"
#include "GLB.h"
#include <math.h>
#include "BubbleIIDlg.h"
#include "GhostThread.h"
#include "BubbleThread.h"
#include "AboutDlg.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CBitmap* GLB::pSelf[8];
CBitmap* GLB::pBMPBackgrounds[25];
CBitmap* GLB::pBMPGhost[24];
int GLB::iBlockHeight=40;
int GLB::iBlockWidth=40;
int GLB::iXBlocks=20;
int GLB::iYBlocks=14;
int* GLB::pIBackMatrix=new int[GLB::iXBlocks*GLB::iYBlocks];
BOOL GLB::bInitiated=FALSE;
CDC* GLB::pMemDC=new CDC;
CBitmap* GLB::pMemBMP=new CBitmap;
BOOL GLB::bGameStarted=FALSE;
CWaterRoutine* GLB::pMyWater=new CWaterRoutine;
BOOL GLB::bHeightAlive=FALSE;
BOOL GLB::bWaterInited=FALSE;
CBubbleIIDlg* GLB::pMainDlg=NULL;
BITMAP* GLB::uBgBMP=(BITMAP *) new BYTE[sizeof(BITMAP)];
BOOL GLB::bGhostsAlive[30];
BOOL GLB::bRepaintThreadAlive=FALSE;
CBitmap* GLB::pBACKBMP=new CBitmap;
CDC* GLB::pBACKDC=new CDC;
ULONG GLB::lBMPLength=0;
int GLB::iGameStage=1;
unsigned int* GLB::pBACKBMPBackUp=NULL;
CGhostThread* GLB::pGhostThread[30];
CBubbleThread* GLB::pBubbleThread[30];
BOOL GLB::bBubbleAlive[30];
CBitmap* GLB::pBMPGameover[30];
//int* GLB::pIBackMatrixBackup=new int[GLB::iXBlocks*GLB::iYBlocks];
enum GameType GLB::eGameType=GAMEOVER;
CDC* GLB::pPartMemDC=new CDC;
int GLB::iGameOverFrameNum=0;
int GLB::iWindowWidth=GLB::iBlockWidth*GLB::iXBlocks;
int GLB::iWindowHeight=GLB::iBlockHeight*GLB::iYBlocks;
int GLB::iBackBMPWidth=GLB::iBlockWidth;
int GLB::iBackBMPHeight=GLB::iBlockHeight;
int GLB::iBackBMPXNum=GLB::iXBlocks;
int GLB::iBackBMPYNum=GLB::iYBlocks;
CBitmap* GLB::pBMPBounsA[9];
int GLB::iBounsAIndex=0;
BOOL GLB::bStageWin=FALSE;
int GLB::iRepaintScoreFrameNum=0;
CAboutDlg* GLB::pAboutDlg=new CAboutDlg;
GLB::GLB()
{
}
GLB::~GLB()
{
}
void GLB::TransparentBlt( HDC hdcDest, // 目标DC
int nXOriginDest, // 目标X偏移
int nYOriginDest, // 目标Y偏移
int nWidthDest, // 目标宽度
int nHeightDest, // 目标高度
HDC hdcSrc, // 源DC
int nXOriginSrc, // 源X起点
int nYOriginSrc, // 源Y起点
int nWidthSrc, // 源宽度
int nHeightSrc, // 源高度
UINT crTransparent // 透明色,COLORREF类型
)
{
HBITMAP hOldImageBMP, hImageBMP = CreateCompatibleBitmap(hdcDest, nWidthDest, nHeightDest); // 创建兼容位图
HBITMAP hOldMaskBMP, hMaskBMP = CreateBitmap(nWidthDest, nHeightDest, 1, 1, NULL); // 创建单色掩码位图
HDC hImageDC = CreateCompatibleDC(hdcDest);
HDC hMaskDC = CreateCompatibleDC(hdcDest);
hOldImageBMP = (HBITMAP)SelectObject(hImageDC, hImageBMP);
hOldMaskBMP = (HBITMAP)SelectObject(hMaskDC, hMaskBMP);
// 将源DC中的位图拷贝到临时DC中
if (nWidthDest == nWidthSrc && nHeightDest == nHeightSrc)
BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hdcSrc, nXOriginSrc, nYOriginSrc, SRCCOPY);
else
StretchBlt(hImageDC, 0, 0, nWidthDest, nHeightDest,
hdcSrc, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc, SRCCOPY);
// 设置透明色
SetBkColor(hImageDC, crTransparent);
// 生成透明区域为白色,其它区域为黑色的掩码位图
BitBlt(hMaskDC, 0, 0, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCCOPY);
// 生成透明区域为黑色,其它区域保持不变的位图
SetBkColor(hImageDC, RGB(0,0,0));
SetTextColor(hImageDC, RGB(255,255,255));
BitBlt(hImageDC, 0, 0, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);
// 透明部分保持屏幕不变,其它部分变成黑色
SetBkColor(hdcDest,RGB(0xff,0xff,0xff));
SetTextColor(hdcDest,RGB(0,0,0));
BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hMaskDC, 0, 0, SRCAND);
// "或"运算,生成最终效果
BitBlt(hdcDest, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest, hImageDC, 0, 0, SRCPAINT);
SelectObject(hImageDC, hOldImageBMP);
DeleteDC(hImageDC);
SelectObject(hMaskDC, hOldMaskBMP);
DeleteDC(hMaskDC);
DeleteObject(hImageBMP);
DeleteObject(hMaskBMP);
}
UINT HeightWater(LPVOID pParam)
{
while(GLB::bHeightAlive)
{
Sleep((int)(rand()*20.0/RAND_MAX+100));
GLB::pMyWater->HeightBlob((int)(rand()*600.0/RAND_MAX),(int)(rand()*422.0/RAND_MAX),(int)(rand()*20.0/RAND_MAX),(int)(rand()*100.0/RAND_MAX),GLB::pMyWater->m_iHpage);
}
return 0;
}
UINT AboutDlgHolder(LPVOID pParam)
{
if(GLB::pAboutDlg->DoModal()==IDOK)
{
GLB::pMainDlg->FinalWins();
}
return 0;
}
UINT Repainter(LPVOID pParam)
{
COLORREF crMask = RGB(0x00,0xff,0x00);
int iHeight=GLB::iBlockHeight*GLB::iYBlocks;
int iWidth=GLB::iBlockWidth*GLB::iXBlocks;
// int iGameOverFrameNum;
//延时等待Ghost启动起来。
Sleep(10);
CDC* pDC=GLB::pMainDlg->GetDC();
while(GLB::bRepaintThreadAlive)
{
// GLB::pMainDlg->RepaintMemBackground();
GLB::RepaintMemBG();
for(int i=0; i<30; i++)
{
if(GLB::pBubbleThread[i]->m_state==BORN)
{
GLB::TransparentBlt(
GLB::pMemDC->m_hDC,
(int)(GLB::pBubbleThread[i]->m_fX),
(int)(GLB::pBubbleThread[i]->m_fY),
GLB::iBlockWidth,
GLB::iBlockHeight,
GLB::pBubbleThread[i]->m_pPartImageMemDC->m_hDC,
0,0,
GLB::iBlockWidth,GLB::iBlockHeight,
crMask);
}
}
for(i=0; i<30; i++)
{
if(GLB::bGhostsAlive[i])
{
GLB::TransparentBlt(
GLB::pMemDC->m_hDC,
(int)(GLB::pGhostThread[i]->m_x),
(int)(GLB::pGhostThread[i]->m_y),
GLB::iBlockWidth,
GLB::iBlockHeight,
GLB::pGhostThread[i]->m_pPartImageMemDC->m_hDC,
0,0,
GLB::iBlockWidth,GLB::iBlockHeight,
crMask);
}
}
GLB::RepaintMemFG();
Sleep(10);
pDC->BitBlt(0,0,iWidth,iHeight+90,GLB::pMemDC,0,0,SRCCOPY);
}
return 0;
}
void GLB::RepaintMemBG()
{
// GLB::pBACKBMP->SetBitmapBits(GLB::lBMPLength<<2,GLB::pBACKBMPBackUp);
// GLB::pMemDC->SelectObject(GLB::pBACKBMP);
//画障碍。
COLORREF crMask = RGB(0x00,0xff,0x00);
int iPicIndex=0, iBackValue=0, i=0, j=0;
for(i=0; i<GLB::iBackBMPXNum; i++)
{
for(j=0; j<GLB::iBackBMPYNum; j++)
{
int Height=GLB::iWindowHeight-j*GLB::iBackBMPHeight;
Height=(Height>GLB::iBackBMPHeight)?GLB::iBackBMPHeight:Height;
GLB::pPartMemDC->SelectObject(GLB::pBMPBackgrounds[(GLB::iGameStage-1)%6+10]);
GLB::pMemDC->BitBlt(
i*GLB::iBackBMPWidth,
j*GLB::iBackBMPHeight,
GLB::iBackBMPWidth,
Height,
GLB::pPartMemDC,
0,0,
SRCCOPY);
}
}
for(i=0; i<GLB::iXBlocks; i++)
{
for(j=0; j<GLB::iYBlocks; j++)
{
iBackValue=*(GLB::pIBackMatrix+j*GLB::iXBlocks+i);
iPicIndex=(iBackValue&0x000000ff)/10;
//如果是森林,改画草地,森林在画前景时用到。
iPicIndex=(iPicIndex==5)?0:iPicIndex;
if(iPicIndex==0||iPicIndex==9)
continue;
GLB::pPartMemDC->SelectObject(GLB::pBMPBackgrounds[iPicIndex]);
if(iPicIndex==3)
{
GLB::TransparentBlt(
GLB::pMemDC->m_hDC,
i*GLB::iBlockWidth,
j*GLB::iBlockHeight,
GLB::iBlockWidth,
GLB::iBlockHeight,
GLB::pPartMemDC->m_hDC,
0,0,
GLB::iBlockWidth,
GLB::iBlockHeight,
crMask);
}
else
{
GLB::pMemDC->BitBlt(
i*GLB::iBlockWidth,
j*GLB::iBlockHeight,
GLB::iBlockWidth,
GLB::iBlockHeight,
GLB::pPartMemDC,
0,0,
SRCCOPY);
}
}
}
}
void GLB::RepaintMemFG()
{
COLORREF crMask = RGB(0x00,0xff,0x00);
GLB::iBounsAIndex=(GLB::iBounsAIndex+1)%45;
int iPicIndex=0, iBackValue=0;
for(int i=0; i<GLB::iXBlocks; i++)
{
for(int j=0; j<GLB::iYBlocks; j++)
{
iBackValue=*(GLB::pIBackMatrix+j*GLB::iXBlocks+i);
//前景只画火焰效果和森林、奖励
if((iBackValue&0x000f0000)==0 && !((iBackValue&0x000000ff)==50 || (iBackValue&0x000000ff)==90))
continue;
if((iBackValue & 0x000f0000)!=0)
{
iPicIndex=20+((iBackValue&0x00f00000)>>20);
}
else
{
iPicIndex=(iBackValue&0x000000ff)/10;
}
if(iPicIndex==9)
{
int xx=GLB::iBounsAIndex/5;
GLB::pPartMemDC->SelectObject(GLB::pBMPBounsA[xx]);
GLB::TransparentBlt(
GLB::pMemDC->m_hDC,
i*GLB::iBlockWidth+12,
j*GLB::iBlockHeight+12,
16,
16,
GLB::pPartMemDC->m_hDC,
0,0,
16,
16,
crMask);
}
else
{
GLB::pPartMemDC->SelectObject(GLB::pBMPBackgrounds[iPicIndex]);
GLB::TransparentBlt(
GLB::pMemDC->m_hDC,
i*GLB::iBlockWidth,
j*GLB::iBlockHeight,
GLB::iBlockWidth,
GLB::iBlockHeight,
GLB::pPartMemDC->m_hDC,
0,0,
GLB::iBlockWidth,
GLB::iBlockHeight,
crMask);
}
}
}
if(GLB::eGameType==GAMEOVER)
{
int num=iGameOverFrameNum/2;
num=(num>29)?29:num;
GLB::pPartMemDC->SelectObject(GLB::pBMPGameover[num]);
iGameOverFrameNum=(iGameOverFrameNum+1)%400;
GLB::TransparentBlt(
GLB::pMemDC->m_hDC,
GLB::iWindowWidth/2-200,
GLB::iWindowHeight/2-32,
400,
64,
GLB::pPartMemDC->m_hDC,
0,0,
400,64,
crMask);
}
if(GLB::iRepaintScoreFrameNum%10==0||GLB::bStageWin)
{
RepaintMemScore();
GLB::iRepaintScoreFrameNum=0;
}
GLB::iRepaintScoreFrameNum++;
}
void GLB::RepaintMemScore()
{
CRect rect(0,GLB::iWindowHeight+1,GLB::iWindowWidth,GLB::iWindowHeight+90);
CBrush graybrush(RGB(100,100,100));
GLB::pMemDC->FillRect(&rect,&graybrush);
CPen blackpen(PS_SOLID,1,RGB(50,50,50));
GLB::pMemDC->SelectObject(&blackpen);
GLB::pMemDC->MoveTo(0,GLB::iWindowHeight+4);
GLB::pMemDC->LineTo(GLB::iWindowWidth,GLB::iWindowHeight+4);
GLB::pMemDC->MoveTo(GLB::iWindowWidth/2+4,GLB::iWindowHeight+4);
GLB::pMemDC->LineTo(GLB::iWindowWidth/2+4,GLB::iWindowHeight+90);
CPen darkgraypen(PS_SOLID,2,RGB(185,185,185));
GLB::pMemDC->SelectObject(&darkgraypen);
GLB::pMemDC->MoveTo(0,GLB::iWindowHeight+3);
GLB::pMemDC->LineTo(GLB::iWindowWidth,GLB::iWindowHeight+3);
GLB::pMemDC->MoveTo(GLB::iWindowWidth/2+2,GLB::iWindowHeight+3);
GLB::pMemDC->LineTo(GLB::iWindowWidth/2+2,GLB::iWindowHeight+90);
CPen lightgraypen(PS_SOLID,1,RGB(240,240,240));
GLB::pMemDC->SelectObject(&lightgraypen);
GLB::pMemDC->MoveTo(0,GLB::iWindowHeight+1);
GLB::pMemDC->LineTo(GLB::iWindowWidth,GLB::iWindowHeight+1);
GLB::pMemDC->MoveTo(GLB::iWindowWidth/2,GLB::iWindowHeight+4);
GLB::pMemDC->LineTo(GLB::iWindowWidth/2,GLB::iWindowHeight+90);
// CPen greenpen(PS_SOLID,1,RGB(0,255,0));
SetBkColor(GLB::pMemDC->m_hDC, RGB(100,100,100));
SetTextColor(GLB::pMemDC->m_hDC, RGB(0,255,0));
// GLB::pMemDC->SelectObject(lightgraypen);
CString s1;
s1.Format("1ST Score:%u Bub:%d Rad:%d Speed:%.1f Life:%d",
GLB::pGhostThread[28]->m_lScore,
GLB::pGhostThread[28]->m_iBubbleNum,
GLB::pGhostThread[28]->m_iBubbleRadius,
GLB::pGhostThread[28]->m_fSpeed,
GLB::pGhostThread[28]->m_iLifeLeft);
CString s2;
s2.Format("2ST Score:%u Bub:%d Rad:%d Speed:%.1f Life:%d",
GLB::pGhostThread[29]->m_lScore,
GLB::pGhostThread[29]->m_iBubbleNum,
GLB::pGhostThread[29]->m_iBubbleRadius,
GLB::pGhostThread[29]->m_fSpeed,
GLB::pGhostThread[29]->m_iLifeLeft);
GLB::pMemDC->TextOut(10,GLB::iWindowHeight+7,s1);
GLB::pMemDC->TextOut(GLB::iWindowWidth/2+15,GLB::iWindowHeight+7,s2);
BOOL bWin=TRUE;
for(int i=0; i<6; i++)
{
if(GLB::pGhostThread[i]->m_eState!=GHOSTDEAD)
{
bWin=FALSE;
break;
}
}
//如果是刚刚赢了这一关
if(bWin&&(!GLB::bStageWin))
{
::PlaySound("SOUND\\WINSTAGE.WAV",NULL,SND_NODEFAULT|SND_ASYNC);
}
if(bWin)
{
GLB::bStageWin=TRUE;
CDC * pTextMemDC=new CDC;
pTextMemDC->CreateCompatibleDC(GLB::pMemDC);
CBitmap * pTextMemBMP=new CBitmap;
pTextMemBMP->CreateCompatibleBitmap(GLB::pMemDC,400,200);
pTextMemDC->SelectObject(pTextMemBMP);
SetBkColor(pTextMemDC->m_hDC,RGB(0,0,0));
SetTextColor(pTextMemDC->m_hDC,RGB(0,255,0));
CString s;
// GLB::iGameStage++;
s.Format("祝贺你进入第%d关。",GLB::iGameStage+1);
pTextMemDC->TextOut(0,0,s);
GLB::TransparentBlt(
GLB::pMemDC->m_hDC,
340,270,
400,
20,
pTextMemDC->m_hDC,
0,0,
400,
20,
RGB(0,0,0));
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -