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

📄 cbdraw.cpp

📁 赤壁之战的游戏源代码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	POINT pt;

	int nX = pstctCF->nX;
	int nY = pstctCF->nY;

	// draw the first level
	i = nY&1;
	int nLayer = pstctCF->nLayer;
//	for( k=0; k<6; k+=2 )
//	for( j=0; j<9; j++ )
	for( k=0; k<8; k+=2 )
	for( j=0; j<11; j++ )
	{
		if( pstctCF->nLocationSize == 0 && j < 5 && k== 0 )	continue;
		pt.x = nX+ptCovering[i][j].x;
		pt.y = nY+ptCovering[i][j].y+k;
		if( EYE_IfOutOfRange( pt.x, pt.y ) )
			continue;

		// draw special grounds around the unit
		struct MAP_GROUND_CODE_STRUCT stctG;
		WORD codeG = MAP_GetGroundData( nLayer, pt.x, pt.y );
		MAP_GroundDeCode( codeG, &stctG );
		if( stctG.nAttr == MAP_SPECIAL_NONE )	continue;

		int nA = stctG.nAttr%4;
		int nB = stctG.nAttr/4;
		int nC = 0;
		if( nB == 2 )	continue;	// 如果是已经被砍伐过的资源则不画
		DRAW_OTHER_Draw( prcCut, 7, (nA<<1)+nC, nLayer, pt.x, pt.y );

/*		// get special code
		struct CTRL_FRAME_STRUCT stctCF;
		Assert( stctG.nAttr != MAP_SPECIAL_NONE );
		if( !MAP_GetSpecFrameData( nLayer, pt.x, pt.y, stctG.nAttr, &stctCF ) )
			continue;

		// draw special unit in current position
		DRAW_DrawUnitSingle( prcCut, &stctCF );
*/
	}		

	// draw the second level
	nLayer ++;
	for( k=0; k<12; k+=2 )
	for( j=0; j<11; j++ )
	{
		if( pstctCF->nLocationSize == 0 && j < 5 && k== 0 )	continue;
		pt.x = nX+ptCovering[i][j].x;
		pt.y = nY+ptCovering[i][j].y+k;
		if( pt.x < 0 ||	pt.y < 0 || pt.x >= MAP_Lib.szNum.cx || pt.y >= MAP_Lib.szNum.cy )
			continue;

		// draw grounds around the unit
		DRAW_DrawSingleG( prcCut, nLayer, pt.x, pt.y, FALSE );
	}

	if( nLayer == 2	)	return;

	// draw the third level right above the unit
	for( j=MAP_nLocationNum[pstctCF->nLocationSize]-1; j>=0; j-- )
	{
		pt.x = nX+MAP_ptLocation[i][j].x;
		pt.y = nY+MAP_ptLocation[i][j].y;

		// draw grounds above the unit
		DRAW_DrawSingleG( prcCut, 2, pt.x, pt.y, FALSE );
	}

	// draw the third level
	for( k=0; k<12; k+=2 )
	for( j=0; j<11; j++ )
	{
		if( pstctCF->nLocationSize == 0 && j < 5 && k== 0 )	continue;
		pt.x = nX+ptCovering[i][j].x;
		pt.y = nY+ptCovering[i][j].y+k;
		if( pt.x < 0 ||	pt.y < 0 || pt.x >= MAP_Lib.szNum.cx || pt.y >= MAP_Lib.szNum.cy )
			continue;

		// draw grounds around the unit
		DRAW_DrawSingleG( prcCut, 2, pt.x, pt.y, FALSE );
	}
}

// 显示一个单元,包含了更新其周围的单元的操作
// draw one unit item
// prcCut	:	只更新此矩形区内的图像
// i,j		:	图素的行号,列号
// bFront	:	是否直接更新到显示屏幕
RECT DRAW_rcUpdate={0,0,0,0};
inline void DRAW_DrawSingleU( CONST RECT *prcCut, int i, int j, BOOL bFront )
{
	//RECT rect;		// source rectangle
	RECT rcCutG, rcCutGSave;	// update region for current position

// get code
	struct CTRL_FRAME_STRUCT stctCF;
	if( !MAP_GetUnitFrameData( i, j, &stctCF, FALSE ) )
		return;

	// 敌人正在埋伏,不显示出来
	struct UNIT_STRUCT *pUnit = MAP_GetUnit( i,j );
	Assert( pUnit );
	if( pUnit->Status.nTaskID == MFU && pUnit->Draw.nPlayer != GAME.nMe )
		return;
	// debug
//	if( pUnit->Status.nTaskID == MFU )
//		return;

	// test if should draw
//	if( !stctCF.bUpdate )	return;

	// below: same as DRAW_DrawSingleS()
// draw this unit in current position
	BOOL bDraw = DRAW_DrawUnitSingle( prcCut, &stctCF );
	
// draw covering items, items which covering this unit
	// get update region
	rcCutGSave = ::MAP_GetUnitRect( DRAW_ptScreenOffset, &stctCF );

	// 显示计谋提示图标(血点)
	if( bDraw && pUnit->Draw.nFile > 28 )	// 建筑没有计谋
		DRAW_Draw8x8( pUnit, &rcCutGSave, prcCut );
	
	// draw covering
	if( bDraw && stctCF.nLayer != 2 
		&& IntersectRect( &rcCutG, &rcCutGSave, prcCut ) )
		DRAW_DrawUnitCovering( &rcCutG, &stctCF );

	// calculate update region
	// The mouse cursor is blinking, so do not use it
/*	RECT rcCutGL, rcCutGLSave;	// update region for previous position
	rcCutGLSave = ::MAP_GetUnitRectLast( DRAW_ptScreenOffset, &stctCF );
	IntersectRect( &rcCutGL, &rcCutGLSave, prcCut );
	UnionRect( &DRAW_rcUpdate, &rcCutGL, &DRAW_rcUpdate );
	UnionRect( &DRAW_rcUpdate, &rcCutG, &DRAW_rcUpdate );
*/
} // DRAW_DrawSingleU()

// 显示一个特殊图素,树木,麦田,陷阱等
// draw one special item
// prcCut	:	只更新此矩形区内的图像
// i,j		:	图素的行号,列号
// bFront	:	是否直接更新到显示屏幕
// Attr		:	特殊图素的属性,非0时有效
// k		:	特殊图素的层号,nAttr非0时有效
inline void DRAW_DrawSingleS( CONST RECT *prcCut, int i, int j, BOOL bFront, int nAttr, int k )
{
	//RECT rect;		// source rectangle
// get code
//	struct CTRL_FRAME_STRUCT stctCF;
	Assert( nAttr != MAP_SPECIAL_NONE );
//	if( !MAP_GetSpecFrameData( k, i, j , nAttr, &stctCF ) )
//		return;

	// below: same as DRAW_DrawSingleU()
// draw this unit in current position
	//DRAW_DrawUnitSingle( prcCut, &stctCF );
	int nA = nAttr%4;
	int nB = nAttr/4;
	int nC = 0;
	if( nB == 2 )	nC = 1;
	DRAW_OTHER_Draw( prcCut, 7, (nA<<1)+nC, k, i, j );
} // DRAW_DrawSingleS()
/////////////////////

/////////////////////
// 显示战场区域内的所有地形图素
// draw ground items
// rcCut	:	只更新此矩形区内的图像
// k		:	地形图素的层号
// bFront	:	是否直接更新到显示屏幕
inline void DRAW_DrawGround( RECT rcCut, int k, BOOL bFront )
{
	for( int j=DRAW_rcScreen.top; j<DRAW_rcScreen.bottom; j++ )
	for( int i=DRAW_rcScreen.left; i<DRAW_rcScreen.right; i++ )
	{
		DRAW_DrawSingleG( &rcCut, k, i, j, bFront );
	}
}

// 显示战场区域内的所有单元图素
// draw unit itmes
// rcCut	:	只更新此矩形区内的图像
// bFront	:	是否直接更新到显示屏幕
inline void DRAW_DrawUnit( RECT rcCut, BOOL bFront )
{
	int i, j;

	// 闪烁动画效果,计数
	if( DRAW_BLINK_nID != MAP_DATA_NONE )
	{
		if( DRAW_BLINK_bDraw == TRUE )
		{	// 显示延时
			if( DRAW_BLINK_nDelay < DRAW_BLINK_DELAY1 )
			{
				DRAW_BLINK_nDelay++;
			}
			else
			{	// 时间到
				DRAW_BLINK_nDelay = 0;
				DRAW_BLINK_bDraw = FALSE;
			}
		}
		else
		{	// 隐藏延时
			if( DRAW_BLINK_nDelay < DRAW_BLINK_DELAY2 )
			{
				DRAW_BLINK_nDelay++;
			}
			else
			{	// 时间到
				DRAW_BLINK_nDelay = 0;
				DRAW_BLINK_bDraw = TRUE;
				DRAW_BLINK_nCounter++;

				if( DRAW_BLINK_nCounter >= DRAW_BLINK_COUNT )
				{	// 结束闪烁
					struct UNIT_STRUCT *pU = MAP_GetUnit( DRAW_BLINK_nID );
					Assert( pU );
					DRAW_BLINK_nID = MAP_DATA_NONE;
					pU->Draw.bUpdate = DRAW_BLINK_nSave;
				}
			}
		}
	}// End of if( DRAW_BLINK_nID != MAP_DATA_NONE )

	// 显示战场区域内的所有单元
	// ~40ms
	for( j=DRAW_rcScreen.top; j<DRAW_rcScreen.bottom; j++ )
	for( i=DRAW_rcScreen.left; i<DRAW_rcScreen.right; i++ )
	{
		DRAW_DrawSingleU( &rcCut, i, j, bFront );
	}   
}

// 是否是正式版
extern MAIN_bRelease; // defined in CBMain.cpp
void DrawHZ( class CDDSurface * pSurface )
{
	HDC hdc=0;
	BOOL bUpdate =FALSE;
	static char strSave[20]="";

	UpdateGFWI();

	if( MAIN_bRelease == TRUE )
		return;	

	if( strcmp( strSave, strCopyright )!= 0 )
	{
		tCopyright.GetDDSurface()->Erase();
		bUpdate = TRUE;
		OutputDebugString( strSave );
		OutputDebugString( "," );
		OutputDebugString( strCopyright );
		OutputDebugString( "\n" );

		tCopyright.MyTextOut( DD_GetBackBuffer(), 24, 460, strCopyright );

		strcpy( strSave, strCopyright );
		RECT rect;
		rect.left = 24;
		rect.top = 460;
		rect.right = rect.left + tCopyright.GetDDSurface()->GetSize().cx;
		rect.bottom = rect.top + tCopyright.GetDDSurface()->GetSize().cy;
		if( bUpdate )	DDC_UpdateScreen( &rect );
	}

}
/////////////////////

/////////////////////
// 拷贝游戏背景面到地形背景面
// prcCut	:	剪裁的范围,如果为NULL,则拷贝整个战场的区域
void DRAW_DrawBack2BkGround( CONST RECT *prcCut /*=NULL */)
{
	POINT ptDest;
	RECT rcSrc;
	if( prcCut == NULL )
	{
		ptDest.x = ptDest.y = 0;
		SetRect( &rcSrc, DRAW_rcClient.left, 
				DRAW_rcClient.top, 
				DRAW_rcClient.right, 
				DRAW_rcClient.bottom ); 
	}
	else
	{
		ptDest.x = prcCut->left - DRAW_rcClient.left,
		ptDest.y = prcCut->top - DRAW_rcClient.top;
		SetRect( &rcSrc, prcCut->left, 
				prcCut->top, 
				prcCut->right, 
				prcCut->bottom ); 
	}
	// draw from backbuffer to bkGround surface
	DD_BltSurface( ptDest, DRAW_sBkGround.GetSurface(), &rcSrc, DD_GetBackBuffer(), DDBLTFAST_NOCOLORKEY );
}

// 拷贝地形背景面到游戏背景面
// prcCut	:	剪裁的范围,如果为NULL,则拷贝整个战场的区域
void DRAW_DrawBkGround2Back( CONST RECT *prcCut/*= NULL*/ )
{
	// draw background
	// ~2.8ms
	POINT ptDest;
	RECT rcSrc;
	if( prcCut == NULL )
	{
		ptDest.x = DRAW_rcClient.left, ptDest.y = DRAW_rcClient.top;
		rcSrc.left = rcSrc.top =0, 
		rcSrc.right = DRAW_rcClient.right - DRAW_rcClient.left,
		rcSrc.bottom = DRAW_rcClient.bottom - DRAW_rcClient.top;
	}
	else
	{
		ptDest.x = prcCut->left, ptDest.y = prcCut->top;
		SetRect( &rcSrc, prcCut->left, 
				prcCut->top, 
				prcCut->right, 
				prcCut->bottom ); 
		OffsetRect( &rcSrc, -DRAW_rcClient.left, -DRAW_rcClient.top );
	}
	DD_BltSurface( ptDest, DD_GetBackBuffer(), &rcSrc, DRAW_sBkGround.GetSurface(), DDBLTFAST_NOCOLORKEY );
}
/////////////////////

/////////////////////
// 显示单元、阴影、水纹的效果、汉字、更新缩略图等
// 每秒钟要运行几十次
// draw maps in every program cycle
#define	DRAW_CLOCK_CIRCLE	5
void DRAW_DrawMaps( void )
{
	if( !DRAW_bLoadMaps )	return;

	// draw background
	// S->S, no colorkey, 5.13ms, 195 frames/sec
	// 将原来保存的地形背景面显示到游戏的背景面上
	DRAW_DrawBkGround2Back( &DRAW_rcClient );

	// draw others lower than units
	DRAW_DrawOthersCOM( OTHER_TYPE_BLOOD );

	// draw units
	// 27 frames/sec, 37 ms
	DRAW_DrawUnit( DRAW_rcClient, TRUE );

	// draw others upper than units
	DRAW_DrawOthersBMP( OTHER_TYPE_FIRE );

//---	
	// draw blinking water
	// 2500 frames/sec, 0.4 ms
#ifndef	_DEBUG
	DRAW_FlipWater();
#endif

	// draw mouse dragging rectangle to back buffer
	// 1550 frames/sec, 0.645ms
	MOUSE_DrawDragRect();

	//	在每轮的循环中,向游戏背景面上重画完地形和单元后,重画阴影,即将阴影背景面贴到游戏背 
	// 景面上.
	// draw shadow, 
	// V->S, colorkey, 8.33ms, 120 frames/sec
	SHADOW_Update2Back();

	// 显示鼠标痕迹,当鼠标点击了地面之后,出现一个指示的手势
	// 必须在最后,在最上面
	DRAW_DrawOthersMouse();

	// draw build surface
	BUILD_Draw( &DRAW_rcClient );

	// draw characters, should be at last
	// English:	5080 frames/sec, nearly 0ms consumed
	// Chinese:	4700 frames/sec, 0.213ms
	DrawHZ( NULL );

//---- begin clock session
// 在此区域内只有满足时钟属性nClkAttr的函数才被运行
	// 把缩略图画到背景面上
	// July 23, 1997
	static int nClock=0;
	int nClkAttr = nClock%DRAW_CLOCK_CIRCLE;
	if( nClkAttr == 1 )
	{
		// draw minimap only in back buffer
		MINI_Update( 0 );
	}
	nClock++;
//---- end clock session


//---- network only
	// July 23, 1997
//	GAME.bNetwork = TRUE;
	FACE_BlitCurrentMenu();

	// 把缩略图更新到前屏幕上
	// July 23, 1997
	if( nClkAttr == 1 )
	{
		// draw minimap only in back buffer
		MINI_Update( 2 );
	}

	// update to front buffer, S->S, no colorkey, 5.56ms, 180 frames/sec
	DDC_UpdateScreen( &DRAW_rcClient );

// DDBLTFAST_NOCOLORKEY
} // DRAW_DrawMaps()
/////////////////////

void UpdateGFWI()
{
	if( GFWI_bUpdate == TRUE )
	{
		char str[20];
		int nColor=97;
		itoa( GAME.Players[GAME.nMe].nGold, str, 10 );
		tGold.GetDDSurface()->Erase( nColor );
		tGold.MyTextOut( DD_GetBackBuffer(), 52, 21, str );
		itoa( GAME.Players[GAME.nMe].nFood, str, 10 );
		tFood.GetDDSurface()->Erase( nColor );
		tFood.MyTextOut( DD_GetBackBuffer(), 155, 21, str );
		itoa( GAME.Players[GAME.nMe].nWood, str, 10 );
		tWood.GetDDSurface()->Erase( nColor );
		tWood.MyTextOut( DD_GetBackBuffer(), 445, 21, str );
		itoa( GAME.Players[GAME.nMe].nIron, str, 10 );
		tIron.GetDDSurface()->Erase( nColor );
		tIron.MyTextOut( DD_GetBackBuffer(), 548, 21, str );

		RECT rect;
		rect.left = 52;
		rect.top = 21;
		rect.right = rect.left + tGold.GetDDSurface()->GetSize().cx+16;
		rect.bottom = rect.top + tGold.GetDDSurface()->GetSize().cy;
		DDC_UpdateScreen( &rect );
		rect.left = 155;
		rect.top = 21;
		rect.right = rect.left + tFood.GetDDSurface()->GetSize().cx+16;
		rect.bottom = rect.top + tFood.GetDDSurface()->GetSize().cy;
		DDC_UpdateScreen( &rect );
		rect.left = 445;
		rect.top = 21;
		rect.right = rect.left + tWood.GetDDSurface()->GetSize().cx+16;
		rect.bottom = rect.top + tWood.GetDDSurface()->GetSize().cy;
		DDC_UpdateScreen( &rect );
		rect.left = 548;
		rect.top = 21;
		rect.right = rect.left + tIron.GetDDSurface()->GetSize().cx+16;
		rect.bottom = rect.top + tIron.GetDDSurface()->GetSize().cy;
		DDC_UpdateScreen( &rect );

		GFWI_bUpdate = FALSE;
	}
}

⌨️ 快捷键说明

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