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

📄 ch18p2_particleemitter.cpp

📁 游戏开发特殊技巧-special.effects.game.programming
💻 CPP
📖 第 1 页 / 共 2 页
字号:

void CParticleEmitter::WriteProperty(FILE *file, const char *strName, D3DXCOLOR &value)
{
  fprintf(file, "%s=(%.4f, %.4f, %.4f, %.4f)\n", strName, value.r, value.g, value.b, value.a);
}

void CParticleEmitter::WriteProperty(FILE *file, const char *strName, D3DXVECTOR3 &value)
{
  fprintf(file, "%s=(%.4f, %.4f, %.4f)\n", strName, value.x, value.y, value.z);
}

void CParticleEmitter::WriteProperty(FILE *file, const char *strName, CMinMax<float> &value)
{
  fprintf(file, "%s=(%.4f, %.4f)\n", strName, value.m_Min, value.m_Max);
}

void CParticleEmitter::WriteProperty(FILE *file, const char *strName, int value)
{
  fprintf(file, "%s=%d\n", strName, value);
}

void CParticleEmitter::WriteProperty(FILE *file, const char *strName, const char *value)
{
  fprintf(file, "%s=%s\n", strName, value);
}

void CParticleEmitter::WriteBlendModeProperty(FILE *file, const char *strName, int value)
{
  for (int q=0; q < NUMBLENDINGMODES; q++) {
    if (m_BlendingModes[q].mode == value) {
      fprintf(file, "%s=%s\n", strName, m_BlendingModes[q].name);
      return;
    }
  }
  throw("Invalid Blending Mode.");
}

void CParticleEmitter::GetRightSideFromValueMap(std::map<std::string, std::string> &valuemap, 
                                   const char *strName, char *dest, int destsize)
{
  std::string str;
  if (valuemap.find(strName) == valuemap.end()) { 
    std::string errorstr;
    errorstr = std::string("Missing property \"") + std::string(strName) + std::string("\"!");
    throw(errorstr);
  }
  strncpy(dest, valuemap[strName].c_str(), destsize);
}

void CParticleEmitter::ReadProperty(std::map<std::string, std::string> &valuemap, 
                                   const char *strName, D3DXCOLOR &value)
{
  char buf[256]; char token[256]; float r,g,b,a;

  GetRightSideFromValueMap(valuemap, strName, buf, sizeof(buf));

  // color is in the form (R,G,B,A)
  PluckFirstField(buf, token, sizeof(token), "("); // skip first (
  PluckFirstField(buf, token, sizeof(token), ","); r = atof(token);
  PluckFirstField(buf, token, sizeof(token), ","); g = atof(token);
  PluckFirstField(buf, token, sizeof(token), ","); b = atof(token);
  PluckFirstField(buf, token, sizeof(token), ")"); a = atof(token);

  value = D3DXCOLOR(r,g,b,a);
}

void CParticleEmitter::ReadProperty(std::map<std::string, std::string> &valuemap, 
                                   const char *strName, D3DXVECTOR3 &value)
{
  char buf[256]; char token[256]; float x,y,z;

  GetRightSideFromValueMap(valuemap, strName, buf, sizeof(buf));

  // vector is in the form (x,y,z)
  PluckFirstField(buf, token, sizeof(token), "("); // skip first (
  PluckFirstField(buf, token, sizeof(token), ","); x = atof(token);
  PluckFirstField(buf, token, sizeof(token), ","); y = atof(token);
  PluckFirstField(buf, token, sizeof(token), ")"); z = atof(token);

  value = D3DXVECTOR3(x,y,z);
}

void CParticleEmitter::ReadProperty(std::map<std::string, std::string> &valuemap, 
                                   const char *strName, CMinMax<float> &value)
{
  char buf[256]; char token[256]; float minvalue,maxvalue;

  GetRightSideFromValueMap(valuemap, strName, buf, sizeof(buf));

  // minmax is in the form (min,max)
  PluckFirstField(buf, token, sizeof(token), "("); // skip first (
  PluckFirstField(buf, token, sizeof(token), ","); minvalue = atof(token);
  PluckFirstField(buf, token, sizeof(token), ")"); maxvalue = atof(token);

  value = CMinMax<float>(minvalue,maxvalue);
}

void CParticleEmitter::ReadProperty(std::map<std::string, std::string> &valuemap, 
                                   const char *strName, int &value)
{
  char buf[256];
  GetRightSideFromValueMap(valuemap, strName, buf, sizeof(buf));
  value = atoi(buf);
}

void CParticleEmitter::ReadProperty(std::map<std::string, std::string> &valuemap, 
                                   const char *strName, std::string &value)
{
  char buf[256];
  GetRightSideFromValueMap(valuemap, strName, buf, sizeof(buf));
  value = buf;
}

void CParticleEmitter::ReadBlendModeProperty(std::map<std::string, std::string> &valuemap, 
                                            const char *strName, int &value)
{
  char buf[256];
  GetRightSideFromValueMap(valuemap, strName, buf, sizeof(buf));
  
  for (int q=0; q < NUMBLENDINGMODES; q++) {
    if (!stricmp(m_BlendingModes[q].name, buf)) {
      value = m_BlendingModes[q].mode;
      return;
    }
  }
  throw("Invalid Blending Mode.");
}

bool CParticleEmitter::Save(const char *strFilename)
{
  try {
    FILE *file = fopen(strFilename, "wt");

    fprintf(file, "[ParticleSystem 1.00]\n");

    WriteProperty(file, "Position", m_vPos);
    WriteProperty(file, "Gravity", m_vGravity);
    WriteProperty(file, "SpawnDir1", m_vSpawnDir1);
    WriteProperty(file, "SpawnDir2", m_vSpawnDir2);

    WriteProperty(file, "StartColor1", m_StartColor1);
    WriteProperty(file, "StartColor2", m_StartColor2);
    WriteProperty(file, "EndColor1", m_EndColor1);
    WriteProperty(file, "EndColor2", m_EndColor2);

    WriteProperty(file, "EmitRate", m_fEmitRate);
    WriteProperty(file, "EmitRadius", m_vEmitRadius);
    WriteProperty(file, "Lifetime", m_fLifetime);
    WriteProperty(file, "Size", m_fSize);

    WriteBlendModeProperty(file, "SrcBlend", m_iSrcBlendMode);
    WriteBlendModeProperty(file, "DestBlend", m_iDestBlendMode);

    WriteProperty(file, "MaxParticles", m_iMaxParticles);
    WriteProperty(file, "Texture", m_strTexFilename.c_str());


    fclose(file);
  }
  catch(std::string e) {
    m_strLastError = e;
    return(false);
  }
  catch(...) {
    m_strLastError = "Unknown error.";
    return(false);
  }

  return(true);
}

bool CParticleEmitter::Load(const char *strFilename)
{
  FILE *file = fopen(strFilename, "rt");
  if (file == NULL) { throw("Can't open file! (invalid filename?)"); }
  try {
    char buf[256];
    char leftside[256];
    char rightside[256];
    std::map<std::string, std::string> valuemap;

    // read first line - should be [ParticleSystem 1.00]
    fgets(buf, sizeof(buf), file);
    if (strstr(buf, "[ParticleSystem 1.00]") == NULL) {
      throw("Invalid Header (missing \"[ParticleSystem 1.00]\")");
    }
    
    // read the entire contents of file into a map.  If we read
    // more than 100 lines, we assume something's wrong and we
    // bail out.

    int count=0;
    while (!feof(file) && count < 1000) {
      // read a line
      fgets(buf, sizeof(buf), file);
      
      // if there's something on that line,
      if (strlen(buf) >= 2) {

        // seperate that line into left and right side of = sign
        memset(leftside, 0, sizeof(leftside));
        memset(rightside, 0, sizeof(rightside));

        PluckFirstField(buf, leftside, sizeof(leftside), "=");
        PluckFirstField(buf, rightside, sizeof(rightside), "\n");
      
        // make sure the stuff to the left of the = sign isn't currently
        // in the map (if it is, throw an error).
        if (valuemap.find(leftside) != valuemap.end()) {
          throw("Duplicate value encountered.");
        }

        // insert left and right sides into map.
        valuemap.insert(std::make_pair(std::string(leftside), std::string(rightside)));
      }

      // increment safety count
      count++;
    }

    if (count == 1000) {
      throw("File too big (most likely not a particle system file)");
    }

    ReadProperty(valuemap, "Position", m_vPos);
    ReadProperty(valuemap, "Gravity", m_vGravity);
    ReadProperty(valuemap, "SpawnDir1", m_vSpawnDir1);
    ReadProperty(valuemap, "SpawnDir2", m_vSpawnDir2);

    ReadProperty(valuemap, "StartColor1", m_StartColor1);
    ReadProperty(valuemap, "StartColor2", m_StartColor2);
    ReadProperty(valuemap, "EndColor1", m_EndColor1);
    ReadProperty(valuemap, "EndColor2", m_EndColor2);

    ReadProperty(valuemap, "EmitRate", m_fEmitRate);
    ReadProperty(valuemap, "EmitRadius", m_vEmitRadius);
    ReadProperty(valuemap, "Lifetime", m_fLifetime);
    ReadProperty(valuemap, "Size", m_fSize);

    ReadBlendModeProperty(valuemap, "SrcBlend", m_iSrcBlendMode);
    ReadBlendModeProperty(valuemap, "DestBlend", m_iDestBlendMode);

    ReadProperty(valuemap, "MaxParticles", m_iMaxParticles);
    ReadProperty(valuemap, "Texture", m_strTexFilename);

    fclose(file);
  }
  catch(const char *e) {
    fclose(file);
    m_strLastError = e;
    return(false);
  }
  catch(...) {
    fclose(file);
    m_strLastError = "Unknown error.";
    return(false);
  }

  return(true);
}
  

⌨️ 快捷键说明

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