Esempio n. 1
0
/**
 * @brief Sets the x speed.
 * @param x_speed the x speed of the object in pixels per second
 */
void StraightMovement::set_x_speed(double x_speed) {

  if (std::fabs(x_speed) <= 1E-6) {
    x_speed = 0;
  }

  this->x_speed = x_speed;
  uint32_t now = System::now();

  // compute x_delay, x_move and next_move_date_x
  if (x_speed == 0) {
    x_move = 0;
  }
  else {
    if (x_speed > 0) {
      x_delay = (uint32_t) (1000 / x_speed);
      x_move = 1;
    }
    else {
      x_delay = (uint32_t) (1000 / (-x_speed));
      x_move = -1;
    }
    set_next_move_date_x(now + x_delay);
  }
  angle = Geometry::get_angle(0, 0, (int) (x_speed * 100), (int) (y_speed * 100));
  initial_xy.set_xy(get_xy());
  finished = false;

  notify_movement_changed();
}
Esempio n. 2
0
/**
 * @brief Sets the speed to zero.
 */
void StraightMovement::stop() {

  double old_angle = this->angle;
  set_x_speed(0);
  set_y_speed(0);
  x_move = 0;
  y_move = 0;
  this->angle = old_angle;

  notify_movement_changed();
}
Esempio n. 3
0
/**
 * @brief Changes the direction of the movement vector, keeping the same speed.
 *
 * x_speed and y_speed are recomputed so that the total speed is unchanged.
 * Warning: if x_speed and y_speed are both equal to zero, this function
 * stops the program on an error message.
 *
 * @param angle the new movement direction in radians
 */
void StraightMovement::set_angle(double angle) {

  if (!is_stopped()) {
    double speed = get_speed();
    set_x_speed(speed * std::cos(angle));
    set_y_speed(-speed * std::sin(angle));
  }
  this->angle = angle;

  notify_movement_changed();
}
Esempio n. 4
0
/**
 * @brief Changes the speed, keeping the same direction of the movement.
 *
 * x_speed and y_speed are recomputed so that the movement direction is unchanged.
 *
 * @param speed the new speed
 */
void StraightMovement::set_speed(double speed) {

  if (x_speed == 0 && y_speed == 0) {
    x_speed = 1;
  }

  // compute the new speed vector
  double old_angle = this->angle;
  set_x_speed(speed * std::cos(old_angle));
  set_y_speed(-speed * std::sin(old_angle));
  this->angle = old_angle;

  notify_movement_changed();
}
Esempio n. 5
0
/**
 * \brief Sets the entity to be controlled by this movement object.
 *
 * This entity can be nullptr if your movement applies to something else than a map entity.
 * However, some subclasses of Movement may require a non nullptr entity because they
 * implement movements that depend on the map content (e.g. to handle the collisions).
 *
 * \param entity The entity to control, or nullptr if the movement should not be
 * attached to a map entity.
 */
void Movement::set_entity(Entity* entity) {

  Debug::check_assertion(drawable == nullptr, "This movement is already assigned to a drawable");

  this->entity = entity;

  if (entity == nullptr) {
    this->xy = { 0, 0 };
  }
  else {
    this->xy = entity->get_xy();
    notify_movement_changed();
  }
  notify_object_controlled();
}
Esempio n. 6
0
/**
 * \brief Sets the drawable to be controlled by this movement object.
 *
 * This entity can be nullptr if your movement applies to something else than a drawable.
 *
 * \param drawable The drawable to control, or nullptr if the movement should not be
 * attached to a drawable.
 */
void Movement::set_drawable(Drawable* drawable) {

  Debug::check_assertion(entity == nullptr, "This movement is already assigned to an entity");

  this->drawable = drawable;

  if (drawable == nullptr) {
    this->xy = { 0, 0 };
  }
  else {
    this->xy = drawable->get_xy();
    notify_movement_changed();
  }
  notify_object_controlled();
}
Esempio n. 7
0
/**
 * \brief Changes the movement of the entity depending on the direction wanted.
 *
 * This function is called when the direction is changed.
 */
void PlayerMovement::compute_movement() {

  // compute the speed vector corresponding to the direction wanted by the player

  if (direction8 == -1) {
    // no movement
    stop();
  }
  else { // the directional keys currently pressed define a valid movement
    set_speed(moving_speed);
    set_angle(Geometry::degrees_to_radians(direction8 * 45));
  }

  // notify the entity that its movement has just changed:
  // indeed, the entity may need to update its sprites
  notify_movement_changed();
}
Esempio n. 8
0
/**
 * \brief Chooses a new direction for the movement.
 */
void RandomMovement::set_next_direction() {

  double angle;
  if (get_entity() == NULL
      || max_radius == 0 // means no limit
      || bounds.contains(get_x(), get_y())) {

    // we are inside the bounds (or there is no bound): pick a random direction
    angle = Geometry::degrees_to_radians(Random::get_number(8) * 45 + 22.5);
  }
  else {

    // we are outside the bounds: get back into the rectangle to avoid going too far
    angle = Geometry::get_angle(get_x(), get_y(), bounds.get_x() + bounds.get_width() / 2, bounds.get_y() + bounds.get_height() / 2);
  }
  set_angle(angle);

  next_direction_change_date = System::now() + 500 + Random::get_number(1500); // change again in 0.5 to 2 seconds

  notify_movement_changed();
}