コード例 #1
0
ファイル: PushingState.cpp プロジェクト: ziz/solarus
/**
 * @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 Updates this state.
 */
void Hero::SwordSwingingState::update() {

  State::update();

  // check the animation
  if (get_sprites().is_animation_finished()) {

    sword_finished = true;
    if (hero.get_movement() == NULL) {

      // if the player is still pressing the sword key, start loading the sword
      if (get_controls().is_key_pressed(GameControls::SWORD)
          && !attacked) {
        hero.set_state(new SwordLoadingState(hero));
      }
      else {
        hero.set_state(new FreeState(hero));
      }
    }
    else {
      // the sword animation is finished, but the movement continues
      hero.get_sprites().set_animation_stopped_normal();
    }
  }

  // check the movement if any
  if (hero.get_movement() != NULL && hero.get_movement()->is_finished()) {
    hero.clear_movement();
    if (sword_finished) {
      hero.set_state(new FreeState(hero));
    }
  }
}
コード例 #3
0
ファイル: SwordLoadingState.cpp プロジェクト: ziz/solarus
/**
 * @brief Updates this state.
 */
void Hero::SwordLoadingState::update() {

  PlayerMovementState::update();

  if (suspended) {
    return;
  }

  uint32_t now = System::now();

  // detect when the sword is loaded (i.e. ready for a spin attack)
  if (!sword_loaded && now >= sword_loaded_date) {
    play_load_sound();
    sword_loaded = true;
  }

  if (!get_controls().is_key_pressed(GameControls::SWORD)) {
    // the player has just released the sword key

    // stop loading the sword, go to the normal state or make a spin attack
    if (!sword_loaded) {
      // the sword was not loaded yet: go to the normal state
      hero.set_state(new FreeState(hero));
    }
    else {
      // the sword is loaded: release a spin attack
      hero.set_state(new SpinAttackState(hero));
    }
  }
}
コード例 #4
0
ファイル: PushingState.cpp プロジェクト: Valodim/solarus
/**
 * @brief Makes the hero stop pushing the entity he is facing.
 */
void Hero::PushingState::stop_moving_pushed_entity() {

  if (pushed_entity != NULL) {
    pushed_entity->stop_movement_by_hero();

    // the hero may have moved one or several pixels too much
    // because he moved before the block, not knowing that the block would not follow him

    switch (pushing_direction4) {

      case 0:
        // east
        hero.set_x(pushed_entity->get_x() - 16);
        break;

      case 1:
        // north
        hero.set_y(pushed_entity->get_y() + 16);
        break;

      case 2:
        // west
        hero.set_x(pushed_entity->get_x() + 16);
        break;

      case 3:
        // south
        hero.set_y(pushed_entity->get_y() - 16);
        break;
    }
    pushed_entity = NULL;
  }

  hero.clear_movement();

  if (!get_controls().is_key_pressed(GameControls::ACTION)) {
    // the hero was pushing an entity without grabbing it

    // stop the animation pushing if his direction changed
    if (get_controls().get_wanted_direction8() != pushing_direction4 * 2) {
      hero.set_state(new FreeState(hero));
    }
  }
  else {
    hero.set_state(new GrabbingState(hero));
  }
}
コード例 #5
0
ファイル: PushingState.cpp プロジェクト: ziz/solarus
/**
 * @brief Makes the hero stop pushing the entity he is facing.
 *
 * This function is called while moving the entity, when the 
 * hero or the entity collides with an obstacle or when
 * the hero's movement is finished.
 */
void Hero::PushingState::stop_moving_pushed_entity() {

  pushed_entity = NULL;
  hero.clear_movement();

  if (!get_controls().is_key_pressed(GameControls::ACTION)) {
    // the hero was pushing an entity without grabbing it

    // stop the animation pushing if his direction changed
    if (get_controls().get_wanted_direction8() != pushing_direction4 * 2) {
      hero.set_state(new FreeState(hero));
    }
  }
  else {
    hero.set_state(new GrabbingState(hero));
  }
}
コード例 #6
0
ファイル: PushingState.cpp プロジェクト: Valodim/solarus
/**
 * @brief Updates this state.
 */
void Hero::PushingState::update() {

  State::update();

  if (!is_moving_grabbed_entity()) { // 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->start_movement_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;
        }
      }
    }
  }
}
コード例 #7
0
ファイル: PullingState.cpp プロジェクト: Valodim/solarus
/**
 * @brief Updates this state.
 */
void Hero::PullingState::update() {

  State::update();

  if (!is_moving_grabbed_entity()) {

    int wanted_direction8 = get_controls().get_wanted_direction8();
    int opposite_direction8 = (get_sprites().get_animation_direction8() + 4) % 8;

    // stop pulling if the action key is released or if there is no more obstacle
    if (!get_controls().is_key_pressed(GameControls::ACTION)
        || !hero.is_facing_obstacle()) {
      hero.set_state(new FreeState(hero));
    }

    // stop pulling the obstacle if the player changes his direction
    else if (wanted_direction8 != opposite_direction8) {
      hero.set_state(new GrabbingState(hero));
    }

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

        if (facing_entity->get_type() == BLOCK) { // TODO use dynamic binding
          hero.try_snap_to_facing_entity();
        }

        if (facing_entity->start_movement_by_hero()) {

          std::string path = "  ";
          path[0] = path[1] = '0' + opposite_direction8;

          hero.set_movement(new PathMovement(path, 40, false, false, false));
          pulled_entity = facing_entity;
        }
      }
    }
  }
}
コード例 #8
0
ファイル: SwordSwingingState.cpp プロジェクト: ziz/solarus
/**
 * @brief Updates this state.
 */
void Hero::SwordSwingingState::update() {

  State::update();

  if (get_sprites().is_animation_finished()) {

    // if the player is still pressing the sword key, start loading the sword
    if (get_controls().is_key_pressed(GameControls::SWORD)) {
      hero.set_state(new SwordLoadingState(hero));
    }
    else {
      hero.set_state(new FreeState(hero));
    }
  }
}