home *** CD-ROM | disk | FTP | other *** search
/ Monster Media 1994 #1 / monster.zip / monster / PROG_C / MSVCPUZL.ZIP / PIECE.CPP < prev    next >
C/C++ Source or Header  |  1993-11-07  |  7KB  |  254 lines

  1. #include "stdafx.h"
  2. #include "math.h"
  3. #include "limits.h"
  4. #include "puzzle.h"
  5. #include "piece.h"
  6.  
  7. #ifdef _DEBUG
  8. #undef THIS_FILE
  9. static char BASED_CODE THIS_FILE[] = __FILE__;
  10. #endif
  11.  
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CPiece
  14. CPiece::CPiece(void)
  15. {
  16.   m_szLogSize.cx=0;
  17.   m_szLogSize.cy=0;
  18.   m_ptLogPos.x=0;
  19.   m_ptLogPos.y=0;
  20.   m_szActSize.cx=0;
  21.   m_szActSize.cy=0;
  22.   m_ptActPos.x=0;
  23.   m_ptActPos.y=0;
  24.   m_bInMotion = FALSE;
  25.   m_nUpLim    = 0;
  26.   m_nDownLim  = 0;
  27.   m_nRightLim = 0;
  28.   m_nLeftLim  = 0;
  29.   m_xHiliteWidth = GetSystemMetrics(SM_CXBORDER)*3;
  30.   m_yHiliteWidth = GetSystemMetrics(SM_CYBORDER)*3;
  31. }
  32. /////////////////////////////////////////////////////////////////////////////
  33. CPiece::CPiece(int x, int y, int dx, int dy)
  34. {
  35.   m_szLogSize.cx=dx;
  36.   m_szLogSize.cy=dy;
  37.   m_ptLogPos.x=x;
  38.   m_ptLogPos.y=y;
  39.   m_szActSize.cx=dx*CPIECE_UNIT;
  40.   m_szActSize.cy=dy*CPIECE_UNIT;
  41.   m_ptActPos.x=x*CPIECE_UNIT;
  42.   m_ptActPos.y=y*CPIECE_UNIT;
  43.   m_bInMotion = FALSE;
  44.   m_nUpLim    = 0;
  45.   m_nDownLim  = 0;
  46.   m_nRightLim = 0;
  47.   m_nLeftLim  = 0;
  48.   m_xHiliteWidth = GetSystemMetrics(SM_CXBORDER)*3;
  49.   m_yHiliteWidth = GetSystemMetrics(SM_CYBORDER)*3;
  50.     
  51. }
  52. /////////////////////////////////////////////////////////////////////////////
  53. CPiece::~CPiece(void)
  54. {}
  55. //////////////////////////////////////////////////////////////////////////////
  56. void CPiece::draw(CDC* pDC)
  57. {
  58. CRect rect(m_ptActPos,m_szActSize);
  59. CRect rectHilite;
  60.  
  61.   pDC->SelectStockObject(GRAY_BRUSH);
  62.   pDC->SelectStockObject(NULL_PEN);  
  63.   pDC->Rectangle(rect);
  64.   rectHilite = rect;
  65.   rectHilite.right = rectHilite.left+m_xHiliteWidth;
  66.   pDC->SelectStockObject(LTGRAY_BRUSH);
  67.   pDC->Rectangle(rectHilite);
  68.   rectHilite = rect;
  69.   rectHilite.bottom = rectHilite.top+m_yHiliteWidth;
  70.   pDC->Rectangle(rectHilite);
  71.   pDC->SelectStockObject(DKGRAY_BRUSH);
  72.   rectHilite = rect;
  73.   rectHilite.left = rectHilite.right - m_xHiliteWidth;
  74.   pDC->Rectangle(rectHilite);
  75.   rectHilite = rect;
  76.   rectHilite.top = rectHilite.bottom - m_yHiliteWidth;
  77.   pDC->Rectangle(rectHilite);
  78.   
  79.   
  80. }
  81. /////////////////////////////////////////////////////////////////////////////
  82. CSize CPiece::GetSize(void)
  83. {
  84.     return m_szLogSize;
  85. }
  86. /////////////////////////////////////////////////////////////////////////////
  87. CPoint CPiece::GetPos(void)
  88. {
  89.     return m_ptLogPos;
  90. }
  91. /////////////////////////////////////////////////////////////////////////////
  92. void CPiece::SetPos(const CPoint& rPT)
  93. {
  94.   m_ptLogPos = rPT;
  95.   m_ptActPos.x = rPT.x*CPIECE_UNIT;
  96.   m_ptActPos.y = rPT.y*CPIECE_UNIT;
  97. }
  98. /////////////////////////////////////////////////////////////////////////////
  99. void CPiece::SetPos(int x, int y)
  100. {
  101.   m_ptLogPos.x = x;
  102.   m_ptLogPos.y = y;
  103.   m_ptActPos.x = x*CPIECE_UNIT;
  104.   m_ptActPos.y = y*CPIECE_UNIT;
  105. }
  106. /////////////////////////////////////////////////////////////////////////////
  107. BOOL CPiece::PtInPiece(CPoint& pt)
  108. {
  109. CRect rect(m_ptActPos,m_szActSize);
  110.  
  111.   return rect.PtInRect(pt);
  112. }
  113. /////////////////////////////////////////////////////////////////////////////
  114. CRect CPiece::rectPiece(void)
  115. {
  116. CRect r(m_ptActPos,m_szActSize);
  117.     
  118.   return r;
  119. }
  120. /////////////////////////////////////////////////////////////////////////////
  121. void CPiece::SetMoveLimits(int up,int right,int down,int left)
  122. {
  123.     m_nUpLim    = up;
  124.     m_nRightLim = right;
  125.     m_nDownLim  = down;
  126.     m_nLeftLim  = left;
  127.     m_bInMotion = FALSE;
  128.     m_bHoriz    = FALSE;
  129.     m_bVert     = FALSE;
  130. }
  131. /////////////////////////////////////////////////////////////////////////////
  132. void CPiece::Move(CPoint& rPoint)
  133. {
  134.  
  135.     if (m_bInMotion)
  136.        {
  137.        int dx;
  138.        int dy;
  139.  
  140.        //Clip point to allowed rectangle
  141.        if ( rPoint.x > m_nMouseRightLim )
  142.           rPoint.x = m_nMouseRightLim;
  143.        else if ( rPoint.x < m_nMouseLeftLim )
  144.           rPoint.x = m_nMouseLeftLim;
  145.        if ( rPoint.y > m_nMouseDownLim )
  146.           rPoint.y = m_nMouseDownLim;
  147.        else if ( rPoint.y < m_nMouseUpLim )
  148.           rPoint.y = m_nMouseUpLim;
  149.           
  150.        dx = rPoint.x - m_ptMouseLast.x;
  151.        dy = rPoint.y - m_ptMouseLast.y;
  152.  
  153.        if (m_bHoriz)
  154.           //We're restricted to the horizontal  
  155.           dy=0;
  156.        else if (m_bVert)
  157.           //We're restricted to the vertical  
  158.           dx=0;
  159.        else 
  160.           {
  161.           //We haven't established the orientation yet
  162.           //  If we can only move vertically or horizontally that will be
  163.           //    our orientation
  164.           //  otherwise the orientation will be in the direction of the 
  165.           //    greatest change
  166.  
  167.           if ( !m_nRightLim && !m_nLeftLim )
  168.              {
  169.              m_bHoriz = FALSE;
  170.              m_bVert  = TRUE; 
  171.              dx=0;
  172.              }   
  173.           else if ( !m_nUpLim && !m_nDownLim )
  174.              {
  175.              m_bHoriz = TRUE;
  176.              m_bVert  = FALSE; 
  177.              dy=0;
  178.              } 
  179.           else if ( abs(dx) > abs(dy) )
  180.              {
  181.              m_bHoriz = TRUE;
  182.              m_bVert  = FALSE; 
  183.              dy=0;
  184.              } 
  185.           else    
  186.              {
  187.              m_bHoriz = FALSE;
  188.              m_bVert  = TRUE; 
  189.              dx=0;
  190.              }
  191.           }
  192.        m_ptActPos.x += dx;
  193.        m_ptActPos.y += dy;
  194.        m_ptMouseLast = rPoint;
  195.        }
  196.     else
  197.        {
  198.        //Motion hasn't started yet. PREPARE!
  199.        m_ptMouseOrg   = rPoint; //Remember where we started
  200.        m_ptMouseLast  = rPoint;
  201.        // Calculate mouse limits
  202.        m_nMouseUpLim    = rPoint.y - m_nUpLim*CPIECE_UNIT;
  203.        m_nMouseRightLim = rPoint.x + m_nRightLim*CPIECE_UNIT;
  204.        m_nMouseDownLim  = rPoint.y + m_nDownLim*CPIECE_UNIT;
  205.        m_nMouseLeftLim  = rPoint.x - m_nLeftLim*CPIECE_UNIT;
  206.        m_bHoriz         = FALSE;  //Don't know the 
  207.        m_bVert          = FALSE;  //direction yet
  208.        m_bInMotion      = TRUE;
  209.        } 
  210. }
  211. /////////////////////////////////////////////////////////////////////////////
  212. void CPiece::Stop(CPoint& rPoint)
  213. {
  214. int OldErr, NewErr, LogPos;
  215.     
  216.   if (m_bHoriz)
  217.     {
  218.     //Find the horizontal logical position which has the least
  219.     //  error with respect to the actual position
  220.     OldErr=INT_MAX;
  221.     for (LogPos=0;LogPos<INT_MAX;LogPos++)
  222.         {
  223.         NewErr=abs(m_ptActPos.x-LogPos*CPIECE_UNIT);
  224.         if (NewErr > OldErr)
  225.            {
  226.            m_ptLogPos.x = LogPos-1;
  227.            m_ptActPos.x = m_ptLogPos.x*CPIECE_UNIT; 
  228.            break;
  229.            }
  230.         else
  231.            OldErr = NewErr;
  232.         }
  233.     }
  234.   else
  235.     {
  236.     //Find the vertical logical position which has the least
  237.     //  error with respect to the actual position    
  238.     OldErr=INT_MAX;
  239.     for (LogPos=0;LogPos<INT_MAX;LogPos++)
  240.         {
  241.         NewErr=abs(m_ptActPos.y-LogPos*CPIECE_UNIT);
  242.         if (NewErr > OldErr)
  243.            {
  244.            m_ptLogPos.y = LogPos-1; 
  245.            m_ptActPos.y = m_ptLogPos.y*CPIECE_UNIT; 
  246.            break;
  247.            }
  248.         else
  249.            OldErr = NewErr;
  250.         }
  251.     }
  252.   m_bInMotion = FALSE;
  253. }
  254.