home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_C
/
MSVCPUZL.ZIP
/
PIECE.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1993-11-07
|
7KB
|
254 lines
#include "stdafx.h"
#include "math.h"
#include "limits.h"
#include "puzzle.h"
#include "piece.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CPiece
CPiece::CPiece(void)
{
m_szLogSize.cx=0;
m_szLogSize.cy=0;
m_ptLogPos.x=0;
m_ptLogPos.y=0;
m_szActSize.cx=0;
m_szActSize.cy=0;
m_ptActPos.x=0;
m_ptActPos.y=0;
m_bInMotion = FALSE;
m_nUpLim = 0;
m_nDownLim = 0;
m_nRightLim = 0;
m_nLeftLim = 0;
m_xHiliteWidth = GetSystemMetrics(SM_CXBORDER)*3;
m_yHiliteWidth = GetSystemMetrics(SM_CYBORDER)*3;
}
/////////////////////////////////////////////////////////////////////////////
CPiece::CPiece(int x, int y, int dx, int dy)
{
m_szLogSize.cx=dx;
m_szLogSize.cy=dy;
m_ptLogPos.x=x;
m_ptLogPos.y=y;
m_szActSize.cx=dx*CPIECE_UNIT;
m_szActSize.cy=dy*CPIECE_UNIT;
m_ptActPos.x=x*CPIECE_UNIT;
m_ptActPos.y=y*CPIECE_UNIT;
m_bInMotion = FALSE;
m_nUpLim = 0;
m_nDownLim = 0;
m_nRightLim = 0;
m_nLeftLim = 0;
m_xHiliteWidth = GetSystemMetrics(SM_CXBORDER)*3;
m_yHiliteWidth = GetSystemMetrics(SM_CYBORDER)*3;
}
/////////////////////////////////////////////////////////////////////////////
CPiece::~CPiece(void)
{}
//////////////////////////////////////////////////////////////////////////////
void CPiece::draw(CDC* pDC)
{
CRect rect(m_ptActPos,m_szActSize);
CRect rectHilite;
pDC->SelectStockObject(GRAY_BRUSH);
pDC->SelectStockObject(NULL_PEN);
pDC->Rectangle(rect);
rectHilite = rect;
rectHilite.right = rectHilite.left+m_xHiliteWidth;
pDC->SelectStockObject(LTGRAY_BRUSH);
pDC->Rectangle(rectHilite);
rectHilite = rect;
rectHilite.bottom = rectHilite.top+m_yHiliteWidth;
pDC->Rectangle(rectHilite);
pDC->SelectStockObject(DKGRAY_BRUSH);
rectHilite = rect;
rectHilite.left = rectHilite.right - m_xHiliteWidth;
pDC->Rectangle(rectHilite);
rectHilite = rect;
rectHilite.top = rectHilite.bottom - m_yHiliteWidth;
pDC->Rectangle(rectHilite);
}
/////////////////////////////////////////////////////////////////////////////
CSize CPiece::GetSize(void)
{
return m_szLogSize;
}
/////////////////////////////////////////////////////////////////////////////
CPoint CPiece::GetPos(void)
{
return m_ptLogPos;
}
/////////////////////////////////////////////////////////////////////////////
void CPiece::SetPos(const CPoint& rPT)
{
m_ptLogPos = rPT;
m_ptActPos.x = rPT.x*CPIECE_UNIT;
m_ptActPos.y = rPT.y*CPIECE_UNIT;
}
/////////////////////////////////////////////////////////////////////////////
void CPiece::SetPos(int x, int y)
{
m_ptLogPos.x = x;
m_ptLogPos.y = y;
m_ptActPos.x = x*CPIECE_UNIT;
m_ptActPos.y = y*CPIECE_UNIT;
}
/////////////////////////////////////////////////////////////////////////////
BOOL CPiece::PtInPiece(CPoint& pt)
{
CRect rect(m_ptActPos,m_szActSize);
return rect.PtInRect(pt);
}
/////////////////////////////////////////////////////////////////////////////
CRect CPiece::rectPiece(void)
{
CRect r(m_ptActPos,m_szActSize);
return r;
}
/////////////////////////////////////////////////////////////////////////////
void CPiece::SetMoveLimits(int up,int right,int down,int left)
{
m_nUpLim = up;
m_nRightLim = right;
m_nDownLim = down;
m_nLeftLim = left;
m_bInMotion = FALSE;
m_bHoriz = FALSE;
m_bVert = FALSE;
}
/////////////////////////////////////////////////////////////////////////////
void CPiece::Move(CPoint& rPoint)
{
if (m_bInMotion)
{
int dx;
int dy;
//Clip point to allowed rectangle
if ( rPoint.x > m_nMouseRightLim )
rPoint.x = m_nMouseRightLim;
else if ( rPoint.x < m_nMouseLeftLim )
rPoint.x = m_nMouseLeftLim;
if ( rPoint.y > m_nMouseDownLim )
rPoint.y = m_nMouseDownLim;
else if ( rPoint.y < m_nMouseUpLim )
rPoint.y = m_nMouseUpLim;
dx = rPoint.x - m_ptMouseLast.x;
dy = rPoint.y - m_ptMouseLast.y;
if (m_bHoriz)
//We're restricted to the horizontal
dy=0;
else if (m_bVert)
//We're restricted to the vertical
dx=0;
else
{
//We haven't established the orientation yet
// If we can only move vertically or horizontally that will be
// our orientation
// otherwise the orientation will be in the direction of the
// greatest change
if ( !m_nRightLim && !m_nLeftLim )
{
m_bHoriz = FALSE;
m_bVert = TRUE;
dx=0;
}
else if ( !m_nUpLim && !m_nDownLim )
{
m_bHoriz = TRUE;
m_bVert = FALSE;
dy=0;
}
else if ( abs(dx) > abs(dy) )
{
m_bHoriz = TRUE;
m_bVert = FALSE;
dy=0;
}
else
{
m_bHoriz = FALSE;
m_bVert = TRUE;
dx=0;
}
}
m_ptActPos.x += dx;
m_ptActPos.y += dy;
m_ptMouseLast = rPoint;
}
else
{
//Motion hasn't started yet. PREPARE!
m_ptMouseOrg = rPoint; //Remember where we started
m_ptMouseLast = rPoint;
// Calculate mouse limits
m_nMouseUpLim = rPoint.y - m_nUpLim*CPIECE_UNIT;
m_nMouseRightLim = rPoint.x + m_nRightLim*CPIECE_UNIT;
m_nMouseDownLim = rPoint.y + m_nDownLim*CPIECE_UNIT;
m_nMouseLeftLim = rPoint.x - m_nLeftLim*CPIECE_UNIT;
m_bHoriz = FALSE; //Don't know the
m_bVert = FALSE; //direction yet
m_bInMotion = TRUE;
}
}
/////////////////////////////////////////////////////////////////////////////
void CPiece::Stop(CPoint& rPoint)
{
int OldErr, NewErr, LogPos;
if (m_bHoriz)
{
//Find the horizontal logical position which has the least
// error with respect to the actual position
OldErr=INT_MAX;
for (LogPos=0;LogPos<INT_MAX;LogPos++)
{
NewErr=abs(m_ptActPos.x-LogPos*CPIECE_UNIT);
if (NewErr > OldErr)
{
m_ptLogPos.x = LogPos-1;
m_ptActPos.x = m_ptLogPos.x*CPIECE_UNIT;
break;
}
else
OldErr = NewErr;
}
}
else
{
//Find the vertical logical position which has the least
// error with respect to the actual position
OldErr=INT_MAX;
for (LogPos=0;LogPos<INT_MAX;LogPos++)
{
NewErr=abs(m_ptActPos.y-LogPos*CPIECE_UNIT);
if (NewErr > OldErr)
{
m_ptLogPos.y = LogPos-1;
m_ptActPos.y = m_ptLogPos.y*CPIECE_UNIT;
break;
}
else
OldErr = NewErr;
}
}
m_bInMotion = FALSE;
}