00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "object/explosion.hpp"
00018
00019 #include "audio/sound_manager.hpp"
00020 #include "badguy/badguy.hpp"
00021 #include "badguy/walking_badguy.hpp"
00022 #include "math/random_generator.hpp"
00023 #include "object/player.hpp"
00024 #include "object/sprite_particle.hpp"
00025 #include "supertux/object_factory.hpp"
00026 #include "supertux/sector.hpp"
00027
00028 #include <math.h>
00029
00030 Explosion::Explosion(const Vector& pos) :
00031 MovingSprite(pos, "images/objects/explosion/explosion.sprite", LAYER_OBJECTS+40, COLGROUP_MOVING),
00032 hurt(true),
00033 push(false),
00034 state(STATE_WAITING)
00035 {
00036 sound_manager->preload("sounds/explosion.wav");
00037 set_pos(get_pos() - (get_bbox().get_middle() - get_pos()));
00038 }
00039
00040 Explosion::Explosion(const Reader& reader) :
00041 MovingSprite(reader, "images/objects/explosion/explosion.sprite", LAYER_OBJECTS+40, COLGROUP_MOVING),
00042 hurt(true),
00043 push(false),
00044 state(STATE_WAITING)
00045 {
00046 sound_manager->preload("sounds/explosion.wav");
00047 }
00048
00049 void
00050 Explosion::explode()
00051 {
00052 if (state != STATE_WAITING)
00053 return;
00054 state = STATE_EXPLODING;
00055
00056 set_action("default", 1);
00057 sprite->set_animation_loops(1);
00058 sound_manager->play("sounds/explosion.wav", get_pos());
00059
00060 #if 0
00061
00062
00063 for (int i = 0; i < 100; i++) {
00064 Vector ppos = bbox.get_middle();
00065 float angle = graphicsRandom.randf(-M_PI_2, M_PI_2);
00066 float velocity = graphicsRandom.randf(450, 900);
00067 float vx = sin(angle)*velocity;
00068 float vy = -cos(angle)*velocity;
00069 Vector pspeed = Vector(vx, vy);
00070 Vector paccel = Vector(0, 1000);
00071 Sector::current()->add_object(new SpriteParticle("images/objects/particles/explosion.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1));
00072 }
00073 #endif
00074
00075 if (push) {
00076 Vector center = get_bbox ().get_middle ();
00077 std::vector<MovingObject*> near_objects = Sector::current()->get_nearby_objects (center, 10.0 * 32.0);
00078
00079 for (size_t i = 0; i < near_objects.size (); i++) {
00080 MovingObject *obj = near_objects[i];
00081 Vector obj_vector = obj->get_bbox ().get_middle ();
00082 Vector direction = obj_vector - center;
00083 float distance = direction.norm ();
00084
00085
00086
00087 if (distance <= 1.0)
00088 continue;
00089
00090
00091
00092 float force = 150.0 * 32.0*32.0 / (distance * distance);
00093 if (force > 200.0)
00094 force = 200.0;
00095
00096 Vector add_speed = direction.unit () * force;
00097
00098 Player *player = dynamic_cast<Player *> (obj);
00099 if (player) {
00100 player->add_velocity (add_speed);
00101 }
00102
00103 WalkingBadguy *badguy = dynamic_cast<WalkingBadguy *> (obj);
00104 if (badguy) {
00105 badguy->add_velocity (add_speed);
00106 }
00107 }
00108 }
00109 }
00110
00111 void
00112 Explosion::update(float )
00113 {
00114 switch(state) {
00115 case STATE_WAITING:
00116 explode();
00117 break;
00118 case STATE_EXPLODING:
00119 if(sprite->animation_done()) {
00120 remove_me();
00121 }
00122 break;
00123 }
00124 }
00125
00126 HitResponse
00127 Explosion::collision(GameObject& other, const CollisionHit& )
00128 {
00129 if ((state != STATE_EXPLODING) || !hurt)
00130 return ABORT_MOVE;
00131
00132 Player* player = dynamic_cast<Player*>(&other);
00133 if(player != 0) {
00134 player->kill(false);
00135 }
00136
00137 BadGuy* badguy = dynamic_cast<BadGuy*>(&other);
00138 if(badguy != 0) {
00139 badguy->kill_fall();
00140 }
00141
00142 return ABORT_MOVE;
00143 }
00144
00145