예제 #1
0
파일: tux.cpp 프로젝트: Karkus476/supertux
void
Tux::tryContinueWalking(float elapsed_time)
{
  if (!moving)
    return;

  // Let tux walk
  offset += TUXSPEED * elapsed_time;

  // Do nothing if we have not yet reached the next tile
  if (offset <= 32)
    return;

  offset -= 32;

  auto sprite_change = worldmap->at_sprite_change(tile_pos);
  ChangeSprite(sprite_change);

  // if this is a special_tile with passive_message, display it
  auto special_tile = worldmap->at_special_tile();
  if(special_tile)
  {
    // direction and the apply_action_ are opposites, since they "see"
    // directions in a different way
    if((direction == D_NORTH && special_tile->apply_action_south) ||
       (direction == D_SOUTH && special_tile->apply_action_north) ||
       (direction == D_WEST && special_tile->apply_action_east) ||
       (direction == D_EAST && special_tile->apply_action_west))
    {
      process_special_tile(special_tile);
    }
  }

  // check if we are at a Teleporter
  auto teleporter = worldmap->at_teleporter(tile_pos);

  // stop if we reached a level, a WORLDMAP_STOP tile, a teleporter or a special tile without a passive_message
  if ((worldmap->at_level())
      || (worldmap->tile_data_at(tile_pos) & Tile::WORLDMAP_STOP)
      || (special_tile && !special_tile->passive_message
          && special_tile->script.empty())
      || (teleporter) || ghost_mode) {
    if(special_tile && !special_tile->map_message.empty()
       && !special_tile->passive_message)
      worldmap->passive_message_timer.start(0);
    stop();
    return;
  }

  // if user wants to change direction, try changing, else guess the direction in which to walk next
  const int tile_data = worldmap->tile_data_at(tile_pos);
  if ((direction != input_direction) && canWalk(tile_data, input_direction)) {
    direction = input_direction;
    back_direction = reverse_dir(direction);
  } else {
    Direction dir = D_NONE;
    if (tile_data & Tile::WORLDMAP_NORTH && back_direction != D_NORTH)
      dir = D_NORTH;
    else if (tile_data & Tile::WORLDMAP_SOUTH && back_direction != D_SOUTH)
      dir = D_SOUTH;
    else if (tile_data & Tile::WORLDMAP_EAST && back_direction != D_EAST)
      dir = D_EAST;
    else if (tile_data & Tile::WORLDMAP_WEST && back_direction != D_WEST)
      dir = D_WEST;

    if (dir == D_NONE) {
      // Should never be reached if tiledata is good
      log_warning << "Could not determine where to walk next" << std::endl;
      stop();
      return;
    }

    direction = dir;
    input_direction = direction;
    back_direction = reverse_dir(direction);
  }

  // Walk automatically to the next tile
  if(direction == D_NONE)
    return;

  Vector next_tile;
  if (!ghost_mode && !worldmap->path_ok(direction, tile_pos, &next_tile)) {
    log_debug << "Tilemap data is buggy" << std::endl;
    stop();
    return;
  }

  auto next_sprite = worldmap->at_sprite_change(next_tile);
  if(next_sprite != NULL && next_sprite->change_on_touch) {
    ChangeSprite(next_sprite);
  }
  //SpriteChange* last_sprite = worldmap->at_sprite_change(tile_pos);
  if(sprite_change != NULL && next_sprite != NULL) {
    log_debug << "Old: " << tile_pos << " New: " << next_tile << std::endl;
    sprite_change->set_stay_action();
  }

  tile_pos = next_tile;
}
예제 #2
0
파일: tux.cpp 프로젝트: HybridDog/supertux
void
Tux::try_continue_walking(float dt_sec)
{
  if (!m_moving)
    return;

  // Let tux walk
  m_offset += TUXSPEED * dt_sec;

  // Do nothing if we have not yet reached the next tile
  if (m_offset <= 32)
    return;

  m_offset -= 32;

  auto sprite_change = m_worldmap->at_sprite_change(m_tile_pos);
  change_sprite(sprite_change);

  // if this is a special_tile with passive_message, display it
  auto special_tile = m_worldmap->at_special_tile();
  if (special_tile)
  {
    // direction and the apply_action_ are opposites, since they "see"
    // directions in a different way
    if ((m_direction == Direction::NORTH && special_tile->get_apply_action_south()) ||
        (m_direction == Direction::SOUTH && special_tile->get_apply_action_north()) ||
        (m_direction == Direction::WEST && special_tile->get_apply_action_east()) ||
        (m_direction == Direction::EAST && special_tile->get_apply_action_west()))
    {
      process_special_tile(special_tile);
    }
  }

  // check if we are at a Teleporter
  auto teleporter = m_worldmap->at_teleporter(m_tile_pos);

  // stop if we reached a level, a WORLDMAP_STOP tile, a teleporter or a special tile without a passive_message
  if ((m_worldmap->at_level()) ||
      (m_worldmap->tile_data_at(m_tile_pos) & Tile::WORLDMAP_STOP) ||
      (special_tile && !special_tile->is_passive_message() && special_tile->get_script().empty()) ||
      (teleporter) ||
      m_ghost_mode)
  {
    if (special_tile && !special_tile->get_map_message().empty() && !special_tile->is_passive_message()) {
      m_worldmap->set_passive_message({}, 0.0f);
    }
    stop();
    return;
  }

  // if user wants to change direction, try changing, else guess the direction in which to walk next
  const int tile_data = m_worldmap->tile_data_at(m_tile_pos);
  if ((m_direction != m_input_direction) && can_walk(tile_data, m_input_direction)) {
    m_direction = m_input_direction;
    m_back_direction = reverse_dir(m_direction);
  } else {
    Direction dir = Direction::NONE;
    if (tile_data & Tile::WORLDMAP_NORTH && m_back_direction != Direction::NORTH)
      dir = Direction::NORTH;
    else if (tile_data & Tile::WORLDMAP_SOUTH && m_back_direction != Direction::SOUTH)
      dir = Direction::SOUTH;
    else if (tile_data & Tile::WORLDMAP_EAST && m_back_direction != Direction::EAST)
      dir = Direction::EAST;
    else if (tile_data & Tile::WORLDMAP_WEST && m_back_direction != Direction::WEST)
      dir = Direction::WEST;

    if (dir == Direction::NONE) {
      // Should never be reached if tiledata is good
      log_warning << "Could not determine where to walk next" << std::endl;
      stop();
      return;
    }

    m_direction = dir;
    m_input_direction = m_direction;
    m_back_direction = reverse_dir(m_direction);
  }

  // Walk automatically to the next tile
  if (m_direction == Direction::NONE)
    return;

  Vector next_tile;
  if (!m_ghost_mode && !m_worldmap->path_ok(m_direction, m_tile_pos, &next_tile)) {
    log_debug << "Tilemap data is buggy" << std::endl;
    stop();
    return;
  }

  auto next_sprite = m_worldmap->at_sprite_change(next_tile);
  if (next_sprite != nullptr && next_sprite->m_change_on_touch) {
    change_sprite(next_sprite);
  }
  //SpriteChange* last_sprite = m_worldmap->at_sprite_change(tile_pos);
  if (sprite_change != nullptr && next_sprite != nullptr) {
    log_debug << "Old: " << m_tile_pos << " New: " << next_tile << std::endl;
    sprite_change->set_stay_action();
  }

  m_tile_pos = next_tile;
}