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

📄 game.cpp

📁 <B>DirectX9.0 3D游戏编程</B>
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	 */
	cNM_LoginRequest req( m_localPlayerName );
	SendToServerR( req );

	DebPrint("[InitClient]: Finished initializing");
}


void cGameApp::ClientFrame( float timeDelta )
{
	/**
	 * Any messages from the server?	if so process them.
	 */
	char			data[ MAX_UDPBUFFERSIZE ];
	HOSTHANDLE		srcHostID;
	cDataExtract	extract;
	unsigned short	amnt;

	/**
	 * Reliable messages new include logins, new disconnects,
	 * votes, chat messages, name/model changes,
	 * Chat messages, votes, name changes, spawns, deaths...
	 * We're not supporting all those options, but feel free to add them.
	 */
	while( ( amnt = m_comm.GetReliableData( data, MAX_UDPBUFFERSIZE, &srcHostID ) ) != 0 )
	{
		extract.SetBuffer( data, amnt * 8 );

		cNetMessage* pMsg = cNetMessageMaker::ConstructMessage( 
			(uchar*)extract.GetBuffer(), 
			extract.GetBufferLengthInBytes() );

		pMsg->SetFrom( srcHostID );

		pMsg->Exec();

		delete pMsg;

	}
	/**
	 * Unreliable messages are pretty much updates and that's it.
	 */
	while( ( amnt = m_comm.GetUnreliableData( data, MAX_UDPBUFFERSIZE, &srcHostID ) ) != 0 )
	{
		extract.SetBuffer( data, amnt * 8 );

		cNetMessage* pMsg = cNetMessageMaker::ConstructMessage( 
			(uchar*)extract.GetBuffer(), 
			extract.GetBufferLengthInBytes() );

		pMsg->SetFrom( srcHostID );

		pMsg->Exec();

		delete pMsg;
	}

	/**
	 * In here is where we should get input.
	 */
	HandleInput();

	/**
	 * Send our movement for this frame out on the wire.
	 */
	if( 
		m_pPlayer && 
		m_pPlayer->GetStatus() == gesAlive && 
		m_bInputTaken )
	{
		// Send the desired state to the server
		cNM_MiniStateChangeRequest msg( 
			m_pPlayer->GetID(), 
			m_desiredState );

		SendToServerUR( msg );

		m_bInputTaken = false;
	}

	/**
	 * Run a mortis check (kill any mortisable objects)
	 */
	m_pWorld->EntIterStart();
	while( !m_pWorld->EntIterDone() )
	{
		MortisCheck( m_pWorld->EntIterCurr() );
		m_pWorld->EntIterNext();
	}


	Sleep( 10 );

	

}

void cGameApp::DrawConsole()
{
	int nLines = m_console.size();
	for( int i=0; i<nLines; i++ )
	{
		Graphics()->DrawTextString( 
			1, 1+16 * i, D3DCOLOR_XRGB( 255, 0, 0), 
			m_console[i].c_str() );
	}
	for( i=0; i<nLines; i++ )
	{
		Graphics()->DrawTextString( 
			0, 16 * i, D3DCOLOR_XRGB( 255, 255, 255), 
			m_console[i].c_str() );
	}
		
}

void cGameApp::RenderFrame( float timeDelta )
{

	// Keep this static to try to keep memory problems at bay.
	static vector< cGameCell* > cellList;
	cellList.reserve( m_pWorld->m_nCells );
	cellList.clear();

	Graphics()->BeginScene();

	if( !m_bConnected )
	{
		Graphics()->Clear( true, true, 0, 1.f );

		DrawConsole();
		Graphics()->DrawTextString( 0, 160, D3DCOLOR_XRGB( 255, 0, 0), "Connecting to server..." );

		Graphics()->Flip();
		Sleep(100);
	}
	else
	{

		if( m_pPlayer->GetStatus() != gesUnSpawned )
		{
			// We can just use the yaw and pitch values.
			m_pPlayer->SetYaw( m_desiredState.m_yaw );
			m_pPlayer->SetPitch( m_desiredState.m_pitch );

			m_pPlayer->RebuildMatrix();
			matrix4 playerMat = m_pPlayer->GetMatrix();

			matrix4 viewMat;
			viewMat.ToInverse( playerMat );
			Graphics()->SetViewMatrix( viewMat );
			Graphics()->Clear( true, true, D3DCOLOR_XRGB( 255, 0, 0 ), 1.0f );
			

			// Generate a frustum for the camera, and use it to do a portal walk.

			// Some info about our rendering...
			char renderInfo[256];

			/**
			 * See if we can find the parent cell of the player
			 */
			sMsg msg( msgFindContainingCell, g_gameWorldID, 0 );
			msg.m_pt = m_pPlayer->GetLoc();
			int parentCell = MsgDaemon()->DeliverMessage( msg );

			if( -1 != parentCell )
			{
				// We found a valid cell.  Use it to do a portal walk.
				matrix4 viewMat = matrix4::Inverse( m_pPlayer->GetMatrix() );
				
				cViewCone cone( 
					PI/3, 
					Graphics()->Width(), 
					Graphics()->Height(), 
					viewMat );

				cGameCell* pCameraCell = (cGameCell*)MsgDaemon()->Get( 
					parentCell 
					);

				pCameraCell->PortalWalk( &cellList, cone );

				sprintf( renderInfo, "%d cells traversed", cellList.size() );
			}
			else
			{
				// We aren't in the bounds of a cell.  Draw
				// everything.
				sprintf( renderInfo, "Portal walk not performed" );
				m_pWorld->TraverseAll( &cellList );
			}

			// Draw all cells in the list
			for_each(
				cellList.begin(),
				cellList.end(),
				ptr_fun(DrawCell) );
			cellList.clear();

			Graphics()->GetDevice()->SetRenderState( D3DRS_LIGHTING, TRUE );
			InitLights();

			// Draw all of the objects
			m_pWorld->EntIterStart();
			while( !m_pWorld->EntIterDone() )
			{
				DrawEnt( m_pWorld->EntIterCurr() );
				m_pWorld->EntIterNext();
			}
			Graphics()->GetDevice()->SetRenderState( D3DRS_LIGHTING, FALSE );
			
			if( m_bDrawScoreboard )
			{
				DrawScoreBoard();
			}
			else
			{
				DrawConsole();
			}

			Graphics()->DrawTextString( 0, 180, D3DCOLOR_XRGB( 0, 0, 255), renderInfo );
		}
		else if( m_pPlayer->GetStatus() == gesUnSpawned )
		{
			Graphics()->Clear( true, true, 0, 1.f );

			DrawConsole();
			Graphics()->DrawTextString( 0, 160, D3DCOLOR_XRGB( 0, 0, 255), "Press Fire key to spawn" );
		}
		else
		{
			Graphics()->Clear( true, true, 0, 1.f );

			DrawConsole();
			Graphics()->DrawTextString( 0, 160, D3DCOLOR_XRGB( 0, 0, 255), "Connected to server..." );
		}
		
		
		
	}

	Graphics()->EndScene();
	Graphics()->Flip();
}


void cGameApp::AddTextLine( const char* text )
{
	// Take the top line off
	m_console.pop_front();

	// Insert the line on the bottom
	m_console.push_back( string( text ) );
}


uint cGameApp::ProcMsg( const sMsg& msg )
{
	cNetMessage* pMsg;

	switch( msg.m_type )
	{

	case msgPrintString:
		assert( msg.m_pData );
		AddTextLine( (const char*)msg.m_pData );
		return 0;

	case msgPlayerCreated:
		{
			int pID = msg.m_i[0];
			m_bConnected = true;
			m_pPlayer = (cGamePlayerEnt*)MsgDaemon()->Get(pID);

			// Don't forget to init the global id
			g_pPlayerID = pID;
		}
		return 0;

	case msgSendToServerR:
		pMsg = (cNetMessage*)msg.m_pData;
		SendToServerR( *pMsg );
		return 0;

	case msgSendToServerUR:
		pMsg = (cNetMessage*)msg.m_pData;
		SendToServerUR( *pMsg );
		return 0;

	case msgGetServerTime:
		return m_comm.GetClock().GetTime();

	default:
		DP0("Bad Message got to cGame\n");
		return -1;
	}
}
////////////////////////////////////////////////////////////////////////////////

void cGameApp::ParseCmdLine( char *cmdLine )
{
	if( cmdLine == NULL )
		return;

	m_localPlayerName = string("Unnamed player");

	// Set up some of our options
	m_bInverseMouse = false;

	// Now scan it for game-related options
	char	pLclCmdLine[ 1024 ], *pTok;

	strcpy( pLclCmdLine, cmdLine );
	pTok = strtok( pLclCmdLine, " " );

	if( !pTok ) return;

	do
	{
		if( strcmp( pTok, "-client" ) == 0 )
		{
			// Grab the sever address
			pTok = strtok( NULL, " " );
			m_IPAddress = string( pTok );

			// Check the IP for correctness.
			if( strchr( m_IPAddress.c_str(), '.' ) == 0 )
				throw cGameError( "[cGameApp::ParseCmdLine]: Invalid IP address specified." );
		}

		else if( strcmp( pTok, "-name" ) == 0 )
		{
			pTok = strtok( NULL, " " );
			m_localPlayerName = string( pTok );
		}

		else if( strcmp( pTok, "-imouse" ) == 0 )
		{
			m_bInverseMouse = true;
		}

		else if( strcmp( pTok, "-noTex" ) == 0 )
		{
			g_useTextures = 0;
		}

	} while( pTok = strtok( NULL, " " ) );


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


// Timeout between weapon shots (in milliseconds)
const DWORD c_weapTimeout = 1500; 

void cGameApp::MakeFireRequest()
{
	// Don't fire if we're not alive
	if( m_pPlayer->GetStatus() != gesAlive )
	{
		return;
	}

	// First attempt should succeed.
	static DWORD lastFire = timeGetTime() - c_weapTimeout;

	DWORD currTime = timeGetTime();

	if( lastFire + c_weapTimeout > currTime )
	{
		// Not enough time has elapsed.
		return;
	}

	// Reset the last fire time, since we're firing now.
	lastFire = currTime;

	// Play the fire sound.
	cSoundWrapper *pSoundWrap = (cSoundWrapper*)Resources()->Get( 202 );
	pSoundWrap->Play();

	cNM_ProjFireRequest msg( m_pPlayer->GetID() );
	SendToServerUR( msg );
	
}

////////////////////////////////////////////////////////////////////////////////

void cGameApp::SendToServerR( cNetMessage& nMsg )
{
	uchar buff[MAX_UDPBUFFERSIZE];
	int len = nMsg.SerializeTo( buff );

	m_comm.ReliableSendTo( 
		(char*)buff,
		len,
		m_serverHost );
}

void cGameApp::SendToServerUR( cNetMessage& nMsg )
{
	uchar buff[MAX_UDPBUFFERSIZE];
	int len = nMsg.SerializeTo( buff );

	m_comm.UnreliableSendTo( 
		(char*)buff,
		len,
		m_serverHost );
}


void cGameApp::HandleInput()
{
	if( m_pPlayer )
		m_desiredState = m_pPlayer->GetState();

	/**
	 * Reset our deltas
	 */
	m_deltaYaw = 0;
	m_deltaPitch = 0;
	m_deltaLoc = point3::Zero;

	m_bInputTaken = false;

	/**
	 * Get input
	 */
	if( Input() )
		Input()->UpdateDevices();

	/**
	 * If we got input, activate the input flag
	 */
	if( m_deltaYaw != 0 ||
		m_deltaPitch != 0 ||
		!(m_deltaLoc == point3::Zero) )
	{
		m_bInputTaken = true;

		Snap( m_deltaPitch, (-PI/2)+EPSILON, (PI/2)-EPSILON );

		m_desiredState.m_yaw += m_deltaYaw;
		m_desiredState.m_pitch += m_deltaPitch;
		m_desiredState.m_vel = m_deltaLoc;
	}

}

bool PlayerCmp( cGamePlayerEnt* pA, cGamePlayerEnt* pB )
{
	// pA preceeds pB if the score is higher.
	if( pA->GetScore() > pB->GetScore() )
		return true;
	return false;
}

void cGameApp::DrawScoreBoard()
{
	// Get the list of players.
	vector< cGamePlayerEnt* > players;
	m_pWorld->ListPlayers( &players );

	// Sort the list
	sort( players.begin(), players.end(), PlayerCmp );

	// Display the list
	int nPlayers = players.size();

	int i;
	for( i=0; i<nPlayers; i++ )
	{
		Graphics()->DrawTextString( 
			21, 21+16 * i, D3DCOLOR_XRGB( 0, 0, 255), 
			players[i]->GetName().c_str() );

		Graphics()->DrawTextString( 
			20, 20+16*i, D3DCOLOR_XRGB( 0, 0, 255), 
			players[i]->GetName().c_str() );

		char buff[20];
		sprintf( buff, "%d", players[i]->GetScore() );

		Graphics()->DrawTextString( 
			201, 21+16 * i, D3DCOLOR_XRGB( 0, 0, 255), 
			buff );
		Graphics()->DrawTextString( 
			200, 20+16 * i, D3DCOLOR_XRGB( 0, 0, 255), 
			buff );
	}
}

⌨️ 快捷键说明

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