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

📄 console.cpp

📁 Visual C++ 游戏开发与设计实例 源代码(所有)
💻 CPP
📖 第 1 页 / 共 3 页
字号:
			CloseHandle(hfile);
			hfile = NULL;
		}
	}
#endif

	return true;
}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
void ConsoleNet::CreateAICmd() {
	TANKCMD		*pcmd = m_pCmd+m_nLocal+1;
	for ( int i=0; i<DEFAINUM; i++ ) {
		if ( m_ppTanks[m_nLocal+1+i]->GetStat() & OBJSTAT_LIVE )	
			*(pcmd+i) = m_ppAiGen[i].Generator( NULL, 0 );
	}
}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
void ConsoleNet::GameMain() {
	static int		counter = 0;
	static DWORD	start_time = 0, last_get;
	static DWORD	frame_start = 0;
	DWORD			end_time;

	if ( m_dwStatus == CONSTAT_ENDGAME )
		return ;

	// Peek and process messages
	if ( !NetList.IsEmpty() ) 
		MsgProcessor( &NetList );

	// Waiting
	if ( m_dwStatus < CONSTAT_WAITMORE ) {
		// TODO: here we should set a time-out event,
		//		and display like this, " Now, connecting... "
		return ;
	} else if ( m_dwStatus == CONSTAT_WAITBEGIN ) {
		last_get = timeGetTime();
		return ;
	} else if ( m_dwStatus == CONSTAT_WAITPLAYER ) {
		if ( bFresh ) {
			cmdbuf = uiCurrentCmd;
			firebuf = bFired;
			bFresh = false;
		}
		if ( bRecvCmd ) {
			last_get = timeGetTime();
			m_dwStatus = CONSTAT_RUNNING;
		} else {
			end_time = timeGetTime();
			if( end_time - last_get > WAITTIMEOUT ) {
				// TODO: Record the lag
				// m_dwStatus = CONSTAT_WAITERROR;
				DebugOutput( 1, "Wait error!" );
				m_dwStatus = CONSTAT_WAITERROR;
			}
			return ;
		}
	}

	// FPS control, 1000/x in theory
	// x = 20, 30 fps
	while ( timeGetTime() - frame_start < 30 );
	frame_start = timeGetTime();
	
	// Running
	if ( m_dwStatus == CONSTAT_RUNNING ) {
		// Excute commands
		BulletsProc();		// 1- Excute bullets earlier than tanks	

#ifdef _DEBUG_CMDOUTPUT
		char	temp[4];
		DebugOutput( 1, "*****Last Get:*****" );
		for ( int i=0; i<DEFTANKNUM; i++ ) {
			itoa(m_pCmd[i].cmd,temp,10);
			DebugOutput( 2, temp, "\t" );
		}
		DebugOutput( 1, "\r\n" );
#endif
		TanksProc();		// 2- Excute tanks

		FoodProc();			// 3- Excute food

		// Exchange command messages
		m_pCmd[m_nLocal].cmd = cmdbuf;
		m_pCmd[m_nLocal].fire = firebuf;
		bFresh = true;

		CreateAICmd();

#ifdef _DEBUG_CMDOUTPUT
		DebugOutput( 1, "*****Generate:*****" );
		for ( int k=m_nLocal; k<m_nLocal+DEFAINUM+1; k++ ) {
			itoa(m_pCmd[k].cmd,temp,10);
			DebugOutput( 2, temp, "\t" );
		}
#endif
		SendCmdMsg( &m_pCmd[m_nLocal], DEFAINUM+1, m_nLocal );	// home-0, enemy-5
		
		// wait next message
		m_dwStatus = CONSTAT_WAITPLAYER;
		m_nMsgCounter = 0;
		ZeroMemory( m_pMsgFlag,sizeof(bool)*m_nPlayers);
		bRecvCmd = false;
	}

	// The app-window is not activated, skip refresh screen
	if ( !g_bActive ) 
		return ;

	// Animations, frame roller
	RollBlockObjects( m_pRiver, m_nNumRiver );
	
	// Redraw land layer
	Display.Clear(0);								// level ground
	Display.Blt(0,0,pMapSolid->GetDDrawSurface(), NULL, DDBLTFAST_SRCCOLORKEY);

	// objects layer
	BlitBullets( m_ppBullets, DEFTANKNUM );
	BlitTanks( m_ppTanks, DEFTANKNUM );
	BlitBases( m_ppBases, 2 );

	// Redraw grass layer, level trees
	Display.Blt(0,0,pMapGrass->GetDDrawSurface(), NULL, DDBLTFAST_SRCCOLORKEY);	
	BlitFood();

	// FPS display
	counter++;
	end_time = timeGetTime();
	if ( end_time - start_time >= 1000 ) {
		start_time = end_time;
		itoa( counter, fps+5, 10 );
		counter = 0;
	}
	pText->DrawText( NULL, "                ", 5, 5, RGB(0,0,0), RGB(0,0,0) );
	pText->DrawText( NULL, fps, 5, 5, RGB(0,0,0), RGB(255,0,0) );
	Display.Blt(0,0,pText->GetDDrawSurface(), NULL, 0);

	// Flip
	Display.Present();
}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
int ConsoleNet::BulletsProc() 
{
		RECT	rt_mobile;
		POINT	step, pt_block;
		DWORD	overland;

		int		hit_blt, hit_tk, hit_block, hit_base;
		POINT	ptChanged[4];

		for ( int i=0; i<DEFTANKNUM; i++ )
		{
			// Create bullet
			if ( m_pCmd[i].fire && !(m_ppTanks[i]->HaveBullet()) ) {
				m_ppBullets[i]->CreateBullet( m_ppTanks[i] );
				pFire->Play();
			}
			else if ( m_ppBullets[i]->GetStat() == OBJSTAT_CADAVER )
				continue;

			// Collision test
			if ( m_ppBullets[i]->GetStat() & OBJSTAT_LIVE )
			{
				// Set coltest parameters
				step = m_ppBullets[i]->GetDirectionUnit();
				rt_mobile = m_ppBullets[i]->GetNextRect();

				// Collistion test of bases
				MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppBases, 2, -1, 
					m_ppBullets[i]->m_uiTeamType, true, hit_base );
				
				// Collistion test of bullets
				MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppBullets, DEFTANKNUM, i,
					m_ppBullets[i]->m_uiTeamType, true, hit_blt );

				// Collistion test of bullets and tanks
				MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppTanks, DEFTANKNUM, i,
					m_ppBullets[i]->m_uiTeamType, true, hit_tk );
				pt_block.x = rt_mobile.left;
				pt_block.y = rt_mobile.top;

				// Collistion test of tanks and blocks
				overland = 0;
				hit_block = 4;					// don't need to remove blocks
				MapInfo.ColRToB( pt_block, WIDTH_16, step, COL_IRON, 
					overland, COL_BRICK, ptChanged, hit_block );

				// Reset and render map
				int		level;
				RECT	*prc = new RECT;
				for( int j=0; j<hit_block; j++ ) {
					MapInfo.BlockLocator( ptChanged[j].x, ptChanged[j].y, prc, level );
//					if ( level == LAYER_GROUND )
						pddsSolid->BltFast( ptChanged[j].x<<5, ptChanged[j].y<<5, pddsRes, prc, 0 );
//					else if ( level == LAYER_TREE ) 
//						pddsGrass->BltFast( ptChanged[i].x<<5, ptChanged[i].y<<5, pddsRes, prc, 0 );
				}

				// Boom and destroy
				m_ppBullets[i]->SetPos( pt_block.x, pt_block.y );
				if ( pt_block.x != rt_mobile.left || pt_block.y != rt_mobile.top ||
					hit_block > 0 ) {
					m_ppBullets[i]->NextStat();
				} else if ( hit_tk >= 0 ) {
					m_ppBullets[i]->Hit( m_ppTanks[hit_tk] );
				} else if ( hit_blt >= 0 ) {
					m_ppBullets[i]->Hit( m_ppBullets[hit_blt] );
				} else if ( hit_base >= 0 ) {
					if ( !( m_ppBases[hit_base]->m_ptyBlood.Minus( m_ppBullets[i]->GetAttack() ) ) )
						SendMsg( NETMSGTK_TEAMVICTORY, &hit_base, sizeof(int) );
					m_ppBullets[i]->NextStat();
					
				}	
			}
			else 
				m_ppBullets[i]->NextStat();
		}
	return 0;
}

//-----------------------------------------------------------------------------
// Name: 
// Desc: 
//-----------------------------------------------------------------------------
int ConsoleNet::TanksProc()
{
		RECT	rt_mobile;
		POINT	step, pt_block;
		int		hit_blt, hit_tk, hit_block, hit_base;
		DWORD	overland, blockland;
		bool	movetest;

		for ( int i=0; i<DEFTANKNUM; i++ ) 
		{
			if ( m_ppTanks[i]->GetStat() & OBJSTAT_CADAVER )
				continue;

			if ( m_ppTanks[i]->GetStat() & OBJSTAT_DIE ) {
				m_ppTanks[i]->NextStat();
				pBoom->Play();
				continue;
			}

			// Convert direction
			if ( m_ppTanks[i]->IsHomeTeam() ^ m_bHomeTeam ) 
				m_pCmd[i].cmd = 5 - m_pCmd[i].cmd;

			// Direction command to excute, 
			if ( m_ppTanks[i]->m_uiIceDir != DIR_NONE ) 	// still sliding
			{
				movetest = true;
				// 	if on ice, modify slide speed each time
				if ( m_pCmd[i].cmd > DIR_NONE && m_pCmd[i].cmd < DIR_MAX ) {
					// After all, reset main direction
					m_ppTanks[i]->m_uiDirection = m_pCmd[i].cmd;
					// Affect the speed by direction
					if ( m_ppTanks[i]->m_uiIceDir == m_pCmd[i].cmd ) {			// speed up
						if ( m_ppTanks[i]->m_nIceStep < MAXSPEEDONICE-2 )
							m_ppTanks[i]->m_nIceStep += 2;
						else
							m_ppTanks[i]->m_nIceStep = MAXSPEEDONICE;
					} else {
						if ( m_ppTanks[i]->m_uiIceDir == 5 - m_pCmd[i].cmd ) 	// opposite
							m_ppTanks[i]->m_nIceStep -= 4;
						else													// others, no effect
							m_ppTanks[i]->m_nIceStep -= 2;
						if ( m_ppTanks[i]->m_nIceStep <= 0 ) {
							movetest = false;
							m_ppTanks[i]->m_uiIceDir = DIR_NONE;
						}
					}
				} else {									// natural friction
					m_ppTanks[i]->m_nIceStep -= 2;
					if ( m_ppTanks[i]->m_nIceStep <= 0 ) {
						movetest = false;
						m_ppTanks[i]->m_uiIceDir = DIR_NONE;
					}
				}

				// Set coltest parameters
				step = m_ppTanks[i]->GetDirUnitOnIce();
				rt_mobile = m_ppTanks[i]->GetNextRectOnIce();
			}
			// Test command to see if it's none
			else if ( m_pCmd[i].cmd == DIR_NONE || m_pCmd[i].cmd == DIR_MAX )
				continue;
			else if ( m_ppTanks[i]->m_uiDirection == m_pCmd[i].cmd )		// move forward
			{
				// Set moving animation flag
				m_ppTanks[i]->m_bMoving = true;

				movetest = true;
				// Set coltest parameters
				step = m_ppTanks[i]->GetDirectionUnit();
				rt_mobile = m_ppTanks[i]->GetNextRect();
			} 
			else 															// just turn around
			{
				movetest = false;
				bool	dirtest = true;
				int		residue;

				// Count a integer step
				rt_mobile = m_ppTanks[i]->GetRect();
				step = m_ppTanks[i]->GetDirectionUnit();
				if ( step.y != 0 ) {								
					residue = m_ppTanks[i]->GetTop() % DEFTURNSTEP;
					if ( residue == 0 ) 
						dirtest = false;
					else if ( residue > DEFTURNSTEP/2 - IsHomeTeam()) {	// down
						residue = DEFTURNSTEP - residue;
						rt_mobile.top += residue;
						rt_mobile.bottom += residue;
					} else {								// up
						rt_mobile.top -= residue;
						rt_mobile.bottom -= residue;
					}
				} else if ( step.x != 0 ) {
					residue = m_ppTanks[i]->GetLeft() % DEFTURNSTEP;
					if ( residue == 0 ) 
						dirtest = false;
					else if ( residue > DEFTURNSTEP/2 - IsHomeTeam()) {	// right
						residue = DEFTURNSTEP - residue;
						rt_mobile.left += residue;
						rt_mobile.right += residue;
					} else {								// left
						rt_mobile.left -= residue;
						rt_mobile.right -= residue;
					}
				}
				// Test if it can move
				if ( dirtest ) {
					MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppTanks, DEFTANKNUM, i,
					m_ppTanks[i]->m_uiTeamType, false, hit_tk );
					if ( hit_tk < 0 )
						m_ppTanks[i]->SetPos( rt_mobile.left, rt_mobile.top );
				}
				// change direction
				m_ppTanks[i]->m_uiDirection = m_pCmd[i].cmd;		
			}

			// Move collision test
			if ( movetest ) {
				// Collistion test of bases
				MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppBases,
					2, -1, 0, false, hit_base );
				
				// Collistion test of bullets
				MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppBullets, DEFTANKNUM, i,
					m_ppTanks[i]->m_uiTeamType, true, hit_blt );

				// Collistion test of tanks
				MapInfo.ColRToMobile( rt_mobile, step, (CMobileObject **)m_ppTanks, DEFTANKNUM, i,
					m_ppTanks[i]->m_uiTeamType, false, hit_tk );

				// Collistion test of tanks and blocks
				pt_block.x = rt_mobile.left;
				pt_block.y = rt_mobile.top;
				overland = COL_ICE;
				blockland = COL_BRICK|COL_IRON;
				if ( !(m_ppTanks[i]->m_dwEquip & EQUIP_SHIP) )
					blockland |= COL_RIVER;
				hit_block = 0;					// don't need to remove blocks
				MapInfo.ColRToB( pt_block, WIDTH_32, step, blockland, 
					overland, 0, NULL, hit_block );

				// Set ice flag
				if ( overland & COL_ICE ) {
					m_ppTanks[i]->m_bOnIce = true;
					if ( m_ppTanks[i]->m_uiIceDir == DIR_NONE ) {
						m_ppTanks[i]->m_nIceStep = m_ppTanks[i]->GetStep();
						m_ppTanks[i]->m_uiIceDir = m_ppTanks[i]->m_uiDirection;
					}

⌨️ 快捷键说明

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