示例#1
0
/**
 * @brief Updates this state.
 */
void Hero::PushingState::update() {

  State::update();

  if (is_moving_grabbed_entity()) { // the hero is pushing an entity and is currently moving it (typically a block)

    // detect when the hero movement is finished
    // because the hero has covered 16 pixels, has reached an obstacle or has aligned the entity on the grid

    PathMovement *movement = (PathMovement*) hero.get_movement();

    bool horizontal = pushing_direction4 % 2 == 0;
    bool has_reached_grid = movement->get_total_distance_covered() > 8
      && ((horizontal && hero.is_aligned_to_grid_x()) || (!horizontal && hero.is_aligned_to_grid_y()));

    if (movement->is_finished() || has_reached_grid) {
      stop_moving_pushed_entity();
    }
  }
  else { // the hero is pushing a fixed obstacle

    // stop pushing if there is no more obstacle
    if (!hero.is_facing_obstacle()) {
      hero.set_state(new FreeState(hero));
    }

    // stop pushing if the player changes his direction
    else if (get_controls().get_wanted_direction8() != pushing_direction4 * 2) {

      if (get_controls().is_key_pressed(GameControls::ACTION)) {
	hero.set_state(new GrabbingState(hero));
      }
      else {
	hero.set_state(new FreeState(hero));
      }
    }

    // see if the obstacle pushed is an entity that the hero can move
    else {
 
      Detector *facing_entity = hero.get_facing_entity();
      if (facing_entity != NULL) { // the obstacle pushed is an entity

	if (facing_entity->get_type() == BLOCK) { // it can be moved by the hero (TODO dynamic binding)
	  hero.try_snap_to_facing_entity();
	}

	if (facing_entity->moved_by_hero()) {

	  std::string path = "  ";
	  path[0] = path[1] = '0' + pushing_direction4 * 2;

	  hero.set_movement(new PathMovement(path, 40, false, false, false));
	  pushed_entity = facing_entity;
	}
      }
    }
  }
}
示例#2
0
/**
 * \brief Notifies this state that the hero has just changed its
 * position.
 */
void Hero::PullingState::notify_position_changed() {

  if (is_moving_grabbed_entity()) {
    // if the entity has made more than 8 pixels and is aligned on the grid,
    // we stop the movement

    PathMovement* movement = static_cast<PathMovement*>(get_hero().get_movement());

    bool horizontal = get_sprites().get_animation_direction() % 2 == 0;
    bool has_reached_grid = movement->get_total_distance_covered() >= 16
      && ((horizontal && pulled_entity->is_aligned_to_grid_x())
          || (!horizontal && pulled_entity->is_aligned_to_grid_y()));

    if (has_reached_grid) {
      pulled_entity->update();
      stop_moving_pulled_entity();
    }
  }
}
示例#3
0
/**
 * @brief Notifies this state that the hero has just changed its
 * position.
 */
void Hero::PushingState::notify_position_changed() {

  if (is_moving_grabbed_entity()) {
    // if the entity has made more than 8 pixels and is aligned on the grid,
    // we stop the movement

    PathMovement *movement = (PathMovement*) hero.get_movement();

    bool horizontal = pushing_direction4 % 2 == 0;
    bool has_reached_grid = movement->get_total_distance_covered() > 8
      && ((horizontal && pushed_entity->is_aligned_to_grid_x())
          || (!horizontal && pushed_entity->is_aligned_to_grid_y()));

    if (has_reached_grid) {
      //std::cout << "stop moving block: the entity has reached the grid\n";
      stop_moving_pushed_entity();
    }
  }
}
示例#4
0
/**
 * \brief Starts this state.
 * \param previous_state the previous state
 */
void Hero::StairsState::start(State* previous_state) {

  State::start(previous_state);

  // movement
  int speed = stairs.is_inside_floor() ? 40 : 24;
  std::string path = stairs.get_path(way);
  PathMovement* movement = new PathMovement(path, speed, false, true, false);

  // sprites and sound
  HeroSprites& sprites = get_sprites();
  if (carried_item == NULL) {
    sprites.set_animation_walking_normal();
  }
  else {
    sprites.set_lifted_item(carried_item);
    sprites.set_animation_walking_carrying();
  }
  sprites.set_animation_direction((path[0] - '0') / 2);
  get_keys_effect().set_action_key_effect(KeysEffect::ACTION_KEY_NONE);

  if (stairs.is_inside_floor()) {
    if (way == Stairs::NORMAL_WAY) {
      // Towards an upper layer: change the layer now
      Layer layer = stairs.get_layer();
      Debug::check_assertion(layer != LAYER_HIGH, "Invalid stairs layer");
      get_entities().set_entity_layer(hero, Layer(layer + 1));
    }
  }
  else {
    sprites.set_clipping_rectangle(stairs.get_clipping_rectangle(way));
    if (way == Stairs::REVERSE_WAY) {
      Rectangle dxy = movement->get_xy_change();
      int fix_y = 8;
      if (path[path.size() - 1] == '2') {
        fix_y *= -1;
      }
      hero.set_xy(hero.get_x() - dxy.get_x(), hero.get_y() - dxy.get_y() + fix_y);
    }
  }
  hero.set_movement(movement);
}