X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fbadguy%2Fbomb.cpp;h=c9e2c8a611fa1e4ed78afa679d9703de36f49272;hb=a3316d68ca17966517c3f7bb0c0cb2b7e612fd0a;hp=66e8348020793f7c43b4caeca26e00b298086513;hpb=62ff7f7776875e9389d10ae2e7b6348e9e5cb9c7;p=supertux.git diff --git a/src/badguy/bomb.cpp b/src/badguy/bomb.cpp index 66e834802..c9e2c8a61 100644 --- a/src/badguy/bomb.cpp +++ b/src/badguy/bomb.cpp @@ -1,20 +1,54 @@ +// $Id$ +// +// SuperTux +// Copyright (C) 2006 Matthias Braun +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + #include -#include "bomb.h" +#include "bomb.hpp" +#include "random_generator.hpp" +#include "object/sprite_particle.hpp" + +Bomb::Bomb(const Vector& pos, Direction dir, std::string custom_sprite /*= "images/creatures/mr_cherry/cherry.sprite"*/ ) + : BadGuy( pos, dir, custom_sprite ) +{ + state = STATE_TICKING; + set_action(dir == LEFT ? "ticking-left" : "ticking-right", 1); + countMe = false; -static const float TICKINGTIME = 1; -static const float EXPLOSIONTIME = 1; + ticking.reset(sound_manager->create_sound_source("sounds/fizz.wav")); + ticking->set_position(get_pos()); + ticking->set_looping(true); + ticking->set_gain(2.0); + ticking->set_reference_distance(32); + ticking->play(); +} -Bomb::Bomb(const Vector& pos, Direction dir) +Bomb::Bomb(const Bomb& other) + : BadGuy(other), state(other.state) { - start_position = pos; - bbox.set_pos(pos); - bbox.set_size(31.8, 31.8); - sprite = sprite_manager->create("bomb"); - state = 0; - timer.start(TICKINGTIME); - this->dir = dir; - sprite->set_action(dir == LEFT ? "ticking-left" : "ticking-right"); + if (state == STATE_TICKING) { + ticking.reset(sound_manager->create_sound_source("sounds/fizz.wav")); + ticking->set_position(get_pos()); + ticking->set_looping(true); + ticking->set_gain(2.0); + ticking->set_reference_distance(32); + ticking->play(); + } } void @@ -23,20 +57,18 @@ Bomb::write(lisp::Writer& ) // bombs are only temporarily so don't write them out... } -HitResponse -Bomb::collision_solid(GameObject& , const CollisionHit& hit) +void +Bomb::collision_solid(const CollisionHit& hit) { - if(fabsf(hit.normal.y) > .5) + if(hit.bottom) physic.set_velocity_y(0); - - return CONTINUE; } HitResponse Bomb::collision_player(Player& player, const CollisionHit& ) { - if(state == 1) { - player.kill(Player::SHRINK); + if(state == STATE_EXPLODING) { + player.kill(false); } return ABORT_MOVE; } @@ -44,26 +76,23 @@ Bomb::collision_player(Player& player, const CollisionHit& ) HitResponse Bomb::collision_badguy(BadGuy& badguy, const CollisionHit& ) { - if(state == 1) + if(state == STATE_EXPLODING) badguy.kill_fall(); return ABORT_MOVE; } void -Bomb::active_action(float ) +Bomb::active_update(float ) { switch(state) { - case 0: - if(timer.check()) { - state = 1; - sprite->set_action("explosion"); - SoundManager::get()->play_sound(IDToSound(SND_EXPLODE), get_pos(), - Sector::current()->player->get_pos()); - timer.start(EXPLOSIONTIME); + case STATE_TICKING: + ticking->set_position(get_pos()); + if(sprite->animation_done()) { + explode(); } break; - case 1: - if(timer.check()) { + case STATE_EXPLODING: + if(sprite->animation_done()) { remove_me(); } break; @@ -71,6 +100,33 @@ Bomb::active_action(float ) } void +Bomb::explode() +{ + ticking->stop(); + state = STATE_EXPLODING; + set_group(COLGROUP_TOUCHABLE); + sound_manager->play("sounds/explosion.wav", get_pos()); + set_action_centered("explosion", 1); + + // spawn some particles + // TODO: provide convenience function in MovingSprite or MovingObject? + for (int i = 0; i < 100; i++) { + Vector ppos = bbox.get_middle(); + float angle = systemRandom.randf(-M_PI_2, M_PI_2); + float velocity = systemRandom.randf(450, 900); + float vx = sin(angle)*velocity; + float vy = -cos(angle)*velocity; + Vector pspeed = Vector(vx, vy); + Vector paccel = Vector(0, 1000); + Sector::current()->add_object(new SpriteParticle("images/objects/particles/kracker.sprite", "default", ppos, ANCHOR_MIDDLE, pspeed, paccel, LAYER_OBJECTS-1)); + } + +} + +void Bomb::kill_fall() { + if (state != STATE_EXPLODING) // we don't want it exploding again + explode(); } +