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

📄 trigger.cpp

📁 [游戏开发参考书-用DirectX编写RPG游戏]这是一个系列的丛书如果你都看并且懂的话你就可以你工作啦!
💻 CPP
字号:
#include "Core_Global.h"
#include "Trigger.h"

cTrigger::cTrigger()
{
  m_NumTriggers = 0;
  m_TriggerParent = NULL;
}

cTrigger::~cTrigger()
{
  Free();
}

long cTrigger::GetNextLong(FILE *fp)
{
  char Buf[1024];
  long Pos = 0;
  int c;

  // Read until EOF or EOL
  while(1) {
    if((c = fgetc(fp)) == EOF)
      break;
    if(c == 0x0a || (c == ' ' && Pos))
      break;
    if((c >= '0' && c <= '9') || c == '.' || c == '-')
      Buf[Pos++] = c;
  }
  if(!Pos)
    return -1;
  Buf[Pos] = 0;

  return atol(Buf);
}

float cTrigger::GetNextFloat(FILE *fp)
{
  char Buf[1024];
  long Pos = 0;
  int c;

  // Read until EOF or EOL
  while(1) {
    if((c = fgetc(fp)) == EOF)
      break;
    if(c == 0x0a || (c == ' ' && Pos))
      break;
    if((c >= '0' && c <= '9') || c == '.' || c == '-')
      Buf[Pos++] = c;
  }
  Buf[Pos] = 0;

  return (float)atof(Buf);
}

BOOL cTrigger::Load(char *Filename)
{
  FILE *fp;
  long Type, ID;
  BOOL Enabled;
  float x1, y1, z1, x2, y2, z2, x3, z3, Radius;
  
  // Remove all current triggers
  Free();

  // Open file
  if((fp=fopen(Filename, "rb"))==NULL)
    return FALSE;

  // Start looping, reading in until EOF reached
  while(1) {
    // Get ID of trigger
    if((ID = GetNextLong(fp)) == -1)
      break;

    // Get type
    Type = GetNextLong(fp);

    // Get enabled status
    Enabled = (GetNextLong(fp)) ? TRUE : FALSE;

    // Read in rest depending on type
    switch(Type) {
      case Trigger_Sphere:
        x1 = GetNextFloat(fp);
        y1 = GetNextFloat(fp);
        z1 = GetNextFloat(fp);
        Radius = GetNextFloat(fp);
        AddSphere(ID, Enabled, x1, y1, z1, Radius);
        break;
      
      case Trigger_Box:
        x1 = GetNextFloat(fp);
        y1 = GetNextFloat(fp);
        z1 = GetNextFloat(fp);
        x2 = GetNextFloat(fp);
        y2 = GetNextFloat(fp);
        z2 = GetNextFloat(fp);
        AddBox(ID, Enabled, x1, y1, z1, x2, y2, z2);
        break;
      
      case Trigger_Cylinder:
        x1 = GetNextFloat(fp);
        y1 = GetNextFloat(fp);
        z1 = GetNextFloat(fp);
        Radius = GetNextFloat(fp);
        y2 = GetNextFloat(fp);
        AddCylinder(ID, Enabled, x1, y1, z1, Radius, y2);
        break;
      
      case Trigger_Triangle:
        x1 = GetNextFloat(fp);
        z1 = GetNextFloat(fp);
        x2 = GetNextFloat(fp);
        z2 = GetNextFloat(fp);
        x3 = GetNextFloat(fp);
        z3 = GetNextFloat(fp);
        y1 = GetNextFloat(fp);
        y2 = GetNextFloat(fp);
        AddTriangle(ID, Enabled, x1, z1, x2, z2, x3, z3, y1, y2);
        break;

      default: fclose(fp);    // Some error occurred
               Free();
               return FALSE;
    }
  }

  fclose(fp);

  return (m_NumTriggers) ? TRUE : FALSE;
}

BOOL cTrigger::Save(char *Filename)
{
  FILE *fp;
  sTrigger *TriggerPtr;

  if(!m_NumTriggers)
    return FALSE;
  if((TriggerPtr = m_TriggerParent) == NULL)
    return FALSE;
  
  // Open file
  if((fp=fopen(Filename, "wb"))==NULL)
    return FALSE;

  // Write out all triggers
  while(TriggerPtr != NULL) {
    // Write out ID and Type of trigger
    fprintf(fp, "%lu ", TriggerPtr->ID);
    fprintf(fp, "%lu ", TriggerPtr->Type);

    // Write out Enabled flag
    fprintf(fp, "%lu ", (TriggerPtr->Enabled) ? 1 : 0);

    // Write out remaining data depending on type
    switch(TriggerPtr->Type) {
      case Trigger_Sphere:
        fprintf(fp, "%lf %lf %lf %lf\r\n", 
                TriggerPtr->x1, TriggerPtr->y1, TriggerPtr->z1, 
                TriggerPtr->Radius);
        break;
      
      case Trigger_Box:
        fprintf(fp, "%lf %lf %lf %lf %lf %lf\r\n", 
                TriggerPtr->x1, TriggerPtr->y1, TriggerPtr->z1, 
                TriggerPtr->x2, TriggerPtr->y2, TriggerPtr->z2);
        break;
      
      case Trigger_Cylinder:
        fprintf(fp, "%lf %lf %lf %lf %lf\r\n", 
                TriggerPtr->x1, TriggerPtr->y1, TriggerPtr->z1, 
                TriggerPtr->Radius, TriggerPtr->y2);
        break;
      
      case Trigger_Triangle:
        fprintf(fp, "%lf %lf %lf %lf %lf %lf %lf %lf\r\n", 
                TriggerPtr->x1, TriggerPtr->z1, 
                TriggerPtr->x2, TriggerPtr->z2, 
                TriggerPtr->x3, TriggerPtr->z3, 
                TriggerPtr->y1, TriggerPtr->y2);
        break;
    }
  }

  fclose(fp);

  return TRUE;
}

sTrigger *cTrigger::AddTrigger(long Type, long ID, BOOL Enabled)
{
  // Allocate a new trigger structure and link in
  sTrigger *Trigger = new sTrigger();
  Trigger->Prev = NULL;
  if((Trigger->Next = m_TriggerParent) != NULL)
    m_TriggerParent->Prev = Trigger;
  m_TriggerParent = Trigger;

  // Set trigger Type, ID, and Enabled flag
  Trigger->Type = Type;
  Trigger->ID = ID;
  Trigger->Enabled = Enabled;

  // Increase trigger count
  m_NumTriggers++;

  return Trigger;
}

BOOL cTrigger::AddSphere(long ID, BOOL Enabled,               \
                         float XPos, float YPos, float ZPos,  \
                         float Radius)
{
  // Create a new trigger structure and link in 
  sTrigger *Trigger = AddTrigger(Trigger_Sphere, ID, Enabled);

  // Setup trigger data
  Trigger->x1 = XPos;
  Trigger->y1 = YPos;
  Trigger->z1 = ZPos;
  Trigger->Radius = Radius * Radius;

  return TRUE;
}

BOOL cTrigger::AddBox(long ID, BOOL Enabled,                  \
                      float XMin, float YMin, float ZMin,     \
                      float XMax, float YMax, float ZMax)
{
  // Create a new trigger structure and link in 
  sTrigger *Trigger = AddTrigger(Trigger_Box, ID, Enabled);

  // Setup trigger data (fix for min/max values)
  Trigger->x1 = min(XMin, XMax);
  Trigger->y1 = min(YMin, YMax);
  Trigger->z1 = min(ZMin, ZMax);
  Trigger->x2 = max(XMin, XMax);
  Trigger->y2 = max(YMin, YMax);
  Trigger->z2 = max(ZMin, ZMax);

  return TRUE;
}
BOOL cTrigger::AddCylinder(long ID, BOOL Enabled,             \
                       float XPos, float YPos, float ZPos,    \
                       float Radius, float Height)
{
  // Create a new trigger structure and link in 
  sTrigger *Trigger = AddTrigger(Trigger_Cylinder, ID, Enabled);

  // Setup trigger data
  Trigger->x1     = XPos;
  Trigger->y1     = YPos;
  Trigger->z1     = ZPos;
  Trigger->Radius = Radius * Radius;
  Trigger->y2     = Height;

  return TRUE;
}

BOOL cTrigger::AddTriangle(long ID, BOOL Enabled,             \
                           float x1, float z1,                \
                           float x2, float z2,                \
                           float x3, float z3,                \
                           float YPos, float Height)
{
  // Create a new trigger structure and link in 
  sTrigger *Trigger = AddTrigger(Trigger_Triangle, ID, Enabled);

  // Setup trigger data
  Trigger->x1 = x1;
  Trigger->z1 = z1;
  Trigger->x2 = x2;
  Trigger->z2 = z2;
  Trigger->x3 = x3;
  Trigger->z3 = z3;
  Trigger->y1 = YPos;
  Trigger->y2 = Height;

  return TRUE;
}

BOOL cTrigger::Remove(long ID)
{
  sTrigger *TriggerPtr, *NextTrigger;
  long Count = 0;

  // Scan through list of triggers
  if((TriggerPtr = m_TriggerParent) != NULL) {
    while(TriggerPtr != NULL) {

      // Remember which is next
      NextTrigger = TriggerPtr->Next;

      // Matched?
      if(TriggerPtr->ID == ID) {

        // Remove from list 
        if(TriggerPtr->Prev != NULL)
          TriggerPtr->Prev->Next = TriggerPtr->Next;
        else
          m_TriggerParent = TriggerPtr->Next;
        if(TriggerPtr->Next != NULL)
          TriggerPtr->Next->Prev = TriggerPtr->Prev;

        // Release memory
        TriggerPtr->Next = NULL;
        delete TriggerPtr;

        // Decrease number of triggers and increase # removed
        m_NumTriggers--;
        Count++;
      }

      // Go to next trigger
      TriggerPtr = NextTrigger;
    }
  }

  // Return TRUE if any found and removed
  return (Count) ? TRUE : FALSE;
}

BOOL cTrigger::Free()
{
  delete m_TriggerParent;
  m_TriggerParent = NULL;
  m_NumTriggers = 0;

  return TRUE;
}

long cTrigger::GetTrigger(float XPos, float YPos, float ZPos)
{
  float XDiff, YDiff, ZDiff, Dist;
  D3DXVECTOR2 vecNorm;
  sTrigger *Trigger;

  // Scan through list of triggers
  if((Trigger = m_TriggerParent) != NULL) {
    while(Trigger != NULL) {

      // Only bother if enabled
      if(Trigger->Enabled == TRUE) {

        // Check based on type
        switch(Trigger->Type) {
          case Trigger_Sphere:
            // Check distance from sphere (using radius)
            XDiff = (float)fabs(Trigger->x1 - XPos);
            YDiff = (float)fabs(Trigger->y1 - YPos);
            ZDiff = (float)fabs(Trigger->z1 - ZPos);
            Dist = XDiff*XDiff+YDiff*YDiff+ZDiff*ZDiff;
            if(Dist <= Trigger->Radius)
              return Trigger->ID;
            break;
    
          case Trigger_Box:
            // Check if inside box
            if(XPos >= Trigger->x1 && XPos <= Trigger->x2) {
              if(YPos >= Trigger->y1 && YPos <= Trigger->y2) {
                if(ZPos >= Trigger->z1 && ZPos <= Trigger->z2)
                  return Trigger->ID;
              }
            }
            break;

          case Trigger_Cylinder:
            // First make sure within height bounds
            if(YPos >= Trigger->y1 &&                         \
               YPos <= Trigger->y1 + Trigger->y2) {
              // Check distance from cylinder
              XDiff = (float)fabs(Trigger->x1 - XPos);
              YDiff = (float)fabs(Trigger->y1 - YPos);
              ZDiff = (float)fabs(Trigger->z1 - ZPos);
              Dist = XDiff*XDiff+YDiff*YDiff+ZDiff*ZDiff;
              if(Dist <= Trigger->Radius)
                return Trigger->ID;
            }
            break;

          case Trigger_Triangle:
            // First make sure within height bounds
            if(YPos >= Trigger->y1 &&                         \
               YPos <= Trigger->y1 + Trigger->y2) {
            
              // Check if point in front of all lines

              // x1,z1 to x2,z2
              D3DXVec2Normalize(&vecNorm,                     \
                     &D3DXVECTOR2(Trigger->z2 - Trigger->z1,  \
                                  Trigger->x1 - Trigger->x2));
              if(D3DXVec2Dot(&D3DXVECTOR2(XPos-Trigger->x1,   \
                                          ZPos-Trigger->z1),  \
                                          &vecNorm) < 0)
                break;

              // x2,z2 to x3,z3
              D3DXVec2Normalize(&vecNorm,                     \
                     &D3DXVECTOR2(Trigger->z3 - Trigger->z2,  \
                                  Trigger->x2 - Trigger->x3));
              if(D3DXVec2Dot(&D3DXVECTOR2(XPos-Trigger->x2,   \
                                          ZPos-Trigger->z2),  \
                                          &vecNorm) < 0)
                break;

              // x3,z3 to x1,z1
              D3DXVec2Normalize(&vecNorm,                     \
                     &D3DXVECTOR2(Trigger->z1 - Trigger->z3,  \
                                  Trigger->x3 - Trigger->x1));
              if(D3DXVec2Dot(&D3DXVECTOR2(XPos-Trigger->x3,   \
                                          ZPos-Trigger->z3),  \
                                          &vecNorm) < 0)
                break;

              return Trigger->ID;
            }
            break;
        }
      }

      // Go to next trigger
      Trigger = Trigger->Next;
    }
  }

  return 0; // 0 means no trigger found
}

BOOL cTrigger::GetEnableState(long ID)
{
  sTrigger *TriggerPtr;

  // Loop through all triggers looking for ID
  if((TriggerPtr = m_TriggerParent) != NULL) {
    while(TriggerPtr != NULL) {

      // If matched ID then set return state
      if(TriggerPtr->ID == ID)
        return TriggerPtr->Enabled;

      // Go to next flag
      TriggerPtr = TriggerPtr->Next;
    }
  }

  // Return FALSE for none found
  return FALSE;
}

BOOL cTrigger::Enable(long ID, BOOL Enable)
{
  sTrigger *TriggerPtr;
  long Count = 0;

  // Loop through all triggers looking for ID
  if((TriggerPtr = m_TriggerParent) != NULL) {
    while(TriggerPtr != NULL) {

      // If matched ID then set flag and increase count
      if(TriggerPtr->ID == ID) {
        TriggerPtr->Enabled = Enable;
        Count++;
      }

      // Go to next flag
      TriggerPtr = TriggerPtr->Next;
    }
  }

  // Return TRUE if any triggers changed
  return (Count) ? TRUE : FALSE;
}

long cTrigger::GetNumTriggers()
{
  return m_NumTriggers;
}

sTrigger *cTrigger::GetParentTrigger()
{
  return m_TriggerParent;
}

⌨️ 快捷键说明

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