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

📄 mapinfo.cpp

📁 VC游戏编程基础
💻 CPP
📖 第 1 页 / 共 2 页
字号:

#include "global.h"
#include "mapinfo.h"

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
CMapInfo::CMapInfo() {
	m_bReversed = false;
	m_nBlocks	= 0;
	m_cxBlocks	= 0;
	m_cyBlocks	= 0;

	m_szFileName = NULL;
	m_ptBase	 = NULL;
	m_pBlocks	 = NULL;
	m_pTankInfo	 = NULL;

}


//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
CMapInfo::~CMapInfo() {
	DestroyMap();
}


//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
void CMapInfo::DestroyMap() {
	//DELETE_PTR( m_szFileName );		// Undefined error here
	//DELETE_ARRAY( m_ptBase );
	//DELETE_ARRAY( m_pBlocks );
	//DELETE_ARRAY( m_pTankInfo );
}


//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
bool CMapInfo::LoadMap( const char *filename ) {
	if ( !filename )
		return false;

	DestroyMap();
	m_szFileName = new char[strlen(filename)+1];
	strcpy( m_szFileName, filename );

	HANDLE			hfile;
	DWORD			read, ret;
	FILEHEADER		header;
	
	// Open exist file
	hfile = CreateFile( m_szFileName, GENERIC_READ,
						0, NULL, OPEN_EXISTING,
						FILE_ATTRIBUTE_NORMAL, NULL );
	if ( hfile == INVALID_HANDLE_VALUE ) 
		goto err_quit_loadmap;
	
	// Read file header and test if the file format is legal
	read = sizeof(FILEHEADER);
	if ( !ReadFile( hfile, (LPVOID)&header, read, &ret, NULL ) ) 
		goto err_quit_loadmap;

	if ( header.dwFileID != GAME_MAP_FILE_IDENTITY ||
		header.dwVersion != GAME_MAP_VER_1_2_0 ) 
		goto err_quit_loadmap;

	// Read base possitions
	m_ptBase = new POINT[2];
	read = sizeof(POINT) * 2;
	if ( !ReadFile( hfile, (LPVOID)m_ptBase, read, &ret , NULL ) )  
		goto err_quit_loadmap;

	// Read tanks' original infomation settings
	m_pTankInfo = new TANKINFO[20];
	if ( !m_pTankInfo )  
		goto err_quit_loadmap;

	read = sizeof(TANKINFO)*20;
	if( !ReadFile( hfile, (LPVOID)m_pTankInfo, read, &ret, NULL ) )  
		goto err_quit_loadmap;

	// Read block infomations
	m_nBlocks = header.nBlocks;
	m_cxBlocks = DEFAULT_CX_BLOCKS;
	m_cyBlocks = DEFAULT_CY_BLOCKS;

	m_pBlocks = new BLOCK[m_nBlocks];
	if ( !m_pBlocks ) 
		goto err_quit_loadmap;

	read = sizeof(BLOCK) * m_nBlocks;
	ZeroMemory( m_pBlocks, read );
	if( !ReadFile( hfile, (LPVOID)m_pBlocks, read, &ret, NULL ) ) 
		goto err_quit_loadmap;

	// Close file handle
	CloseHandle(hfile);

	// Need to be added in further version of map
	m_uiTankNum = 20;

	return true;

	// False return
err_quit_loadmap:

	CloseHandle(hfile);
	DestroyMap();
	m_nBlocks  = 0;
	m_cxBlocks = 0;
	m_cyBlocks = 0;
	return false;
}


//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
void CMapInfo::SetReversed( bool flag ) {
	if ( m_bReversed != flag && CenterRotate180() )
		m_bReversed = flag;
}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
void CMapInfo::ConvertCoord( CObject * pobj ) {
	pobj->SetPos( g_FrameLeft - pobj->GetLeft(), g_FrameLeft - pobj->GetTop() );
}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
void CMapInfo::Protect( RECT rt, bool flag, POINT *ppts, int &changed ) {
	int x, y;
	int xend = rt.left/32+1, yend = rt.top/32+1;
	int total = 0;

	for ( y = yend-2; y <= yend; y++ )  {
		if ( y < 0 || y > m_cyBlocks-2)
			continue;
		for ( x = xend-2; x <= xend; x++ ) {
			if ( x < 0 || x > m_cxBlocks-2)
				continue;
			if ( total < changed ) {
				if ( flag )
					(m_pBlocks+y*m_cyBlocks+x)->byClass = LAND_IRON;
				else
					(m_pBlocks+y*m_cyBlocks+x)->byClass = LAND_BRICK;
				ppts[total].x = x;
				ppts[total].y = y;
				total++;
			}
		}
	}
	changed = total;
}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
bool CMapInfo::CenterRotate180() {
	if ( !(HorReverseMap() && VerReverseMap()) )
		return false;

	// Reverse base position too
	if ( m_ptBase ) {
		m_ptBase[0].x = (m_cxBlocks-2)*32-m_ptBase[0].x;
		m_ptBase[0].y = (m_cyBlocks-2)*32-m_ptBase[0].y;
		m_ptBase[1].x = (m_cxBlocks-2)*32-m_ptBase[1].x;
		m_ptBase[1].y = (m_cyBlocks-2)*32-m_ptBase[1].y;
	}
	return true;
}


//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
bool CMapInfo::HorReverseMap() {
	if ( !m_pBlocks || m_cxBlocks == 0)
		return false;

	int			i,j,half,opp;
	BLOCK		block;

	half = (m_cxBlocks-1)/2;			// Divide to two pars, left and right
	for(j=0; j<m_cyBlocks-1; j++) {
		for(i=0; i<half; i++) {
			// exchange b[j][i] and b[j][19-i]
			opp = m_cxBlocks-2-i;
			HorReverseBlock(i,j);
			HorReverseBlock(opp,j);
			block = *(m_pBlocks+j*m_cyBlocks+i);
			*(m_pBlocks+j*m_cyBlocks+i) = *(m_pBlocks+j*m_cyBlocks+opp);
			*(m_pBlocks+j*m_cyBlocks+opp) = block;
		}
	}
	return true;
}


//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
bool CMapInfo::VerReverseMap() {
	if ( !m_pBlocks || m_cyBlocks == 0)
		return false;

	int			i,j,half,opp;
	BLOCK		block;

	half = (m_cyBlocks-1)/2;			// Divide to two parts, up and down
	for(i=0; i<m_cxBlocks-1; i++)	{
		for(j=0; j<half; j++) {
			// exchange b[j][i] and b[19-j][i]
			opp = m_cyBlocks-2-j;
			VerReverseBlock( i, j );
			VerReverseBlock( i, opp );
			block = *( m_pBlocks + j*m_cyBlocks + i);
			*( m_pBlocks + j*m_cyBlocks+i ) = *( m_pBlocks + opp*m_cyBlocks+i );
			*( m_pBlocks+ opp*m_cyBlocks+i ) = block;
		}
	}

	return true;
}


//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
void CMapInfo::HorReverseBlock( int x, int y ) {
	BYTE	b1,b2,b3,b4,obs;

	obs = (m_pBlocks+y*m_cyBlocks+x)->byObstacle;

	if(obs != 0 && obs != 0x0f) {
		b1 = obs & 0x01;
		b2 = obs & 0x02;
		b3 = obs & 0x04;
		b4 = obs & 0x08;
		(m_pBlocks+y*m_cyBlocks+x)->byObstacle = (b1<<3) +
			(b2<<1) + (b3>>1) + (b4>>3);
	}
}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
void CMapInfo::VerReverseBlock( int x, int y ) {
	BYTE	b1,b2,b3,b4,obs;

	obs = (m_pBlocks+y*m_cyBlocks+x)->byObstacle;

	if(obs != 0 && obs != 0x0f)	{
		b1 = obs & 0x01;
		b2 = obs & 0x02;
		b3 = obs & 0x04;
		b4 = obs & 0x08;
		(m_pBlocks+y*m_cyBlocks+x)->byObstacle = (b1<<1) + 
			(b2>>1) + (b3<<1) + (b4>>1);
	}
}
//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
int	CMapInfo::BlockCounter( DWORD land, CObjBlock *pobb ) {
	int		counter = 0;
	BLOCK	*pblk;
	for ( int i=0; i<m_cyBlocks-1; i++ )
		for ( int j=0; j<m_cxBlocks-1; j++ ) {
			pblk = m_pBlocks+i*m_cxBlocks+j;
			if ( pblk->byClass == land ) {
				if ( pobb ) {
					pobb[counter].CreateObjBlock( j, i, land );
					pobb[counter].SetTotalFrame( 3 );
				}
				counter++;
			}
		}
	return counter;
}


//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
bool CMapInfo::BlockLocator( int x, int y, RECT *prc, int &level ) {
	BLOCK	*pblock = m_pBlocks + x + y*m_cxBlocks;
	DWORD	dwLocType; 

	level = LAYER_GROUND;
	switch(pblock->byClass)
	{
	case LAND_BRICK:
		dwLocType = LOC_BLOCK_BRICK0;
		break;
	case LAND_IRON:	
		dwLocType = LOC_BLOCK_IRON0;
		break;
	case LAND_RIVER:
		dwLocType = LOC_BLOCK_RIVER0;
		break;		
	case LAND_GRASS:
		dwLocType = LOC_BLOCK_GRASS0;
		level = LAYER_TREE;
		break;
	case LAND_ICE:
		dwLocType = LOC_BLOCK_ICE0;
		break;
	case LAND_NONE:
	default:		
		dwLocType = LOC_BLOCK_NONE;
	}

	int		*pres = &ResArray[dwLocType][0];
	prc->left = pblock->byObstacle * (*(pres+RESSIZE_WIDTH)) + (*(pres+RESPOS_LEFT));
	prc->top  = *(pres+RESPOS_TOP);
	prc->right  = prc->left + (*(pres+RESSIZE_WIDTH));
	prc->bottom = prc->top + (*(pres+RESSIZE_HEIGHT));

	return true;
}



//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
bool CMapInfo::ObjectLocator( CObject *pobj, RECT *prc, int &level ) {
	DWORD	type = pobj->GetType();

	if ( type == OBJTYPE_TANK ) {
		prc->top  = RES_POST_TANK;
		prc->left = RES_POSL_TANK;
		prc->left +=  ((CObjTank *)pobj)->m_uiDirection - 1;
		prc->left  *= g_FrameSmall;
		prc->top   *= g_FrameSmall;
		level = LAYER_TANK;
	} else if ( type == OBJTYPE_BULLET ) {
		prc->top  = 128;
		prc->left = pobj->GetFrameCurrent() * g_FrameSmall;
		level = LAYER_BULLET;
	} else if ( type == OBJTYPE_BASE ) {
		prc->top  = RES_POST_BASE;
		prc->left = RES_POSL_BASE;
	}

	prc->right  = prc->left + pobj->GetWidth();
	prc->bottom = prc->top + pobj->GetHeight();

	return true;
}


//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
bool CMapInfo::ObjBlockLocator( CObjBlock *poblk, RECT *prc, int &level ) {
	if ( poblk->GetLand() == LAND_RIVER ) {
		BLOCK	*pblock = m_pBlocks + poblk->GetBx() + 
							poblk->GetBy()*m_cxBlocks;
		prc->left = pblock->byObstacle + RES_POSL_LAND;
		prc->top = RES_POST_LAND_RIVER + poblk->GetFrameCurrent();
		prc->left  *= g_FrameSmall;
		prc->top   *= g_FrameSmall;
		prc->right  = prc->left + g_FrameSmall;
		prc->bottom = prc->top + g_FrameSmall;
		level = LAYER_GROUND;
	}
	return true;
}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
bool CMapInfo::ColR2R( RECT &rt_move, RECT rt_stable, POINT step ) {
	bool	intersect = false;

	SetRect( &rt_move, rt_move.left - rt_stable.right, rt_move.top - rt_stable.bottom,
			rt_move.right - rt_stable.left, rt_move.bottom - rt_stable.top );
	
	while ( rt_move.left * rt_move.right < 0  && rt_move.top * rt_move.bottom < 0 ) {
		intersect = true;
		if ( step.x != 0 ) {
			rt_move.left -= step.x;
			rt_move.right -= step.x;
		} else if ( step.y != 0 ) {
			rt_move.top -= step.y;
			rt_move.bottom -= step.y;
		} else
			break;
	}
	
	rt_move.left += rt_stable.right;
	rt_move.top += rt_stable.bottom;
	rt_move.right += rt_stable.left;
	rt_move.bottom += rt_stable.top;

⌨️ 快捷键说明

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