00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "object/block.hpp"
00018
00019 #include "audio/sound_manager.hpp"
00020 #include "badguy/badguy.hpp"
00021 #include "object/coin.hpp"
00022 #include "object/flower.hpp"
00023 #include "object/growup.hpp"
00024 #include "object/player.hpp"
00025 #include "object/portable.hpp"
00026 #include "supertux/constants.hpp"
00027
00028 static const float BOUNCY_BRICK_MAX_OFFSET = 8;
00029 static const float BOUNCY_BRICK_SPEED = 90;
00030 static const float EPSILON = .0001f;
00031 static const float BUMP_ROTATION_ANGLE = 10;
00032
00033 Block::Block(SpritePtr newsprite) :
00034 sprite(newsprite),
00035 bouncing(false),
00036 breaking(false),
00037 bounce_dir(0),
00038 bounce_offset(0),
00039 original_y(-1)
00040 {
00041 bbox.set_size(32, 32.1f);
00042 set_group(COLGROUP_STATIC);
00043 sound_manager->preload("sounds/upgrade.wav");
00044 sound_manager->preload("sounds/brick.wav");
00045 }
00046
00047 Block::~Block()
00048 {
00049 }
00050
00051 HitResponse
00052 Block::collision(GameObject& other, const CollisionHit& )
00053 {
00054 Player* player = dynamic_cast<Player*> (&other);
00055 if(player) {
00056 if(player->get_bbox().get_top() > get_bbox().get_bottom() - SHIFT_DELTA) {
00057 hit(*player);
00058 }
00059 }
00060
00061
00062
00063
00064
00065 Portable* portable = dynamic_cast<Portable*> (&other);
00066 MovingObject* moving_object = dynamic_cast<MovingObject*> (&other);
00067 bool is_portable = ((portable != 0) && portable->is_portable());
00068 bool hit_mo_from_below = ((moving_object == 0) || (moving_object->get_bbox().get_bottom() < (get_bbox().get_top() + SHIFT_DELTA)));
00069 if(bouncing && !is_portable && hit_mo_from_below) {
00070
00071
00072 BadGuy* badguy = dynamic_cast<BadGuy*> (&other);
00073 if(badguy) {
00074 badguy->kill_fall();
00075 }
00076
00077
00078 Coin* coin = dynamic_cast<Coin*> (&other);
00079 if(coin) {
00080 coin->collect();
00081 }
00082
00083
00084 GrowUp* growup = dynamic_cast<GrowUp*> (&other);
00085 if(growup) {
00086 growup->do_jump();
00087 }
00088
00089 }
00090
00091 return FORCE_MOVE;
00092 }
00093
00094 void
00095 Block::update(float elapsed_time)
00096 {
00097 if(!bouncing)
00098 return;
00099
00100 float offset = original_y - get_pos().y;
00101 if(offset > BOUNCY_BRICK_MAX_OFFSET) {
00102 bounce_dir = BOUNCY_BRICK_SPEED;
00103 movement = Vector(0, bounce_dir * elapsed_time);
00104 if(breaking){
00105 break_me();
00106 }
00107 } else if(offset < BOUNCY_BRICK_SPEED * elapsed_time && bounce_dir > 0) {
00108 movement = Vector(0, offset);
00109 bounce_dir = 0;
00110 bouncing = false;
00111 sprite->set_angle(0);
00112 } else {
00113 movement = Vector(0, bounce_dir * elapsed_time);
00114 }
00115 }
00116
00117 void
00118 Block::draw(DrawingContext& context)
00119 {
00120 sprite->draw(context, get_pos(), LAYER_OBJECTS+1);
00121 }
00122
00123 void
00124 Block::start_bounce(GameObject* hitter)
00125 {
00126 if(original_y == -1){
00127 original_y = bbox.p1.y;
00128 }
00129 bouncing = true;
00130 bounce_dir = -BOUNCY_BRICK_SPEED;
00131 bounce_offset = 0;
00132
00133 MovingObject* hitter_mo = dynamic_cast<MovingObject*>(hitter);
00134 if (hitter_mo) {
00135 float center_of_hitter = hitter_mo->get_bbox().get_middle().x;
00136 float offset = (get_bbox().get_middle().x - center_of_hitter)*2 / get_bbox().get_width();
00137 sprite->set_angle(BUMP_ROTATION_ANGLE*offset);
00138 }
00139 }
00140
00141 void
00142 Block::start_break(GameObject* hitter)
00143 {
00144 start_bounce(hitter);
00145 breaking = true;
00146 }
00147
00148