コード例 #1
0
void FlameCreator::Create(Game& game) {
  MapPtr map = game.GetMap();
  const Position pos = m_position;   // center (left,bottom point) of the fire/flame/blast/whatever
  double length_up(0), length_left(0), length_down(0), length_right(0);  // length of flame in four directions
  const size_t fireRange = GetRange();

  // determine how long can flame become because of map obstacles
  for (size_t i=1; i<=fireRange; ++i) {
    if (map->IsFieldStandable(pos.x,pos.y+i))
      length_up++;
    else
      break;
  }
  for (size_t i=1; i<=fireRange; ++i) {
    if (map->IsFieldStandable(pos.x,pos.y-i))
      length_down++;
    else
      break;
  }
  for (size_t i=1; i<=fireRange; ++i) {
    if (map->IsFieldStandable(pos.x+i,pos.y))
      length_right++;
    else
      break;
  }
  for (size_t i=1; i<=fireRange; ++i) {
    if (map->IsFieldStandable(pos.x-i,pos.y))
      length_left++;
    else
      break;
  }

  /* Computations below u change at your own risk. Be sure u know what is going on here.
     All length_* are computed the same way, so I describe only length_right variable.
     What we want to do is to decrease length_right by a small value, when
     length_right==fireRange - we dont want it to collide with field that is on flame's
     right side, so we make it a bit smaller.

     sizeFactor & positionOffset are used to center flames (including center flame). Why?
     Because then their's aabbs become centered. We *assume* that field's size is (1.0,1.0).
   */

  length_right += (length_right==fireRange) ? -.01 : 0;
  length_left += (length_left==fireRange) ? -.01 : 0;
  length_down += (length_down==fireRange) ? -.01 : 0;
  length_up += (length_up==fireRange) ? -.01 : 0;

  // we need to rescale width & height of flames' lengths
  const double sizeFactor = .99;
  const double positionOffset = (1-sizeFactor)/2.0;
  
  const double flameWidth = (1.0/g_tiles_on_screen_in_x) * sizeFactor;
  const double flameHeight = (1.0/g_tiles_on_screen_in_y) * sizeFactor;
  const double up = length_up/static_cast<double>(g_tiles_on_screen_in_y);
  const double down = length_down/static_cast<double>(g_tiles_on_screen_in_y);
  const double left = length_left/static_cast<double>(g_tiles_on_screen_in_x);
  const double right = length_right/static_cast<double>(g_tiles_on_screen_in_x);

  game.AddObject(FlamePtr(new Flame(pos+Position(1+positionOffset, 0+positionOffset),
                                    Size(right,flameHeight), FD::Right)));         // right arm
  game.AddObject(FlamePtr(new Flame(pos+Position(0+positionOffset, 1+positionOffset),
                                    Size(flameWidth,up), FD::Up)));                // top arm
  game.AddObject(FlamePtr(new Flame(pos-Position(length_left,0-positionOffset),
                                    Size(left,flameHeight), FD::Left)));  // left arm
  game.AddObject(FlamePtr(new Flame(pos-Position(0-positionOffset,length_down),
                                    Size(flameWidth,down), FD::Down)));   // bottom arm
  game.AddObject(FlamePtr(new Flame(pos+Position(positionOffset, positionOffset),
                                    Size(flameWidth,flameHeight), FD::Center)));
}