00001 // SuperTux 00002 // Copyright (C) 2006 Matthias Braun <matze@braunis.de> 00003 // 00004 // This program is free software: you can redistribute it and/or modify 00005 // it under the terms of the GNU General Public License as published by 00006 // the Free Software Foundation, either version 3 of the License, or 00007 // (at your option) any later version. 00008 // 00009 // This program is distributed in the hope that it will be useful, 00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 // GNU General Public License for more details. 00013 // 00014 // You should have received a copy of the GNU General Public License 00015 // along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 00017 #include "badguy/plant.hpp" 00018 00019 #include "object/player.hpp" 00020 #include "sprite/sprite.hpp" 00021 #include "supertux/object_factory.hpp" 00022 00023 static const float PLANT_SPEED = 80; 00024 static const float WAKE_TIME = .5; 00025 00026 Plant::Plant(const Reader& reader) : 00027 BadGuy(reader, "images/creatures/plant/plant.sprite"), 00028 timer(), 00029 state() 00030 { 00031 state = PLANT_SLEEPING; 00032 } 00033 00034 void 00035 Plant::initialize() 00036 { 00037 //FIXME: turns sspiky around for debugging 00038 dir = dir == LEFT ? RIGHT : LEFT; 00039 00040 state = PLANT_SLEEPING; 00041 physic.set_velocity_x(0); 00042 sprite->set_action(dir == LEFT ? "sleeping-left" : "sleeping-right"); 00043 } 00044 00045 void 00046 Plant::collision_solid(const CollisionHit& hit) 00047 { 00048 if(hit.top || hit.bottom) { 00049 physic.set_velocity_y(0); 00050 } else if(hit.left || hit.right) { 00051 dir = dir == LEFT ? RIGHT : LEFT; 00052 sprite->set_action(dir == LEFT ? "left" : "right"); 00053 physic.set_velocity_x(-physic.get_velocity_x()); 00054 } 00055 } 00056 00057 HitResponse 00058 Plant::collision_badguy(BadGuy& , const CollisionHit& hit) 00059 { 00060 if(state != PLANT_WALKING) return CONTINUE; 00061 00062 if(hit.left || hit.right) { 00063 dir = dir == LEFT ? RIGHT : LEFT; 00064 sprite->set_action(dir == LEFT ? "left" : "right"); 00065 physic.set_velocity_x(-physic.get_velocity_x()); 00066 } 00067 00068 return CONTINUE; 00069 } 00070 00071 void 00072 Plant::active_update(float elapsed_time) { 00073 BadGuy::active_update(elapsed_time); 00074 00075 if(state == PLANT_SLEEPING) { 00076 00077 Player* player = this->get_nearest_player(); 00078 if (player) { 00079 Rectf mb = this->get_bbox(); 00080 Rectf pb = player->get_bbox(); 00081 00082 bool inReach_left = (pb.p2.x >= mb.p2.x-((dir == LEFT) ? 256 : 0)); 00083 bool inReach_right = (pb.p1.x <= mb.p1.x+((dir == RIGHT) ? 256 : 0)); 00084 bool inReach_top = (pb.p2.y >= mb.p2.y); 00085 bool inReach_bottom = (pb.p1.y <= mb.p1.y); 00086 00087 if (inReach_left && inReach_right && inReach_top && inReach_bottom) { 00088 // wake up 00089 sprite->set_action(dir == LEFT ? "waking-left" : "waking-right"); 00090 if(!timer.started()) timer.start(WAKE_TIME); 00091 state = PLANT_WAKING; 00092 } 00093 } 00094 } 00095 00096 if(state == PLANT_WAKING) { 00097 if(timer.check()) { 00098 // start walking 00099 sprite->set_action(dir == LEFT ? "left" : "right"); 00100 physic.set_velocity_x(dir == LEFT ? -PLANT_SPEED : PLANT_SPEED); 00101 state = PLANT_WALKING; 00102 } 00103 } 00104 00105 } 00106 00107 /* EOF */