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

📄 winmain.cpp

📁 programming Role-playing Games With Directx 源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
///////////////////////////////////////////////////////////
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 + -