📄 winmain.cpp
字号:
///////////////////////////////////////////////////////////
void cApp::AssignID(sMessage *Msg)
{
sAssignPlayerIDMessage *apidm;
// Error checking
if(m_Players == NULL || m_Players[0].dpnidPlayer)
return;
// Get pointer to message data
apidm = (sAssignPlayerIDMessage*)Msg;
EnterCriticalSection(&m_UpdateCS);
m_Players[0].dpnidPlayer = apidm->Header.PlayerID;
LeaveCriticalSection(&m_UpdateCS);
}
void cApp::CreatePlayer(sMessage *Msg)
{
sCreatePlayerMessage *cpm;
long PlayerNum, i;
// Error checking
if(m_Players == NULL || !m_Players[0].dpnidPlayer)
return;
// Get pointer to message data
cpm = (sCreatePlayerMessage*)Msg;
// Don't add local player to list
if(cpm->Header.PlayerID == m_Players[0].dpnidPlayer)
return;
// Make sure player not already in list while at
// same time finding an empty slot.
PlayerNum = -1;
for(i=1;i<MAX_PLAYERS;i++) {
if(m_Players[i].Connected == TRUE) {
if(m_Players[i].dpnidPlayer==cpm->Header.PlayerID)
return;
} else
PlayerNum = i;
}
// Return error if no open slots
if(PlayerNum == -1)
return;
// Enter critical section
EnterCriticalSection(&m_UpdateCS);
// Add player data
m_Players[PlayerNum].Connected = TRUE;
m_Players[PlayerNum].dpnidPlayer = cpm->Header.PlayerID;
m_Players[PlayerNum].XPos = cpm->XPos;
m_Players[PlayerNum].YPos = cpm->YPos;
m_Players[PlayerNum].ZPos = cpm->ZPos;
m_Players[PlayerNum].Direction = cpm->Direction;
m_Players[PlayerNum].Speed = 0.0f;
m_Players[PlayerNum].State = STATE_IDLE;
m_NumPlayers++;
// Leave critical section
LeaveCriticalSection(&m_UpdateCS);
}
void cApp::DestroyPlayer(sMessage *Msg)
{
sDestroyPlayerMessage *dpm;
long PlayerNum;
// Error checking
if(m_Players == NULL || !m_Players[0].dpnidPlayer)
return;
// Get pointer to message data
dpm = (sDestroyPlayerMessage*)Msg;
// Don't remove local player from list
if(dpm->Header.PlayerID == m_Players[0].dpnidPlayer)
return;
// Get player number in list
if((PlayerNum = GetPlayerNum(dpm->Header.PlayerID)) == -1)
return;
// Enter critical section
EnterCriticalSection(&m_UpdateCS);
// Set player as disconnected
m_Players[PlayerNum].Connected = FALSE;
m_NumPlayers--;
// Leave critical section
LeaveCriticalSection(&m_UpdateCS);
}
void cApp::ChangeState(sMessage *Msg)
{
sStateChangeMessage *scm;
sRequestPlayerInfoMessage rpim;
long PlayerNum;
// Error checking
if(m_Players == NULL || !m_Players[0].dpnidPlayer)
return;
// Get pointer to message data
scm = (sStateChangeMessage*)Msg;
// Get player number in list
if((PlayerNum = GetPlayerNum(scm->Header.PlayerID)) == -1) {
// Unknown player - request info
if(PlayerNum == -1) {
// Construct message
rpim.Header.Type = MSG_PLAYER_INFO;
rpim.Header.Size = sizeof(sRequestPlayerInfoMessage);
rpim.Header.PlayerID = m_Players[0].dpnidPlayer;
rpim.PlayerID = scm->Header.PlayerID;
// Send message to server
SendNetworkMessage(&rpim, DPNSEND_NOLOOPBACK);
return;
}
}
// Enter critical section
EnterCriticalSection(&m_UpdateCS);
// Store new sytate info
m_Players[PlayerNum].Time = timeGetTime();
m_Players[PlayerNum].State = scm->State;
m_Players[PlayerNum].XPos = scm->XPos;
m_Players[PlayerNum].YPos = scm->YPos;
m_Players[PlayerNum].ZPos = scm->ZPos;
m_Players[PlayerNum].Direction = scm->Direction;
m_Players[PlayerNum].Speed = scm->Speed;
m_Players[PlayerNum].Latency = scm->Latency;
// Bounds latency to 1 second
if(m_Players[PlayerNum].Latency > 1000)
m_Players[PlayerNum].Latency = 1000;
// Adjust time based on latency
m_Players[PlayerNum].Time -= m_Players[PlayerNum].Latency;
// Leave critical section
LeaveCriticalSection(&m_UpdateCS);
}
///////////////////////////////////////////////////////////
// App initialization functions
///////////////////////////////////////////////////////////
BOOL cApp::SelectAdapter()
{
int Result;
// Hide main window
ShowWindow(GethWnd(), SW_HIDE);
// Build a list of network adapters
m_Adapters.Init();
// Open connection dialog
Result=DialogBox(GethInst(), MAKEINTRESOURCE(IDD_CONNECT), \
GethWnd(), ConnectDialogProc);
// Don't continue if quit selected
if(Result == FALSE)
return FALSE;
// Show main window
ShowWindow(GethWnd(), SW_SHOW);
// Continue if user selected OK
return TRUE;
}
BOOL cApp::InitializeGame()
{
long i;
// Initialize the graphics device and set display mode
m_Graphics.Init();
m_Graphics.SetMode(GethWnd(), TRUE, TRUE);
m_Graphics.SetPerspective(D3DX_PI/4, 1.3333f, 1.0f, 20000.0f);
ShowMouse(FALSE);
// Get a font
m_Font.Create(&m_Graphics, "Arial", 16);
// Initialize input and input devices
m_Input.Init(GethWnd(), GethInst());
m_Keyboard.Create(&m_Input, KEYBOARD);
m_Mouse.Create(&m_Input, MOUSE, TRUE);
// Load the mesh and create an NodeTree mesh from it
m_TerrainMesh.Load(&m_Graphics, "..\\Data\\Arena.x", \
"..\\Data\\");
m_NodeTreeMesh.Create(&m_Graphics, &m_TerrainMesh, QUADTREE);
// Load the meshes and animations
m_CharacterMesh.Load(&m_Graphics, "..\\Data\\Warrior.x", \
"..\\Data\\");
m_WeaponMesh.Load(&m_Graphics, "..\\Data\\Sword.x", "..\\Data\\");
m_CharacterAnim.Load("..\\Data\\Warrior.x", &m_CharacterMesh);
m_CharacterAnim.SetLoop(TRUE, "Walk");
m_CharacterAnim.SetLoop(TRUE, "Idle");
m_CharacterAnim.SetLoop(FALSE, "Swing");
m_CharacterAnim.SetLoop(FALSE, "Hurt");
// Set the camera angle
m_CamAngle = 0.0f;
// Create player structures
m_Players = new sPlayer[MAX_PLAYERS]();
// Setup player data
for(i=0;i<MAX_PLAYERS;i++) {
m_Players[i].Body.Create(&m_Graphics, &m_CharacterMesh);
m_Players[i].Weapon.Create(&m_Graphics, &m_WeaponMesh);
m_Players[i].Weapon.AttachToObject(&m_Players[i].Body, \
"Bip01_R_Finger11");
m_Players[i].Weapon.Rotate(1.57f, 0.0f, 0.0f);
}
// Setup local player structure
m_NumPlayers = 1;
m_Players[0].Connected = TRUE;
m_Players[0].Direction = 0.0f;
m_Players[0].XPos = 0.0f;
m_Players[0].YPos = 0.0f;
m_Players[0].ZPos = 0.0f;
m_Players[0].Speed = 512.0f;
m_Players[0].State = STATE_IDLE;
return TRUE;
}
BOOL cApp::JoinGame()
{
// Initialize network and try to connect to host
m_Client.Init();
if(m_Client.Connect(m_guidAdapter, m_HostIP, 9123, \
m_Name, "RPGGAME", NULL) == FALSE)
return FALSE;
return TRUE; // Return success
}
///////////////////////////////////////////////////////////
// Game logic code
///////////////////////////////////////////////////////////
void cApp::UpdatePlayers()
{
long i;
float XMove, ZMove, Dist, Speed;
long Elapsed;
// Process all active player movements
for(i=0;i<MAX_PLAYERS;i++) {
if(m_Players[i].Connected == TRUE) {
// Get elapsed time from now and state time
Elapsed = timeGetTime() - m_Players[i].Time;
// Process player movement state
if(m_Players[i].State == STATE_MOVE) {
// Calculate amount of movement by time movement processed
Speed = (float)Elapsed / 1000.0f * m_Players[i].Speed;
XMove = (float)sin(m_Players[i].Direction) * Speed;
ZMove = (float)cos(m_Players[i].Direction) * Speed;
// Check for movement collisions -
// can't walk past anything blocking path
if(m_NodeTreeMesh.CheckIntersect(
m_Players[i].XPos,
m_Players[i].YPos + 16.0f,
m_Players[i].ZPos,
m_Players[i].XPos + XMove,
m_Players[i].YPos + 16.0f,
m_Players[i].ZPos + ZMove,
&Dist) == TRUE)
XMove = ZMove = 0.0f;
// Update coordinates
EnterCriticalSection(&m_UpdateCS);
m_Players[i].XPos += XMove;
m_Players[i].YPos = 0.0f;
m_Players[i].ZPos += ZMove;
m_Players[i].Time = timeGetTime(); // Reset time
LeaveCriticalSection(&m_UpdateCS);
}
// Set new animations as needed
if(m_Players[i].State == STATE_IDLE) {
if(m_Players[i].LastAnim != ANIM_IDLE) {
EnterCriticalSection(&m_UpdateCS);
m_Players[i].LastAnim = ANIM_IDLE;
m_Players[i].Body.SetAnimation( \
&m_CharacterAnim, "Idle", timeGetTime() / 32);
LeaveCriticalSection(&m_UpdateCS);
}
} else
if(m_Players[i].State == STATE_MOVE) {
if(m_Players[i].LastAnim != ANIM_WALK) {
EnterCriticalSection(&m_UpdateCS);
m_Players[i].LastAnim = ANIM_WALK;
m_Players[i].Body.SetAnimation( \
&m_CharacterAnim, "Walk", timeGetTime() / 32);
LeaveCriticalSection(&m_UpdateCS);
}
} else
if(m_Players[i].State == STATE_SWING) {
if(m_Players[i].LastAnim != ANIM_SWING) {
EnterCriticalSection(&m_UpdateCS);
m_Players[i].LastAnim = ANIM_SWING;
m_Players[i].Body.SetAnimation( \
&m_CharacterAnim, "Swing", timeGetTime() / 32);
LeaveCriticalSection(&m_UpdateCS);
}
} else
if(m_Players[i].State == STATE_HURT) {
if(m_Players[i].LastAnim != ANIM_HURT) {
EnterCriticalSection(&m_UpdateCS);
m_Players[i].LastAnim = ANIM_HURT;
m_Players[i].Body.SetAnimation( \
&m_CharacterAnim, "Hurt", timeGetTime() / 32);
LeaveCriticalSection(&m_UpdateCS);
}
}
}
}
}
void cApp::RenderScene()
{
cFrustum Frustum;
float Radius;
long i;
// Center camera on player using CamAngle
m_Camera.Point(m_Players[0].XPos + \
(float)cos(m_CamAngle) * 300.0f, \
m_Players[0].YPos + 100.0f, \
m_Players[0].ZPos + \
(float)sin(m_CamAngle) * 300.0f, \
m_Players[0].XPos, \
m_Players[0].YPos, \
m_Players[0].ZPos);
// Set camera and construct frustum
m_Graphics.SetCamera(&m_Camera);
Frustum.Construct(&m_Graphics);
// Render scene
m_Graphics.Clear();
if(m_Graphics.BeginScene() == TRUE) {
// Draw the terrain
m_Graphics.EnableZBuffer(TRUE);
m_NodeTreeMesh.Render(&Frustum);
// Draw all characters active and in view
for(i=0;i<MAX_PLAYERS;i++) {
if(m_Players[i].Connected == TRUE) {
// Bounds check if player in view
m_Players[i].Body.GetBounds(NULL,NULL,NULL,NULL, \
NULL,NULL,&Radius);
if(Frustum.CheckSphere(m_Players[i].XPos, \
m_Players[i].YPos, \
m_Players[i].ZPos, \
Radius) == TRUE) {
// Position character and rotate
m_Players[i].Body.Move(m_Players[i].XPos, \
m_Players[i].YPos, \
m_Players[i].ZPos);
m_Players[i].Body.Rotate(0.0f, \
m_Players[i].Direction, \
0.0f);
// Render body and weapon
m_Players[i].Body.UpdateAnimation(timeGetTime()/32, \
TRUE);
m_Players[i].Body.Render();
m_Players[i].Weapon.Render();
}
}
}
m_Graphics.EndScene();
}
m_Graphics.Display(); // Display the scene
}
///////////////////////////////////////////////////////////
// Client class code
///////////////////////////////////////////////////////////
BOOL cClient::ConnectComplete(DPNMSG_CONNECT_COMPLETE *Msg)
{
// Save connection status
if(Msg->hResultCode == S_OK)
g_Connected = TRUE;
else
g_Connected = FALSE;
return TRUE;
}
BOOL cClient::Receive(DPNMSG_RECEIVE *Msg)
{
// Send message to application class instance (if any)
if(g_Application != NULL)
g_Application->Receive(Msg);
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -