00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "object/bicycle_platform.hpp"
00018
00019 #include <math.h>
00020
00021 #include "object/player.hpp"
00022 #include "object/portable.hpp"
00023 #include "supertux/object_factory.hpp"
00024 #include "supertux/sector.hpp"
00025
00026 BicyclePlatform::BicyclePlatform(const Reader& reader) :
00027 MovingSprite(reader, LAYER_OBJECTS, COLGROUP_STATIC),
00028 master(0),
00029 slave(0),
00030 center(),
00031 radius(128),
00032 angle(0),
00033 angular_speed(0),
00034 contacts(),
00035 momentum(0)
00036 {
00037 center = get_pos();
00038 }
00039
00040 BicyclePlatform::BicyclePlatform(BicyclePlatform* master) :
00041 MovingSprite(*master),
00042 master(master),
00043 slave(this),
00044 center(master->center),
00045 radius(master->radius),
00046 angle(master->angle + M_PI),
00047 angular_speed(0),
00048 contacts(),
00049 momentum(0)
00050 {
00051 set_pos(get_pos() + Vector(master->get_bbox().get_width(), 0));
00052 master->master = master;
00053 master->slave = this;
00054 }
00055
00056 BicyclePlatform::~BicyclePlatform()
00057 {
00058 if ((this == master) && (master)) {
00059 slave->master = 0;
00060 slave->slave = 0;
00061 }
00062 if ((master) && (this == slave)) {
00063 master->master = 0;
00064 master->slave = 0;
00065 }
00066 master = 0;
00067 slave = 0;
00068 }
00069
00070 HitResponse
00071 BicyclePlatform::collision(GameObject& other, const CollisionHit& )
00072 {
00073
00074
00075 MovingObject* mo = dynamic_cast<MovingObject*>(&other);
00076 if (!mo) return FORCE_MOVE;
00077 if ((mo->get_bbox().p2.y) > (get_bbox().p1.y + 2)) return FORCE_MOVE;
00078
00079 Player* pl = dynamic_cast<Player*>(mo);
00080 if (pl) {
00081 if (pl->is_big()) momentum += 1;
00082 Portable* po = pl->get_grabbed_object();
00083 MovingObject* pomo = dynamic_cast<MovingObject*>(po);
00084 if (contacts.insert(pomo).second) momentum += 1;
00085 }
00086
00087 if (contacts.insert(&other).second) momentum += 1;
00088 return FORCE_MOVE;
00089 }
00090
00091 void
00092 BicyclePlatform::update(float elapsed_time)
00093 {
00094 if (!slave) {
00095 Sector::current()->add_object(new BicyclePlatform(this));
00096 return;
00097 }
00098 if (!master) {
00099 return;
00100 }
00101 if (this == slave) {
00102 angle = master->angle + M_PI;
00103 while (angle < 0) { angle += 2*M_PI; }
00104 while (angle > 2*M_PI) { angle -= 2*M_PI; }
00105 Vector dest = center + Vector(cosf(angle), sinf(angle)) * radius - (bbox.get_size() * 0.5);
00106 movement = dest - get_pos();
00107 }
00108 if (this == master) {
00109 float momentum_diff = momentum - slave->momentum;
00110 contacts.clear(); momentum = 0;
00111 slave->contacts.clear(); slave->momentum = 0;
00112
00113 float angular_momentum = cosf(angle) * momentum_diff;
00114
00115 angular_speed += (angular_momentum * elapsed_time) * M_PI;
00116 angular_speed *= 1 - elapsed_time * 0.2;
00117 angle += angular_speed * elapsed_time;
00118 while (angle < 0) { angle += 2*M_PI; }
00119 while (angle > 2*M_PI) { angle -= 2*M_PI; }
00120 angular_speed = std::min(std::max(angular_speed, static_cast<float>(-128*M_PI*elapsed_time)), static_cast<float>(128*M_PI*elapsed_time));
00121 Vector dest = center + Vector(cosf(angle), sinf(angle)) * radius - (bbox.get_size() * 0.5);
00122 movement = dest - get_pos();
00123
00124 center += Vector(angular_speed, 0) * elapsed_time * 32;
00125 slave->center += Vector(angular_speed, 0) * elapsed_time * 32;
00126
00127 }
00128 }
00129
00130