改写扫雷游戏,增加鼠标功能

2025-03-02 04:22:07
推荐回答(1个)
回答1:

void CMineWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
//按钮所在的区域
CRect rcBtn(m_uBtnRect[1], 15, m_uBtnRect[2], 39);
//雷区所在的区域
CRect rcMineArea(MINE_AREA_LEFT, MINE_AREA_TOP,
MINE_AREA_LEFT + m_uXNum * MINE_WIDTH, MINE_AREA_TOP + m_uYNum * MINE_HEIGHT);

SetCapture(); // capture the mouse cursor
m_bClickBtn = FALSE;
m_bLRBtnDown = FALSE;

if (rcBtn.PtInRect(point))
{// click in the button area
m_bClickBtn = TRUE;
m_uBtnState = BUTTON_DOWN;
InvalidateRect(rcBtn);
}
else if (rcMineArea.PtInRect(point))
{// click in the mine area
// change mine state by gamestate
switch(m_uGameState)
{
case GS_WAIT: case GS_RUN:
m_pNewMine = GetMine(point.x, point.y);
if (!m_pNewMine) return;
if (m_pNewMine->uState == STATE_NORMAL)
{
m_pNewMine->uState = STATE_EMPTY;
}
if (m_pNewMine->uState == STATE_DICEY)
{
m_pNewMine->uState = STATE_DICEY_DOWN;
}
m_pOldMine = m_pNewMine;
break;
case GS_DEAD: case GS_VICTORY:
return;
break;
default :
break;
}
m_uBtnState = BUTTON_CLICK;
InvalidateRect(rcBtn);
// both of the left button and the right button are pushing down
if (nFlags == (MK_LBUTTON | MK_RBUTTON))
{
m_bLRBtnDown = TRUE;
OnLRBtnDown(m_pOldMine->uRow, m_pOldMine->uCol);
}
InvalidateRect(rcMineArea);
}
else
{ // click in other area
if (m_uGameState == GS_WAIT || m_uGameState == GS_RUN)
{
m_uBtnState = BUTTON_CLICK;
InvalidateRect(rcBtn);
}
}

CWnd::OnLButtonDown(nFlags, point);
}

void CMineWnd::OnLButtonUp(UINT nFlags, CPoint point)
{
//笑脸图按钮所在的区域
CRect rcBtn(m_uBtnRect[1], 15, m_uBtnRect[2], 39);
//雷区所在的区域
CRect rcMineArea(MINE_AREA_LEFT, MINE_AREA_TOP,
MINE_AREA_LEFT + m_uXNum * MINE_WIDTH,
MINE_AREA_TOP + m_uYNum * MINE_HEIGHT);

if (rcBtn.PtInRect(point))
{// 点击笑脸图

Invalidate();
InitGame();
}
else if (rcMineArea.PtInRect(point))
{//点击雷区域
CString value;
UINT around = 0;

//根据不同的游戏状态作处理
switch(m_uGameState)
{
//游戏进行状态
case GS_WAIT: case GS_RUN:
// first get the MINEWND which if pushing down
m_pOldMine = GetMine(point.x, point.y);
if (!m_pOldMine)
{
ReleaseCapture();
return;
}
// do normal process
// judge whether the lr button are both pushed down
//检测判断当前状态是否为左右鼠标同时按下
if (m_bLRBtnDown)
{
m_bLRBtnDown = FALSE;
OnLRBtnUp(m_pOldMine->uRow, m_pOldMine->uCol);
if (m_uGameState == GS_WAIT)
{
m_uBtnState = BUTTON_NORMAL;
Invalidate();
ReleaseCapture();
return;
}
// if the around flags number equal to the around mines number, expand.
//假若周围已经标识的雷=周围真正的雷数,拓展
if (m_pOldMine->uState != STATE_FLAG)
{
OpenAround(m_pOldMine->uRow, m_pOldMine->uCol);
}
// check whether the MINEWND around the special MINEWND is a mine, if it is then dead.
if (ErrorAroundFlag(m_pOldMine->uRow, m_pOldMine->uCol))
{

Dead(m_pOldMine->uRow, m_pOldMine->uCol);
ReleaseCapture();
return;
}
}
else
{
// start the game, init the mines area
//如果游戏尚未开始,点击左键启动游戏
if (m_uGameState == GS_WAIT)
{
if (m_uTimer)
{
KillTimer(ID_TIMER_EVENT);
m_uTimer = 0;
}
// the following five lines refresh the remining mine num rect immediately
// when click in the mine area at the first time
m_uSpendTime = 1;
Invalidate();
if (m_bSoundful)
{
sndPlaySound((LPCTSTR)LockResource(m_pSndClock), SND_MEMORY | SND_ASYNC | SND_NODEFAULT);
}
//启动定时器
m_uTimer = SetTimer(ID_TIMER_EVENT, 1000, NULL);
//布雷
LayMines(m_pOldMine->uRow, m_pOldMine->uCol); // lay all the mines down
//改变游戏状态为"运行/GS_RUN"
m_uGameState = GS_RUN;

}

if (m_pOldMine->uOldState == STATE_NORMAL)
{//当该雷区域为正常未作标记才打开
// first judge if the special MINEWND is a mine
//如果该区域为雷,则死亡
if (IsMine(m_pOldMine->uRow, m_pOldMine->uCol))
{
Dead(m_pOldMine->uRow, m_pOldMine->uCol);
ReleaseCapture();
return;
}
// the special MINEWND is not a mine
//不是雷的时候,获取其周围的雷数目
around = GetAroundNum(m_pOldMine->uRow, m_pOldMine->uCol);
// 如果为空白区域,拓展,否则打开该区域(显示周围有多少雷数)
if (around == 0) ExpandMines(m_pOldMine->uRow, m_pOldMine->uCol);
else DrawDownNum(m_pOldMine, around);
}
else if (m_pOldMine->uOldState == STATE_DICEY)
{//标志为“?”问号的时候
m_pOldMine->uState = STATE_DICEY;
}

//判断是否为胜利
if (Victory())
{
Invalidate();
ReleaseCapture();
return;
}
}
break;
case GS_VICTORY:
case GS_DEAD:
ReleaseCapture(); // release the cursor
return;
default :
break;
}
m_uBtnState = BUTTON_NORMAL;
Invalidate();
}
else
{//点击非雷区域
if (m_uGameState == GS_WAIT || m_uGameState == GS_RUN)
{
m_uBtnState = BUTTON_NORMAL;
InvalidateRect(rcBtn);
}
}

ReleaseCapture(); // release the cursor
CWnd::OnLButtonUp(nFlags, point);
}

void CMineWnd::OnRButtonDown(UINT nFlags, CPoint point)
{
//笑脸图按钮所在的区域
CRect rcBtn(m_uBtnRect[1], 15, m_uBtnRect[2], 39);
//雷区所在的区域
CRect rcMineArea(MINE_AREA_LEFT, MINE_AREA_TOP,
MINE_AREA_LEFT + m_uXNum * MINE_WIDTH,
MINE_AREA_TOP + m_uYNum * MINE_HEIGHT);

m_bLRBtnDown = FALSE;

if (rcMineArea.PtInRect(point))
{//点击雷区域
if (m_uGameState == GS_WAIT || m_uGameState == GS_RUN)
{
m_pNewMine = GetMine(point.x, point.y);
if (!m_pNewMine) return;
// both of the left button and the right button are pushing down
if (nFlags == (MK_LBUTTON | MK_RBUTTON))
{
m_bLRBtnDown = TRUE;
OnLRBtnDown(m_pNewMine->uRow, m_pNewMine->uCol);
}
else
{
switch(m_pNewMine->uState)
{
case STATE_NORMAL:
m_pNewMine->uState = STATE_FLAG;
m_pNewMine->uOldState = STATE_FLAG;
m_nLeaveNum--;
break;
case STATE_FLAG:
m_pNewMine->uState = STATE_DICEY;
m_pNewMine->uOldState = STATE_DICEY;
m_nLeaveNum++;
break;
case STATE_DICEY:
m_pNewMine->uState = STATE_NORMAL;
m_pNewMine->uOldState = STATE_NORMAL;
break;
default:
break;
}
}
Invalidate();

}
}

CWnd::OnRButtonDown(nFlags, point);
}

void CMineWnd::OnRButtonUp(UINT nFlags, CPoint point)
{
CRect rcBtn(m_uBtnRect[1], 15, m_uBtnRect[2], 39);
CRect rcMineArea(MINE_AREA_LEFT, MINE_AREA_TOP,
MINE_AREA_LEFT + m_uXNum * MINE_WIDTH, MINE_AREA_TOP + m_uYNum * MINE_HEIGHT);

m_pOldMine = GetMine(point.x, point.y);
if (!m_pOldMine) return;
// judge whether the lr button are both pushed down
if (m_bLRBtnDown)
{
m_bLRBtnDown = FALSE;
OnLRBtnUp(m_pOldMine->uRow, m_pOldMine->uCol);
if (m_uGameState == GS_WAIT)
{
m_uBtnState = BUTTON_NORMAL;
Invalidate();
return;
}
// if the around flags number equal to the around mines number, expand.
if (m_pOldMine->uState != STATE_FLAG)
{
OpenAround(m_pOldMine->uRow, m_pOldMine->uCol);
}
// check whether the MINEWND around the special MINEWND is a mine, if it is then dead.
if (ErrorAroundFlag(m_pOldMine->uRow, m_pOldMine->uCol))
{
// Dead(m_pOldMine->uRow, m_pOldMine->uCol);
// ReleaseCapture();
return;
}
}
else
{
Victory();
}

CWnd::OnRButtonUp(nFlags, point);
}

void CMineWnd::OnMouseMove(UINT nFlags, CPoint point)
{
if (nFlags == MK_LBUTTON || nFlags == (MK_LBUTTON | MK_RBUTTON))
{
CRect rcBtn(m_uBtnRect[1], 15, m_uBtnRect[2], 39);
CRect rcMineArea(MINE_AREA_LEFT, MINE_AREA_TOP,
MINE_AREA_LEFT + m_uXNum * MINE_WIDTH, MINE_AREA_TOP + m_uYNum * MINE_HEIGHT);

if (rcBtn.PtInRect(point))
{ // point in button area
switch(m_uGameState)
{
case GS_RUN:
m_uBtnState = (m_bClickBtn) ? BUTTON_DOWN : BUTTON_CLICK;
break;
case GS_DEAD: case GS_VICTORY:
if (m_bClickBtn) m_uBtnState = BUTTON_DOWN;
break;
default:
break;
}
InvalidateRect(rcBtn);
}
else if (rcMineArea.PtInRect(point))
{ // point in mine area
switch(m_uGameState)
{
case GS_RUN:
m_pNewMine = GetMine(point.x, point.y);
if (!m_pNewMine || !m_pOldMine) return;
if (m_pNewMine->uCol != m_pOldMine->uCol ||
m_pNewMine->uRow != m_pOldMine->uRow)
{
// change the new mine rect state
switch(m_pNewMine->uState)
{
case STATE_NORMAL:
m_pNewMine->uState = STATE_EMPTY;
break;
case STATE_DICEY:
m_pNewMine->uState = STATE_DICEY_DOWN;
break;
}
// resume the old mine rect state
switch(m_pOldMine->uOldState)
{
case STATE_NORMAL:
m_pOldMine->uState = STATE_NORMAL;
break;
case STATE_DICEY:
m_pOldMine->uState = STATE_DICEY;
break;
default :
break;
}
// judge whether the lr button are pushed down
if (m_bLRBtnDown)
{
OnLRBtnUp(m_pOldMine->uRow, m_pOldMine->uCol);
OnLRBtnDown(m_pNewMine->uRow, m_pNewMine->uCol);
}
m_pOldMine = m_pNewMine;
}
InvalidateRect(rcMineArea);
break;
case GS_VICTORY: case GS_DEAD:
return;
default:
break;
}
}
else
{ // point in other area
switch(m_uGameState)
{
case GS_RUN:
m_uBtnState = (m_bClickBtn) ? BUTTON_NORMAL : BUTTON_CLICK;
if (m_pNewMine)
{
if (m_pNewMine->uOldState == STATE_NORMAL)
{
m_pNewMine->uState = STATE_NORMAL;
}
else if (m_pNewMine->uOldState == STATE_DICEY)
{
m_pNewM