Example #1
0
/**
 * \brief Updates the position.
 */
void RelativeMovement::update() {

  if (entity_followed == nullptr) {
    finished = true;
    return;
  }

  if (entity_followed->is_being_removed()) {
    finished = true;
    entity_followed = nullptr;
  }
  else {

    Point next = entity_followed->get_xy() + entity_offset;
    Point dnext = next - get_xy();

    if (!are_obstacles_ignored()) {

      if (!finished && (dnext.x != 0 || dnext.y != 0)) {

        if (!test_collision_with_obstacles(dnext)) {
          set_xy(next);
        }
        else {
          finished = true;
          notify_obstacle_reached();
        }
      }
    }
    else {
      set_xy(next);
    }
  }
}
Example #2
0
void StraightMovement::update() {
	Movement::update();
	
	if(!is_suspended()) {
		uint32_t now = System::now();
		bool current_move_y = move_y != 0 && now >= next_move_date_y;
		bool current_move_x = move_x != 0 && now >= next_move_date_x;

		while(current_move_x || current_move_y) {
			// save current coordinates.
			Rectangle old_xy(get_x(), get_y());

			if(current_move_x) {	// time to move in x direction.
				if(current_move_y) {	// time to move in y direction.
					if(next_move_date_x <= next_move_date_y) {	//	we first move in x direction.
						update_x();
						if(now >= next_move_date_y) {
							update_y();
						}
					} else {
						update_y();								// we first move in y direciton.
						if(now >= next_move_date_x) {
							update_x();
						}
					}
				} else {	// we only move in x direction.
					update_x();
				}
			} else {	// we only move in y direction.
				update_y();
			}

			if(get_entity() != NULL && !finished) {
				// movement is successful old coordinates have changed.
				bool success = (get_x() != old_xy.get_x() || get_y() != old_xy.get_y()
					&& (move_x != 0 || move_y != 0));

				// no movement notify obstacle.
				if(!success) {
					notify_obstacle_reached();
					set_finished();
				}
			}

			// check if we continue wit movement.
			now = System::now();
			current_move_x = move_x != 0 && now >= next_move_date_x;
			current_move_y = move_y != 0 && now >= next_move_date_y;
		}
	}
}
Example #3
0
/**
 * @brief Computes the position of the object controlled by this movement.
 *
 * This function should be called whenever the angle, the radius or the center changes.
 */
void CircleMovement::recompute_position() {

  Rectangle center = this->center_point;
  if (center_entity != NULL) {
    center.add_xy(center_entity->get_xy());
  }

  const Rectangle &xy = Geometry::get_xy(center, Geometry::degrees_to_radians(current_angle), current_radius);
  if (get_entity() == NULL
      || !test_collision_with_obstacles(xy.get_x() - get_entity()->get_x(), xy.get_y() - get_entity()->get_y())) {
    set_xy(xy);
    notify_position_changed();
  }
  else {
    notify_obstacle_reached();
  }
}
Example #4
0
/**
 * \brief Computes the position of the object controlled by this movement.
 *
 * This function should be called whenever the angle, the radius or the center changes.
 */
void CircleMovement::recompute_position() {

  Point center = this->center_point;
  if (center_entity != nullptr) {
    center += center_entity->get_xy();
  }

  Point xy = Geometry::get_xy(center, Geometry::degrees_to_radians(current_angle), current_radius);
  if (get_entity() == nullptr
      || !test_collision_with_obstacles(xy - get_entity()->get_xy())) {
    set_xy(xy);
    notify_position_changed();
  }
  else {
    notify_obstacle_reached();
  }
}
Example #5
0
/**
 * \brief Updates the position.
 */
void FollowMovement::update() {

  if (entity_followed == NULL) {
    finished = true;
    return;
  }

  if (entity_followed->is_being_removed()) {
    finished = true;
    RefCountable::unref(entity_followed);
    entity_followed = NULL;
  }
  else {

    int next_x = entity_followed->get_x() + x;
    int next_y = entity_followed->get_y() + y;

    int dx = next_x - get_x();
    int dy = next_y - get_y();

    if (!are_obstacles_ignored()) {

      if (!finished && (dx != 0 || dy != 0)) {

        if (!test_collision_with_obstacles(dx, dy)) {
          set_x(next_x);
          set_y(next_y);
        }
        else {
          finished = true;
          notify_obstacle_reached();
        }
      }
    }
    else {
      set_x(next_x);
      set_y(next_y);
    }
  }
}
Example #6
0
/**
 * @brief Updates the position of the object controlled by this movement.
 *
 * This function is called repeatedly.
 */
void StraightMovement::update() {

  if (!is_suspended()) {
    uint32_t now = System::now();

    bool x_move_now = x_move != 0 && now >= next_move_date_x;
    bool y_move_now = y_move != 0 && now >= next_move_date_y;

    while (x_move_now || y_move_now) { // while it's time to move

      // save the current coordinates
      Rectangle old_xy(get_x(), get_y());

      if (x_move_now) {
        // it's time to make an x move

        if (y_move_now) {
          // but it's also time to make a y move

          if (next_move_date_x <= next_move_date_y) {
            // x move first
            update_x();
            if (now >= next_move_date_y) {
              update_y();
            }
          }
          else {
            // y move first
            update_y();
            if (now >= next_move_date_x) {
              update_x();
            }
          }
        }
        else {
          update_x();
        }
      }
      else {
        update_y();
      }

      if (!is_suspended() && get_entity() != NULL && !finished) {

        // the movement was successful if the entity's coordinates have changed
        // and the movement was not stopped
        bool success = (get_x() != old_xy.get_x() || get_y() != old_xy.get_y())
            && (x_move != 0 || y_move != 0);

        if (!success) {
          notify_obstacle_reached();
        }
      }

      now = System::now();

      if (!finished && max_distance != 0 && Geometry::get_distance(initial_xy.get_x(),
          initial_xy.get_y(), get_x(), get_y()) >= max_distance) {
        set_finished();
      }
      else {
        x_move_now = x_move != 0 && now >= next_move_date_x;
        y_move_now = y_move != 0 && now >= next_move_date_y;
      }
    }
  }

  // Do this at last so that Movement::update() knows whether we are finished.
  Movement::update();
}