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

📄 chars.cpp

📁 [游戏开发参考书-用DirectX编写RPG游戏]这是一个系列的丛书如果你都看并且懂的话你就可以你工作啦!
💻 CPP
📖 第 1 页 / 共 5 页
字号:
            if(ToProcess == TRUE)
              Item(CharPtr, CharPtr,                          \
                   CharPtr->ItemNum, CharPtr->CharItem);
            break;

          case CHAR_DIE:
            Death(CharPtr->Attacker, CharPtr);
            DeadChar = TRUE;   // Mark character as dead
            ToProcess = FALSE; // Don't allow updates
            break;
        }
      }

      // Clear movement
      XMove = YMove = ZMove = 0.0f;

      // Only continue if allowed (in case character died)
      if(ToProcess == TRUE) {

        // Only allow updates if lock/timer not in use 
        if(CharPtr->Enabled == TRUE &&                        \
           !CharPtr->ActionTimer &&                           \
           CharPtr->Locked == FALSE) {

          // Reset action
          CharPtr->Action = CHAR_IDLE;

          // Get movement
          if(CharPtr->Type == CHAR_PC)
            PCUpdate(CharPtr, Elapsed, &XMove, &YMove, &ZMove);
          else
            CharUpdate(CharPtr, Elapsed, &XMove,&YMove,&ZMove);

          // Check for validity of movement (clear if invalid)
          if(CheckMove(CharPtr,&XMove,&YMove,&ZMove)==FALSE) {
            XMove = YMove = ZMove = 0.0f;
            CharPtr->Action = CHAR_IDLE;
          }
        }

        // Process movement of character
        ProcessUpdate(CharPtr, XMove, YMove, ZMove);

        // Increase action charge of character
        CharPtr->Charge += ((float)Elapsed / 1000.0f *        \
                                   GetCharge(CharPtr));
        if(CharPtr->Charge > 100.0f)
          CharPtr->Charge = 100.0f;
      }

      // Process timed ailments (only on live characters)
      if(DeadChar == FALSE && CharPtr->Ailments) {

        // Sleeping characters have 4% to wake up
        if(CharPtr->Ailments & AILMENT_SLEEP && (rand()%100)<4)
          CharPtr->Ailments &= ~AILMENT_SLEEP;

        // Paralyzed character have 2% chance to recover
        if(CharPtr->Ailments & AILMENT_PARALYZE &&            \
                                           (rand() % 100) < 2)
            CharPtr->Ailments &= ~AILMENT_PARALYZE;

        // Posion removes 2 hp every 2 seconds
        if(CharPtr->Ailments & AILMENT_POISON &&              \
                              EffectCounter >= 4000) {
          CharPtr->HealthPoints -= 2;
          SetMessage(CharPtr, "Poison -2 HP", 500,            \
                  D3DCOLOR_RGBA(0,255,64,255));
        }
      }
    }

    // Go to next character
    CharPtr = NextChar;
  }

  // Reset effect counter (after 4 seconds)
  if(EffectCounter >= 4000) 
    EffectCounter = 0;

  return TRUE;
}

BOOL cCharacterController::Render(                            \
               long       Elapsed,                            \
               cFrustum  *Frustum,                            \
               float      ZDistance)
{
  cFrustum     ViewFrustum;  // Local viewing frustum
  float        Radius;       // Bounding radius
  sCharacter  *CharPtr; 
  DWORD        Time;

  // Variables for printing messages
  BOOL         GotMatrices = FALSE;
  D3DXMATRIX   matWorld, matView, matProj;
  D3DXVECTOR3  vecPos;
  D3DVIEWPORT8 vpScreen;
  float        MaxY;         // Height of character

  // Error checking
  if(m_Graphics == NULL)
    return FALSE;

  // Return success if no character to draw
  if((CharPtr = m_CharacterParent) == NULL)
    return TRUE;

  // Construct the viewing frustum (if none passed)
  if((m_Frustum = Frustum) == NULL) {
    ViewFrustum.Construct(m_Graphics, ZDistance);
    m_Frustum = &ViewFrustum;
  }

  // Get time to update animations (30fps) if
  // elapsed value passed == -1
  if(Elapsed == -1)
    Time = timeGetTime() / 30;
 
  // Loop through each character and draw
  while(CharPtr != NULL) {
    // Update animation based on elapsed time passed
    if(Elapsed != -1) {
      CharPtr->LastAnimTime += (Elapsed/30);
      Time = CharPtr->LastAnimTime;
    }

    CharPtr->Object.GetBounds(NULL,NULL,NULL,                 \
                              NULL,&MaxY,NULL,&Radius);

    // Draw character if in viewing frustum
    if(m_Frustum->CheckSphere(CharPtr->Object.GetXPos(),      \
                              CharPtr->Object.GetYPos(),      \
                              CharPtr->Object.GetZPos(),      \
                              Radius) == TRUE) {
      CharPtr->Object.UpdateAnimation(Time, TRUE);
      CharPtr->Object.Render();

      // Draw character's weapon
      if(CharPtr->Def.Weapon != -1)
        CharPtr->WeaponObject.Render();

      // Draw message if needed
      if(CharPtr->MessageTimer > 0) {

        // Get the matrices and viewport if not done already
        if(GotMatrices == FALSE) {
          GotMatrices = TRUE;

          // Get the world, projection, and view transformations
          D3DXMatrixIdentity(&matWorld);
          m_Graphics->GetDeviceCOM()->GetTransform(           \
                                  D3DTS_VIEW, &matView);
          m_Graphics->GetDeviceCOM()->GetTransform(           \
                                  D3DTS_PROJECTION, &matProj);

          // Get viewport
          m_Graphics->GetDeviceCOM()->GetViewport(&vpScreen);
        }

        // Project coordinates to screen  
        D3DXVec3Project(&vecPos,                              \
                  &D3DXVECTOR3(CharPtr->XPos,                 \
                               CharPtr->YPos+(MaxY*0.5f),     \
                               CharPtr->ZPos),                \
                  &vpScreen, &matProj, &matView, &matWorld);

        // Print message
        m_Font->Print(CharPtr->Message,                       \
                      (long)vecPos.x, (long)vecPos.y,         \
                      0, 0, CharPtr->MessageColor);
      }
    }

    // go to next character    
    CharPtr = CharPtr->Next;
  }

  return TRUE;
}

float cCharacterController::GetXZRadius(sCharacter *Character)
{
  float MinX, MaxX, MinZ, MaxZ;
  float x, z;

  // Error checking
  if(Character == NULL)
    return 0.0f;

  Character->Object.GetBounds(&MinX, NULL, &MinZ,             \
                              &MaxX, NULL, &MaxZ, NULL);
  x = (float)max(fabs(MinX), fabs(MaxX));
  z = (float)max(fabs(MinZ), fabs(MaxZ));

  return max(x, z);
}

///////////////////////////////////////////////////////////
// Set/Get Functions
///////////////////////////////////////////////////////////
sCharacter *cCharacterController::GetParentCharacter()
{
  return m_CharacterParent;
}

sCharacter *cCharacterController::GetCharacter(long IDNum)
{
  sCharacter *CharPtr;

  // Scan through all characters
  if((CharPtr = m_CharacterParent) != NULL) {
    while(CharPtr != NULL) {
    
      // Return character
      if(IDNum == CharPtr->ID)
        return CharPtr;
   
      // Go to next character
      CharPtr = CharPtr->Next;
    }
  }

  return NULL;
}

float cCharacterController::GetSpeed(sCharacter *Character)
{
  float Speed;
  
  // Error checking
  if(Character == NULL)
    return 0.0f;

  // Calculate adjusted speed
  Speed = Character->Def.Speed;

  if(Character->Ailments & AILMENT_SLOW)
    Speed *= 0.5f;
  if(Character->Ailments & AILMENT_FAST)
    Speed *= 1.5f;

  // Bounds check value
  if(Speed < 1.0f)
    Speed = 1.0f;

  return Speed;
}

long cCharacterController::GetAttack(sCharacter *Character)
{
  long Attack;
  
  // Error checking
  if(Character == NULL)
    return 0;

  // Calculate adjusted attack
  Attack = Character->Def.Attack;

  // Adjust attack based on item value (in %(Value/100)+1)
  if(Character->Def.Weapon != -1 && m_MIL != NULL) {
    Attack = (long)((float)Attack *                           \
             (((float)m_MIL[Character->Def.Weapon].Value /    \
             100.0f) + 1.0f));
  }

  if(Character->Ailments & AILMENT_WEAK)
    Attack = (long)((float)Attack * 0.5f);
  if(Character->Ailments & AILMENT_STRONG)
    Attack = (long)((float)Attack * 1.5f);

  return Attack;
}

long cCharacterController::GetDefense(sCharacter *Character)
{
  long Defense;
  
  // Error checking
  if(Character == NULL)
    return 0;

  // Calculate adjusted defense
  Defense = Character->Def.Defense;
  
  if(Character->Def.Armor != -1 && m_MIL != NULL)
    Defense = (long)((float)Defense *                         \
             (((float)m_MIL[Character->Def.Armor].Value /     \
             100.0f) + 1.0f));

  if(Character->Def.Shield != -1 && m_MIL != NULL)
    Defense = (long)((float)Defense *                         \
             (((float)m_MIL[Character->Def.Shield].Value /    \
             100.0f) + 1.0f));

  if(Character->Ailments & AILMENT_WEAK)
    Defense = (long)((float)Defense * 0.5f);
  if(Character->Ailments & AILMENT_STRONG)
    Defense = (long)((float)Defense * 1.5f);

  // Bounds check value
  if(Defense < 0)
    Defense = 0;

  return Defense;
}

long cCharacterController::GetAgility(sCharacter *Character)
{
  long Agility;
  
  // Error checking
  if(Character == NULL)
    return 0;

  // Calculate adjusted agility
  Agility = Character->Def.Agility;
  
  if(Character->Ailments & AILMENT_CLUMSY)
    Agility = (long)((float)Agility * 0.75f);
  if(Character->Ailments & AILMENT_SUREFOOTED)
    Agility = (long)((float)Agility * 1.5f);

  return Agility;
}

long cCharacterController::GetResistance(sCharacter *Character)
{
  long Resistance;
  
  // Error checking
  if(Character == NULL)
    return 0;

  // Calculate adjusted resistance
  Resistance = Character->Def.Resistance;
  
  if(Character->Ailments & AILMENT_ENCHANTED)
    Resistance = (long)((float)Resistance * 0.5f);
  if(Character->Ailments & AILMENT_BARRIER)
    Resistance = (long)((float)Resistance * 1.5f);

  return Resistance;
}

long cCharacterController::GetMental(sCharacter *Character)
{
  long Mental;
  
  // Error checking
  if(Character == NULL)
    return 0;

  // Calculate adjusted mental
  Mental = Character->Def.Mental;
  
  if(Character->Ailments & AILMENT_DUMBFOUNDED)
    Mental = (long)((float)Mental * 0.5f);

  return Mental;
}

long cCharacterController::GetToHit(sCharacter *Character)
{
  long ToHit;
  
  // Error checking
  if(Character == NULL)
    return 0;

  // Calculate adjusted to hit
  ToHit = Character->Def.ToHit;
  
  if(Character->Ailments & AILMENT_BLIND)
    ToHit = (long)((float)ToHit * 0.75f);
  if(Character->Ailments & AILMENT_HAWKEYE)
    ToHit = (long)((float)ToHit * 1.5f);

  return ToHit;
}

float cCharacterController::GetCharge(sCharacter *Character)
{
  float Charge;
  
  // Error checking
  if(Character == NULL)
    return 0;

  // Calculate adjusted charge
  Charge = Character->Def.ChargeRate;
  
  if(Character->Ailments & AILMENT_SLOW)
    Charge = Charge * 0.75f;
  if(Character->Ailments & AILMENT_FAST)
    Charge = Charge * 1.5f;

  return Charge;
}

cCharICS *cCharacterController::GetICS(long IDNum)
{
  sCharacter *CharPtr;

  if((CharPtr = GetCharacter(IDNum)) == NULL)
    return NULL;
  return CharPtr->CharICS;
}

BOOL cCharacterController::SetLock(long IDNum, BOOL State)
{
  sCharacter *CharPtr;

  // Get pointer to character
  if((CharPtr = GetCharacter(IDNum)) == NULL)
    return FALSE;

  // Set new value
  CharPtr->Locked = State;
  return TRUE;
}

BOOL cCharacterController::SetActionTimer(long IDNum, long Timer)
{
  sCharacter *CharPtr;

  // Get pointer to character
  if((CharPtr = GetCharacter(IDNum)) == NULL)
    return FALSE;

  // Set new value
  CharPtr->ActionTimer = Timer;
  return TRUE;
}

BOOL cCharacterController::SetAction(sCharacter *Character,   \

⌨️ 快捷键说明

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