X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fbadguy%2Fkugelblitz.cpp;h=2e304bb5496f8fc9986d040d8dee6c4ec3cdfe27;hb=18c69f4aa24d496f84a088d60c18b180c293dace;hp=bab4d32ac4acea0b364bb1baeec4a5e7adb850f9;hpb=680d0b663b56663d7277251358bc6e5cdaf10037;p=supertux.git diff --git a/src/badguy/kugelblitz.cpp b/src/badguy/kugelblitz.cpp index bab4d32ac..2e304bb54 100644 --- a/src/badguy/kugelblitz.cpp +++ b/src/badguy/kugelblitz.cpp @@ -1,87 +1,117 @@ -// $Id: Kugelblitz.cpp 2654 2005-06-29 14:16:22Z wansti $ -// // SuperTux -// Copyright (C) 2005 Marek Moeckel +// 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 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 3 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 +// along with this program. If not, see . + +#include "badguy/kugelblitz.hpp" +#include "math/random_generator.hpp" +#include "object/camera.hpp" +#include "object/player.hpp" +#include "sprite/sprite.hpp" +#include "supertux/object_factory.hpp" +#include "supertux/sector.hpp" +#include "util/reader.hpp" -#include "kugelblitz.hpp" +#define LIFETIME 5 +#define MOVETIME 0.75 +#define BASE_SPEED 200 +#define RAND_SPEED 150 -static const float JUMPSPEED=600; -static const float Kugelblitz_MID_TOLERANCE=4; -static const float Kugelblitz_LOW_TOLERANCE=2; +static const float X_OFFSCREEN_DISTANCE = 1600; +static const float Y_OFFSCREEN_DISTANCE = 1200; -Kugelblitz::Kugelblitz(const lisp::Lisp& reader) - : groundhit_pos_set(false) +Kugelblitz::Kugelblitz(const Reader& reader) : + BadGuy(reader, "images/creatures/kugelblitz/kugelblitz.sprite"), + pos_groundhit(), + groundhit_pos_set(false), + dying(), + movement_timer(), + lifetime(), + direction(), + state() { reader.get("x", start_position.x); - start_position.y = 0; //place above visible area - bbox.set_size(63.8, 127.8); - sprite = sprite_manager->create("kugelblitz"); sprite->set_action("falling"); physic.enable_gravity(false); + countMe = false; } void -Kugelblitz::write(lisp::Writer& writer) +Kugelblitz::initialize() { - writer.start_list("kugelblitz"); - - writer.write_float("x", start_position.x); - writer.write_float("y", start_position.y); - - writer.end_list("kugelblitz"); + physic.set_velocity_y(300); + physic.set_velocity_x(-20); //fall a little to the left + direction = 1; + dying = false; } void -Kugelblitz::activate() +Kugelblitz::collision_solid(const CollisionHit& chit) { - physic.set_velocity_y(-300); + hit(chit); } HitResponse -Kugelblitz::collision_solid(GameObject& , const CollisionHit& chit) +Kugelblitz::collision_player(Player& player, const CollisionHit& ) { - return hit(chit); + if(player.is_invincible()) { + explode(); + return ABORT_MOVE; + } + // hit from above? + if(player.get_movement().y - get_movement().y > 0 && player.get_bbox().p2.y < + (get_bbox().p1.y + get_bbox().p2.y) / 2) { + // if it's not is it possible to squish us, then this will hurt + if(!collision_squished(player)) + player.kill(false); + explode(); + return FORCE_MOVE; + } + player.kill(false); + explode(); + return FORCE_MOVE; } HitResponse Kugelblitz::collision_badguy(BadGuy& other , const CollisionHit& chit) { + //Let the Kugelblitz explode, too? The problem with that is that + //two Kugelblitzes would cancel each other out on contact... other.kill_fall(); return hit(chit); } HitResponse -Kugelblitz::hit(const CollisionHit& chit) +Kugelblitz::hit(const CollisionHit& hit) { // hit floor? - if(chit.normal.y < -.5) { + if(hit.bottom) { if (!groundhit_pos_set) { pos_groundhit = get_pos(); groundhit_pos_set = true; } - bbox.set_size(63.8, 63.8); sprite->set_action("flying"); physic.set_velocity_y(0); - physic.set_velocity_x(100); + //Set random initial speed and direction + direction = systemRandom.rand(2)? 1: -1; + int speed = (BASE_SPEED + (systemRandom.rand(RAND_SPEED))) * direction; + physic.set_velocity_x(speed); + movement_timer.start(MOVETIME); + lifetime.start(LIFETIME); - } else if(chit.normal.y < .5) { // bumped on roof + } else if(hit.top) { // bumped on roof physic.set_velocity_y(0); } @@ -91,7 +121,94 @@ Kugelblitz::hit(const CollisionHit& chit) void Kugelblitz::active_update(float elapsed_time) { + if (lifetime.check()) { + explode(); + } + else { + if (groundhit_pos_set) { + if (movement_timer.check()) { + if (direction == 1) direction = -1; else direction = 1; + int speed = (BASE_SPEED + (systemRandom.rand(RAND_SPEED))) * direction; + physic.set_velocity_x(speed); + movement_timer.start(MOVETIME); + } + } + /* + if (Sector::current()->solids->get_tile_at(get_pos())->getAttributes() == 16) { + //HIT WATER + Sector::current()->add_object(new Electrifier(75,1421,1.5)); + Sector::current()->add_object(new Electrifier(76,1422,1.5)); + explode(); + } + if (Sector::current()->solids->get_tile_at(get_pos())->getAttributes() == 48) { + //HIT ELECTRIFIED WATER + explode(); + } + */ + } BadGuy::active_update(elapsed_time); } -IMPLEMENT_FACTORY(Kugelblitz, "kugelblitz") +void +Kugelblitz::kill_fall() +{ +} + +void +Kugelblitz::explode() +{ + if (!dying) { + sprite->set_action("pop"); + lifetime.start(0.2f); + dying = true; + } + else remove_me(); +} + +void +Kugelblitz::try_activate() +{ + //FIXME: Don't activate Kugelblitz before it's on-screen + float scroll_x = Sector::current()->camera->get_translation().x; + float scroll_y = Sector::current()->camera->get_translation().y; + + /* Activate badguys if they're just around the screen to avoid + * the effect of having badguys suddenly popping up from nowhere. + */ + if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE && + start_position.x < scroll_x - bbox.get_width() && + start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE && + start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) { + dir = RIGHT; + set_state(STATE_ACTIVE); + activate(); + } else if (start_position.x > scroll_x && + start_position.x < scroll_x + X_OFFSCREEN_DISTANCE && + start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE && + start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) { + dir = LEFT; + set_state(STATE_ACTIVE); + activate(); + } else if (start_position.x > scroll_x - X_OFFSCREEN_DISTANCE && + start_position.x < scroll_x + X_OFFSCREEN_DISTANCE && + ((start_position.y > scroll_y && + start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) || + (start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE && + start_position.y < scroll_y))) { + dir = start_position.x < scroll_x ? RIGHT : LEFT; + set_state(STATE_ACTIVE); + activate(); + } else if(state == STATE_INIT + && start_position.x > scroll_x - X_OFFSCREEN_DISTANCE + && start_position.x < scroll_x + X_OFFSCREEN_DISTANCE + && start_position.y > scroll_y - Y_OFFSCREEN_DISTANCE + && start_position.y < scroll_y + Y_OFFSCREEN_DISTANCE) { + dir = LEFT; + set_state(STATE_ACTIVE); + activate(); + } +} + +IMPLEMENT_FACTORY(Kugelblitz, "kugelblitz"); + +/* EOF */