void
Background::draw(DrawingContext& context)
{
  if(image.get() == NULL)
    return;
    
  int w = (int) image->get_width();
  int h = (int) image->get_height();
  int sx = int(pos.x-context.get_translation().x * speed) % w - w;
  int sy = int(pos.y-context.get_translation().y * speed_y) % h - h;
  int center_image_py = int(pos.y-context.get_translation().y * speed_y);
  int bottom_image_py = int(pos.y-context.get_translation().y * speed_y) + h;
  context.push_transform();
  context.set_translation(Vector(0, 0));
  for(int x = sx; x < SCREEN_WIDTH; x += w) {
    for(int y = sy; y < SCREEN_HEIGHT; y += h) {
      if (image_top.get() != NULL && (y < center_image_py)) {
        context.draw_surface(image_top.get(), Vector(x, y), layer);
        continue;
      } 
      if (image_bottom.get() != NULL && (y >= bottom_image_py)) {
        context.draw_surface(image_bottom.get(), Vector(x, y), layer);
        continue;
      }
      context.draw_surface(image.get(), Vector(x, y), layer);
    }
  }
  context.pop_transform();
}
Example #2
0
void
TileMap::draw(DrawingContext& context)
{
  // skip draw if current opacity is 0.0
  if (current_alpha == 0.0) return;

  context.push_transform();
  if(draw_target != DrawingContext::NORMAL) {
    context.push_target();
    context.set_target(draw_target);
  }

  if(drawing_effect != 0) context.set_drawing_effect(drawing_effect);

  if (editor_active) {
    if(current_alpha != 1.0) {
      context.set_alpha(current_alpha);
    }
  } else {
    context.set_alpha(current_alpha/2);
  }

  /* Force the translation to be an integer so that the tiles appear sharper.
   * For consistency (i.e., to avoid 1-pixel gaps), this needs to be done even
   * for solid tilemaps that are guaranteed to have speed 1.
   * FIXME Force integer translation for all graphics, not just tilemaps. */
  float trans_x = roundf(context.get_translation().x);
  float trans_y = roundf(context.get_translation().y);
  context.set_translation(Vector(int(trans_x * speed_x),
                                 int(trans_y * speed_y)));

  Rectf draw_rect = Rectf(context.get_translation(),
        context.get_translation() + Vector(SCREEN_WIDTH, SCREEN_HEIGHT));
  Rect t_draw_rect = get_tiles_overlapping(draw_rect);
  Vector start = get_tile_position(t_draw_rect.left, t_draw_rect.top);

  Vector pos;
  int tx, ty;

  for(pos.x = start.x, tx = t_draw_rect.left; tx < t_draw_rect.right; pos.x += 32, ++tx) {
    for(pos.y = start.y, ty = t_draw_rect.top; ty < t_draw_rect.bottom; pos.y += 32, ++ty) {
      int index = ty*width + tx;
      assert (index >= 0);
      assert (index < (width * height));

      if (tiles[index] == 0) continue;
      const Tile* tile = tileset->get(tiles[index]);
      assert(tile != 0);
      tile->draw(context, pos, z_pos);
    } /* for (pos y) */
  } /* for (pos x) */

  if(draw_target != DrawingContext::NORMAL) {
    context.pop_target();
  }
  context.pop_transform();
}
void ParticleSystem::draw(DrawingContext& context)
{
  float scrollx = context.get_translation().x;
  float scrolly = context.get_translation().y;

  context.push_transform();
  context.set_translation(Vector(max_particle_size,max_particle_size));

  std::vector<Particle*>::iterator i;
  for(i = particles.begin(); i != particles.end(); ++i) {
    Particle* particle = *i;

    // remap x,y coordinates onto screencoordinates
    Vector pos;

    pos.x = fmodf(particle->pos.x - scrollx, virtual_width);
    if(pos.x < 0) pos.x += virtual_width;

    pos.y = fmodf(particle->pos.y - scrolly, virtual_height);
    if(pos.y < 0) pos.y += virtual_height;

    //if(pos.x > virtual_width) pos.x -= virtual_width;
    //if(pos.y > virtual_height) pos.y -= virtual_height;

    context.draw_surface(particle->texture, pos, particle->angle, Color(1.0f, 1.0f, 1.0f), Blend(), z_pos);
  }

  context.pop_transform();
}
Example #4
0
void ParticleSystem::draw(DrawingContext& context)
{
  if(!enabled)
    return;

  float scrollx = context.get_translation().x;
  float scrolly = context.get_translation().y;

  context.push_transform();
  context.set_translation(Vector(max_particle_size,max_particle_size));

  for(const auto& particle : particles) {
    // remap x,y coordinates onto screencoordinates
    Vector pos;

    pos.x = fmodf(particle->pos.x - scrollx, virtual_width);
    if(pos.x < 0) pos.x += virtual_width;

    pos.y = fmodf(particle->pos.y - scrolly, virtual_height);
    if(pos.y < 0) pos.y += virtual_height;

    //if(pos.x > virtual_width) pos.x -= virtual_width;
    //if(pos.y > virtual_height) pos.y -= virtual_height;

    context.color().draw_surface(particle->texture, pos, particle->angle, Color(1.0f, 1.0f, 1.0f), Blend(), z_pos);
  }

  context.pop_transform();
}
void
SpecialRiser::draw(DrawingContext& context)
{
  context.push_transform();
  context.set_translation(
      context.get_translation() + Vector(0, -32 + offset));
  child->draw(context);
  context.pop_transform();
}
Example #6
0
void
Background::draw(DrawingContext& context)
{
  if(image.get() == NULL)
    return;

  Sizef level_size(Sector::current()->get_width(),
                   Sector::current()->get_height());
  Sizef screen(SCREEN_WIDTH, SCREEN_HEIGHT);
  Sizef translation_range = level_size - screen;
  Vector center_offset(context.get_translation().x - translation_range.width  / 2.0f,
                       context.get_translation().y - translation_range.height / 2.0f);

  // FIXME: We are not handling 'pos'
  draw_image(context, Vector(level_size.width / 2.0f, level_size.height / 2.0f) + center_offset * (1.0f - speed));
}
Example #7
0
void
Background::draw(DrawingContext& context)
{
  if(Editor::is_active() && !EditorInputCenter::render_background)
    return;

  if(image.get() == NULL)
    return;

  Sizef level_size(Sector::current()->get_width(),
                   Sector::current()->get_height());
  Sizef screen(SCREEN_WIDTH, SCREEN_HEIGHT);
  Sizef translation_range = level_size - screen;
  Vector center_offset(context.get_translation().x - translation_range.width  / 2.0f,
                       context.get_translation().y - translation_range.height / 2.0f);

  float px = has_pos_x ? pos.x : level_size.width/2;
  float py = has_pos_y ? pos.y : level_size.height/2;
  draw_image(context, Vector(px, py) + center_offset * (1.0f - speed));
}
Example #8
0
void
TileMap::draw(DrawingContext& context)
{
  // skip draw if current opacity is 0.0
  if (m_current_alpha == 0.0f) return;

  context.push_transform();

  if (m_flip != NO_FLIP) context.set_flip(m_flip);

  if (m_editor_active) {
    if (m_current_alpha != 1.0f) {
      context.set_alpha(m_current_alpha);
    }
  } else {
    context.set_alpha(m_current_alpha/2);
  }

  const float trans_x = context.get_translation().x;
  const float trans_y = context.get_translation().y;
  const bool normal_speed = m_editor_active && Editor::is_active();
  context.set_translation(Vector(trans_x * (normal_speed ? 1.0f : m_speed_x),
                                 trans_y * (normal_speed ? 1.0f : m_speed_y)));

  Rectf draw_rect = context.get_cliprect();
  Rect t_draw_rect = get_tiles_overlapping(draw_rect);
  Vector start = get_tile_position(t_draw_rect.left, t_draw_rect.top);

  Vector pos;
  int tx, ty;

  std::unordered_map<SurfacePtr,
                     std::tuple<std::vector<Rectf>,
                                std::vector<Rectf>>> batches;

  for (pos.x = start.x, tx = t_draw_rect.left; tx < t_draw_rect.right; pos.x += 32, ++tx) {
    for (pos.y = start.y, ty = t_draw_rect.top; ty < t_draw_rect.bottom; pos.y += 32, ++ty) {
      int index = ty*m_width + tx;
      assert (index >= 0);
      assert (index < (m_width * m_height));

      if (m_tiles[index] == 0) continue;
      const Tile& tile = m_tileset->get(m_tiles[index]);

      if (g_debug.show_collision_rects) {
        tile.draw_debug(context.color(), pos, LAYER_FOREGROUND1);
      }

      const SurfacePtr& surface = Editor::is_active() ? tile.get_current_editor_surface() : tile.get_current_surface();
      if (surface) {
        std::get<0>(batches[surface]).emplace_back(surface->get_region());
        std::get<1>(batches[surface]).emplace_back(pos,
                                                   Sizef(static_cast<float>(surface->get_width()),
                                                         static_cast<float>(surface->get_height())));
      }
    }
  }

  Canvas& canvas = context.get_canvas(m_draw_target);

  for (auto& it : batches)
  {
    const SurfacePtr& surface = it.first;
    if (surface) {
      canvas.draw_surface_batch(surface,
                                std::move(std::get<0>(it.second)),
                                std::move(std::get<1>(it.second)),
                                m_current_tint, m_z_pos);
    }
  }

  context.pop_transform();
}
Example #9
0
void
TileMap::draw(DrawingContext& context)
{
  // skip draw if current opacity is 0.0
  if (current_alpha == 0.0) return;

  context.push_transform();
  if(draw_target != DrawingContext::NORMAL) {
    context.push_target();
    context.set_target(draw_target);
  }

  if(drawing_effect != 0) context.set_drawing_effect(drawing_effect);
  if(current_alpha != 1.0) context.set_alpha(current_alpha);

  /* Force the translation to be an integer so that the tiles appear sharper.
   * For consistency (i.e., to avoid 1-pixel gaps), this needs to be done even
   * for solid tilemaps that are guaranteed to have speed 1.
   * FIXME Force integer translation for all graphics, not just tilemaps. */
  float trans_x = roundf(context.get_translation().x);
  float trans_y = roundf(context.get_translation().y);
  context.set_translation(Vector(int(trans_x * speed_x),
                                 int(trans_y * speed_y)));

  Rectf draw_rect = Rectf(context.get_translation(),
        context.get_translation() + Vector(SCREEN_WIDTH, SCREEN_HEIGHT));
  Rect t_draw_rect = get_tiles_overlapping(draw_rect);

  // Make sure the tilemap is within draw view
  if (t_draw_rect.is_valid()) {
    Vector start = get_tile_position(t_draw_rect.left, t_draw_rect.top);

    Vector pos;
    int tx, ty;

    for(pos.x = start.x, tx = t_draw_rect.left; tx < t_draw_rect.right; pos.x += 32, ++tx) {
      for(pos.y = start.y, ty = t_draw_rect.top; ty < t_draw_rect.bottom; pos.y += 32, ++ty) {
        int index = ty*width + tx;
        assert (index >= 0);
        assert (index < (width * height));

        if (tiles[index] == 0) continue;
        const Tile* tile = tileset->get(tiles[index]);
        assert(tile != 0);

        tile->draw(context, pos, z_pos, current_tint);
      } /* for (pos y) */
    } /* for (pos x) */

    /* Make sure that tiles with images larger than 32x32 that overlap
     * the draw rect will be drawn, even if their tile position does
     * not fall within the draw rect. */
    static const int EXTENDING_TILES = 32;
    int ex_left = std::max(0, t_draw_rect.left-EXTENDING_TILES);
    int ex_top = std::max(0, t_draw_rect.top-EXTENDING_TILES);
    Vector ex_start = get_tile_position(ex_left, ex_top);

    for (pos.x = start.x, tx = t_draw_rect.left; tx < t_draw_rect.right; pos.x += 32, ++tx) {
      for (pos.y = ex_start.y, ty = ex_top; ty < t_draw_rect.top; pos.y += 32, ++ty) {
        int index = ty*width + tx;
        assert (index >= 0);
        assert (index < (width * height));

        if (tiles[index] == 0) continue;
        const Tile* tile = tileset->get(tiles[index]);
        assert(tile != 0);

        SurfacePtr image = tile->get_current_image();
        if (image) {
          int h = image->get_height();
          if (h <= 32) continue;

          if (pos.y + h > start.y)
            tile->draw(context, pos, z_pos, current_tint);
        }
      }
    }

    for (pos.x = ex_start.x, tx = ex_left; tx < t_draw_rect.right; pos.x += 32, ++tx) {
      for(pos.y = ex_start.y, ty = ex_top; ty < t_draw_rect.bottom; pos.y += 32, ++ty) {
        int index = ty*width + tx;
        assert (index >= 0);
        assert (index < (width * height));

        if (tiles[index] == 0) continue;
        const Tile* tile = tileset->get(tiles[index]);
        assert(tile != 0);

        SurfacePtr image = tile->get_current_image();
        if (image) {
          int w = image->get_width();
          int h = image->get_height();
          if (w <= 32 && h <= 32) continue;

          if (pos.x + w > start.x && pos.y + h > start.y)
            tile->draw(context, pos, z_pos, current_tint);
        }
      }
    }
  }

  if(draw_target != DrawingContext::NORMAL) {
    context.pop_target();
  }
  context.pop_transform();
}