Index: Games/Pingus/src/pingu_action.cxx =================================================================== RCS file: /usr/local/cvsroot/Games/Pingus/src/pingu_action.cxx,v retrieving revision 1.8 diff -u -r1.8 pingu_action.cxx --- Games/Pingus/src/pingu_action.cxx 16 Sep 2002 20:31:09 -0000 1.8 +++ Games/Pingus/src/pingu_action.cxx 13 Oct 2002 17:58:17 -0000 @@ -18,7 +18,9 @@ // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include +#include #include "col_map.hxx" +#include "force_vector.hxx" #include "world.hxx" #include "pingu.hxx" #include "pingu_action.hxx" @@ -82,6 +84,117 @@ return true; return false; +} + +void +PinguAction::move_with_forces (float x_to_add, float y_to_add) +{ + Vector force_to_apply = pingu->get_velocity(); + + // Add any additional forces that are required + force_to_apply.x += x_to_add; + force_to_apply.y += y_to_add; + + // Put the force together with any existing forces, including gravity + pingu->set_velocity( ForcesHolder::apply_forces(pingu->get_pos(), + force_to_apply) ); + + Vector resultant_force = pingu->get_velocity(); + + // 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 (fabs(resultant_force.x) > fabs(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(fabs(resultant_force.x)); + x_inc = denominator; + y_inc = static_cast(fabs(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(fabs(resultant_force.y)); + x_inc = static_cast(fabs(resultant_force.x)); + y_inc = denominator; + } + + // Keep moving the Pingu until there is only a fraction left + while (resultant_force.x <= -1 || resultant_force.x >= 1 + || resultant_force.y <= -1 || resultant_force.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; + + // Move the Pingu depending on what the direction of the force is + if (resultant_force.x >= 1) + { + // Check what is to the right of the Pingu + if (rel_getpixel(pingu->direction, 0) != Groundtype::GP_NOTHING + || head_collision_on_walk(pingu->direction, 0)) + { + break; + } + + pingu->set_x(pingu->get_x() + 1); + resultant_force.x--; + } + else if (resultant_force.x <= -1) + { + // Check what is to the left of the Pingu + if (rel_getpixel(-(pingu->direction), 0) != Groundtype::GP_NOTHING + || head_collision_on_walk(-(pingu->direction), 0) ) + { + break; + } + + pingu->set_x(pingu->get_x() - 1); + resultant_force.x++; + } + } + + 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 (resultant_force.y >= 1) + { + if (rel_getpixel(0, -1) != Groundtype::GP_NOTHING) + break; + + pingu->set_y(pingu->get_y() + 1); + resultant_force.y--; + } + else if (resultant_force.y <= -1) + { + if (head_collision_on_walk(0, 1)) + break; + + pingu->set_y(pingu->get_y() - 1); + resultant_force.y++; + } + } + } + } /* EOF */