65.9K
CodeProject is changing. Read more.
Home

Bubble Breaker by MFC

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.75/5 (6 votes)

Oct 22, 2009

BSD

1 min read

viewsIcon

28376

downloadIcon

1377

Plant bubble breaker's game from WinCE to Windows XP by MFC

BubbleBreakerSource

Introduction

This is a "bubble breaker" game. It comes along with general CWnd:

  • CBubbleBreakerPanel
  • CBubbleMovingTool
  • CBubble2DArray
  • CBubbleImageList
  • CScene
  • CUndoManager
  • CBubbleSelector

Background

I liked Bubble Breaker game for WindowCE developed by oopdreams software Inc., so I wanted to plant it to Windows XP by MFC.

Using the Code

CBubbleBreakerPanel is derived from CWnd,and it is the main framework. It handles mouse and Keyboard events, and handles GDI drawing and so on.

OnLButtonDown is like this:

void CBubbleBreakerPanel::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CWnd::OnLButtonDown(nFlags, point);
	if (m_rcNewGameZone.PtInRect(point)){
		NewScene(TRUE);
		Invalidate(FALSE);
		return;
	}
	else if (m_rcMenuZone.PtInRect(point)){
		if (m_Menu.GetSafeHmenu()){
			CMenu*pSubMenu = m_Menu.GetSubMenu(0);
			if (pSubMenu){
				ClientToScreen(&point);	
							}
		}
		return;
	}

void CBubbleBreakerPanel::DrawBubbleSelector(CDC*pDC)
{
	if (m_pBubbleSelector && (m_pBubbleSelector->GetCount() >= 2 ))
	{
		for(int iIndex = 0;iIndex<m_pBubbleSelector->GetCount();iIndex++){
			CBubble*pBubble = m_pBubbleSelector->GetAt(iIndex);
			if (pBubble->iState == BubbleSelected){
				CPen penBlack(PS_SOLID,1,COLOR_BLACK);
				(CPen*)pDC->SelectObject(&penBlack);
				
				CBubble*pLeftBubble = (pBubble->X - 1 >= 0) ? 
					&m_pBubbles[pBubble->Y*m_iXBubbleNums+
					pBubble->X-1] : NULL;
				CBubble*pRightBubble = (pBubble->X + 1 < 
					m_iXBubbleNums) ? &m_pBubbles
					[pBubble->Y*m_iXBubbleNums+pBubble->X+1] 
					: NULL;
				CBubble*pTopBubble = (pBubble->Y - 1 >= 0) ? 
					&m_pBubbles[(pBubble->Y-1)*
					m_iXBubbleNums+pBubble->X] : NULL;
				CBubble*pBottomBubble = (pBubble->Y + 1 < 
					m_iYBubbleNums) ? &m_pBubbles
					[(pBubble->Y+1)*m_iXBubbleNums+pBubble->X] 
					: NULL;
				
				int iPosX = pBubble->PosX + pBubble->OffsetX;
				int iPosY = pBubble->PosY + pBubble->OffsetY;
				
					if ((pLeftBubble == NULL) || 
					(pLeftBubble->iState != BubbleSelected)) {
					pDC->MoveTo(iPosX - pBubble->
					iRadius - 1,iPosY - pBubble->iRadius - 1);
					pDC->LineTo(iPosX - pBubble->
					iRadius - 1,iPosY + pBubble->iRadius + 1);
				}
				if ((pRightBubble == NULL) || 
					(pRightBubble->iState != BubbleSelected)){
					pDC->MoveTo(iPosX + pBubble->iRadius + 1,
						iPosY - pBubble->iRadius - 1);
					pDC->LineTo(iPosX + pBubble->iRadius + 1,
						iPosY + pBubble->iRadius + 1);
				}
				if ((pTopBubble == NULL) || (pTopBubble->iState 
						!= BubbleSelected)){
					pDC->MoveTo(iPosX - pBubble->
					iRadius - 1,iPosY - pBubble->iRadius - 1);
					pDC->LineTo(iPosX + pBubble->
					iRadius + 1,iPosY - pBubble->iRadius - 1);
				}
				if ((pBottomBubble == NULL) || (pBottomBubble->
						iState != BubbleSelected)){
					pDC->MoveTo(iPosX - pBubble->iRadius - 1,
						iPosY + pBubble->iRadius + 1);
					pDC->LineTo(iPosX + pBubble->iRadius + 1,
						iPosY + pBubble->iRadius + 1);
				}
			}
		}
	}
} 

CBubbleMovingTool is designed to handle bubbles movement, and CBubbleMovingToolH is derived from CBubbleMovingTool to handle horizon movement, and CBubbleMovingToolV to handle vertical movement, and HCBubbleMovingToolVH to handle horizon movement first and handle vertical movement.

CBubbleMovingToolH::ReArrangeRow is like this:

void CBubbleMovingToolH::ReArrangeRow(int iyIndex)
{
	if (m_pBubbles)
	{
		CBubble2DArray bubble2dArray(m_pBubbles,m_iXBubbleNums,m_iYBubbleNums);
		CBubble *pTempBubbles = new CBubble[m_iXBubbleNums];
		int ixValidCount = 0;

		if (pTempBubbles){ 
			for (int ixIndex = m_iXBubbleNums - 1;ixIndex >= 0;ixIndex--)
			{
				CBubble *pBubble = bubble2dArray.GetBubble
						(ixIndex,iyIndex);
				if (pBubble && (pBubble->iState == BubbleActive) )
				{
					pTempBubbles[ixValidCount].iColorIndex = 
							pBubble->iColorIndex;
					pTempBubbles[ixValidCount].iState = 
							pBubble->iState;
					ixValidCount++;
				}
			}

			for (int ixIndex = 0;ixIndex<m_iXBubbleNums;ixIndex++){
				CBubble *pBubble = bubble2dArray.GetBubble
							(ixIndex,iyIndex);
				pBubble->iState = BubbleNone;
			}
		}

		if (pTempBubbles)
		{
			
			for (int ixIndex = m_iXBubbleNums - 1 ,ixValidIndex = 0;
					ixValidIndex<ixValidCount;ixIndex--)
			{
				CBubble *pBubble = bubble2dArray.GetBubble
						(ixIndex,iyIndex);
				if (pBubble)
				{
					pBubble->iColorIndex = 
					pTempBubbles[ixValidIndex].iColorIndex;
					pBubble->iState = pTempBubbles
							[ixValidIndex].iState;
					ixValidIndex++;
				}
			}
			
			delete []pTempBubbles;
			pTempBubbles = NULL;
		}
	}
}

CBubbleSelectoris is designed to handle bubbles' selection.

CBubbleSelector PtInSelector is like this:

BOOL CBubbleSelector::PtInSelector(CPoint point)
{
    BOOL bFounded = FALSE;
    if (GetCount() >= 2)
    {
        for(int iIndex = 0;iIndex<GetCount();iIndex++)
        {
            CBubble*pBubble = GetAt(iIndex);
            if (pBubble)
            {
                CRect rcBubbble = pBubble->GetRect();
                rcBubbble.InflateRect(1,1,1,1);
                if (rcBubbble.PtInRect(point)){
                    bFounded = TRUE;// Action
                }
            }
        }
    }

    return bFounded;
}

Points of Interest

I am planning to give it full GDI+ support for drawing.

I'm also planning to make sure it runs perfectly well on Windows platforms.

History

  • Oct 22 2009: First release

About the Author

I've been programming Windows since 1997.
I am interested in Windows kernal programming, image processing, network tech, UI framework, and C/C++/C#/MFC and so on.
I have been working for the Government since 2000.