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

📄 puzzlvw.cpp

📁 MS VC++ 开发斐切比塔游戏范例
💻 CPP
字号:
// puzzlvw.cpp : implementation of the CPuzzleView class
//

#include "stdafx.h"
#include "afxcoll.h"
#include "puzzle.h"

#include "puzzldoc.h"
#include "puzzlvw.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CPuzzleView

IMPLEMENT_DYNCREATE(CPuzzleView, CView)

BEGIN_MESSAGE_MAP(CPuzzleView, CView)
    //{{AFX_MSG_MAP(CPuzzleView)
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_WM_MOUSEMOVE()
    ON_COMMAND(ID_RESET, OnReset)
    ON_UPDATE_COMMAND_UI(ID_RESET, OnUpdateReset)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPuzzleView construction/destruction

CPuzzleView::CPuzzleView()
{
CRect rect;

  m_bCaptured = FALSE;
  m_selectedPiece = NULL;
  
  m_board.Add(new CPiece(1,0,2,2)); // The goal piece
  m_board.Add(new CPiece(0,0,1,2));
  m_board.Add(new CPiece(3,0,1,2));
  m_board.Add(new CPiece(0,2,1,2));
  m_board.Add(new CPiece(1,2,2,1));
  m_board.Add(new CPiece(3,2,1,2));
  m_board.Add(new CPiece(1,3,1,1));
  m_board.Add(new CPiece(2,3,1,1));
  m_board.Add(new CPiece(0,4,1,1));
  m_board.Add(new CPiece(3,4,1,1));

  ResetPieces();

  m_height = 5;
  m_width  = 4;
  
  //SizeToPuzzle();
  
  
}

CPuzzleView::~CPuzzleView()
{
    for ( int i=0;i<m_board.GetSize();i++)
      delete ((CPiece *)m_board[i]);
}
/////////////////////////////////////////////////////////////////////////////
void CPuzzleView::SizeToPuzzle(void)
{
CFrameWnd* pwndMain = GetParentFrame();
RECT rectMain;

  pwndMain->GetWindowRect(&rectMain);
  pwndMain->MoveWindow(rectMain.left,rectMain.top,m_width*50,
                       m_height*50,TRUE);
}
/////////////////////////////////////////////////////////////////////////////
void CPuzzleView::ResetPieces(void)
{
  ((CPiece*)m_board[0])->SetPos(1,0);
  ((CPiece*)m_board[1])->SetPos(0,0);
  ((CPiece*)m_board[2])->SetPos(3,0);
  ((CPiece*)m_board[3])->SetPos(0,2);
  ((CPiece*)m_board[4])->SetPos(1,2);
  ((CPiece*)m_board[5])->SetPos(3,2);
  ((CPiece*)m_board[6])->SetPos(1,3);
  ((CPiece*)m_board[7])->SetPos(2,3);
  ((CPiece*)m_board[8])->SetPos(0,4);
  ((CPiece*)m_board[9])->SetPos(3,4);
}
/////////////////////////////////////////////////////////////////////////////
// CPuzzleView drawing

void CPuzzleView::OnDraw(CDC* pDC)
{
    for ( int i=0;i<m_board.GetSize();i++)
      ((CPiece *)m_board[i])->draw(pDC);
}
/////////////////////////////////////////////////////////////////////////////
//BOOL CPuzzleView::PreCreateWindow(CREATESTRUCT& cs)
//{
//  cs.style = WS_OVERLAPPED | WS_MINIMIZE | WS_SYSMENU | WS_VISIBLE | WS_CHILD;
//  cs.x  = 0;
//  cs.y  = 0;
//  cs.cx = 200;
//  cs.cy = 250;
//  return CView::PreCreateWindow(cs);
//}
/////////////////////////////////////////////////////////////////////////////
//void CPuzzleView::OnGetMinMaxInfo(MINMAXINFO FAR *lpMMI)
//{
//  lpMMI->ptMaxSize.x = m_width*CPIECE_UNIT;
//  lpMMI->ptMaxSize.y = m_height*CPIECE_UNIT;
//  lpMMI->ptMinTrackSize.x = m_width*CPIECE_UNIT;
//  lpMMI->ptMinTrackSize.y = m_height*CPIECE_UNIT;
//}
/////////////////////////////////////////////////////////////////////////////
// CPuzzleView diagnostics

#ifdef _DEBUG
void CPuzzleView::AssertValid() const
{
    CView::AssertValid();
}

void CPuzzleView::Dump(CDumpContext& dc) const
{
    CView::Dump(dc);
}

CPuzzleDoc* CPuzzleView::GetDocument() // non-debug version is inline
{
    ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CPuzzleDoc)));
    return (CPuzzleDoc*) m_pDocument;
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CPuzzleView message handlers

void CPuzzleView::OnLButtonDown(UINT nFlags, CPoint point)
{
CPiece* p;

    // TODO: Add your message handler code here and/or call default
    
    TRACE("entering CPuzzleView::OnLButtonDown - point = %d, %d\n",
          point.x,point.y);
          
    for ( int i=0;i<m_board.GetSize();i++)
      {
      p=(CPiece*)m_board[i];
      if (p->PtInPiece(point))
        {
        //You've found the selected piece
        if ( CanMove(p))
          {
          m_selectedPiece = p;
          SetCapture();
          p->Move(point);
          }  
        break;
        }
      }
      
}
//////////////////////////////////////////////////////////////////////////////
void CPuzzleView::OnLButtonUp(UINT nFlags, CPoint point)
{
CRect oldRect,newRect,invalidRect;

    if (m_selectedPiece)
      {
      CPoint ptSolved(1,3);
      
      oldRect = m_selectedPiece->rectPiece();    
      m_selectedPiece->Stop(point);
      newRect = m_selectedPiece->rectPiece();
      invalidRect = oldRect | newRect;
      InvalidateRect(invalidRect,TRUE);
      ReleaseCapture();
      m_selectedPiece = NULL;
      //Check for solution
      if ( ((CPiece*)m_board[0])->GetPos() == ptSolved )
        MessageBox( "Puzzle Solved", "Puzzle" );
      }
}

void CPuzzleView::OnMouseMove(UINT nFlags, CPoint point)
{
CRect oldRect,newRect,invalidRect;


  if (m_selectedPiece)
    {
    oldRect = m_selectedPiece->rectPiece();    
    m_selectedPiece->Move(point);
    newRect = m_selectedPiece->rectPiece();
    invalidRect = oldRect | newRect;
    InvalidateRect(invalidRect,TRUE);
    }

}
/////////////////////////////////////////////////////////////////////////////
BOOL CPuzzleView::OnBoard(CPoint& pt,CPiece* p)
{
CSize sz = p->GetSize();
    
    if (pt.x<0)
       return FALSE;
    if (pt.y<0)
       return FALSE;
    if (pt.x+sz.cx > m_width)
       return FALSE;
    if (pt.y+sz.cy > m_height)
       return FALSE;
       
    return TRUE;             
}
/////////////////////////////////////////////////////////////////////////////
BOOL CPuzzleView::Conflict(CPoint& pt,CPiece* p)
{
CSize szP = p->GetSize(); //The size of the selected piece
CRect rectP(pt,szP);      //The logical rectangle of the selected piece 
                          //  at the target point
CPiece* pTestPc;          //The current piece I'm testing against
    
    for (int i=0;i<m_board.GetSize();i++) //Check against each piece
        {
        if ( (pTestPc = (CPiece *)m_board[i]) != p ) //Except itself
           {
           CRect rectTest(pTestPc->GetPos(),pTestPc->GetSize()); 
           CRect rectIntersect = rectP & rectTest;
             if ( rectIntersect.IsRectEmpty() )
               continue; //No conflict with this piece
             else
               return TRUE; //conflict found
           }
        }
    return FALSE; //no conflict
}

/////////////////////////////////////////////////////////////////////////////
BOOL CPuzzleView::CanMove(CPiece* p)
{
int up,down,left,right;
int i;    

  //Can the piece move in any of the four directions and if so, how far?

  //Can it move up?
  up=0;
  for ( i=1; i<m_height; i++ ) //Try movin 1 space then 2, etc.
      {
      CPoint ptTarget = p->GetPos();

        ptTarget.y -= i; //Move target point up
        if ( OnBoard(ptTarget,p))
          if ( !Conflict(ptTarget,p))
            {
            up = i; //Can move up i units
            continue;
            }
        break; //No need to try another    
      }     


  //Can I move right?
  right=0;
  for ( i=1; i<m_width; i++ ) //Try movin 1 space then 2, etc.
      {
      CPoint ptTarget = p->GetPos();

        ptTarget.x += i; //Move target point to the right
        if ( OnBoard(ptTarget,p))
          if ( !Conflict(ptTarget,p))
            {
            right = i; //Can move right i units
            continue;
            }
        break;    
      }

  //Can I move left?
  left=0;
  for ( i=1; i<m_width; i++ ) //Try movin 1 space then 2, etc.
      {
      CPoint ptTarget = p->GetPos();

        ptTarget.x -= i; //Move target point to the left
        if ( OnBoard(ptTarget,p))
          if ( !Conflict(ptTarget,p))
            {
            left = i; //Can move left i units
            continue;
            }
        break;    
      }


  //Can it move down?
  down=0;
  for ( i=1; i<m_height; i++ ) //Try movin 1 space then 2, etc.
      {
      CPoint ptTarget = p->GetPos();

        ptTarget.y += i; //Move target point up
        if ( OnBoard(ptTarget,p))
          if ( !Conflict(ptTarget,p))
            {
            down = i; //Can move up i units
            continue;
            }            
        break;    
      }

  p->SetMoveLimits(up,right,down,left);

  return up|down|left|right;

}

void CPuzzleView::OnReset()
{
    ResetPieces();
    InvalidateRect(NULL);
}

void CPuzzleView::OnUpdateReset(CCmdUI* pCmdUI)
{
    pCmdUI->Enable();    
}

⌨️ 快捷键说明

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