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

📄 cbbuild.cpp

📁 这是一个游戏程序源码
💻 CPP
字号:
/////////////
//	CBBuild.cpp		:	v0011
//	Written by		:	Liu Gang
//	Compiler		:	Microsoft Visual C++ 4.0 & DirectX
//	Library			:	DDraw.Lib
//	Copyright (C)	:	1996 WayAhead Corporation
//	v0010			:	Mar.7.1997
//	v0011			:	Mar.28.1997, changed BUILD_sBorder to BUILD_ptBorder
/////////////
// implementation file
// display build maps when placing buildings
// 当建造建筑时,点击一个建筑按钮后,鼠标变成一个建筑的影象,
// 随着鼠标移动,战场上能够建造建筑的地方(格子)为绿色网格覆盖,
// 不能建造的地方为红色网格覆盖,本文件就是显示这个部分。

#include "stdafx.h"
#include "Assert.h"
#include "CBBuild.h"
#include "DDCompo.h"
#include "CBMAP.h"
#include "CBMouse.h"
#include "CBDraw.h"

#include<stdio.h>
/////////////
// members, globals
BOOL BUILD_bEnable = FALSE;
class	CDDSurface BUILD_sBack, *BUILD_psBorder;
BOOL BUILD_bCreated = FALSE;
SIZE BUILD_szBack = {144, 120};	// 背景面的大小
SIZE BUILD_szItem = {0, 0};		// 图素的大小
SIZE BUILD_szBorder = {0, 0};	// 图素边界的大小
int	 BUILD_nSize=0;				// 图素的大小类型
int BUILD_nLocationNum[4] = { 1, 4, 9, 16 };
/////////////

//////////////////
// other map surfaces, in CBDraw.cpp
extern class	CDDSurface	DRAW_sOtherMap[MAP_OTHER_NUM];
//////////////////

/////////////
DWORD BUILD_nCode;
BOOL BUILD_bLocation[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
/////////////

//---------------LWC
#ifdef	_MAP_COMPRESS_
#include "L_image.h"
extern class  CPicture_image	DRAW_ImageLib;	// CBDraw.cpp
extern RECT DRAW_rcClient;						// CBDraw.cpp
extern POINT MAP_ptLocation[2][MAP_LOCATION_MAX];		// CBMap.cpp
#endif
//---------------LWC

/////////////
// declared in CBDraw.cpp
extern POINT DRAW_ptScreenOffset;
/////////////


void BUILD_draw2Back( LPRECT prcCut, int nLayer, POINT ptPosG, BOOL bFront = FALSE );
void BUILD_drawBorders( LPRECT prcCut, POINT ptPosG );
void BUILD_drawBorder( LPRECT prcCut, int nLayer, POINT ptTopLeftG, int nType );

/////////////
BOOL BUILD_Load()
{
#ifdef	_DEBUG
	if( BUILD_bCreated )
	{
		ErrorMessage( hwndGame, BUILD_ERROR_ID+0, "Shadow surfaces have been created!" );
		return FALSE;
	}
#endif

	// has color key , in system memory
	if( !BUILD_sBack.Create( BUILD_szBack.cx, BUILD_szBack.cy, TRUE, FALSE ) )
	{
//		OutputDebugString( "BUILD_Load: Cannot create back surface in video memory!\n" );
//		if( !BUILD_sBack.Create( BUILD_szBack.cx, BUILD_szBack.cy, TRUE, FALSE ) )
		{
			ErrorMessage( hwndGame, BUILD_ERROR_ID+1, "Cannot create build background surface!" );
			return FALSE;
		}
	}

	// load shadow source image file
	// color key, system memory
	//if( !BUILD_sBorder.LoadBitmap( filename, TRUE, FALSE ) )
	BUILD_psBorder = &DRAW_sOtherMap[5];
	if( BUILD_psBorder == NULL || BUILD_psBorder->GetSurface() == NULL )
	{
		ErrorMessage( hwndGame, BUILD_ERROR_ID+2, "Cannot create build border surface!" );
		return FALSE;
	}

	BUILD_bCreated = TRUE;
	return TRUE;
}

void BUILD_Release()
{
#ifdef	_DEBUG
	if( !BUILD_bCreated )
	{
		ErrorMessage( hwndGame, BUILD_ERROR_ID+10, "Try to release build surfaces before load them!" );
		return;
	}
#endif

	BUILD_sBack.Release();
	//BUILD_sBorder.Release();
	BUILD_bCreated = FALSE;
}
/////////////

/////////////
// 把建筑的影像贴到建造背景面中
void BUILD_Set( DWORD codeU )
{
#ifdef	_DEBUG
	if( BUILD_bCreated == FALSE )
		OutputDebugString( "BUILD_Set Error(0): the surfaces have not been created!\n" );
	if( codeU == MAP_DATA_NONE )
		OutputDebugString( "BUILD_Set Error(0): code is invalid!\n" );
#endif

	struct MAP_UNIT_CODE_STRUCT stctU;
	MAP_UnitDeCode( codeU, &stctU );
	
	BUILD_nCode = codeU;

	// set size
	BUILD_nSize = MAP_Lib.Unit[stctU.nFile].nLocationSize;
	int nFrame = MAP_Lib.AniSeq[stctU.nFile].nOffset;

	// set size of item
	BUILD_szItem = MAP_Lib.Unit[stctU.nFile].szItem;

	// calc border size
	BUILD_szBorder.cx = (BUILD_nSize+1)*MAP_Lib.szItem.cx;
	BUILD_szBorder.cy = (BUILD_nSize+1)*MAP_Lib.szItem.cy;

	// clear the background surface
	BUILD_sBack.Erase();

	LPDIRECTDRAWSURFACE2 pSurDest = BUILD_sBack.GetSurface();
	DDSURFACEDESC       ddsdDest;
	ddsdDest.dwSize = sizeof( ddsdDest );

	// 注意:这里有一个容易引起错误的地方:
	// P_image()的第三个参数,不应该是ddsdDest.dwWidth,而应该是
	// ddsdDest.lPitch,这是指指针换行所应跳过的距离
	// 在很多情况下,这两个值是相等,而在这里第一次贴图时不是。
	if( pSurDest->Lock( NULL, &ddsdDest, DDLOCK_WAIT, NULL ) == DD_OK )
	{
		DRAW_ImageLib.P_image(0, 0, ddsdDest.lPitch, 
				(char*)ddsdDest.lpSurface,
				0, nFrame );
		pSurDest->Unlock( NULL );
	}
}

void BUILD_draw2Back( LPRECT prcCut, int nLayer, POINT ptPosG, BOOL bFront )
{
	POINT ptPos;
	RECT rcCutOld, rcCut;
	POINT ptTopLeft;
	POINT ptDest;
	RECT rcSrc;

#ifdef	_DEBUG
	if( BUILD_bCreated == FALSE )
		OutputDebugString( "BUILD_Set Error(0): the surfaces have not been created!\n" );
#endif

	// change grid to point
	ptPos = MOUSE_Grid2Point( nLayer, ptPosG );

	// get origenal destination rectangle on screen
	ptTopLeft.x = ptPos.x - (BUILD_szItem.cx>>1);
	ptTopLeft.y = ptPos.y + (MAP_Lib.szItem.cy>>1) - BUILD_szItem.cy;
	SetRect( &rcCutOld, ptTopLeft.x, ptTopLeft.y, 
			ptTopLeft.x+BUILD_szItem.cx, ptTopLeft.y+BUILD_szItem.cy );
	if( !IntersectRect( &rcCut, &rcCutOld, prcCut ) )
		return;

	// calc positions
	ptDest.x = rcCut.left, ptDest.y = rcCut.top;
	rcSrc.left = rcCut.left - rcCutOld.left;
	rcSrc.top = rcCut.top - rcCutOld.top;
	rcSrc.right = BUILD_szItem.cx - (rcCutOld.right - rcCut.right);
	rcSrc.bottom = BUILD_szItem.cy - (rcCutOld.bottom - rcCut.bottom);
	
	// draw to back
	BUILD_sBack.BltToBack( ptDest, &rcSrc );

	// draw from back buffer to front buffer
	if( bFront )
		DDC_UpdateScreen( prcCut );
}

void BUILD_drawBorder( LPRECT prcCut, POINT ptTopLeft, int nType )
{
	RECT rcCutGOld, rcCutG;
	POINT ptDest;
	RECT rcSrc;

	SetRect( &rcCutGOld, ptTopLeft.x, ptTopLeft.y,
		ptTopLeft.x+MAP_Lib.szItem.cx, ptTopLeft.y+MAP_Lib.szItem.cy );
	if( !IntersectRect( &rcCutG, &rcCutGOld, prcCut ) )
		return;

	ptDest.x = rcCutG.left, ptDest.y = rcCutG.top;
	rcSrc.left = rcCutG.left - rcCutGOld.left;
	rcSrc.top = rcCutG.top - rcCutGOld.top + nType*MAP_Lib.szItem.cy;
	rcSrc.right = MAP_Lib.szItem.cx + ( rcCutG.right - rcCutGOld.right );
	rcSrc.bottom = MAP_Lib.szItem.cy + ( rcCutG.bottom - rcCutGOld.bottom ) 
					+ nType*MAP_Lib.szItem.cy;

	//BUILD_sBorder.BltToBack( ptDest, &rcSrc );
	BUILD_psBorder->BltToBack( ptDest, &rcSrc );
}

void BUILD_drawBorders( LPRECT prcCut, int nLayer, POINT ptPosG )
{
	POINT ptTopLeft, ptPosGNext;

	int bOdd = ptPosG.y%2;
	for( int i=0; i< BUILD_nLocationNum[BUILD_nSize]; i++ )
	{
		// get positions in this location			
		ptPosGNext.x = ptPosG.x + MAP_ptLocation[bOdd][i].x;
		ptPosGNext.y = ptPosG.y + MAP_ptLocation[bOdd][i].y;
		// change grid to point
		ptTopLeft = MOUSE_Grid2Point( nLayer, ptPosGNext );
		ptTopLeft.x -= MAP_Lib.szItem.cx>>1;
		ptTopLeft.y -= MAP_Lib.szItem.cy>>1;
		if( BUILD_bLocation[i] == MAP_REGION_SUCCESS )
		{
			BUILD_drawBorder( prcCut, ptTopLeft, 1 );
		}
		else
		{
			BUILD_drawBorder( prcCut, ptTopLeft, 0 );
		}
	}
}

void BUILD_Enable( BOOL bEnable/* = TRUE*/ )
{
	BUILD_bEnable = bEnable;
}

inline BOOL BUILD_IfEnable()
{
	return BUILD_bEnable;
}

void BUILD_Draw( LPRECT prcCut/*=NULL*/ )
{
	POINT ptPos, ptPosG;

	if( !BUILD_bEnable )	return;
	
	// get mouse cursor position
	GetCursorPos( &ptPos );

	// change positoin to grids
	struct MOUSE_HITRESULT_STRUCT hit;
	if( !MOUSE_HitTestG( ptPos, &hit, 0 ) )	return;
	Assert( hit.nType == MOUSE_HITRESULT_GROUND );
	ptPosG = hit.ptHit;

	// draw building image to back buffer
	BUILD_draw2Back( prcCut, 0, ptPosG );

	// draw border indicate can build or not
	// calc points
	MAP_TestRegionBuild( 0, ptPosG, BUILD_nCode, BUILD_bLocation, BUILD_nLocationNum[BUILD_nSize] );
	// draw
	BUILD_drawBorders( prcCut, 0, ptPosG );
}

int BUILD_IfCan()
{
	if( !BUILD_bEnable )
	{
		OutputDebugString( "CBBuild BUILD_IfCan() Warning(1): test build result before set it!\n" );
		return FALSE;
	}
	
	for( int i=0; i<BUILD_nLocationNum[BUILD_nSize]; i++ )
	{
		if( BUILD_bLocation[i] != MAP_REGION_SUCCESS )
			return BUILD_bLocation[i];
	}
	return MAP_REGION_SUCCESS;
}
/////////////

⌨️ 快捷键说明

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