⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bubblethread.cpp

📁 泡泡堂单机版
💻 CPP
字号:
// BubbleThread.cpp : implementation file
//

#include "stdafx.h"
#include "BubbleII.h"
#include "BubbleThread.h"
#include "GhostThread.h"
#include "GLB.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CBubbleThread

IMPLEMENT_DYNCREATE(CBubbleThread, CWinThread)

CBubbleThread::CBubbleThread()
{
	m_iType=1;
	m_bAlive=TRUE;
	m_pPartMemDC=NULL;
	m_pPartImageMemDC=NULL;

	m_iWidth=GLB::iBlockWidth*GLB::iXBlocks;
	m_iHeight=GLB::iBlockHeight*GLB::iYBlocks;
	m_bExplodeImmediately=FALSE;
	m_iDownFlashNum=m_iUpFlashNum=m_iLeftFlashNum=m_iRightFlashNum=0;

	for(int i=0; i<24;i++)
		m_pPartMemBMP[i]=NULL;
	m_state=DEAD;
	m_iFrameCount=0;
}

CBubbleThread::~CBubbleThread()
{
	for(int i=0; i<12; i++)
	{
		if(m_pPartMemBMP[i]!=NULL)
			delete m_pPartMemBMP[i];
	}
	delete m_pPartImageMemDC;
}

BOOL CBubbleThread::InitInstance()
{
	// TODO:  perform and per-thread initialization here
	return TRUE;
}

int CBubbleThread::ExitInstance()
{
	// TODO:  perform any per-thread cleanup here
	return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CBubbleThread, CWinThread)
	//{{AFX_MSG_MAP(CBubbleThread)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBubbleThread message handlers

void CBubbleThread::InitiateDCs(CDC *pDC)
{
	m_pDC=pDC;
/*
	for(int i=0; i<12; i++)
	{
		m_pPartMemBMP[i]=new CBitmap;
		m_pPartMemBMP[i]->LoadBitmap(100+(i/3)*10+(i%3));
	}
*/
	m_pPartMemBMP[0]=new CBitmap;
	m_pPartMemBMP[0]->LoadBitmap(300);
	m_pPartMemBMP[1]=new CBitmap;
	m_pPartMemBMP[1]->LoadBitmap(310);
	m_pPartMemBMP[2]=new CBitmap;
	m_pPartMemBMP[2]->LoadBitmap(311);
	m_pPartMemBMP[3]=new CBitmap;
	m_pPartMemBMP[3]->LoadBitmap(320);
	m_pPartMemBMP[4]=new CBitmap;
	m_pPartMemBMP[4]->LoadBitmap(321);

	m_pPartImageMemDC=new CDC;
	m_pPartImageMemDC->CreateCompatibleDC(pDC);
	m_pPartImageMemDC->SelectObject(m_pPartMemBMP[m_iFrameCount]);
	m_state=DEAD;
}

void CBubbleThread::SetBubble(int index, int iOwnerIndex, double x, double y, double radius, int waittime)
{
	m_iIndex=index;
	m_fX=x;
	m_fY=y;
	m_iWaittime=waittime;
	m_fRadius=radius;
	m_state=BORN;
	m_bAlive=TRUE;
	m_bExplodeImmediately=FALSE;
	m_iOwnerIndex=iOwnerIndex;
	// xxxx xxxx | xxxx xxxx | xxxx xxxx | xxxx xxxx   前景数组的结构
	// 				    ^火焰(0x00010000*15)^背景(0x000000ff)
	//						   ^Bubble+序号(0x00008000)
	//			   ^奖励+序号(0x00800000)

	m_piCenter=GLB::pIBackMatrix+((int)(m_fX)/GLB::iBlockWidth)
					+((int)(m_fY)/GLB::iBlockHeight)*GLB::iXBlocks;
	(*m_piCenter) |= (0x00008000+m_iIndex*256);
}

int CBubbleThread::Run() 
{
	int BORNSLEEPTIME=200,EXPLODESLEEPTIME=20,DEADSLEEPTIME=200;
	while(GLB::bGameStarted)
	{
		while(m_state==BORN)
		{
			if(m_iWaittime>BORNSLEEPTIME &&!m_bExplodeImmediately)
			{
				m_pPartImageMemDC->SelectObject(m_pPartMemBMP[m_iFrameCount]);
				m_iFrameCount++;
				m_iFrameCount%=5;
				Sleep(BORNSLEEPTIME);
				m_iWaittime-=BORNSLEEPTIME;
			}
			else
			{
				//设定爆炸的动画为0.4秒
				m_iWaittime=250;
				//还原前景里的内容,去掉Bubble
				m_state=EXPLODE;
				(*m_piCenter) &= 0xffff00ff;
			}
		}
		if(m_state==EXPLODE)
		{
			::PlaySound("SOUND\\BUBBLEEXPLODE.WAV",NULL,SND_NODEFAULT|SND_ASYNC);
			DoExplode();
			while(m_iWaittime>EXPLODESLEEPTIME)
			{
				Sleep(EXPLODESLEEPTIME);
				m_iWaittime-=EXPLODESLEEPTIME;
			}
			DoCleanExplode();

			//反向擦除火焰

			m_state=DEAD;
		}
		while(m_state==DEAD)
		{
			Sleep(DEADSLEEPTIME);
		}
	}
	return 0;
}

BOOL CBubbleThread::CanBubbleFlashPass(int xx, int yy, int *Inc, int idirect)
{
	int* piTag=GLB::pIBackMatrix+xx+yy*GLB::iXBlocks;
//	int* piLastTag;
	char* pcTag=(char *)piTag;
	//不可通过
	if(*pcTag==40||*pcTag==60)
	{
		TRACE("Reach Iron\t");
		return FALSE;
	}
	//其他Bubble
	if((*piTag & 0x8000)==0x8000)
	{
		//可以简写为((*piTag)/256)%128  ↓
		GLB::pBubbleThread[((*piTag)/256-0x80)%128]->ExplodeImmediately();
		*pcTag = 0;
		PushFlash(idirect,piTag);

		(*Inc)++;
		TRACE("Light \r\n");
		return FALSE;
	}
	//判断杀伤
	for(int i=0; i<30; i++)
	{
		if(!GLB::bGhostsAlive[i])
			continue;
		if((abs((int)(GLB::iBlockWidth*xx-GLB::pGhostThread[i]->m_x))<(GLB::iBlockWidth-5))
		  &&abs((int)(GLB::iBlockHeight*yy-GLB::pGhostThread[i]->m_y))<(GLB::iBlockHeight-5))
		{
			GLB::pGhostThread[i]->m_eState=LOCKED;
		}
	}
	//可爆破障碍
	if(*pcTag==20||*pcTag==30)
	{
		//将背景障碍抹去
//		*pcTag=0;
		double r=rand()*4.0/RAND_MAX;
		*pcTag=(r<=3.0)?0:90;
//		*pcTag=90;
		//火焰加1
		PushFlash(idirect,piTag);

		TRACE("Reach Block\t");
		(*Inc)++;
		return FALSE;
	}

	PushFlash(idirect,piTag);
	(*Inc)++;
	TRACE("Set Fire\t");
	return TRUE;
}

void CBubbleThread::ExplodeImmediately()
{
	m_bExplodeImmediately=TRUE;
	m_state=EXPLODE;
	(*m_piCenter) &= 0xffff00ff;
}

BOOL CBubbleThread::DeFlash(int xx, int yy)
{
	int* piTag=GLB::pIBackMatrix+xx+yy*GLB::iXBlocks;
	*piTag -= 0x00010000;
	return TRUE;
}

void CBubbleThread::DoExplode()
{
	int BORNSLEEPTIME=200,EXPLODESLEEPTIME=20,DEADSLEEPTIME=200;
	int iCenterX=((int)(m_fX))/GLB::iBlockWidth;
	int iCenterY=((int)(m_fY))/GLB::iBlockHeight;
	int  xx,yy;
	BOOL bLeft=TRUE, bRight=TRUE, bUp=TRUE, bDown=TRUE;

	(*m_piCenter) += 0x00010000;
	(*m_piCenter) &= 0xff0fffff;
	(*m_piCenter) |= 0x00400000;

	Sleep(EXPLODESLEEPTIME);
	m_iWaittime-=EXPLODESLEEPTIME;

	for(int i=1; i<(int)m_fRadius; i++)
	{
		if(bLeft)
		{
			xx=iCenterX-i;
			yy=iCenterY;
			if(xx<0)
				bLeft=FALSE;
			else
				bLeft=CanBubbleFlashPass(xx,yy,&m_iLeftFlashNum,1);
		}
		if(bRight)
		{
			xx=iCenterX+i;
			yy=iCenterY;
			if(xx>=GLB::iXBlocks)
				bRight=FALSE;
			else
				bRight=CanBubbleFlashPass(xx,yy,&m_iRightFlashNum,3);
		}
		if(bUp)
		{
			xx=iCenterX;
			yy=iCenterY-i;

			if(yy<0)
				bUp=FALSE;
			else
				bUp=CanBubbleFlashPass(xx,yy,&m_iUpFlashNum,0);
		}
		if(bDown)
		{					
			xx=iCenterX;
			yy=iCenterY+i;
			if(yy>=GLB::iYBlocks)
				bDown=FALSE;
			else
				bDown=CanBubbleFlashPass(xx,yy,&m_iDownFlashNum,2);
		}
		Sleep(EXPLODESLEEPTIME);
		m_iWaittime-=EXPLODESLEEPTIME;
		CString s;
		s.Format("m_iIndex=%d,i=%d\r\n",m_iIndex,i);
		TRACE(s);
	}
}

void CBubbleThread::DoCleanExplode()
{
	int iCenterX=((int)(m_fX))/GLB::iBlockWidth;
	int iCenterY=((int)(m_fY))/GLB::iBlockHeight;
	int  xx,yy;

	(*m_piCenter) -= 0x00010000;

	for(int i=1; i<=m_iUpFlashNum; i++)
	{
		xx=iCenterX;
		yy=iCenterY-i;
		DeFlash(xx,yy);
	}
	m_iUpFlashNum=0;

	for(i=1; i<=m_iLeftFlashNum; i++)
	{
		xx=iCenterX-i;
		yy=iCenterY;
		DeFlash(xx,yy);
	}
	m_iLeftFlashNum=0;

	for(i=1; i<=m_iDownFlashNum; i++)
	{
		xx=iCenterX;
		yy=iCenterY+i;
		DeFlash(xx,yy);
	}
	m_iDownFlashNum=0;

	for(i=1; i<=m_iRightFlashNum; i++)
	{
		xx=iCenterX+i;
		yy=iCenterY;
		DeFlash(xx,yy);
	}
	m_iRightFlashNum=0;
}

void CBubbleThread::PushFlash(int idirect, int *piTag)
{
	*piTag += 0x00010000;
	int *piLastTag=piTag;
	switch(idirect)
	{
	case 0:
		//如果向上推,则下一行对应位置置4
		*piTag&=0xff0fffff;

		piLastTag+=GLB::iXBlocks;

		*piLastTag&=0xff0fffff;
		*piLastTag|=0x00400000;
		break;
	case 1:
		//如果向左推,则右边1个位置置4
		*piTag&=0xff0fffff;
		*piTag|=0x00100000;

		piLastTag++;

		*piLastTag&=0xff0fffff;
		*piLastTag|=0x00400000;
		break;
	case 2:
		//如果向下推,则上一行对应位置置4
		*piTag&=0xff0fffff;
		*piTag|=0x00200000;

		piLastTag-=GLB::iXBlocks;

		*piLastTag&=0xff0fffff;
		*piLastTag|=0x00400000;
		break;
	case 3:
		//如果向右推,则左边1个位置置4
		*piTag&=0xff0fffff;
		*piTag|=0x00300000;

		piLastTag--;

		*piLastTag&=0xff0fffff;
		*piLastTag|=0x00400000;
		break;
	default:
		break;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -