// DiamondStatic.cpp : implementation file
//
#include "stdafx.h"
#include "CSDemo.h"
#include "DiamondStatic.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDiamondStatic
//
/////////////////////////////////////////////////////////////////////////////
// :)很高兴您对这些代码感兴趣。您可以随意修改,但请保留以下的声明。
//
// Programe: 2002.7.17~7.19 HangZhou WenSan Road
// Note: 2002.8.20 HeFei WangJiang West Road
// Author: Zhang Qinhua
// E-mail: CodeStylite@hotmail.com; a.cong@yeah.net
// QQ: 1080221
//////////////////////////////////////////////////////////////////////
//
// 这些代码是前阵子太无聊时写的。
//
// 工作已经整整一年了,一年来都是用vc在开发CAPP/PDM,自己做的工作
// 只是写写模块,感觉没太多的热情,只是添加了爱好变成职业后的无奈。
//
// 因为在大学时用vb写过类似的方块,所以这个东西只花了3个晚上的
// 时间,大概10小时左右,而大部分时间在做美化。
//
// 由于太懒,不想对该程序再做更多的优化。很高兴您能帮我做下去。
// 希望你只是作为一种爱好。
//
// 本程序主要是CDiamondShape, CDiamondStatic;
// CDiamondShape是方块形状类。
// CDiamondStatic是方块窗口类,从CStatic继承的。
/////////////////////////////////////////////////////////////////////
//==================================================================
// 构造函数:
// 初始化随机种子;
// 初始化区域数据;
// 新建下一个形状;
// 设置游戏状态;
//==================================================================
CDiamondStatic::CDiamondStatic()
{
srand( (unsigned)time(NULL) );
for( int nRowIndex = 0; nRowIndex < ROW; nRowIndex ++ )
for( int nColIndex = 0; nColIndex < COL; nColIndex ++ )
m_Data[nRowIndex][nColIndex] = false;
m_ShapeNext.NewShape();
m_nPoints = 0;
m_nElapse = 200;
m_nState = ST_PRE;
}
CDiamondStatic::~CDiamondStatic()
{
}
BEGIN_MESSAGE_MAP(CDiamondStatic, CStatic)
//{{AFX_MSG_MAP(CDiamondStatic)
ON_WM_PAINT()
ON_WM_TIMER()
ON_WM_ERASEBKGND()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CDiamondStatic message handlers
//==================================================================
// 画函数
//==================================================================
void CDiamondStatic::OnPaint()
{
CPaintDC dc(this);
//---------------------
// 暂停或运行时 画
// 边界线;
// 分数显示;
// 当前的已固定方块;
// 当前方块;
// 下一个方块;
if( m_nState == ST_PLAY || m_nState == ST_PAUSE )
{
CPen penWhite( PS_SOLID, 1, RGB(255,255,255) );
CPen penGray( PS_SOLID, 1, RGB(128,128,128) );
CPen *pOld = NULL;
dc.MoveTo( LEN * COL + 3, 0 );
dc.LineTo( LEN * COL + 3, LEN * ROW );
pOld = dc.SelectObject( &penWhite );
dc.MoveTo( LEN * COL + 1, 0 );
dc.LineTo( LEN * COL + 1, LEN * ROW );
dc.SelectObject( &penGray );
dc.MoveTo( LEN * COL + 2, 0 );
dc.LineTo( LEN * COL + 2, LEN * ROW );
dc.SelectObject( pOld );
penGray.DeleteObject();
penWhite.DeleteObject();
CRect rt( 125, 80, 180, 130 );
CString str;
str.Format( "Points\n%d", m_nPoints );
DrawShadowText( &dc, rt, str );
for( int nRow = 0; nRow < ROW; nRow ++ )
DrawFixLine( &dc, nRow );
m_Shape.Draw( &dc );
m_ShapeNext.Draw( &dc );
}
//---------------------------------
// 预备状态 画
// How To Play;
if( m_nState == ST_PRE )
{
CRect rtNote( 5, 5, 185, 30 );
CString strNote;
strNote = "Diamond v1.0";
dc.SetTextColor( RGB(200,0,0) );
DrawShadowText( &dc, rtNote, strNote );
rtNote.SetRect( 0, 30, 185, 300 );
strNote.LoadString( IDS_NOTE );
dc.SetTextColor( RGB(0,122,0) );
DrawShadowText( &dc, rtNote, strNote );
}
}
//==================================================================
// 画阴影文字
//==================================================================
void CDiamondStatic::DrawShadowText( CDC *pDC, CRect rt, CString strText )
{
pDC->SetBkMode( 0 );
pDC->DrawText( strText, rt, DT_CENTER );
rt.OffsetRect(-1, -1 );
pDC->SetTextColor( RGB(220,220,220) );
pDC->DrawText( strText, rt, DT_CENTER );
}
//==================================================================
// 画框架,测试时用。
//==================================================================
void CDiamondStatic::DrawFrame( CDC *pDC )
{
int nRowCount = ROW;
int nColCount = COL;
int nIndex;
CPoint ptFirst( 0, 0 );
CPoint ptLast( LEN * nColCount, 0 );
for( nIndex = 0; nIndex <= nRowCount; nIndex ++ )
{
pDC->MoveTo( ptFirst );
pDC->LineTo( ptLast );
ptFirst.y += LEN;
ptLast.y += LEN;
}
ptFirst = CPoint( 0, 0 );
ptLast = CPoint( 0, LEN * nRowCount );
for( nIndex = 0; nIndex <= nColCount; nIndex ++ )
{
pDC->MoveTo( ptFirst );
pDC->LineTo( ptLast );
ptFirst.x += LEN;
ptLast.x += LEN;
}
}
//==================================================================
// 画已固定行,即已下落的方块。
//==================================================================
void CDiamondStatic::DrawFixLine( CDC *pDC, int nRow, bool bErase/*=false*/ )
{
for( int nCol = 0; nCol < COL; nCol ++ )
if( bErase )
CDiamondShape::DrawCell( pDC, CPoint( nCol, nRow ), m_crData[nRow][nCol], true );
else
CDiamondShape::DrawCell( pDC, CPoint( nCol, nRow ), m_crData[nRow][nCol], !m_Data[nRow][nCol] );
}
//==================================================================
// 方块形状的改变。 nMode = 0/1/2/3
//==================================================================
bool CDiamondStatic::ChangeShape( int nMode )
{
CClientDC dc(this);
CDiamondShape sp( m_Shape );
switch( nMode )
{
case 0: // To Left
{
sp.m_ptBase.x = m_Shape.m_ptBase.x - 1;
if( ShapeValid( sp ) )
{
m_Shape.Draw( &dc, true );
m_Shape.m_ptBase.x = sp.m_ptBase.x;
m_Shape.Draw( &dc );
return true;
}
}
break;
case 1: // To Right;
{
sp.m_ptBase.x = m_Shape.m_ptBase.x + 1;
if( ShapeValid( sp ) )
{
m_Shape.Draw( &dc, true );
m_Shape.m_ptBase.x = sp.m_ptBase.x;
m_Shape.Draw( &dc );
return true;
}
}
break;
case 2: // To Down;
{
sp.m_ptBase.y = m_Shape.m_ptBase.y + 1;
if( ShapeValid( sp ) )
{
m_Shape.Draw( &dc, true );
m_Shape.m_ptBase.y = sp.m_ptBase.y;
m_Shape.Draw( &dc );
return true;
}
}
break;
case 3: // Metamorphose
{
sp.m_nShape = ( m_Shape.m_nShape + 1 ) % 4;
if( ShapeValid( sp ) )
{
m_Shape.Draw( &dc, true );
m_Shape.m_nShape = sp.m_nShape;
m_Shape.InitData();
m_Shape.Draw( &dc );
return true;
}
}
break;
}
return false;
}
//==================================================================
// 形状位置是否有效。越界检测。
//==================================================================
bool CDiamondStatic::ShapeValid( CDiamondShape sp )
{
if( sp.m_nShape < 0 || sp.m_nShape >= COL )
return false;
CPoint ptLocal;
for( int nRow = 0; nRow < 3; nRow ++ )
{
for( int nCol = 0; nCol < 3; nCol ++ )
{
ptLocal.x = sp.m_ptBase.x + nCol;
ptLocal.y = sp.m_ptBase.y + nRow;
if( sp.m_nData[nRow][nCol] &&
(ptLocal.x < 0 || ptLocal.x >= COL || ptLocal.y >= ROW ) )
return false;
if( sp.m_nData[nRow][nCol] && m_Data[ptLocal.y][ptLocal.x] )
return false;
}
}
if( sp.m_nID == 0 )
{
if( sp.m_nShape == 1 || sp.m_nShape == 3 )
{
ptLocal.x = sp.m_ptBase.x + 1;
ptLocal.y = sp.m_ptBase.y + 3;
}
else
{
ptLocal.x = sp.m_ptBase.x + 3;
ptLocal.y = sp.m_ptBase.y + 1;
}
if( m_Data[ptLocal.y][ptLocal.x] || ptLocal.x < 0
|| ptLocal.x >= COL || ptLocal.y >= ROW )
return false;
}
return true;
}
//==================================================================