Example #1
0
void
Slider::update ()
{
  sprite[pingu->direction].update();

  for (int i = 0; i < speed && rel_getpixel(1, 0) == Groundtype::GP_NOTHING; ++i)
  {
    pingu->set_x(pingu->get_x() + static_cast<float>(pingu->direction));

    if (rel_getpixel(0, -1) ==  Groundtype::GP_NOTHING)
    {
      speed = (speed > 5) ? 5 : speed;

      if (pingu->direction.is_right())
      {
        pingu->set_velocity(pingu->get_velocity() + Vector3f(speed, 0.0));
      } 
      else
      {
        pingu->set_velocity(pingu->get_velocity() + Vector3f(-speed, 0.0));
      }

      pingu->set_action(ActionName::WALKER);
      return;
    }
  }

  speed -= 7 * 0.025f;
  if (speed < 1)
  {
    pingu->set_action(ActionName::WALKER);
    return;
  }
}
Example #2
0
Blocker::Blocker(Pingu* p)
  : PinguAction(p)
{
  sprite.load(Direction::LEFT,  "pingus/player" + pingu->get_owner_str() + "/blocker/left");
  sprite.load(Direction::RIGHT, "pingus/player" + pingu->get_owner_str() + "/blocker/right");

  if (   rel_getpixel(0,-1)  ==  Groundtype::GP_NOTHING
      && rel_getpixel(0, -2) ==  Groundtype::GP_GROUND)
    {
      pingu->set_y(pingu->get_y() + 1);
    }
  else if (   rel_getpixel(0,-1) ==  Groundtype::GP_NOTHING
	   && rel_getpixel(0,-2) ==  Groundtype::GP_NOTHING
	   && rel_getpixel(0,-3) ==  Groundtype::GP_GROUND)
    {
      pingu->set_y(pingu->get_y() + 2);
    }
}
Example #3
0
bool
Digger::have_something_to_dig ()
{
  if (rel_getpixel(0, -1) !=  Groundtype::GP_NOTHING)
    {
      if (rel_getpixel(0, -1) ==  Groundtype::GP_SOLID)
	{
	  Sound::PingusSound::play_sound("chink");
	  return false;
	}
      else
	return true;
    }
  else
    {
      return false;
    }
}
bool
PinguAction::head_collision_on_walk (int x, int y)
{
  int pixel = rel_getpixel(x, y + pingu_height);

  if (pixel != Groundtype::GP_NOTHING && !(pixel & Groundtype::GP_BRIDGE))
    return true;

  return false;
}
Example #5
0
void
Digger::update ()
{
  sprite.update ();

  if (rel_getpixel(0, -1) ==  Groundtype::GP_WATER
      || rel_getpixel(0, -1) ==  Groundtype::GP_LAVA)
    {
      pingu->set_action(Actions::Drown);
      return;
    }

  if (++digger_c >= 5)
    {
      digger_c = 0;
      dig();
    }

  if (!have_something_to_dig())
    {
      dig ();
      pingu->set_action(Actions::Walker);
    }
}
bool
PinguAction::collision_on_walk (int x, int y)
{
  bool collision = false;
  int pixel = Groundtype::GP_NOTHING;

  for (int pingu_y = 0; pingu_y <= pingu_height; ++pingu_y)
  {
    pixel = rel_getpixel(x, y + pingu_y);

    if (pixel != Groundtype::GP_NOTHING && pixel != Groundtype::GP_BRIDGE)
    {
      collision = true;
      break;
    }
  }

  return collision;
}
Example #7
0
void
Floater::update()
{
    sprite.update ();

    pingu->set_velocity(Vector3f(0.0f, 1.0f));

    if (rel_getpixel(0, -1) == Groundtype::GP_NOTHING)
    {
        ++step;
        if (step > 0)
        {
            pingu->set_y(pingu->get_y() + 1);
            step = 0;
        }
    }
    else
    {
        pingu->set_action (ActionName::WALKER);
    }
}
Example #8
0
void
Walker::update ()
{
  // update the sprite
  walker[pingu->direction].update(0.033f);
  floaterlayer[pingu->direction].update(0.033f);

  Vector3f last_pos = pingu->get_pos();

  /* How should this code work?

     1) Check that the Pingu stands still on ground, if not turn it into
     a faller or drown. The reason we do so, is that we catch situations
     where a digger or a similar action removed the ground under the
     walker.

     2) If pingu is still on ground, we can preprare the next step

     3) Check if up-hill or down-hill is required

     4)

  */

  if (rel_getpixel(1, 0) == Groundtype::GP_OUTOFSCREEN) 
  {
    pingu->set_x(pingu->get_x() + static_cast<float>(pingu->direction));
    return;
  }

  if (rel_getpixel(0, -1) ==  Groundtype::GP_WATER)
  {
    pingu->set_action(ActionName::DROWN);
    return;
  }

  // The Pingu stands no longer on ground, the cause for this could be
  // a digger, miner or a bomber
  if (rel_getpixel(0, -1) ==  Groundtype::GP_NOTHING)
  {
    // We search for the nearest ground below the pingu, if we can't
    // find anything within a few pixels, we will turn into a faller
    bool found_ground = false;
    int i;
    for (i = -2; i > -5; --i)
    {
      if (!(rel_getpixel(0, i) == Groundtype::GP_NOTHING))
      {
        found_ground = true;
        break;
      }
    }

    if (found_ground)
    {
      pingu->set_y(pingu->get_y() - static_cast<float>(i));
    }
    else
    {
      pingu->set_action(ActionName::FALLER);
      return;
    }
  }

  // FIXME: here we could/should scan more pixels
  if (rel_getpixel(1, 0) == Groundtype::GP_BRIDGE
      && !head_collision_on_walk(1, 1))  // bridge
  {
    // simple, stupid, but working bridge code
    // FIXME: We don't check if we 'drift' into a solid ground block
    pingu->set_pos(pingu->get_x() + static_cast<float>(pingu->direction),
                   pingu->get_y() - 1.0f); // pingus 'float' through bridges
  }
  else
  {
    // Non of the trivial moves worked, so we do up-hill or down-hill walking
    // FIXME: currently the pingu takes multiple steps at once when
    // FIXME: working uphill, this looks kind of ugly

    // FIXME: rel_getpixel works on the current pos, so modifing pos
    // FIXME: is evil, a backup copy might help

    // if infront is a pixel
    // Pingu is walking up the mountain
    // we can continue walking up. search for the correct y_pos
    int y_inc = 0;
    int possible_y_step = 0;
    bool found_next_step = false;
    for (y_inc = -max_steps; y_inc <= max_steps; ++y_inc)
    {// up/down-hill scan
      if ((  rel_getpixel(1, y_inc)     == Groundtype::GP_NOTHING
             || rel_getpixel(1, y_inc)     == Groundtype::GP_BRIDGE) // FIXME: This causes a rather huge step
          && rel_getpixel(1, y_inc - 1) != Groundtype::GP_NOTHING)
      { // FIXME:
        found_next_step = true;
        possible_y_step = y_inc;
        // No break here, since we always want to use the highest possible position
        //break;
      }
    }

    if (found_next_step)
    {
      // pos.y has a reversed co-system to rel_getpixel()?
      pingu->set_pos(pingu->get_x() + static_cast<float>(pingu->direction),
                     pingu->get_y() - static_cast<float>(possible_y_step));
    }
    else
    {
      if (rel_getpixel(1, 0) !=  Groundtype::GP_NOTHING)
      {
        // We reached a wall
        if (pingu->request_wall_action())
        {
          pout(PINGUS_DEBUG_ACTIONS)
            << "Pingu: We are in front of a wall, setting persistant action" << std::endl;
          return;
        }

        // No persitent action found, so change the direction
        pingu->direction.change();
      }
      else
      {
        // We take the step, so that we are in the air
        pingu->set_x(pingu->get_x() + static_cast<float>(pingu->direction));
        // We reached a cliff
        pingu->set_action(ActionName::FALLER);
        return;
      }
    }
  }

  // This is moved here to fix the bug where pingu stuck turning both
  // sides indefinetely when a head collision occured. the fix needs the
  // above downhill walk being done before head collision check.
  if (head_collision_on_walk(0, 0))
  {
    pout(PINGUS_DEBUG_ACTIONS) << "Pingu: Head collision" << std::endl;

    //if the new position causes a head collision, we are already
    //stuck in a wall, so lets go back to the old position
    pingu->direction.change();
    pingu->set_pos(last_pos);
    return;
  }

  /*
    for(int y_inc=1; y_inc <= max_steps; ++y_inc)
    {
    if (rel_getpixel(1, -y_inc) == ColMap::WATER)
    {
    pingu->set_paction ("drown");
    return;
    }
    else if(rel_getpixel(1, -y_inc) != ColMap::NOTHING)
    { // there is land
    pingu->pos.y += y_inc - 1;
    break;
    }
    }
  */
}
Example #9
0
bool
Blocker::standing_on_ground()
{
  return (rel_getpixel(0,-1) !=  Groundtype::GP_NOTHING);
}
Example #10
0
void
PinguAction::move_with_forces ()
{
  // Apply gravity
  pingu->set_velocity(pingu->get_velocity() + Vector3f(0.0f, 1.0f));

#if 0 // New Code
  Vector3f pos        = pingu->get_pos();
  Vector3f target_pos = pos + pingu->get_velocity();
  Vector3f dir        = target_pos - pingu->get_pos();
  Vector3f velocity   = pingu->get_velocity();

  float length = dir.length();
  dir.normalize();

  for(float i = 0; i < length; ++i)
  {
    pingu->set_pos(pos + (dir * i));

    // If there is something below the Pingu
    if (rel_getpixel(0, -1) != Groundtype::GP_NOTHING)
    {
      // FIXME: this shouldn't be really here, but its a
      // FIXME: quick&dirty way to kill falling pingus
      if (velocity.y > Actions::Faller::deadly_velocity+1)
      {
        // log_debug("Velocity: " << velocity);
        pingu->set_action(Actions::Splashed);
        return;
      }
      else
      {
        // Make it so that the Pingu won't go down any further.
        pingu->set_velocity(Vector3f(0, 0));
        return;
      }
    }
    else if (head_collision_on_walk(0, 1))
    {
      return;
    }
    else if (collision_on_walk(1, 0))
    {
      // Make the Pingu bounce off the wall
      velocity.x = -velocity.x / 3.0f;
      pingu->set_velocity(velocity);
      pingu->direction.change();
      return;
    }
  }
#else // Old Code

  // FIXME: What does this variable do?
  Vector3f resultant_force = pingu->get_velocity();

  // FIXME: and what is this all about?! Can't we just use floats?
  // Strictly speaking x_numerator should be initialised with
  // (resultant_force.y / 2) and y_numerator with (resultant_force.x / 2).
  // This would make the algorithm essentially match the Mid-Point Line
  // Algorithm.  However, zero should do and is more comprehendable.
  int x_numerator = 0;
  int y_numerator = 0;
  int denominator = 0;
  int x_inc = 0;
  int y_inc = 0;

  if (Math::abs(resultant_force.x) > Math::abs(resultant_force.y))
  {
    // Initialise so that we move in whole pixels in x direction and
    // 'fractions' of a pixel in y direction.
    denominator = static_cast<int>(Math::abs(resultant_force.x));
    x_inc = denominator;
    y_inc = static_cast<int>(Math::abs(resultant_force.y));
  }
  else
  {
    // Initialise so that we move in whole pixels in y direction and
    // 'fractions' of a pixel in x direction.
    denominator = static_cast<int>(Math::abs(resultant_force.y));
    x_inc = static_cast<int>(Math::abs(resultant_force.x));
    y_inc = denominator;
  }

  Vector3f force_counter = resultant_force;

  // Keep moving the Pingu until there is only a fraction left
  while (   force_counter.x <= -1
            || force_counter.x >=  1
            || force_counter.y <= -1
            || force_counter.y >=  1)
  {
    x_numerator += x_inc;

    // Is it now not a fraction?
    if (x_numerator >= denominator)
    {
      // Revert back to being a fraction
      x_numerator -= denominator;

      // If there is something to the left of the Pingu
      if (collision_on_walk(1, 0))
      {
        // Make the Pingu reflect off the wall
        force_counter.x = -(force_counter.x);
        resultant_force.x = -(resultant_force.x/3);

        pingu->set_velocity(resultant_force);

        pingu->direction.change();
      }
      else
      {
        // Move the Pingu left
        pingu->set_x(pingu->get_x() + static_cast<float>(pingu->direction));
        force_counter.x -= static_cast<float>(pingu->direction);
      }
    }

    y_numerator += y_inc;

    // Is it now not a fraction?
    if (y_numerator >= denominator)
    {
      // Revert back to being a fraction
      y_numerator -= denominator;

      // Move the Pingu depending on what the direction of the force is
      if (force_counter.y >= 1)
      {
        // If there is something below the Pingu
        if (rel_getpixel(0, -1) != Groundtype::GP_NOTHING)
        {
          // FIXME: this shouldn't be really here, but its a
          // FIXME: quick&dirty way to kill falling pingus
          if (resultant_force.y >= deadly_velocity)
          {
            pingu->set_action(ActionName::SPLASHED);
            return;
          }
          // Make it so that the Pingu won't go down any further.
          pingu->set_velocity(Vector3f(0, 0));
          return;
        }
        else
        {
          // Move the Pingu down
          pingu->set_y(pingu->get_y() + 1);
          force_counter.y--;
        }
      }
      else if (force_counter.y <= -1)
      {
        // If there is something in the way above the Pingu
        if (head_collision_on_walk(0, 1))
        {
          // Make it so that the Pingu won't go up any further.
          force_counter.y = 0;
          resultant_force.y = 0;

          pingu->set_velocity(resultant_force);
        }
        else
        {
          // Move the Pingu up
          pingu->set_y(pingu->get_y() - 1);
          force_counter.y++;
        }
      }
    }
  }
#endif
}