Index: Games/Pingus/src/actions/bomber.cxx =================================================================== RCS file: /usr/local/cvsroot/Games/Pingus/src/actions/bomber.cxx,v retrieving revision 1.17 diff -u -r1.17 bomber.cxx --- Games/Pingus/src/actions/bomber.cxx 6 Oct 2002 23:14:33 -0000 1.17 +++ Games/Pingus/src/actions/bomber.cxx 13 Oct 2002 17:46:35 -0000 @@ -84,11 +84,18 @@ { sprite.update (); - // Make a Bomber act like a Floater - pingu->set_velocity(Vector(0.0, 0.0)); - - if (rel_getpixel(0, -1) == Groundtype::GP_NOTHING) - pingu->set_y(pingu->get_y() + 1); + // Move the Bomber according to the forces that currently exist, subtracting + // the velocity due to the fact that the Pingu is ballooning up. Best to + // make it -1.0 so that exploding Walkers etc... remain "stationary." + move_with_forces (0.0, -1.0); + + // If the Bomber hasn't 'exploded' yet and it has hit Water or Lava + if (sprite.get_frame () <= 9 && (rel_getpixel(0, -1) == Groundtype::GP_WATER + || rel_getpixel(0, -1) == Groundtype::GP_LAVA)) + { + pingu->set_action(Actions::Drown); + return; + } if (sprite.get_frame () > 9 && !sound_played) { WorldObj::get_world()->play_wav("sounds/plop.wav", pingu->get_pos ()); Index: Games/Pingus/src/actions/faller.cxx =================================================================== RCS file: /usr/local/cvsroot/Games/Pingus/src/actions/faller.cxx,v retrieving revision 1.28 diff -u -r1.28 faller.cxx --- Games/Pingus/src/actions/faller.cxx 4 Oct 2002 11:38:29 -0000 1.28 +++ Games/Pingus/src/actions/faller.cxx 13 Oct 2002 17:46:35 -0000 @@ -20,7 +20,6 @@ #include #include "../col_map.hxx" #include "../debug.hxx" -#include "../force_vector.hxx" #include "../globals.hxx" #include "../graphic_context.hxx" #include "../pingu.hxx" @@ -65,46 +64,9 @@ if (pingu->get_velocity().y > 5.0 && pingu->request_fall_action()) return; - // Apply all forces - pingu->set_velocity(ForcesHolder::apply_forces(pingu->get_pos(), pingu->get_velocity())); - - Vector newp = pingu->get_velocity(); - - // Update x and y by moving the penguin to it's target *slowly* - // and checking if the penguin has hit the bottom at each loop - while ( rel_getpixel(0, -1) == Groundtype::GP_NOTHING - && (fabs(newp.x) >= 1 || fabs(newp.y) >= 1)) - { - if (fabs(newp.x) >= 1) - { - // Since the velocity might be a - // fraction stop when we are within 1 unit of the target - if (newp.x > 0) - { - pingu->set_x(pingu->get_x() + 1); - newp.x--; - } - else - { - pingu->set_x(pingu->get_x() - 1); - newp.x++; - } - } - - if (fabs(newp.y) >= 1) - { - if (newp.y > 0) - { - pingu->set_y(pingu->get_y() + 1); - newp.y--; - } - else - { - pingu->set_y(pingu->get_y() - 1); - newp.y++; - } - } - } + // Move the Faller according to the forces that currently exist, which + // includes gravity. + move_with_forces (0.0, 0.0); // Now that the Pingu is moved, check if he hits the ground. if (rel_getpixel(0, -1) == Groundtype::GP_NOTHING) @@ -116,7 +78,8 @@ } else // Ping is on ground/water/something { - if (rel_getpixel(0, -1) == Groundtype::GP_WATER) + if (rel_getpixel(0, -1) == Groundtype::GP_WATER + || rel_getpixel(0, -1) == Groundtype::GP_LAVA) { pingu->set_action(Actions::Drown); return; 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:46:36 -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 */